On Thu, Feb 24, 2022 at 02:14:55PM +0000, Laura Smith wrote: > Thanks David for your comprehesive reply. It looks like perhaps the match > trick is the cleanest way.
BTW, IMO the descriptin and example in the man page of pf.conf is more clear than the FAQ. -Otto > > > ------- Original Message ------- > > On Thursday, February 24th, 2022 at 11:27, David Gwynne <da...@gwynne.id.au> > wrote: > > > On Wed, Feb 23, 2022 at 04:55:05PM +0000, Laura Smith wrote: > > > > > I've never had occasion to use bi-nat before and I'm struggling a little > > > to wrap my head around the concept. > > > > > > The OpenBSD FAQ (https://www.openbsd.org/faq/pf/nat.html) gives the > > > following example: > > > > > > "pass on tl0 from $web_serv_int to any binat-to $web_serv_ext" > > > > > > However I'm not clear on how this fits into the overall filtering > > > strategy ? i.e. building logically on the example above, how do I say > > > "only allow inbound bi-nat for ports 80 & 443". > > > > > > The FAQ makes an obscure statement "TCP and UDP ports are never modified > > > with binat-to rules as they are with nat rules.", which I'm guessing is > > > where the answer lies. But I'm not clear what this means in context ? > > > > > > Thanks ! > > > > turns out binat is syntactic sugar, so it can be understood in terms of > > > > nat and rdr rules. let's say 192.0.2.1 is your external ip, 10.0.0.1 > > > > is your internal ip, and em0 is your external interface: > > > > dlg@ix ~$ echo 'pass on em0 inet from 10.0.0.1 to any binat-to 192.0.2.1' | > > pfctl -vnf - > > > > pass out on em0 inet from 10.0.0.1 to any flags S/SA nat-to 192.0.2.1 > > static-port > > > > pass in on em0 inet from any to 192.0.2.1 flags S/SA rdr-to 10.0.0.1 > > > > i read that as any connection to my external ip is forwarded to the > > > > backend, and any connection from my backend server is rewritten to > > > > appear as if it's coming from my external ip. this could be useful if > > > > you've got a small public ip address allocation (eg a /29) from an > > > > ISP and don't want to burn the network and broadcast addresses by > > > > putting them on an actual subnet. you would binat every public IP > > > > to a backend on a private IP instead. id personally use p2p tunnels > > > > from the router to each backend, but maybe MTU/MRU is precious too? > > > > anyway, in terms of policy, restricting this to ports 80 and 443 > > > > looks a bit clumsy: > > > > dlg@ix ~$ echo 'pass on em0 inet from 10.0.0.1 to any port { 80 443 } > > binat-to 192.0.2.1' | pfctl -vnf - > > > > stdin:1: port only applies to tcp/udp > > > > stdin:1: skipping rule due to errors > > > > stdin:1: port only applies to tcp/udp > > > > stdin:1: skipping rule due to errors > > > > stdin:1: port only applies to tcp/udp > > > > stdin:1: skipping rule due to errors > > > > stdin:1: rule expands to no valid combination > > > > stdin:1: port only applies to tcp/udp > > > > stdin:1: skipping rule due to errors > > > > stdin:1: port only applies to tcp/udp > > > > stdin:1: skipping rule due to errors > > > > stdin:1: rule expands to no valid combination > > > > stdin:1: rule expands to no valid combination > > > > dlg@ix ~$ echo 'pass on em0 inet proto tcp from 10.0.0.1 to any port { 80 > > 443 } binat-to 192.0.2.1' | pfctl -vnf - > > > > pass out on em0 inet proto tcp from 10.0.0.1 to any port = 80 flags S/SA > > nat-to 192.0.2.1 static-port > > > > pass in on em0 inet proto tcp from any port = 80 to 192.0.2.1 flags S/SA > > rdr-to 10.0.0.1 > > > > pass in on em0 inet proto tcp from any port = 443 to 192.0.2.1 flags S/SA > > rdr-to 10.0.0.1 > > > > pass out on em0 inet proto tcp from 10.0.0.1 to any port = 443 flags S/SA > > nat-to 192.0.2.1 static-port > > > > pass in on em0 inet proto tcp from any port = 443 to 192.0.2.1 flags S/SA > > rdr-to 10.0.0.1 > > > > yeah. im not sure the pass out rules are that useful in practice. > > > > if you had a default allow policy, then binat could make sense. you'd > > > > have a pass binat rule followed by block rules to filter out the > > > > exceptions to your default policy. > > > > another option could be using match and tags: > > > > dlg@ix ~$ cat /tmp/rules > > > > match on em0 inet from 10.0.0.1 to any binat-to 192.0.2.1 tag backend > > > > pass out on em0 tagged backend > > > > pass in on em0 inet proto tcp to port { 80 443 } tagged backend > > > > dlg@ix ~$ pfctl -vnf /tmp/rules > > > > match out on em0 inet from 10.0.0.1 to any tag backend nat-to 192.0.2.1 > > static-port > > > > match in on em0 inet from any to 192.0.2.1 tag backend rdr-to 10.0.0.1 > > > > pass in on em0 inet proto tcp from any to any port = 80 flags S/SA tagged > > backend > > > > pass in on em0 inet proto tcp from any to any port = 443 flags S/SA tagged > > backend > > > > pass out on em0 all flags S/SA tagged backend > > > > dlg >