From owner-freebsd-pf@FreeBSD.ORG Sun Apr 20 23:53:00 2008 Return-Path: Delivered-To: freebsd-pf@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 517A0106566B for ; Sun, 20 Apr 2008 23:53:00 +0000 (UTC) (envelope-from jay@jcornwall.me.uk) Received: from vps1.jcornwall.me.uk (vps1.jcornwall.me.uk [193.227.111.74]) by mx1.freebsd.org (Postfix) with ESMTP id DF0A78FC15 for ; Sun, 20 Apr 2008 23:52:59 +0000 (UTC) (envelope-from jay@jcornwall.me.uk) Received: from [82.70.152.17] (cobra.home.jcornwall.me.uk [82.70.152.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by vps1.jcornwall.me.uk (Postfix) with ESMTP id 46B0152002F; Mon, 21 Apr 2008 00:53:53 +0100 (BST) Message-ID: <480BD757.5030606@jcornwall.me.uk> Date: Mon, 21 Apr 2008 00:52:55 +0100 From: "Jay L. T. Cornwall" User-Agent: Thunderbird 2.0.0.12 (X11/20080227) MIME-Version: 1.0 To: freebsd-pf@freebsd.org References: <4807E452.4090304@jcornwall.me.uk> <48090340.50200@jcornwall.me.uk> <200804202131.58491.max@love2party.net> In-Reply-To: <200804202131.58491.max@love2party.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: Re: PF + if_bridge + NAT anomaly X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Apr 2008 23:53:00 -0000 Max Laier wrote: > I think what happend in your scenario is that a state was created for > the flow on *IN* bridge0 which would then prevent NAT from happening. > Would you be up to share your complete working setup for future > reference? Sure. Here are my modified sysctls: net.inet.ip.fw.enable=0 net.link.bridge.pfil_bridge=0 net.inet.ip.fw.dyn_keepalive=0 The last one seemed to be necessary to keep persistent connections stable. Even with a very rudimentary PF setup I had SSH and IMAPS sessions dropping like flies until I disabled dyn_keepalive. tcpdump showed the keepalive packets going out, apparently with no reply, then the connection would (rightly) die. Here's the PF script. It's a half-firewall, in that I trust outbound traffic, but I don't foresee any problems modifying it to be completely exclusive. The public address block is masked as XXX.XXX.XXX.XXX. # === Macros === int_if = "vr0" ext_if = "vr1" bridge_if = "bridge0" lan_ips = "{192.168.1.0/24 XXX.XXX.XXX.16/29}" nat_from_ips = "192.168.1.0/24" nat_to_ip = "XXX.XXX.XXX.21" bittorrent_ips = "XXX.XXX.XXX.19" ident_ips = "XXX.XXX.XXX.19" ssh_ips = "{XXX.XXX.XXX.17 XXX.XXX.XXX.18 XXX.XXX.XXX.20}" bittorrent_ports = "6881:6889" # === Tables === table persist # === Options === # Don't filter on loopback. (Not necessary and would collide with # antispoof.) set skip on lo0 # === Scrub === # Clean incoming packets on all interfaces. Scrubbing outbound packets # would be redundant, save for those originating from the firewall # itself. We assume the firewall machine is secure. scrub in all # === Queueing === # === Translation === # NAT through the external interface from a private subnet to a specific # IP bound to the bridge interface. This IP may be an alias. nat on $ext_if from $nat_from_ips to any -> $nat_to_ip # === Filter rules === # Deny inbound traffic only. Assume all outbound traffic is legimitate. block in all # Deny hosts that have been banned for connection overloading. block in quick on $ext_if from # Protect the loopback interface from spoofing. We cannot protect the # bridge interface or it would block NAT. antispoof quick for { lo0 } # Allow free inbound traffic on the LAN interface. We will do all # external-to-LAN filtering on the vr1 interface. pass in quick on $int_if # Maintain outbound state on all interfaces. pass out quick on $int_if pass out quick on $bridge_if pass out quick on $ext_if # Open holes for packets destined for LAN services. This does *not* # cover the bridge itself. pass in quick on $ext_if proto tcp from any to $bittorrent_ips port \ $bittorrent_ports pass in quick on $ext_if proto tcp from any to $ident_ips port auth pass in quick on $ext_if proto tcp from any to $ssh_ips port ssh \ flags S/SA synproxy state \ (max-src-conn-rate 5/20, overload flush global) # The bridge needs its own set of service holes, applying to both # internal and external hosts. pass in quick on $bridge_if proto udp from $lan_ips to any port domain pass in quick on $bridge_if proto tcp from any to any port ssh \ flags S/SA synproxy state \ (max-src-conn-rate 5/20, overload flush global) -- Jay L. T. Cornwall http://www.jcornwall.me.uk/