The Correct Way to Lock Out an IP Address From Your Server

I’ve been getting something like a one-person DoS attack overnight, it seems — a single IP address hitting port 80 hundreds of times a minute, generating endless 404s, and chewing up noticeable bandwidth — so I had to add a rule to my iptables to block the IP address at fault. Here’s how to do it:

First, list your current iptable rules, with line numbers, for easy reference:

$ sudo iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
3    REJECT     all  --  0.0.0.0/0            127.0.0.0/8         reject-with icmp-port-unreachable 
4    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:25 
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:587 

etc...

Add a new rule to block the offending IP address (“xxx.yyy.zzz.www”).

$ sudo iptables -I INPUT 1 -s xxx.yyy.zzz.www -j DROP

This will insert the new rule at position 1, just prior to the rule that accepts TCP incoming traffic on port 22 for SSH and passes it to fail2ban.

Save the updated table and restart the service.

$ sudo service iptables save
$ sudo service iptables restart
$ sudo iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    DROP       all  --  200.85.152.75        0.0.0.0/0           
2    fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    REJECT     all  --  0.0.0.0/0            127.0.0.0/8         reject-with icmp-port-unreachable 
5    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:25 
7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:587 

etc...

Some suggestions for doing this that turn up on Google have used the “-A” (Add) flag rather than the “-I” (Insert) flag. This will not work in most cases, it would add the new rule to the end of the INPUT chain, after the rule that accepts (for instance) HTTP packets. If the banned IP address were attempting to access port 80, if would be ACCEPTed by that rule before it could get DROPped by the new rule.

The position of the rule is important: if it follows a rule which would accept the traffic otherwise, the new rule will have no effect. Placing it before the rules for general public traffic ensures that the annoyance in question can’t consume resources by trying to do things like load non-existent web pages. In fact, by checking first, the IP address is effectively firewalled from the server.

Leave a Reply

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