Last week I’ve shown you how to get started with IPtables and create and delete rules. This week I’m going to show you how to save the rules you write. This will ensure the rules you apply are re-applied once you reboot or restart IPtables.
There are some rules which you may not want to persist. For example: if you temporarily block an IP address for guessing passwords, it’s not necessary to keep the block forever. The IP address will probably be used by somebody else later and the attack will stop shortly after you block the IP address anyway.
There are multiple ways to save IPtables rules, I’m going to show the most straight-forward ones for CentOS and Ubuntu.
CentOS: Persistent IPtable Rules
CentOS can automatically load the IPtables configuration from a config file in /etc. This file may or may not exist, depending on how you installed CentOS or which template you have used. Therefore I’m going to assume an empty file.
Open up /etc/sysconfig/iptables, make sure it is empty and add the following lines to it:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
I’ll explain what these lines mean first, then we’ll move on to adding a persistent rule.
*filter
This means we’re talking about the filter table and not any of the other ones.
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
Here we set the default policy for every chain. As you can see, it’s ACCEPT. You can also change this to DROP, but I only advise you to do that after adding enough ACCEPT rules so your server remains available.
[0:0]
The two zeroes for each rule above are the packet and byte counts for the policy for that chain. Once your chain accepts a packet, it increases that number with 1 for the packet and the number of bytes of the packet. When you reboot or restart IPtables, these are now reset to 0. If you want to save the packet and byte counts, well, read on. I’ll get to that later.
COMMIT
This is the last line in the file and always should be. This commits the configuration above and “actives” it.
Any rules you may want to add, should be added between the following lines:
:OUTPUT ACCEPT [0:0]
-> ADD YOUR RULES HERE
COMMIT
So, for example, if we wanted to drop all TCP traffic to port 8080, this is what the file would look like:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp –destination-port 8080 -j DROP
COMMIT
As you can see, I added the following rule without prefixing it with the ‘sudo iptables’ commands like you do on the command line.
sudo iptables -A INPUT -p tcp –destination-port 8080 -j DROP
If you now save the file and restart IPtables, the rule should still be there. So, try it out (unless you have something important on port 8080) and run ‘iptables -L’. You should see something like this:
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp — anywhere anywhere tcp dpt:webcacheChain FORWARD (policy ACCEPT)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
As you can see, all TCP traffic going to port 8080 is dropped. IPtables translates known ports to their purpose and uses that as a label, which in this case is ‘webcache’:
tcp dpt:webcache
So, that’s it! You can now persist IPtables rules!
Ubuntu: Persistent IPtable Rules
On Ubuntu, a package is required which will ensure similar behavior as on CentOS. Install the package ‘iptables-persistent’. Answer both questions with ‘Yes’ and don’t be put off by the error message at the end.
sudo apt-get install iptables-persistent
The package skips an error-check which makes the installer return an error. The package is still installed, though. To fix the error and complete the installation without any errors, run the following commands:
sudo sed \
-i ‘s/\(modprobe -q ip6\?table_filter\)/\1 || true/g’ \
/var/lib/dpkg/info/iptables-persistent.postinst; \
sudo apt-get install iptables-persistent
This will add the error check and install iptables-persistent again. You’re now good to go.
With this package installed, IPtables rules are automatically loaded upon boot.
Open up /etc/iptables/rules.v4, make sure it is empty and add the following lines to it:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
I’ll explain what these lines mean first, then we’ll move on to adding a persistent rule.
*filter
This means we’re talking about the filter table and not any of the other ones.
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
Here we set the default policy for every chain. As you can see, it’s ACCEPT. You can also change this to DROP, but I only advise you to do that after adding enough ACCEPT rules so your server remains available.
[0:0]
The two zeroes for each rule above are the packet and byte counts for the policy for that chain. Once your chain accepts a packet, it increases that number with 1 for the packet and the number of bytes of the packet. When you reboot or restart IPtables, these are now reset to 0. If you want to save the packet and byte counts, well, read on. I’ll get to that later.
COMMIT
This is the last line in the file and always should be. This commits the configuration above and “actives” it.
Any rules you may want to add, should be added between the following lines:
:OUTPUT ACCEPT [0:0]
-> ADD YOUR RULES HERE
COMMIT
So, for example, if we wanted to drop all TCP traffic to port 8080, this is what the file would look like:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp –destination-port 8080 -j DROP
COMMIT
As you can see, I added the following rule without prefixing it with the ‘sudo iptables’ commands like you do on the command line.
sudo iptables -A INPUT -p tcp –destination-port 8080 -j DROP
If you now save the file and restart IPtables, the rule should still be there. So, try it out (unless you have something important on port 8080) and run ‘iptables -L’. You should see something like this:
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp — anywhere anywhere tcp dpt:http-altChain FORWARD (policy ACCEPT)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
As you can see, all TCP traffic going to port 8080 is dropped. IPtables translates known ports to their purpose and uses that as a label, which in this case is ‘http-alt’ (Ubuntu and CentOS differ on this):
tcp dpt:http-alt
So, that’s it! You can now persist IPtables rules!
How to saving existing IPtables rules
What if you’ve set up your IPtables on the CLI or maybe added some ad-hoc rules you’d like to persist? Well, there’s an option to save that with a single command. This command also saves the packet and byte count and may include the chains of other tables, but it could potentially save you time.
Let’s give this a try and add the following rule:
sudo iptables -A INPUT -p tcp –destination-port 9090 -j DROP
Now, let’s persist this rule.
CentOS
On CentOS, run:
sudo /etc/init.d/iptables save
This should output something like this:
[mpkossen@host ~]$ sudo /etc/init.d/iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
[mpkossen@host ~]$
That’s it! IPtables saved! Including the rule we’ve just added. Check it out in /etc/sysconfig/iptables.
Ubuntu
On Ubuntu, the persistent-iptables package takes care of saving.
Run:
sudo /etc/init.d/iptables-persistent save
Which should output the following:
mpkossen@host:~$ sudo /etc/init.d/iptables-persistent save
* Saving rules…
* IPv4…
* IPv6… [OK]
mpkossen@host:~$
If you now open up /etc/iptables/rules.v4, you should see the following content:
# Generated by iptables-save v1.4.12 on Tue Aug 13 00:23:49 2013
*nat
:PREROUTING ACCEPT [5509:341010]
:POSTROUTING ACCEPT [3807:261429]
:OUTPUT ACCEPT [3807:261429]
COMMIT
# Completed on Tue Aug 13 00:23:49 2013
# Generated by iptables-save v1.4.12 on Tue Aug 13 00:23:49 2013
*mangle
:PREROUTING ACCEPT [147327:16511117]
:INPUT ACCEPT [147327:16511117]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [151091:20832369]
:POSTROUTING ACCEPT [151091:20832369]
COMMIT
# Completed on Tue Aug 13 00:23:49 2013
# Generated by iptables-save v1.4.12 on Tue Aug 13 00:23:49 2013
*filter
:INPUT ACCEPT [1:44]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:40]
-A INPUT -p tcp -m tcp –dport 8080 -j DROP
-A INPUT -p tcp -m tcp –dport 9090 -j DROP
COMMIT
# Completed on Tue Aug 13 00:23:49 2013
It isn’t more complicated than that!
Final notes on persistent rules for IPtables
As a final note, I would like to explain the rule(s) we’ve added:
sudo iptables -A INPUT -p tcp -m tcp –dport 9090 -j DROP
We’re blocking a specific port for a specific protocol here. The protocol (-p) flag is required in order to block a port, in this case we’ve chosen ‘tcp’, but ‘udp’ or ‘all’ are examples of other options. With -m (match extensions) the extension is loaded that enables port blocking. In this case, it’s the TCP extension. There’s a lot of others as well. We’ve blocked traffic to a _destination_ port (–dport), which is the port where the traffic is headed. We can also block traffic originating from certain source ports (–sport).
That’s it for this week! Enjoy IPtables!
Related Posts:
- How to Rapidly Install Java, OpenJDK & Oracle JDK on your VPS - December 14, 2015
- It’s been a great ride - December 14, 2015
- Cheap Windows VPS – $21/quarter 1GB KVM-based Windows VPS in 11 worldwide locations - November 30, 2015
there’s save command in centos’ iptables init.d script.
Yes, you are right. Thanks for pointing that out. My CentOS box is currently giving grieve to me when I run this command, but I will amend the guide once I get it fixed.
OpenVZ hosting owners, learn and teach others! Avoid confusing..
Another great tutorial by Maarten Kossen. Kudos!
Thanks, Radi!!
I’ve always just used the iptables-save/iptables-restore commands directly in Ubuntu, as per http://askubuntu.com/a/119398/150985
iptables-persistent apparently just wraps those two commands into an easy package. Thanks, I might start using it.
Good tutorial and bookmarked it, thanks!
It’s a good intro, I’d highly recommend using the built in tools to manage your rules through. Modifying the rules manually is dancing with danger.
I have come up with a quick intro to iptables on CentOS here: https://www.thriftydevil.com.au/technology/using-iptables-on-centos-6 (ignore the out of date certifiate… I’ll get round to that one day)
… This might be more appropriate for anyone else not using a Debian based OS.
Nice tutorial you’ve written up there. Good resource for people getting started with iptables on CentOS 6.