#!/usr/bin/gawk -f BEGIN { paths["wget"] = "/usr/bin/wget"; paths["ip"] = "/sbin/ip"; paths["mktemp"] = "/bin/mktemp"; paths["diff"] = "/usr/bin/diff"; paths["sort"] = "/bin/sort"; paths["bunzip2"] = "/usr/bin/bunzip2"; paths["gunzip"] = "/bin/gunzip"; paths["tmpdir"] = "/var/tmp/"; paths["iptables"] = "/sbin/iptables"; # null-route nexthop table to use bgptable = "blacklists"; # null-route prefix. List index number will be used as last octet nullpfx = "127.0.0."; # reject or drop? target["iproute"] = "drop"; target["iptables"] = "reject"; # args to wget file. recc'd that http_proxy is set in environment # especially if one is testing and running script regularly. wgetargs = " -q -t 3 -O " # we want first index to be 2, cause 127.1 is well-known. listsindex = 1; #listname is used for iptables chain / ip route table name #num is used for blackhole route table nexthop, ie 127.num #field is field in file which contains prefix # lists["spews","url"] = "http://www.spews.org/spews_list_level1.txt"; # lists["spews","num"] = ++listsindex; # lists["spews","field"] = 1; # listnames = listnames " spews"; # lists["spewsl2","url"] = "http://www.spews.org/spews_list_level2.txt"; # lists["spewsl2","num"] = ++listsindex; # lists["spewsl2","field"] = 1; # listnames = listnames " spewsl2"; lists["wirehub-permblockIP","url"] = "http://basic.wirehub.nl/permblockIP.txt"; lists["wirehub-permblockIP","field"] = 1; lists["wirehub-permblockIP","num"] = ++listsindex; listnames = listnames " wirehub-permblockIP"; # defunct? # lists["sengir","url"] = "http://www.sengir.demon.co.uk/j_ips.txt"; # #lists["sengir","field"] = 1; # #lists["sengir","num"] = ++listsindex; # listnames = listnames " sengir"; lists["pdl","url"] = "http://www.pan-am.ca/pdl/pdl-list.txt.bz2"; lists["pdl","field"] = 1; lists["pdl","num"] = ++listsindex; listnames = listnames " pdl"; lists["rsl","url"] = "http://relays.visi.com/rsl-list.txt.bz2"; lists["rsl","field"] = 1; lists["rsl","num"] = ++listsindex; listnames = listnames " rsl"; lists["dsbl","url"] = "http://dsbl.org/zones/rbldns-list.dsbl.org.bz2"; lists["dsbl","field"] = 1; lists["dsbl","num"] = ++listsindex; listnames = listnames " dsbl"; lists["dsbl-mh","url"] = "http://dsbl.org/zones/rbldns-multihop.dsbl.org.bz2"; lists["dsbl-mh","field"] = 1; lists["dsbl-mh","num"] = ++listsindex; listnames = listnames " dsbl-mh"; # lists["fiveten","url"] = "http://www.five-ten-sg.com/blackhole.list"; # lists["fiveten","field"] = 1; # lists["fiveten","num"] = ++listsindex; # listnames = listnames " fiveten"; # lists["xbl","url"] = "ftp://erik.selwerd.nl/erik/xbl/{%y%m%d}.bz2"; # lists["xbl","field"] = 1; # lists["xbl","num"] = ++listsindex; # listnames = listnames " xbl"; # blackholes to use, they will all have blackholes- prepended # to list name. index number is in order found here. blackholescourl = "http://blackholes.us/zones/country/"; blackholesco = "thailand taiwan singapore russia nigeria"; blackholesco = blackholesco " malaysia korea japan "; blackholesco = blackholesco " hongkong china brazil argentina"; blackholesispurl = "http://blackholes.us/zones/isp/"; blackholesisp = "yipes xo wanadoo-fr verio valueweb"; blackholesisp = blackholesisp " valuenet skynetweb rr rackspace "; blackholesisp = blackholesisp " pajo level3 interbusiness "; blackholesisp = blackholesisp " internap inflow he epoch eli cw "; blackholesisp = blackholesisp " cybercon covad ciberlynx "; blackholesisp = blackholesisp " broadwing above"; } function doinstall(cmd) { if (args["print"]) print cmd; if (args["install"]) return system(cmd); return 0; } function flushtable(table ,cmd) { cmd = paths["ip"] " route flush table " table; return doinstall(cmd); } function flushchain(chain ,cmd) { cmd = paths["iptables"] " -F " chain; return doinstall(cmd); } function flushcache(table ,cmd) { cmd = paths["ip"] " route flush cache " table; return doinstall(cmd); } function blackhole(method,pfx,nxhop,table ,cmd) { cmd = paths["ip"] " route " method " " pfx " via " nxhop " table " table; return doinstall(cmd); } function addprohibit(pfx,table ,cmd) { cmd = paths["ip"] " route add prohibit " pfx " table " table; return doinstall(cmd); } function addrule(pfx,chain ,cmd) { cmd = paths["iptables"] " -A " chain " -s " pfx " -j "; if (target["iptables"] == "reject") cmd = cmd " REJECT"; else if (target["iptables"] == "drop") cmd = cmd " DROP"; return doinstall(cmd); } function mktemp(pattern ,file,cmd) { cmd = paths["mktemp"] " -q " pattern; cmd | getline file; close(cmd); if (file == ""){ return; } else { return file; } } function geturl(url,file ,cmd) { cmd = paths["wget"] wgetargs file " " url; if (args["print"]) print cmd; return system(cmd); } function fetchlist(list ,pattern,cmd,file,nfile) { file=""; pattern = paths["tmpdir"] "blacklists-" list ".XXXXXX"; if ( (file = mktemp(pattern)) == "") { if (args["debug"]) print "f1"; return ""; } if (args["debug"]) print "fetchlist, file: " file; if (lists[list,"url"] ~ /\{.*\}/) { time = (systime()-(3600*36)); match(lists[list,"url"], /\{(.*)\}/, a); stamp = strftime(a[1], time); gsub(/\{.*\}/, stamp, lists[list,"url"]); if (args["debug"]) print "stamp replace: " lists[list,"url"]; } if ( geturl(lists[list,"url"],file) ) { if (args["debug"]) print "f2 " lists[list,"url"]; cmd = "rm " file; system(cmd); return ""; } if (lists[list,"url"] ~ /\.bz2$/ ) { nfile = file ".bz2"; cmd = "mv " file " " nfile; if (system(cmd)) { if (args["debug"]) print "f3"; return ""; } cmd = paths["bunzip2"] " " nfile; if (system(cmd)) { if (args["debug"]) print "f4"; return ""; } } if (lists[list,"url"] ~ /\.gz$/ ) { nfile = file ".gz"; cmd = "mv " file " " nfile; if (system(cmd)) { if (args["debug"]) print "f5"; return ""; } cmd = paths["gunzip"] " " nfile; if (system(cmd)) { if (args["debug"]) print "f6"; return ""; } } return file; } function installist(file,list ) { if (args["debug"]) print "installist " file; while (getline < file) { # make sure we have something resembling an IP if ($lists[list,"field"] !~ /^[0-9]/) continue; if (args["iproute"]) if (addprohibit($lists[list,"field"],list)) return 1; if (args["iptables"]) if (addrule($lists[list,"field"],list)) return 1; } close(file); } function dumpips(list,file,pos ,cmd,str) { cmd = paths["ip"] " route list table " list; if (args["debug"]) print cmd; while (cmd | getline > 0) { if (args["debug"]) print "dumpips " $0; if (list == bgptable) { print $1,$3 >> file; } else { str = $pos nullpfx lists[list,"listindex"] print str >> file; } } close(file); close(cmd); return 0; } function difflists(old,new ,cmd,file,pattern) { pattern = paths["tmpdir"] "blacklists-diff.XXXXXX"; if ( (file = mktemp(pattern)) == "") { return ""; } if (args["debug"]) print "difflist " old,new; cmd = paths["diff"] " -u " old " " new " > " file; if (system(cmd)) { system("rm " file); return ""; } else { return file; } } function sort(file ,tmpf) { if (args["debug"]) print "sort " file; pattern = paths["tmpdir"] "blacklists-tmp.XXXXXX"; if ( (tmpf = mktemp(pattern)) == "") { return 1; } if ( system(("mv " file " " tmpf)) ) { return 1; } cmd = paths["sort"] " " tmpf " > " file; if (system(cmd)) { ret = 1; } else { ret = 0; } system("rm " tmpf); return ret; } function usage () { print ARGV[0] " [-d|--debug] [-n|--noinstall] [-p|--print]"; print ARGV[0] " [-h|--help] [-t|--iptables] [-r|--iproute]"; print ARGV[0] " [-c|--create]"; print " --debug:\tenable debug"; print " --noinstall:\tdo not install routes/rules"; print " --print:\tprint commands which would be run"; print " --iptables:\tenable iptables rules"; print " --iprules:\tenable ip routes"; print " --create:\tcreate iptables chains"; print " if neither iptables nor ip route is enabled, script prints"; print " information as to which lists it is configured with."; print " for ip routes, you must have added table names and id numbers" print " to the rt_tables file." panic=0; exit 0; } BEGIN { args["debug"] = 0; args["print"] = 0; args["install"] = 1; args["iproute"] = 0; args["iptables"] = 0; args["create"] = 0; for (i = 1; i < ARGC; i++) { if (ARGV[i] ~ /-d$|-debug/) args["debug"] = 1; else if (ARGV[i] ~ /-h$|-help/) usage(); else if (ARGV[i] ~ /-n$|-noinstall/) args["install"] = 0; else if (ARGV[i] ~ /-p$|-print/) args["print"] = 1; else if (ARGV[i] ~ /-t$|-iptable/) args["iptables"] = 1; else if (ARGV[i] ~ /-r$|-iproute/) args["iproute"] = 1; else if (ARGV[i] ~ /-c$|-create/) args["create"] = 1; else usage(); delete ARGV[i]; } split(blackholesco,a); for (i in a) { listname = "blackholes-" a[i]; listnames = listnames " " listname; listurl = blackholescourl a[i] ".txt"; lists[listname,"url"] = listurl; lists[listname,"num"] = ++listsindex; lists[listname,"field"] = 2; } delete a; split(blackholesisp,a) for (i in a) { listname = "blackholes-" a[i]; listnames = listnames " " listname; listurl = blackholesispurl a[i] ".txt"; lists[listname,"url"] = listurl; lists[listname,"num"] = ++listsindex; lists[listname,"field"] = 2; } delete a; split(listnames,listn); if ( !(args["iproute"] || args["iptables"] || args["create"]) ) { printf ("Neither --iproute nor --iptables specified"); printf (", displaying config, see -h\n\n"); printf ("%3s %-25s\t%s\n", "num","name","url"); for (i=1; i 0) { if (args["debug"]) print "modify blacklist " $0 if ($1 ~ /^\+/) { gsub(/^\+/,"",$1); blackhole("add",$1,$2,"blacklists"); } else if ($1 ~ /^\-/) { gsub(/^\-/,"",$1); blackhole("del",$1,$2,"blacklists"); } } if (args["debug"]) print "finished"; panic = 0; # system("rm " file); # system("rm " fallips); # system("rm " fblacklist); exit 0; } END { if (panic) { for (i in listn) { if (args["debug"]) "flushing " listn[i]; if (args["iproute"]) flushtable(listn[i]); if (args["iptables"]) flushchain(listn[i]); } exit 1; } }