Note: This is an old article with content which is out of date.

I have a website hosted on a VPS which is protected by Fail2Ban. Thus far I’ve found most would-be attackers quickly move on when their IP addresses have been blocked a few times. Occasionally one of the blighters will persist, hence I use iptables to permanently drop all of the traffic eminating from their IP.

To block an offending IP, using a remote shell, issue the following command:

sudo iptables -A INPUT -s <IPADDRESS> -j DROP

Substitute <IPADDRESS> for the attackers actual IP address. For example, blocking any traffic from, which just happens to be one of Google’s public DNS servers:

sudo iptables -A INPUT -s -j DROP

If you are logged in as a root user, then of course you can ommit “sudo”. Now you might be wondering how the command actually works.


The first part of the command means append our new rule to the “INPUT” chain. A chain is simply a collection of rules. Most distributions I’ve worked with have had, by default, three chains, “INPUT, FORWARD and OUTPUT. Their intended purposes seem fairly self explanatory.


This part of the command is specifying a source address. It can be a network address specified with a mask or a single IP specified without a mask. The mask can be supplied in either IPv4 or CIDR notation.


The final part of the rule is called the jump target. Or in other words, the action iptables should take if a packet matches our rule. The jump target could be various things but in our use case, we are only interested in one of iptables built-in targets called “DROP”. Using this target means that any packets matching our rule will be silently dropped.

So in summary, our example rule will drop any packets with a source IP address of

Persisting your iptables Rules

Depending on your situation, you may or may not make your new iptables rule persist following a reboot. The rule which you’ve just added will not be reloaded into memory following a reboot or a restart of the iptables process because it’s not been stored anywhere other than in memory. To make rule persistence possible, there are some additional steps needed.

The first thing we need to do is save the current iptables rules. This can be achieved with the following command:

iptables-save > /etc/network/iptables.rules

This will create a file in our /etc/network/ folder. You can tweak this location to suit your individual needs/preferences. The second step is ensuring the rules are loaded automatically. Some folk tend to pop this in the rc.local, but my personal preference is with the interfaces definition in /etc/netwrok/interfaces. For example:

auto eth0
iface eth0 inet dhcp
    pre-up iptables-restore < /etc/network/iptables.rules

I’ve written this blog based on experience with Ubuntu Server and Debian. I believe for Redhat/Fedora the process of persisting rules is slightly simpler. Just issue the following command:

service iptables save

This should write a file in /etc/sysconfig that is read automatically when iptables is started.

I believe there’s also a package to facilitate the persistence of iptables rules available in Debian and Ubuntu. If you’re interested, take a peek at