Use ipset and iptables to block traffic

Print Friendly, PDF & Email

Source: – 445352

Here’s how you can block traffic coming from an IP, list of IPs, full networks or even entire countries. This is done under a Debian 7 x86 server so adapt the commands to your distro of choice…

1 – Install ipset, for commands reference check

apt-get install ipset

2 – Setup your sets, sets are basically lists in which you’ll add all the IP or IP networks to it, in this case I’m creating a list to support IP Networks (x.x.x.x/yy form). If you need to create a set to support individual IPs use the hash:ip option.

#Create 3 lists, 2 to support networks and 1 to support single IP addresses
#hash:net = Networks
#hash:ip = single IPs
# Command is ipset -N setname [set options], but I'm using default
# options here
ipset -N china hash:net
ipset -N some-country  hash:net
ipset -N badguys hash:ip
# Now we list the just created sets with:
ipset -L

3 – Setup the rules in iptables, this is how I do it, I create a new chain called blocked_traffic, I add a single rule to DROP everything on that chain (so everything that ends up in that chain will be dropped) then I add some JUMP rules to the INPUT chain so everything that match my sets (created by ipset) will automatically JUMP to the chain blocked_traffic and die…

#1 Create the chain and add the DROP rule to ip
iptables -N blocked_traffic
iptables -A blocked_traffic -j DROP
#2 Create the rules in the INPUT chain to check for traffic comming
# from the ipset sets
iptables -A INPUT -m set --match-set china src -j blocked_traffic
iptables -A INPUT -m set --match-set some-country src -j blocked_traffic
iptables -A INPUT -m set --match-set badguys src -j blocked_traffic
# these last 3 rules will send everything that matches the sets created by ip# set to the blocked_traffic chain.

the reason I send them to another chain and then I drop them is because you may want to do something latter with that traffic, perhaps pass that traffic to another interface or whatever you’d like to do otherwise you could just go iptables -A INPUT -m set –match-set china src -j DROP but I like using extra chains as I may find a good use for that traffic at some point you never know…

4 – Right now nothing is being blocked as nothing match the ipset rules, of course we haven’t put any networks or IPs there! let’s add some spammers or port scanners to those lists…

#We create a text file with the spammers ip addresses
# these will be public addresses mostly I'm just using private ones for
# simplicity sake

##Add individual IPs
touch /home/user/spammers.txt
echo >> /home/user/spammers.txt
echo >> /home/user/spammers.txt

## Add networks
touch /home/user/networks.txt
echo >> /home/user/networks.txt
echo >> /home/user/networks.txt

## Now we use those txt files to update our sets
For i in $(cat /home/user/spammers.txt ); do ipset -A badguys $i; done
For i in $(cat /home/user/networks.txt ); do ipset -A china $i; done

##Now let's check our lists with:
ipset -L

5 – Saving the config, as of now you’re blocking the traffic with those lists and everything works perfectly fine but if you decide to reboot your server all those rules will be gone! ipset doesn’t save the config automatically  so you have to restore it (much alike iptables-restore). Another tricky part is that ipset needs to start and restore the config BEFORE iptables otherwise iptables will fail to restore its config as those rules will not exist until ipset restore its bits. Just add the restore command for ipset to whatever script you use to restore iptables but before iptables-restore.

##Saving the ipset sets and ip/networks to a file
ipset save > /etc/ipset_config.file
##Save iptables rules
iptables-save > /etc/iptables.up.rules
##I use the /etc/network/interfaces file to restore my iptables
## I add the post-up rules to it in this order
post-up ipset restore < /etc/ipset_config.file
post-up iptables-restore < /etc/iptables.up.rules
# so when you restart the machine and the interface comes up it'll
# execure the ipset restore followed by the iptables restore
# that way all the sets will be there and iptables won't fail to restore.

Done! now you have multiple ip and networks blocked from your server…

useful link to check ip blocks

Related Post