Created Saturday 14 January 2017
IPset is a companion application to IPtables. It'll allow you to quickly block IP-addresses. We will use it to block out known IPs (blocklists) - like Tor exit notes.
Installation
$ pacman -S ipset
# Then enable the service
$ systemctl enable ipset.service
Usage
#IPset is used by creating a set, then adding IPs to that set and binding it with the IPtable rules
# To create a new set
$ ipset create myset hash:net
# Then add any IP you like blocked to that set (ex)
$ ipset add myset 14.144.0.0/12
$ ipset add myset 27.8.0.0/13
$ ipset add myset 58.16.0.0/15
# To make IPtables DROP the IPs provided by IPset, create a rule
$ iptables -I INPUT -m set --match-set myset src -j DROP
# These blocked IPs are not persistent. To make them persistent, save them in a ipset.conf
$ sudo zsh -c "ipset save > /etc/ipset.conf"
Commands
# To view the set
$ ipset list
# To delete the set named myset
$ ipset destroy myset
# To delete all sets
$ ipset destroy
Blocklist
# pg2ipset is a tool that takes content from the PG2 IP Blocklist, and blocks those IPs with ipset
$ yaourt -S pg2ipset-git
# This also requires you to have the wget package installed
$ pacman -S wget
#To update the IP list daily, create a Cron job - see more in Additional System Tools
# First, save this script - ex ~/dotfiles/scripts/ipset-update.sh
#!/bin/bash # ipset-update.sh (C) 2012-2015 Matt Parnell http://www.mattparnell.com # Licensed under the GNU-GPLv2+ # place to keep our cached blocklists LISTDIR="/var/cache/blocklists" # create cache directory for our lists if it isn't there [ ! -d $LISTDIR ] && mkdir $LISTDIR # countries to block, must be lcase COUNTRIES=(af ae ir iq tr cn sa sy ru ua hk id kz kw ly) # bluetack lists to use - they now obfuscate these so get them from # https://www.iblocklist.com/lists.php BLUETACKALIAS=(DShield Bogon Hijacked DROP ForumSpam WebExploit Ads Proxies BadSpiders CruzIT Zeus Palevo Malicious Malcode Adservers) BLUETACK=(xpbqleszmajjesnzddhv lujdnbasfaaixitgmxpp usrcshglbiilevmyfhse zbdlwrqkabxbcppvrnos ficutxiwawokxlcyoeye ghlzqtqxnzctvvajwwag dgxtneitpuvgqqcpfulq xoebmbyexwuiogmbyprb mcvxsnihddgutbjfbghy czvaehmjpsnwwttrdoyl ynkdjqsjyfmilsgbogqf erqajhwrxiuvjxqrrwfj npkuuhuxcsllnhoamkvm pbqcylkejciyhmwttify zhogegszwduurnvsyhdf) # ports to block tor users from PORTS=(80 443 6667 22 21) # remove old countries list [ -f $LISTDIR/countries.txt ] && rm $LISTDIR/countries.txt # remove the old tor node list [ -f $LISTDIR/tor.txt ] && rm $LISTDIR/tor.txt # enable bluetack lists? ENABLE_BLUETACK=1 # enable country blocks? ENABLE_COUNTRY=1 # enable tor blocks? ENABLE_TORBLOCK=1 #cache a copy of the iptables rules IPTABLES=$(iptables-save) importList(){ if [ -f $LISTDIR/$1.txt ] || [ -f $LISTDIR/$1.gz ]; then echo "Importing $1 blocks..." ipset create -exist $1 hash:net maxelem 4294967295 ipset create -exist $1-TMP hash:net maxelem 4294967295 ipset flush $1-TMP &> /dev/null #the second param determines if we need to use zcat or not if [ $2 = 1 ]; then zcat $LISTDIR/$1.gz | grep -v \# | grep -v ^$ | grep -v 127\.0\.0 | pg2ipset - - $1-TMP | ipset restore else awk '!x[$0]++' $LISTDIR/$1.txt | grep -v \# | grep -v ^$ | grep -v 127\.0\.0 | sed -e "s/^/add\ \-exist\ $1\-TMP\ /" | ipset restore fi ipset swap $1 $1-TMP &> /dev/null ipset destroy $1-TMP &> /dev/null # only create if the iptables rules don't already exist if ! echo $IPTABLES|grep -q "\-A\ INPUT\ \-m\ set\ \-\-match\-set\ $1\ src\ \-\j\ DROP"; then iptables -A INPUT -m set --match-set $1 src -j ULOG --ulog-prefix "Blocked input $1" iptables -A FORWARD -m set --match-set $1 src -j ULOG --ulog-prefix "Blocked fwd $1" iptables -A FORWARD -m set --match-set $1 dst -j ULOG --ulog-prefix "Blocked fwd $1" iptables -A OUTPUT -m set --match-set $1 dst -j ULOG --ulog-prefix "Blocked out $1" iptables -A INPUT -m set --match-set $1 src -j DROP iptables -A FORWARD -m set --match-set $1 src -j DROP iptables -A FORWARD -m set --match-set $1 dst -j REJECT iptables -A OUTPUT -m set --match-set $1 dst -j REJECT fi else echo "List $1.txt does not exist." fi } if [ $ENABLE_BLUETACK = 1 ]; then # get, parse, and import the bluetack lists # they are special in that they are gz compressed and require # pg2ipset to be inserted i=0 for list in ${BLUETACK[@]}; do if [ eval $(wget --quiet -O /tmp/${BLUETACKALIAS[i]}.gz http://list.iblocklist.com/?list=$list&fileformat=p2p&archiveformat=gz) ]; then mv /tmp/${BLUETACKALIAS[i]}.gz $LISTDIR/${BLUETACKALIAS[i]}.gz else echo "Using cached list for ${BLUETACKALIAS[i]}." fi echo "Importing bluetack list ${BLUETACKALIAS[i]}..." importList ${BLUETACKALIAS[i]} 1 i=$((i+1)) done fi if [ $ENABLE_COUNTRY = 1 ]; then # get the country lists and cat them into a single file for country in ${COUNTRIES[@]}; do if [ eval $(wget --quiet -O /tmp/$country.txt http://www.ipdeny.com/ipblocks/data/countries/$country.zone) ]; then cat /tmp/$country.txt >> $LISTDIR/countries.txt rm /tmp/$country.txt fi done importList "countries" 0 fi if [ $ENABLE_TORBLOCK = 1 ]; then # get the tor lists and cat them into a single file for ip in $(ip -4 -o addr | awk '!/^[0-9]*: ?lo|link\/ether/ {gsub("/", " "); print $4}'); do for port in ${PORTS[@]}; do if [ eval $(wget --quiet -O /tmp/$port.txt https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=$ip&port=$port) ]; then cat /tmp/$port.txt >> $LISTDIR/tor.txt rm /tmp/$port.txt fi done done importList "tor" 0 fi
# Make the file executable
$ chmod o+x ~/dotfiles/scripts/ipset-update.sh
# Then create the Cron job to run the script on a daily basis
$ sudo crontab -e
# And insert
0 0 * * * sh /home/stick/dotfiles/scripts/ipset-update.sh >/dev/null 2>&1