IPTables gotcha

Device name with negation

IPTables will happily create a rule for an interface with a name that starts with an exclamation mark like !docker0. But if you want to match traffic on any interface except docker0, then you must put the exclamation mark before the option and not before the name. So ! -o docker0 instead of -o !docker0.

This is documented in the manual but it's an easy mistake to make and it cost me a bunch of time today!

Wrong:

iptables -t nat -A POSTROUTING -o !docker0 -j MASQUERADE

Right:

iptables -t nat -A POSTROUTING ! -o docker0 -j MASQUERADE

Note both these rules will appear exactly the same when listing the rules:

$ iptables -t nat -A POSTROUTING -o \!docker0 -j MASQUERADE
$ iptables -t nat -A POSTROUTING \! -o docker0 -j MASQUERADE
$ iptables -vt nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any !docker0 anywhere anywhere
0 0 MASQUERADE all -- any !docker0 anywhere anywhere

🗣 Comments

I manually review comments so it may take a while for your comment to get published.