nftables stateless NAT in raw table mangles fragmented UDP packets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi

We have using kernel 5.10 and nftables(0.9.8-3.1) from debian for a
stateless NAT GW. We are using the nftables "raw" tables to replace
statically source and destination addresses for pakets traversing the
host with two nftables map, without any connection tracking. The bug is
also reproducible in a Debian 5.16 kernel from experimental.

If fragmented UDP packets are traversing the gateway the second fragment
gets modified at the location where in a non fragmented packet the UDP
checksum would be located.

On the Sample below the packet content at 0x1a-0x1b was changes from
0x61 0x61 to 0xba 0x9e 


This is a minimized version of the ruleset which expedites the bug:

nft list ruleset

table ip raw {
    map M_publicip_in {
        type ipv4_addr : ipv4_addr
        elements = { 100.64.1.1 : 10.1.2.3 }

    }

    map M_publicip_out {
        type ipv4_addr : ipv4_addr
        elements = { 10.1.2.3 : 100.64.1.1 }
    }

    chain PREROUTING {
        type filter hook prerouting priority -300; policy accept;

        jump publicip_out
        jump publicip_in
    }

    chain publicip_out {
        ip saddr set ip saddr map @M_publicip_out accept
    }

    chain publicip_in {
        ip daddr set ip daddr map @M_publicip_in accept
    }
}


This is a fragmented udp packet before NAT:

root@debian:~# tcpdump -l  -i eth0 -nvvvx
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length
262144 bytes
21:50:15.314671 IP (tos 0x0, ttl 64, id 3756, offset 0, flags [+], proto
UDP (17), length 1500)
    10.2.1.1.45866 > 100.64.1.1.9999: UDP, length 2013
    0x0000:  4500 05dc 0eac 2000 4011 d621 0a02 0101
    0x0010:  6440 0101 b32a 270f 07e5 0016 4865 6c6c
    0x0020:  6f2c 2057 6f72 6c64 2161 6161 6161 6161
    0x0030:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0040:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0050:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0060:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0070:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0080:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0090:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0100:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0110:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0120:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0130:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0140:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0150:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0160:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0170:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0180:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0190:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0200:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0210:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0220:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0230:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0240:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0250:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0260:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0270:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0280:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0290:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0300:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0310:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0320:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0330:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0340:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0350:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0360:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0370:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0380:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0390:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0400:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0410:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0420:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0430:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0440:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0450:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0460:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0470:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0480:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0490:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0500:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0510:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0520:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0530:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0540:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0550:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0560:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0570:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0580:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0590:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05d0:  6161 6161 6161 6161 6161 6161
21:50:15.314687 IP (tos 0x0, ttl 64, id 3756, offset 1480, flags [none],
proto UDP (17), length 561)
    10.2.1.1 > 100.64.1.1: ip-proto-17
    0x0000:  4500 0231 0eac 00b9 4011 f913 0a02 0101
    0x0010:  6440 0101 6161 6161 6161 6161 6161 6161
    0x0020:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0030:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0040:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0050:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0060:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0070:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0080:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0090:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0100:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0110:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0120:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0130:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0140:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0150:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0160:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0170:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0180:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0190:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0200:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0210:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0220:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0230:  61


This is a fragmented udp packet after NAT. See the second fragment at
offset 0x1a and compare it with the previous example

21:49:32.999088 IP (tos 0x0, ttl 63, id 87, offset 0, flags [+], proto
UDP (17), length 1500)
    10.2.1.1.46549 > 10.1.2.3.9999: UDP, length 2013
    0x0000:  4500 05dc 0057 2000 3f11 3eb4 0a02 0101
    0x0010:  0a01 0203 b5d5 270f 07e5 56a8 4865 6c6c
    0x0020:  6f2c 2057 6f72 6c64 2161 6161 6161 6161
    0x0030:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0040:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0050:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0060:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0070:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0080:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0090:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0100:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0110:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0120:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0130:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0140:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0150:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0160:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0170:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0180:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0190:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0200:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0210:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0220:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0230:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0240:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0250:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0260:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0270:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0280:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0290:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x02f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0300:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0310:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0320:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0330:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0340:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0350:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0360:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0370:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0380:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0390:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x03f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0400:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0410:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0420:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0430:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0440:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0450:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0460:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0470:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0480:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0490:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x04f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0500:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0510:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0520:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0530:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0540:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0550:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0560:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0570:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0580:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0590:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x05d0:  6161 6161 6161 6161 6161 6161
21:49:32.999096 IP (tos 0x0, ttl 63, id 87, offset 1480, flags [none],
proto UDP (17), length 561)
    10.2.1.1 > 10.1.2.3: ip-proto-17
    0x0000:  4500 0231 0057 00b9 3f11 61a6 0a02 0101
    0x0010:  0a01 0203 6161 6161 6161 ba9e 6161 6161
    0x0020:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0030:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0040:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0050:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0060:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0070:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0080:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0090:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x00f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0100:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0110:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0120:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0130:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0140:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0150:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0160:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0170:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0180:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0190:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01a0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01b0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01c0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01d0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01e0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x01f0:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0200:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0210:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0220:  6161 6161 6161 6161 6161 6161 6161 6161
    0x0230:  61


The behaviour could be reproduced using the VM with a freshly installed
debian bullseye and the following script. The script setups two
different  Network namespaces which are used for reproducing the bug.
(On our prodcution Setup no NNS are used)


#!/bin/bash

# ============================================================
# setup nns test
# here traffic for ip 100.64.1.1 will be rewritten to 10.1.2.3
ip netns add test
ip link add eth1 type veth
ip link set dev veth0 netns test name eth0

ip link set dev eth1 up
ip address add 10.2.1.1/30 dev eth1

ip netns exec test ip link set dev eth0 up
ip netns exec test ip address add 10.2.1.2/30 dev eth0

ip route add 100.64.1.1/32 via 10.2.1.2

# Load nftables rules for stateless nat
ip netns exec test /usr/sbin/nft -f test.nft


# ============================================================
# setup nns test2
# here the ip adress 10.1.2.3 is bound
ip netns add test2
ip netns exec test2 ip link add eth0 type veth
ip netns exec test2 ip link set dev veth0 netns test name eth1
ip netns exec test2 ip link set dev eth0 up
ip netns exec test2 ip address add 10.1.2.3/28 dev eth0

ip netns exec test ip link set dev eth1 up
ip netns exec test ip address add 10.1.2.1/28 dev eth1


# =================
# Enable forwarding
# =================
/sbin/sysctl net.ipv4.conf.all.forwarding=1
ip netns exec test /sbin/sysctl net.ipv4.conf.all.forwarding=1
ip netns exec test2 /sbin/sysctl net.ipv4.conf.all.forwarding=1


The following python script is used to send  fragmented UDP frames from
the root NNS to the test NNS


#!env python3
import socket

byte_message = bytes("Hello, World!" + "a"*2000, "utf-8")

opened_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
opened_socket.sendto(byte_message, ("100.64.1.1", 9999))








[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux