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
> 

Reply via email to