The other day I was looking for a method of filtering IP packets with a certain hex payload pattern between a veth-pair on a Linux bridge. Fortunately, it turns out that
iptables has this matching string module extension, i.e.,
--match string --algo [kmp | bm] --hex-string [pattern].
Basically, the requirement was to allow only IPv4 or IPv6 packets forwarded on this Linux bridge that had the payload pattern
0xdeadc0de. Other packets at L3, being forwarded on this bridge, should be dropped. The bridge and the veth-pair interfaces are represented in Figure 1.
As far IPv4 packets, these rules will do the trick, where
$1 is the argument
I had to insert these rules in the beginning of the
FORWARD chain since this host running this Linux bridge already had other rules in place.
Now, for IPv6 packets it can get a bit tricky since at Layer 3, ICMPv6 can’t be totally filtered out, otherwise neighbor resolution wouldn’t work. Turns out, this python application, which is generating traffic with the hex
0xdeadc0de payload was not using any other type of ICMPv6 message, so it was acceptable to allow only this hex pattern and ICMPv6 messages type 135 (neighbor solicitation) and 136 (neighbor advertisement):
Now let’s run some tests to make sure it’s filtering properly. I’ll test four traffic flows:
- IPv4 with
- IPv4 with a different payload, e.g.,
- IPv6 with
- IPv6 with a different payload e.g.,
No packets have been accepted yet. The drop counter had incremented because of other random traffic present in this network:
Now, after four IPv4 packets sent with
0xdeadc0de, you can double check the first counters, they were forwarded:
To just blow up the drop counter, I’ll generate 1000 IPv4 packets with
0xdeadcafe, as you can see the drop counter on
dveth0-end2 incremented by more than 1000, still only the previous 4 packets were forwarded:
Similarly to the previous tests with IPv4, let’s start with four IPv6 packets with
Neighbor advertisement and neighbor solicitation packets were forwarded too. Now, let’s generate 1000 IPv6 packets with
0xdeadcafe, as you can see, there was an increase of more than 1000 in the drop counter:
Awesome! The filtering in place is working at the kernel level, filtering at layer 3 as expected.