What is the canonical way to store iptables rules

iptables, the standard Linux firewall, does not save rules between reboots. You have to take care of this yourself. There are many ways to do this. What is the canonical way to do this? What are best practices?

I'll answer with my own solution, but I'm interested in other / better solutions.


Here are some example rules. Save them to /etc/iptables.rules

# Generated by iptables-save v1.3.6 on Wed Oct 24 17:07:29 2007
*filter
:INPUT ACCEPT [89458:132056082]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [263904:15667452]
-A INPUT -i lo -j ACCEPT 
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 
-A INPUT -j DROP 
COMMIT
# Completed on Wed Oct 24 17:07:29 2007

add this line at the end of /etc/network/interfaces

pre-up iptables-restore < /etc/iptables.rules

We use alot of iptables rules, so in order to ease administration we do the following:

  • Rules are all called from scripts - scripts are called from /etc/init.d/firewall (custom script)
  • A file of server names / network names (ip address variables) is kept, and included in every iptables script for consistency.
  • separate scripts are kept for each subnet (ie. private / DMZ / VPN, etc) to make things easier to find. Rules that belong in 2 scripts (such as those restricting communication b/w private and DMZ) are put in the more "secure" network's script
  • wherever possible, loops and nested loops are used to keep the scripts as short as possible.
  • every new rule or change is documented with comments preceding the appropriate section of the script.

I don't know if this is the best way to do this, but it has worked well for us.