Date: Mon, 21 Apr 2008 00:52:55 +0100 From: "Jay L. T. Cornwall" <jay@jcornwall.me.uk> To: freebsd-pf@freebsd.org Subject: Re: PF + if_bridge + NAT anomaly Message-ID: <480BD757.5030606@jcornwall.me.uk> In-Reply-To: <200804202131.58491.max@love2party.net> References: <4807E452.4090304@jcornwall.me.uk> <48090340.50200@jcornwall.me.uk> <200804202131.58491.max@love2party.net>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <ssh-bruteforce> 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 <ssh-bruteforce> # 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 <ssh-bruteforce> 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 <ssh-bruteforce> flush global) -- Jay L. T. Cornwall http://www.jcornwall.me.uk/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?480BD757.5030606>