Thursday, July 04, 2024

Re: Packet filter can't NAT devices 2 hops away?

On 2024-07-03, jrmu <jrmu@ircnow.org> wrote:
>
> When I run $ ping 1.1.1.1 from R2, packets are successfully NAT'd to the
> public IP address, and ping works.
>
> However, when I run $ ping 1.1.1.1 from any other node (R3, R4, or R5), the
> packets are sent to R1 but not properly NAT'd. Here is what I see when I run
> tcpdump on the egress interface:
>
> host# tcpdump -ne -i em1 'host 1.1.1.1'
> tcpdump: listening on em1, link-type EN10MB
> 14:34:25.531207 00:25:90:5a:2d:92 ac:1f:6b:fe:ca:98 0800 98: 10.5.3.1 > 1.1.1.1: icmp: echo request
> 14:34:26.549336 00:25:90:5a:2d:92 ac:1f:6b:fe:ca:98 0800 98: 10.5.3.1 > 1.1.1.1: icmp: echo request
> 14:34:27.549307 00:25:90:5a:2d:92 ac:1f:6b:fe:ca:98 0800 98: 10.5.3.1 > 1.1.1.1: icmp: echo request
> 14:34:28.549275 00:25:90:5a:2d:92 ac:1f:6b:fe:ca:98 0800 98: 10.5.3.1 > 1.1.1.1: icmp: echo request
>
> The ping from node R5 is properly routed to R1, and is being sent out the
> egress interface, but for some reason, R1 is not properly performing NAT. NAT
> seems only to work for devices directly connected to R1.

NAT certainly works on packets coming from multiple hops away.

Check your pf rules carefully. And check your routing/bridging config
carefully, this setup with loads of veb and whatever vports certainly
makes things more complicated. Do you actually need it, what are you
trying to achieve with it? Simplify if you can. As far as I'm concerned
ridging on pf boxes would be a special case that I'd try to avoid unless
there's no alternative.

Standard PF diagnosis tools are to add "log" to various rules, or add
"match log(matches)" to the top of the ruleset, and tcpdump -nei pflog0,
but N.B. due to a bug in (iirc) 7.3 to 7.5 the rule numbers printed by
tcpdump will be wrong if you have any anchors in the ruleset - that's
fixed in -current.

> At R1, I have this packet filter rule to perform NAT on packets going to the
> Internet:
>
> match out on egress from !(egress:network) to any nat-to (egress:0)

This line by itself doesn't help much, the position of the match rule
(and of course any "set skip") can make a difference.

For simplicity and performance I'd also suggest:

- avoid "from !(egress:network)", there aren't many places where this
is really useful. listing the specific prefix or prefixes that you want
to nat (10.0.0.0/8 might work for you) is simpler to debug and avoids an
extra couple of lookups for each newly created state.

- avoid "nat-to (egress:0)" if possible (only needed for a dynamic
address) and use a specific address instead.


--
Please keep replies on the mailing list.

No comments:

Post a Comment