Bug #4639
closedNAT fails to correctly translate udp port numbers embedded in certain ICMP error packets
0%
Description
I think I found a bug in the NAT of the packet filter, but I am not sure. My
setup is as follows.
client (linux)
|
| bridge0, mtu=1500
|
pfsense 2.2.2 (FreeBSD 10.1-RELEASE-p9)
|
| pppoe0, mtu=1492
|
internet
On the client, I run the following command:
- nping --udp 8.8.8.8 -g 10000 -p 20000 --data-length 1472 --df
This generates five UDP packets of IP length 1500, set the do not fragment
option, and send them from source port 10000 to destination port 20000. I have
verified by packet capture that this really happens.
As the mtu of the pppoe link is 1492, the packets cannot reach their
destination, so pfsense generates "ICMP fragmentation needed" error packets. I
expect five such packets, and I indeed receive five, but the first one (!)
seems to be corrupted, as I will now explain.
I run the following command (with following output) on pfsense:
- pfctl
s state | grep 1000010.0.0.101:10000 NO_TRAFFIC:SINGLE
bridge0 udp 8.8.8.8:20000 <
pppoe0 udp 84.112.84.112:59518 (10.0.0.101:10000) -> 8.8.8.8:20000 SINGLE:NO_TRAFFIC
Each of the five ICMP packets should have embedded the header of the respective
offending 1500-byte packet. The NAT should appropriately map the port numbers.
However, the first packet receieved from the client has source port 59518
(the untranslated one) in the UDP header embedded in the ICMP packet.
The other four ICMP packets are fine (source port 10000, which is the correct,
translated, value).
Note that this only happens for ICMP error packets originating at the pfsense
router itself. ICMP error packets of the same type but from a router in the
public internet are always translated correctly (all five!) before being
forwarded to the client.
Updated by Daniel Haid over 9 years ago
I have now tried to reproduce this on a pure FreeBSD 10.1 installation, but everything seems to be working correctly there. All packets are received with the translated source port.
Updated by Daniel Haid over 9 years ago
I found the pf-rule that causes the problem:
pass out route-to ( pppoe0 2.2.2.2 ) from 1.1.1.1 to !1.1.1.1/32 tracker 1000004861 keep state allow-opts label "let out anything from firewall host itself"
Strangely enough, removing this rule makes the errant NAT behaviour go away. As a workaround I have now temporarily commented out the corresponding block in /etc/inc/filter.inc. Everything seems to work even without this rule.
What is the purpose of this rule? Why are locally generated packet ever routed at all?
Updated by Chris Buechler over 9 years ago
- Category set to Operating System
- Assignee set to Chris Buechler
The route-to is for multi-WAN purposes. It sounds like it has some impact on things in this case. I'll see if I can replicate.
Updated by Chris Buechler over 8 years ago
- Status changed from New to Feedback
- Target version set to 2.3.2
I believe this is the issue in FreeBSD PR 201519.
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=201519
Luiz imported the fixes for that into 2.3.2.
Daniel: could you please try the latest 2.3.2 snapshot from snapshots.pfsense.org to help confirm?
Updated by Chris Buechler over 8 years ago
- Status changed from Feedback to Resolved
Pretty sure this overlaps with PR 201519, which is confirmed fixed.
Daniel: if you're still seeing issues on 2.3.2, please follow up.