Iptables u32 matching nat


I'm currently setting up IPtables to redirect certain UDP payloads to my application.

Here is an example of what I have working so far:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x54536F75 && 0>>22&0x3C@16=0x72636520 && 0>>22&0x3C@20=0x456E6769 && 0>>22&0x3C@24=0x6E652051 && 0>>22&0x3C@28=0x75657279' -j REDIRECT --to-port 21015

This is working, it will redirect packets containing the payload:


from one port to my application on another.

The problem is, I have another piece of data I wish to redirect, but it's not the same all the time. The packet looks like this:


However, the packet can also sometimes look like this:


I've tried something such as this:

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32  '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12=0x55' -j REDIRECT --to-port 21015

I'm guessing the problem is something to-do with me trying to match 2 bytes rather than the 4 as normal? The above doesn't error but it also doesn't redirect the packets.

asked on Server Fault Jun 19, 2016 by Xulu

1 Answer


That would be at your convenience (in one line, but I had to display it like this to have bold working):

iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12>>24=0x55' -j REDIRECT --to-port 21015


iptables -t nat -I PREROUTING -p udp -d {IPDST} --dport 27055 -m u32 --u32 '0>>22&0x3C@8=0xFFFFFFFF && 0>>22&0x3C@12&0xFF000000=0x55000000' -j REDIRECT --to-port 21015

In both cases you remove from the equation the part you don't want to compare, either by shifting 3 bytes to the right and keeping only the 1st one, or by using a mask that will keep in the equation only the 1st byte. The second one is more flexible.

There's an example in man iptables-extensions similar to the 1st choice:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0"


This is the first 4 bytes of the ICMP payload, of which byte 0 is the ICMP type. Therefore, we simply shift the value 24 to the right to throw out all but the first byte and compare the result with 0.

Also note that since it's the nat table, if the source port doesn't change, only the first UDP packet will be considered. After this conntrack will handle the flow and your rule won't see the other packets. So if each packet is independent, make sure the source port changes, and you might have to use the nfct tool along with a -j CT --timeout rule to shorten conntrack's "memory" and avoid filling its tables.

answered on Server Fault Nov 27, 2016 by A.B • edited Nov 28, 2016 by A.B

User contributions licensed under CC BY-SA 3.0