iptables rule in pf

Ermal Luçi ermal.luci at gmail.com
Thu May 8 16:41:30 UTC 2008


On Thu, May 8, 2008 at 1:58 PM, Daniel Roethlisberger <daniel at roe.ch> wrote:
> CZUCZY Gergely <gergely.czuczy at harmless.hu> 2008-05-08:
>> On Thu, 08 May 2008 11:36:26 +0300 Oleksandr Samoylyk
>> <oleksandr at samoylyk.sumy.ua> wrote:
>> > >> That iptables rule worked for any destination.
>> > > You cannot rewrite a packet's destination address to _any_
>> > > destination.
>> > >
>> > > It's like you cannot submit a package at the post office with the
>> > > destination address "any". It's just meaningless.
>> >
>> > However it works with iptables. :)
>> >
>> > What can I do in my situation in order to gain the same
>> > functionality by means of pf or other additional daemons?
>> No, it doesn't. That iptables rule only affects the port number, where
>> it defaults to the original dst address. So it defaults to something,
>> where as pf doesn't. With pf you have to explicitly specify the
>> rewritten dst IP.
>>
>> In my first reply I've told you to read the openbsd FAQ. You haven't
>> done it. I _strongly_ suggest you, before doing your next reply to the
>> list. go and read that FAQ. Here's the URL once more, I bet you've
>> lost it under your desk...  http://www.openbsd.org/faq/pf/
>
> Netfilter allows to rewrite the destination port without rewriting the
> destination address.  It would seem like that this is not possible with
> pf, at least not using rdr.  But it is not necessary, since
> my.smtp.server is the only destination on port 25 that will not be
> dropped by the previous rule, so you can just specify my.smtp.server as
> destination in the rdr rule.
>
> Just in case this is about submitting mail around port 25 filters (in
> contrast to a fixed MTA-MTA "tunnel" on port 2525), you probably want to
> use SMTP AUTH on the submission port (587) to solve this problem, not
> just provide plain SMTP on a different port.  On the submission port,
> authentication is mandatory, which prevents it being used by spambots to
> deliver mail directly to your MTA.  Using submission and blocking port
> 25 for end-user address ranges does have anti-spam benefits.
>
> --
> Daniel Roethlisberger
> http://daniel.roe.ch/
> _______________________________________________
> freebsd-pf at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-pf
> To unsubscribe, send any mail to "freebsd-pf-unsubscribe at freebsd.org"
>

How about this patch.
I have not really tested it but should do just port rewriting with a rule as

rdr on $int proto tcp from any to any port 255 -> port 25 any

Ermal

Index: contrib/pf/pfctl/parse.y
===================================================================
RCS file: /home/ncvs/src/contrib/pf/pfctl/parse.y,v
retrieving revision 1.8
diff -u -r1.8 parse.y
--- contrib/pf/pfctl/parse.y	3 Jul 2007 12:30:02 -0000	1.8
+++ contrib/pf/pfctl/parse.y	8 May 2008 16:33:30 -0000
@@ -3326,6 +3326,12 @@
 			$$->host = $2;
 			$$->rport.a = $$->rport.b = $$->rport.t = 0;
 		}
+		| ARROW PORT rport {
+			$$ = calloc(1, sizeof(struct redirection));
+                        if ($$ == NULL)
+                                err(1, "redirection: calloc");
+                        $$->rport = $4;
+		}
 		| ARROW redirspec PORT rport	{
 			$$ = calloc(1, sizeof(struct redirection));
 			if ($$ == NULL)
@@ -3442,6 +3448,13 @@
 			pool_opts.marker |= POM_STICKYADDRESS;
 			pool_opts.opts |= PF_POOL_STICKYADDR;
 		}
+		| ANY {
+			if (pool_opts.type) {
+                                yyerror("pool type cannot be redefined");
+                                YYERROR;
+                        }
+                        pool_opts.type = PF_POOL_ANY;
+		}
 		;

 redirection	: /* empty */			{ $$ = NULL; }
@@ -3549,6 +3562,10 @@
 					YYERROR;
 				}
 			} else {
+				r.rpool.opts = $10.type;
+				if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
+                                    PF_POOL_ANY) {
+
 				if ($9 == NULL || $9->host == NULL) {
 					yyerror("translation rule requires '-> "
 					    "address'");
@@ -3562,6 +3579,14 @@
 					YYERROR;
 				if (check_netmask($9->host, r.af))
 					YYERROR;
+				}
+
+				if ((r.rpool.opts & PF_POOL_TYPEMASK) ==
+                                    PF_POOL_ANY && r.action != PF_RDR) {
+					yyerror("any pool type valid only for rdr"
+                                            " action");
+                                        YYERROR;
+                                }

 				r.rpool.proxy_port[0] = ntohs($9->rport.a);

@@ -3596,7 +3621,6 @@
 					break;
 				}

-				r.rpool.opts = $10.type;
 				if ((r.rpool.opts & PF_POOL_TYPEMASK) ==
 				    PF_POOL_NONE && ($9->host->next != NULL ||
 				    $9->host->addr.type == PF_ADDR_TABLE ||
@@ -3614,7 +3638,7 @@
 				    "is only supported in round-robin "
 				    "redirection pools"))
 					YYERROR;
-				if ($9->host->next != NULL) {
+				if ($9 != NULL && $9->host != NULL && $9->host->next != NULL) {
 					if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
 					    PF_POOL_ROUNDROBIN) {
 						yyerror("only round-robin "
Index: sys/contrib/pf/net/pf.c
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pf.c,v
retrieving revision 1.46.2.1
diff -u -r1.46.2.1 pf.c
--- sys/contrib/pf/net/pf.c	25 Nov 2007 19:26:46 -0000	1.46.2.1
+++ sys/contrib/pf/net/pf.c	8 May 2008 16:33:31 -0000
@@ -2859,13 +2859,18 @@
 			}
 			break;
 		case PF_RDR: {
-			if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
-				return (NULL);
-			if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
-			    PF_POOL_BITMASK)
-				PF_POOLMASK(naddr, naddr,
-				    &r->rpool.cur->addr.v.a.mask, daddr,
-				    pd->af);
+			 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
+                            PF_POOL_ANY) {
+				PF_ACPY(naddr, daddr, pd->af);
+			} else {
+				if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
+                                        return (NULL);
+				if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
+			    		PF_POOL_BITMASK)
+					PF_POOLMASK(naddr, naddr,
+				    		&r->rpool.cur->addr.v.a.mask, daddr,
+				    		pd->af);
+			}

 			if (r->rpool.proxy_port[1]) {
 				u_int32_t	tmp_nport;
Index: sys/contrib/pf/net/pfvar.h
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pfvar.h,v
retrieving revision 1.16.2.1
diff -u -r1.16.2.1 pfvar.h
--- sys/contrib/pf/net/pfvar.h	12 Apr 2008 18:26:48 -0000	1.16.2.1
+++ sys/contrib/pf/net/pfvar.h	8 May 2008 16:33:31 -0000
@@ -130,7 +130,7 @@
 	  PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
 #define PF_POOL_IDMASK		0x0f
 enum	{ PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
-	  PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
+	  PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN, PF_POOL_ANY };
 enum	{ PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
 	  PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED };
 #define PF_POOL_TYPEMASK	0x0f


More information about the freebsd-pf mailing list