LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

IPtables Persistent Rules

lowendtutorial

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:webcache

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain 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-alt

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain 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!

mpkossen

9 Comments

  1. there’s save command in centos’ iptables init.d script.

    August 13, 2013 @ 1:10 pm | Reply
    • Maarten Kossen:

      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.

      August 13, 2013 @ 2:19 pm | Reply
  2. Lucas:

    OpenVZ hosting owners, learn and teach others! Avoid confusing..

    August 13, 2013 @ 7:05 pm | Reply
  3. Another great tutorial by Maarten Kossen. Kudos!

    August 14, 2013 @ 6:26 am | Reply
    • Maarten Kossen:

      Thanks, Radi!!

      August 19, 2013 @ 4:27 am | Reply
  4. Bob:

    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.

    August 14, 2013 @ 2:55 pm | Reply
  5. Good tutorial and bookmarked it, thanks!

    August 15, 2013 @ 1:02 pm | Reply
  6. 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.

    August 17, 2013 @ 10:52 am | Reply
    • Maarten Kossen:

      Nice tutorial you’ve written up there. Good resource for people getting started with iptables on CentOS 6.

      August 19, 2013 @ 4:30 am | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *