Thursday, February 24, 2022

Re: PF bi-nat

Thanks David for your comprehesive reply. It looks like perhaps the match trick is the cleanest way.


------- Original Message -------

On Thursday, February 24th, 2022 at 11:27, David Gwynne <david@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

No comments:

Post a Comment