I got to thinking about something the other day when I rebuilt my webserver using Debian 5.0. How does Debian/Ubuntu standardize on reloading the iptables rules at boot time?
I know that Red Hat and its variants use the /etc/sysconfig/iptables file as a save and restore point, and there is an init script, iptables, that starts at boot prior to the network script, but is there a similar standard on Debian/Ubuntu?
The solution I’ve come up with (and I’m very curious to hear what others have done) is the following:
First, I manually enter my base iptables rules…
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 17.88.115.150/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 111.70.51.51/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 16.10.111.177/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-host-unreachable
...etc, etc.
*(ip addresses have been scrambled to protect their identity) 🙂
I then run:
iptables-save > /etc/default/iptables
From this point forward I manually update my ruleset by editing the file directly with a text editor.
To reload these rules at boot-time I have added a line to my /etc/network/interfaces configuration as follows:
auto eth0
iface eth0 inet static
address foo
netmask bar
gateway baz
dns-search domain.tld
dns-nameservers foo
pre-up iptables-restore < /etc/default/iptables
That last line tells the machine that, before you activate these network settings, run iptables-restore and read from the file /etc/default/iptables. This seems to work well enough so far, but I’m still curious what others have done. Do you simply write an init script on your own and maintain the ruleset within that file? Do you use a file similar to what I’ve done, but source it via an init script? I’m curious, as there does not seem to be a standard that I’m aware of.
I used iptables-save and iptables-restore too, but I made an init script instead of hacking around in /etc/network/interfaces. Felt much cleaner somehow. Settings file went to /etc instead of /etc/default.
(I can’t seem to do OpenID from livejournal… I click Yes on their site and get shown a HTTP authentication window from your site…)
I use a short script in /etc/network/if-up.d which contains other scripts such as reloading OpenSSH so it can bind to the new address, running ntpdate, etc.
$ cat /etc/network/if-up.d/iptables
iptables-restore < /etc/iptables.up.rules
The only gotcha I can think of with doing it in /etc/network/interfaces is that you are tying the ruleset to a specific interface. If that interface doesn’t come up for some reason, the iptables rules don’t get loaded.
It is too bad that iptables-save doesn’t have options to save the rules by interface, such that we could save global rules, and load them when lo starts, and interface specific rules that could be loaded with each interface.
As things stand, I would probably have the pre-up bound to lo, rather than eth0.
I’m using ufw on my boxes and it seems to take care of that on it’s own, storing the rules in /var/lib/ufw/user.rules. However your solution seems fairly solid to me.
I actually liked the Redhat init script that much that I just copied to my Ubuntu install and made come changes from there.
It just saves the tables to /etc/iptables/config now.
I just use something like shorewall… way easier to maintain in the long run.
It’s worth remembering with the proliferation of Xen based Virtual Hosting, that /etc/network/interfaces seems to be commonly replaced at bootup.
You’re probably safer to stick this in
/etc/network/if-up.d
With the new Upstart init system, I just create a new file, /etc/event.d/iptables :
# Script to start firewall
# Save rules with iptables-save > /etc/default/iptables
start on runlevel 1
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
exec /sbin/iptables-restore < /etc/default/iptables
That way, you aren’t changing any existing files, just adding the new one. On every reboot, the iptables rules get loaded. You can check that they are loaded with:
sudo /sbin/iptables-save | less
I’m using /etc/rc.local. The script of iptables I save in some file, and then loaded in rc.local
–budiw
I do the rc.local as well.
Got to love Google and the Debian community. Thank you for helping me to decide which way is best for this very task.
I use Firewall Builder to create my rules (God I love that program) and save the rules into defaults as per the way you advise. However, I’m with Adam on using a script in if-up.d to restore, it just makes more sense to me personally.
Great advice from all, however.
/Tig