Spamhaus‘ DROP (Don’t Route Or Peer) and EDROP lists are sets of IPs controlled by bad people. Basically IPs that are very likely going to cause trouble so might as well block them completely. Details.
The following script will load a pf table with these networks. It will get drop.txt and, if uncommented, edrop.txt, cut the comments, compare to the existing list, if different flush the table and add the new blocks, then kill all existing connections to bad IPs.
Should probably be run once per day, do not run it more often than once per hour or you’ll be banned. OpenBSD doesn’t have fetch, so I’m using ftp, but ftp works fine on FreeBSD too, so no need to change that.
pf.conf should contain lines similar to these:
table <spamhaus_drop> persist block drop log quick from <spamhaus_drop> to any block drop log quick from any to <spamhaus_drop> |
spamdrop.sh:
#!/bin/sh ##### # it will fetch drop.txt and edrop.txt from spamhaus.org and add the IPs # to pf's table $TABLE # # in pf.conf: # table <spamhaus_drop> persist # block drop log quick from <spamhaus_drop> to any # block drop log quick from any to <spamhaus_drop> ##### WORKDIR="/tmp" # where to put temporary files TABLE="spamhaus_drop" # name of the table in pf.conf STDOUT="/dev/null" # /dev/null to suppress messages, /dev/stdout to see them if [[ ! -d $WORKDIR ]]; then echo "$WORKDIR doesn't exist, abandoning" exit 1 fi # check if table is really used pfctl -s rules | grep $TABLE > $STDOUT if [[ $? > 0 ]]; then echo "WARNINIG: seems like $TABLE has no rules associated with it in pf.conf" fi cd $WORKDIR # get drop.txt, prepare drop.work for pfctl ftp http://www.spamhaus.org/drop/drop.txt > $STDOUT if [[ $? != 0 ]]; then echo "ERROR: failed fetching drop.txt, abandoning" exit 1 fi sed 's/\;.*$// ; s/\ // ; /^$/d' drop.txt > drop.work # Get edrop.txt too, uncomment this section if you want it #ftp http://www.spamhaus.org/drop/edrop.txt > $STDOUT #if [[ $? != 0 ]]; then # echo "ERROR: failed fetching edrop.txt, abandoning" # rm drop.txt # exit 1 #fi #sed 's/\;.*$// ; s/\ // ; /^$/d' edrop.txt >> drop.work # final file will need to be sorted by IP for comparing it with pf's table sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n drop.work > drop.temp mv drop.temp drop.work # compare drop.work with the table, replace table if different pfctl -t $TABLE -T show | sed s/\ *// > spamhaus.work diff drop.work spamhaus.work > /dev/null if [[ $? = 0 ]]; then # uncoment if you want cron reports #echo "pf's $TABLE table didn't change since last update" rm -f drop.txt edrop.txt drop.work spamhaus.work # cleanup exit 0 fi # flush the table pfctl -t $TABLE -T flush > $STDOUT # load the new drop list pfctl -f drop.work -t $TABLE -T add > $STDOUT # kill all existing connections to IPs in the list DEATHLIST=`pfctl -t $TABLE -T show` for i in $DEATHLIST; do pfctl -k $i 2>&1 | grep -v "killed 0 states from 1 sources and 0 destinations" > $STDOUT done # uncomment if you want cron reports #echo "pf's $TABLE table updated" rm -f drop.txt edrop.txt drop.work spamhaus.work # cleanup exit 0 |
The way it is, it will NOT fetch edrop.txt and it will be silent if successful. Uncomment the respective lines if you want this behaviour changed.
To add it to OpenBSD’s daily run create or edit daily.local to something like:
#!/bin/sh /etc/netconf/spamdrop.sh |
Mind the permissions on daily.local, it should be o-rwx.