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