Can DROP be used on other operating systems?
Can DROP be used on other operating systems?
For those who use PC routers, here’s a little Perl script to turn the CIDR blocks in the DROP list into Unix route commands. Different versions of route have slightly different syntax, so you need to pick the one that works with your version. Some versions of route take CIDR notation, others require netmasks, so un-comment the one that works for you. (Note the obvious perl one-liner to turn a bit number into a dotted quad.)
To make day-to-day changes, use -o oldfile where oldfile is the previous version, and it’ll give you just route delete and route add for the changes. This script is set up to fetch the current list and update once a day, which is frequent enough for nearly all networks, given the slow day-to-day churn and very conservative listing policy of the DROP list.
Please DO NOT auto-fetch the DROP list more than once per hour!
These are all old, but still useful. Use at your own discretion!
<br /><br /><br />
#!/usr/bin/perl<br /><br /><br />
# -*- perl -*-</p><br /><br />
<p>use Getopt::Std;<br /><br /><br />
use strict;<br /><br /><br />
use vars qw{%nets $n $m $opt_o};</p><br /><br />
<p>getopts(‘o:’);</p><br /><br />
<p>while(<>) {<br /><br /><br />
if(($n, $m) = m{(\d+\.\d+\.\d+\.\d+)/(\d+)}) {<br /><br /><br />
# local sanity check<br /><br /><br />
die “local network $n” if $n =~ /^127.|^208.31./;</p><br /><br />
<p> $nets{$n} = $m;<br /><br /><br />
} else {<br /><br /><br />
print “#??? $_\n”;<br /><br /><br />
}<br /><br /><br />
}</p><br /><br />
<p># do old thing here sometime<br /><br /><br />
if($opt_o) {<br /><br /><br />
open(OLD, $opt_o) or die “Cannot open $opt_o $!”;</p><br /><br />
<p> while(<OLD>) {<br /><br /><br />
if(($n, $m) = m{(\d+\.\d+\.\d+\.\d+)/(\d+)}) {<br /><br /><br />
my $mask = join ‘.’,unpack “CCCC”, pack “N”, -1<<(32-$m);</p><br /><br />
<p> if(exists $nets{$n} and $nets{$n} == $m) {<br /><br /><br />
print “# exists route add -net $n/$m\n”;<br /><br /><br />
delete $nets{$n};<br /><br /><br />
} else {<br /><br /><br />
#print “route delete -net $n -netmask $mask\n”;<br /><br /><br />
print “route delete -net $n/$m\n”;<br /><br /><br />
}<br /><br /><br />
} else {<br /><br /><br />
print “#??? $_\n”;<br /><br /><br />
}<br /><br /><br />
}<br /><br /><br />
close OLD;<br /><br /><br />
}</p><br /><br />
<p>while(($n, $m) = each %nets) {<br /><br /><br />
my $mask = join ‘.’,unpack “CCCC”, pack “N”, -1<<(32-$m);</p><br /><br />
<p> #print “route add -net $n -netmask $m 127.1 -blackhole # m\n”;<br /><br /><br />
print “route add -net $n/$m 127.1 -blackhole\n”;</p><br /><br />
<p>}<br /><br /><br />
Here’s the code for using DROP in Linux firewalls:
<br /><br /><br />
#!/bin/bash</p><br /><br />
<p>#Script to add firewall rules to a linux system to completely block<br /><br /><br />
#all traffic to and from networks in the spamhaus drop list.</p><br /><br />
<p>#Copyright 2009, William Stearns, wstearns@pobox.com<br /><br /><br />
#Released under the GPL. This and other tools can be found at<br /><br /><br />
#http://www.stearns.org/</p><br /><br />
<p>#Sole (optional) command line parameter is the file location of the<br /><br /><br />
#drop list, such as:</p><br /><br />
<p>#cd /var/lib/<br /><br /><br />
#wget http://www.spamhaus.org/drop/drop.lasso<br /><br /><br />
# ./spamhaus-drop /var/lib/drop.lasso</p><br /><br />
<p>#While the DROP file should be regularly updated, this should<br /><br /><br />
#probably be about once per day or less frequently; do _not_<br /><br /><br />
#download DROP more than once an hour.</p><br /><br />
<p>if [ -n “$1″ ]; then<br /><br /><br />
DropList=”$1″<br /><br /><br />
else<br /><br /><br />
DropList=”./drop.lasso”<br /><br /><br />
fi<br /><br /><br />
if [ ! -s “$DropList” ]; then<br /><br /><br />
echo “Unable to find drop list file $DropList . Perhaps do:” >&2<br /><br /><br />
echo “wget http://www.spamhaus.org/drop/drop.lasso -O $DropList”<br /><br /><br />
echo “exiting.” >&2<br /><br /><br />
exit 1<br /><br /><br />
fi</p><br /><br />
<p>if [ ! -x /sbin/iptables ]; then<br /><br /><br />
echo “Missing iptables command line tool, exiting.” >&2<br /><br /><br />
exit 1<br /><br /><br />
fi</p><br /><br />
<p>cat “$DropList” \<br /><br /><br />
| sed -e ‘s/;.*//’ \<br /><br /><br />
| grep -v ‘^ *$’ \<br /><br /><br />
| while read OneNetBlock ; do<br /><br /><br />
/sbin/iptables -I INPUT -s “$OneNetBlock” -j DROP<br /><br /><br />
/sbin/iptables -I OUTPUT -d “$OneNetBlock” -j DROP<br /><br /><br />
/sbin/iptables -I FORWARD -s “$OneNetBlock” -j DROP<br /><br /><br />
/sbin/iptables -I FORWARD -d “$OneNetBlock” -j DROP<br /><br /><br />
done<br /><br /><br />
Bill Stearns also provides this tcpdump command line. It’s tested on Linux and probably works in any Unix/Posix environment, including Cygwin on Windows. A tcpdump error message “Warning: Kernel filter failed: Cannot allocate memory” seems to indicate that the filter can’t fit in kernel memory, and it appears that tcpdump then switches over to filtering in userspace.
tcpdump -tnp `cat /var/lib/drop.lasso | sed -e
's/;.*//' | grep -v '^ *$' | ( read OneAddr ; echo -n "net $OneAddr" ;
while read OneAddr ; do echo -n " or net $OneAddr" ; done ; echo )`
Here is a script that converts the DROP list into Qmail’s tcpserver blacklist:
<br /><br /><br />
#!/usr/bin/perl<br /><br /><br />
#<br /><br /><br />
# This script converts CIDR notation from STDIN or specified files to<br /><br /><br />
# the format used for generating tcpserver’s blacklist.<br /><br /><br />
#<br /><br /><br />
# Usage example:<br /><br /><br />
#<br /><br /><br />
# Add this cronjob:<br /><br /><br />
# 0 0 * * * /usr/bin/wget http://www.spamhaus.org/drop/drop.lasso -O- 2>/dev/null|/usr/bin/drop2blacklist.pl >/etc/tcp.smtp.droplist<br /><br /><br />
#<br /><br /><br />
# Then generate your tcpserver’s CDB files as follow (or modify qmailctl as needed):<br /><br /><br />
# cat /etc/tcp.smtp /etc/tcp.smtp.droplist|tcprules /etc/tcp.smtp.cdb /etc/.tcp.smtp.tmp<br /><br /><br />
# chmod 644 /etc/tcp.smtp.cdb<br /><br /><br />
#<br /><br /><br />
#<br /><br /><br />
# Author: Thomas Guyot-Sionnest <tguyot@gmail.com><br /><br /><br />
# This script has been released into the public domain.<br /><br /><br />
# This script comes with absolutely no warranty.<br /><br /><br />
#</p><br /><br />
<p>use strict;<br /><br /><br />
use warnings;<br /><br /><br />
use Net::IP;</p><br /><br />
<p># Make this an empty string to remove the trailing dot<br /><br /><br />
my $dot = ‘.’;</p><br /><br />
<p>while (<>) {<br /><br /><br />
next if (m/^\s*(?:;.*)?$/);<br /><br /><br />
s/\s*;.*//;<br /><br /><br />
my $ip = Net::IP->new($_) or die (“Invalid IP Address: ‘$_’\n”);<br /><br /><br />
die (“IPv6 not supported\n”) if ($ip->version() != 4);<br /><br /><br />
print map { “$_:deny\n” } rangeexpand($ip->ip(), $ip->last_ip());<br /><br /><br />
}</p><br /><br />
<p>sub rangeexpand {<br /><br /><br />
my $lowr = shift;<br /><br /><br />
my $highr = shift;</p><br /><br />
<p> return ipexpand(split(/\./, “$lowr.$highr”));<br /><br /><br />
}</p><br /><br />
<p>sub ipexpand {<br /><br /><br />
my @low = splice(@_,0,4);<br /><br /><br />
my @high = splice(@_,0,4);</p><br /><br />
<p> my @list;<br /><br /><br />
if ($low[0] != $high[0]) {<br /><br /><br />
push(@list, ipexpand(@low,$low[0],255,255,255));<br /><br /><br />
for (my $i=$low[0]+1; $i<$high[0]; $i++) {<br /><br /><br />
push(@list, ipexpand($i,0,0,0,$i,255,255,255));<br /><br /><br />
}<br /><br /><br />
push(@list,ipexpand($high[0],0,0,0,@high));<br /><br /><br />
} elsif ($low[1] != $high[1]) {<br /><br /><br />
if ($low[1] == 0 && $high[1] == 255) {<br /><br /><br />
push(@list,”$low[0]$dot”);<br /><br /><br />
} else {<br /><br /><br />
push(@list,ipexpand(@low,$low[0],$low[1],255,255));<br /><br /><br />
for (my $i=$low[1]+1; $i<$high[1]; $i++) {<br /><br /><br />
push(@list,ipexpand($low[0],$i,0,0,$low[0],$i,255,255));<br /><br /><br />
}<br /><br /><br />
push(@list,ipexpand($high[0],$high[1],0,0,@high));<br /><br /><br />
}<br /><br /><br />
} elsif ($low[2] != $high[2]) {<br /><br /><br />
if ($low[2] == 0 && $high[2] == 255) {<br /><br /><br />
push(@list,”$low[0].$low[1]$dot”);<br /><br /><br />
} else {<br /><br /><br />
push(@list,ipexpand(@low,$low[0],$low[1],$low[2],255));<br /><br /><br />
for (my $i=$low[2]+1; $i<$high[2]; $i++) {<br /><br /><br />
push(@list,ipexpand($low[0],$low[1],$i,0,$low[0],$low[1],$i,255));<br /><br /><br />
}<br /><br /><br />
push(@list,ipexpand($high[0],$high[1],$high[2],0,@high));<br /><br /><br />
}<br /><br /><br />
} elsif ($low[3] != $high[3]) {<br /><br /><br />
if ($low[3] == 0 && $high[3] == 255) {<br /><br /><br />
push(@list,”$low[0].$low[1].$low[2]$dot”);<br /><br /><br />
} else {<br /><br /><br />
push(@list,map { “$low[0].$low[1].$low[2].$_” } $low[3]..$high[3]);<br /><br /><br />
}<br /><br /><br />
} else {<br /><br /><br />
push(@list,”$low[0].$low[1].$low[2].$low[3]”);<br /><br /><br />
}</p><br /><br />
<p> return @list<br /><br /><br />
}<br /><br /><br />