Simple Iptables Blacklist

firewallAnyone that has run a server for any length of time quickly learns that the Internet is full of spammers, bots and other characters you would prefer didn’t exist. A firewall is key to keeping these guys out and Linux comes with a Kernel level firewall called iptables that can be employed for this purpose. The only downside of iptables is that people who don’t deal with it on a regular basis tend to find its syntax a little bit daunting.

In this post I am going to run you through the process of setting up a basic firewall IP blacklist. Using a bash script to read an blacklist of IP addresses and feeding these to iptables so they can no longer access your server.

First up create decide where you would like the script to live. for this example I am just going to put it in /root/scripts. i.e

mkdir /root/scripts

nano firewall.sh

Then copy in the following shell code into the file and save.

[codesyntax lang=”bash” lines=”normal”]

#!/bin/bash
# ---------------------------
_input=/root/scripts/blocked_ips.txt
_pub_if="eth0"
IPT=/sbin/iptables
 
[ ! -f "$_input" ] && { echo "$0: File $_input not found."; exit 1; }
 
# Unlimited lo access
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
 
### Setup our black list ###
$IPT -N droplist
 
# Filter out comments and blank lines
# store each ip or subnet in $ip
egrep -v "^#|^$" x | while IFS= read -r ip
do
        # Append everything to droplist
	$IPT -A droplist -i ${_pub_if} -s $ip -j LOG --log-prefix "IP found on blacklist"
	$IPT -A droplist -i ${_pub_if} -s $ip -j DROP
done <"${_input}"
 
# Finally, insert or append our black list 
$IPT -I INPUT -j droplist
$IPT -I OUTPUT -j droplist
$IPT -I FORWARD -j droplist

[/codesyntax]

Now you simply need to create a file to store the blocked IP addresses, for the purposes of this example I am calling mine mine blocked_ips.txt. But you can call your blacklist whatever you would like just be sure to change the file set as _input on line 3 of the script.

Into your blacklist file simply add each individual IP addresses or address range in CIDR format on a new line then save e.g

220.33.0.123
37.187.71.0/24
27.16.0.0/12
27.128.0.0/15

No simply run the firewall.sh script to create the iptables rules to block these hosts. To check the rules are in place type the command:

iptables –list

This should show display rules similar to:

Chain droplist (3 references)
target     prot opt source               destination         
LOG        all  —  37.187.71.0/24       anywhere             LOG level warning prefix “IP found on blacklist”
DROP       all  —  37.187.71.0/24       anywhere            
LOG        all  —  27.16.0.0/12         anywhere             LOG level warning prefix “IP found on blacklist”
DROP       all  —  27.16.0.0/12         anywhere            

With time you will also be able to see lines in your machines syslog showing hosts blocked by the firewall:

Jun 14 16:51:35 mx10292 kernel: [305613.135767] IP found on blacklistIN=eth0 OUT= MAC=56:2d:a2:c3:88:78:90:e2:ba:6d:fd:92:08:00 SRC=183.60.212.157 DST=112.63.21.142 LEN=60 TOS=0x00 PREC=0x00 TTL=42 ID=55301 DF PROTO=TCP SPT=47473 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0

This approach will give you a quick and dirty firewall, but be forewarned the rules will not persist after a reboot. To make the rules persist after a reboot I recommend you install the iptables-persistent package. To use simply install

apt-get update
apt-get install iptables-persistent

Then hit yes when it asks if you would like to save the currently active rules. If you choose to use the iptables-persistent package when you update your blacklist be sure to flush the current rules, run the firewall script then use the iptables-save command so the rules are updated and persist i.e

iptables –flush
/root/scripts/firewall.sh
iptables-save > /etc/iptables/rules.v4

Related Posts:

Video tutorial showing the creation of simple iptables rules

Blocking VocusPR spam with iptables

Further Reading:

Netfilter homepage