Is it possible to write a nftables rule that filters on byte value(s) at an offset in a UDP payload? I am able to do so using netfilter queue in userspace, but wondering if there's an expression that can be used in an actual rule.
Asked
Active
Viewed 2,337 times
1 Answers
1
Yes you can do this using nftables raw payloads, as long as its in fixed locations (you won't get the variable position features of iptables' string match, nor all of iptables' u32 match features, but not its complexity either, especially easier with TCP packets having TCP options). Actually you can even alter it with a recent enough kernel (>= 4.10). Of course size can't change.
Example: when receiving UDP destination port 5555 packets, replace, if found in data offsets 3-5, the 3 bytes 0x66 0x6F 0x6F ("foo") with the 3 bytes in data offsets 0-2 in the same packet. Values are in bits rather than bytes, and UDP data is 64 bits after UDP header (@th), hence position 64+3*8=88, size 3*8=24 to replace with position 64 size 24:
# nft add table inet myfilter
# nft add chain inet myfilter myinputmangle '{ type filter hook input priority 0; policy accept; }'
# nft add rule inet myfilter myinputmangle udp dport 5555 @th,88,24 0x666f6f @th,88,24 set @th,64,24

A.B
- 11,090
- 2
- 24
- 45
-
I am trying a similar approach to alter the vlan id but cannot get it working with @ll. Do you happen to have an example using @ll? Thanks – mhristache Jul 07 '20 at 17:47
-
@mhristache the vlan ID is available at layer 2, but inet is starting at layer 3. to have a chance to alter the vlan ID, you must use the bridge family or the netdev family. You should also check if you can do this without nftables at all: using vlan sub-interfaces and/or bridge functionalities (including vlan aware bridge). – A.B Jul 13 '20 at 14:14
-
Yes, I am trying with bridge family. I can successfully match the vlan id and e.g. drop the corresponding packets but it does not work to change the vlan id. With older versions of nftables (the version that comes with Ubuntu 18.04) it actually adds a new vlan tag on top of the existing one. With the latest version of nftables (built from master) if does not do any change. So it looks like a limitation. As a workaround, I am now adding a vlan aware bridge in between, as you also suggested. – mhristache Jul 13 '20 at 20:34
-
The third command always leads to this error (I use ubuntu 18.04 LTS with a 5.4 kernel and nft 0.8.2): `Error: conflicting protocols specified: udp vs. unknown add rule inet myfilter myinputmangle udp dport 5555 @th,88,24 0x666f6f @th,88,24 set @th,64,24` – Kevin Meier Oct 22 '20 at 11:08
-
I've solved my problem by using nft 0.9.3 – Kevin Meier Oct 22 '20 at 12:05