O'Reilly logo

Linux Server Hacks by Rob Flickenger

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Hack #49. Using Custom Chains in iptables

Keep your firewall rules under control with custom chains

By default, the iptables filter table consists of three chains: INPUT, FORWARD, and OUTPUT. You can add as many custom chains as you like to help simplify managing large rule sets. Custom chains behave just as built-in chains, introducing logic that must be passed before the ultimate fate of a packet is determined.

To create a new chain, use the -N switch:

root@mouse:~# iptables -N fun-filter

You can see which chains are defined at any time with the standard -L switch:

root@mouse:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination 

Chain FORWARD (policy ACCEPT)
target prot opt source destination 

Chain OUTPUT (policy ACCEPT)
target prot opt source destination 

Chain fun-filter (0 references)
target prot opt source destination

In order to make use of your custom chain, you'll have to jump to it from somewhere. Let's add a jump to the fun-filter chain we've just created straight from the INPUT chain:

root@mouse:~# iptables -t filter -A INPUT -j fun-filter

Now your custom chain can grow to any sort of complexity you like. For example, you may want to match packets based on the source MAC address:

root@mouse:~# iptables -A fun-filter -m mac  -- mac-source 11:22:33:aa:bb:cc \
  -j ACCEPT
root@mouse:~# iptables -A fun-filter -m mac  -- mac-source de:ad:be:ef:00:42 \
  -j ACCEPT
root@mouse:~# iptables -A fun-filter -m mac  -- mac-source 00:22:44:fa:ca:de
  -j REJECT  -- reject-with icmp-host-unreachable
root@mouse:~# iptables -A fun-filter -j RETURN

The RETURN jump at the end of the table makes processing resume back in the chain that called this one (in this case, back in the INPUT chain). Again, show what all of your tables look like with the -L switch:

root@mouse:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination 
fun-filter all -- anywhere anywhere 

Chain FORWARD (policy ACCEPT)
target prot opt source destination 

Chain OUTPUT (policy ACCEPT)
target prot opt source destination 

Chain fun-filter (0 references)
target prot opt source destination 
ACCEPT all -- anywhere anywhere MAC 11:22:33:AA:BB:CC 
ACCEPT all -- anywhere anywhere MAC DE:AD:BE:EF:00:42 
REJECT all -- anywhere anywhere MAC 00:22:44:FA:CA:DE reject-with icmp-host-
unreachable 
RETURN all -- anywhere anywhere

You can jump into any number of custom defined chains and even jump between them. This helps to isolate rules that you're developing from the standard system policy rules, and enable and disable them easily. If you want to stop using your custom chain temporarily, you can simply delete the jump from the INPUT chain (rather than flushing the entire custom chain):

root@mouse:~# iptables -t filter -D INPUT -j fun-filter

If you decide to delete your custom chain, use -X:

root@mouse:~# iptables -X fun-filter

Note that there can be no references to your custom chain if you try to delete it; use -F to flush the chain first if there are still rules referring to your chain.

When properly managed, even the most complex iptables rulesets can be easily read, if you use intuitively named custom chains.

See also:

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required