Perhaps, like me, you find the OpenDNS service handy, but wish it
allowed more than 50 black or white list entries. Well, you
could try to get the OpenDNS folks to quote you a price for
increasing the number of entries, but they'll laugh at you. (Really, I
tried. They laughed at me. Then I told them I was a Real Corporation,
and they quoted me $600/month for some insane DNS appliance that I could
host onsite. Apparently that has no limit on the black/white
list size.)
There has to be a better way, right?
Enter the Raspberry PI.
Install a nice Wheezy-based Raspbian, and then edit your
/etc/network/interfaces to add a second IP address for eth0:
auto eth0:0
allow-hotplug eth0:0
iface eth0:0 inet static
address 192.168.170.103
netmask 255.255.255.0
(In my case, the Raspberry's eth0 is at 192.168.170.105.)
apt-get install daemontools daemontools-run ucspi-tcp
Then build your own djbdns using the package from sid, since
it didn't make it into wheezy for some reason or other:
tar -xzf djbdns_1.05.orig.tar.gz
gunzip djbdns_1.05-9~exp1.diff.gz
cd djbdns-1.05/
patch -Np1 -i ../djbdns_1.05-9~exp1.diff
emacs conf-cc # add -include /usr/include/errno.h
make
make setup check
useradd gdnscache
useradd gdnslog
dnscache-conf gdnscache gdnslog /etc/dnscache 192.168.170.105
useradd gtinydns
tinydns-conf gtinydns gdnslog /etc/tinydns 192.168.170.103
cd /etc/service/tinydns/root
echo 1 > /etc/service/dnscache/env/FORWARDONLY
echo 100000000 > /etc/service/dnscache/env/CACHESIZE
echo 104857600 > /etc/service/dnscache/env/DATALIMIT
echo "208.67.222.222" > /etc/service/dnscache/root/servers/@
echo "208.67.220.220" >> /etc/service/dnscache/root/servers/@
ln -s /etc/dnscache /etc/service/dnscache
ln -s /etc/tinydns /etc/service/tinydns
So now we have dnscache listening at 192.168.170.105 (the PI's primary
IP address) and we have tinydns listening at 192.168.170.103 (the PI's
bogus secondary IP address.) Arrange your DHCP so that nobody else gets
192.168.170.103, and also so that everybody uses 192.168.170.105 for
DNS. Those entries in the root/servers/@ file above will force dnscache
to forward requests for things it doesn't know about to the OpenDNS
servers at 208.67.222.222 and 208.67.220.220.
Now configure the PI's tinydns to be an authoritatve DNS server for
the entire internet:
cat >/etc/tinydns/root/data<<EOF
.aero:192.168.170.103:a:259200
.asia:192.168.170.103:a:259200
.biz:192.168.170.103:a:259200
.cat:192.168.170.103:a:259200
.com:192.168.170.103:a:259200
.coop:192.168.170.103:a:259200
.info:192.168.170.103:a:259200
.int:192.168.170.103:a:259200
.jobs:192.168.170.103:a:259200
.mobi:192.168.170.103:a:259200
.museum:192.168.170.103:a:259200
.name:192.168.170.103:a:259200
.net:192.168.170.103:a:259200
.org:192.168.170.103:a:259200
.post:192.168.170.103:a:259200
.pro:192.168.170.103:a:259200
.tel:192.168.170.103:a:259200
.travel:192.168.170.103:a:259200
.xxx:192.168.170.103:a:259200
.edu:192.168.170.103:a:259200
.gov:192.168.170.103:a:259200
.mil:192.168.170.103:a:259200
.ac:192.168.170.103:a:259200
.ad:192.168.170.103:a:259200
.ae:192.168.170.103:a:259200
.af:192.168.170.103:a:259200
.ag:192.168.170.103:a:259200
.ai:192.168.170.103:a:259200
.al:192.168.170.103:a:259200
.am:192.168.170.103:a:259200
.an:192.168.170.103:a:259200
.ao:192.168.170.103:a:259200
.aq:192.168.170.103:a:259200
.ar:192.168.170.103:a:259200
.as:192.168.170.103:a:259200
.at:192.168.170.103:a:259200
.au:192.168.170.103:a:259200
.aw:192.168.170.103:a:259200
.ax:192.168.170.103:a:259200
.az:192.168.170.103:a:259200
.ba:192.168.170.103:a:259200
.bb:192.168.170.103:a:259200
.bd:192.168.170.103:a:259200
.be:192.168.170.103:a:259200
.bf:192.168.170.103:a:259200
.bg:192.168.170.103:a:259200
.bh:192.168.170.103:a:259200
.bi:192.168.170.103:a:259200
.bj:192.168.170.103:a:259200
.bm:192.168.170.103:a:259200
.bn:192.168.170.103:a:259200
.bo:192.168.170.103:a:259200
.br:192.168.170.103:a:259200
.bs:192.168.170.103:a:259200
.bt:192.168.170.103:a:259200
.bv:192.168.170.103:a:259200
.bw:192.168.170.103:a:259200
.by:192.168.170.103:a:259200
.bz:192.168.170.103:a:259200
.ca:192.168.170.103:a:259200
.cc:192.168.170.103:a:259200
.cd:192.168.170.103:a:259200
.cf:192.168.170.103:a:259200
.cg:192.168.170.103:a:259200
.ch:192.168.170.103:a:259200
.ci:192.168.170.103:a:259200
.ck:192.168.170.103:a:259200
.cl:192.168.170.103:a:259200
.cm:192.168.170.103:a:259200
.cn:192.168.170.103:a:259200
.co:192.168.170.103:a:259200
.cr:192.168.170.103:a:259200
.cs:192.168.170.103:a:259200
.cu:192.168.170.103:a:259200
.cv:192.168.170.103:a:259200
.cx:192.168.170.103:a:259200
.cy:192.168.170.103:a:259200
.cz:192.168.170.103:a:259200
.dd:192.168.170.103:a:259200
.de:192.168.170.103:a:259200
.dj:192.168.170.103:a:259200
.dk:192.168.170.103:a:259200
.dm:192.168.170.103:a:259200
.do:192.168.170.103:a:259200
.dz:192.168.170.103:a:259200
.ec:192.168.170.103:a:259200
.ee:192.168.170.103:a:259200
.eg:192.168.170.103:a:259200
.eh:192.168.170.103:a:259200
.er:192.168.170.103:a:259200
.es:192.168.170.103:a:259200
.et:192.168.170.103:a:259200
.eu:192.168.170.103:a:259200
.fi:192.168.170.103:a:259200
.fj:192.168.170.103:a:259200
.fk:192.168.170.103:a:259200
.fm:192.168.170.103:a:259200
.fo:192.168.170.103:a:259200
.fr:192.168.170.103:a:259200
.ga:192.168.170.103:a:259200
.gb:192.168.170.103:a:259200
.gd:192.168.170.103:a:259200
.ge:192.168.170.103:a:259200
.gf:192.168.170.103:a:259200
.gg:192.168.170.103:a:259200
.gh:192.168.170.103:a:259200
.gi:192.168.170.103:a:259200
.gl:192.168.170.103:a:259200
.gm:192.168.170.103:a:259200
.gn:192.168.170.103:a:259200
.gp:192.168.170.103:a:259200
.gq:192.168.170.103:a:259200
.gr:192.168.170.103:a:259200
.gs:192.168.170.103:a:259200
.gt:192.168.170.103:a:259200
.gu:192.168.170.103:a:259200
.gw:192.168.170.103:a:259200
.gy:192.168.170.103:a:259200
.hk:192.168.170.103:a:259200
.hm:192.168.170.103:a:259200
.hn:192.168.170.103:a:259200
.hr:192.168.170.103:a:259200
.ht:192.168.170.103:a:259200
.hu:192.168.170.103:a:259200
.id:192.168.170.103:a:259200
.ie:192.168.170.103:a:259200
.il:192.168.170.103:a:259200
.im:192.168.170.103:a:259200
.in:192.168.170.103:a:259200
.io:192.168.170.103:a:259200
.iq:192.168.170.103:a:259200
.ir:192.168.170.103:a:259200
.is:192.168.170.103:a:259200
.it:192.168.170.103:a:259200
.je:192.168.170.103:a:259200
.jm:192.168.170.103:a:259200
.jo:192.168.170.103:a:259200
.jp:192.168.170.103:a:259200
.ke:192.168.170.103:a:259200
.kg:192.168.170.103:a:259200
.kh:192.168.170.103:a:259200
.ki:192.168.170.103:a:259200
.km:192.168.170.103:a:259200
.kn:192.168.170.103:a:259200
.kp:192.168.170.103:a:259200
.kr:192.168.170.103:a:259200
.kw:192.168.170.103:a:259200
.ky:192.168.170.103:a:259200
.kz:192.168.170.103:a:259200
.la:192.168.170.103:a:259200
.lb:192.168.170.103:a:259200
.lc:192.168.170.103:a:259200
.li:192.168.170.103:a:259200
.lk:192.168.170.103:a:259200
.lr:192.168.170.103:a:259200
.ls:192.168.170.103:a:259200
.lt:192.168.170.103:a:259200
.lu:192.168.170.103:a:259200
.lv:192.168.170.103:a:259200
.ly:192.168.170.103:a:259200
.ma:192.168.170.103:a:259200
.mc:192.168.170.103:a:259200
.md:192.168.170.103:a:259200
.me:192.168.170.103:a:259200
.mg:192.168.170.103:a:259200
.mh:192.168.170.103:a:259200
.mk:192.168.170.103:a:259200
.ml:192.168.170.103:a:259200
.mm:192.168.170.103:a:259200
.mn:192.168.170.103:a:259200
.mo:192.168.170.103:a:259200
.mp:192.168.170.103:a:259200
.mq:192.168.170.103:a:259200
.mr:192.168.170.103:a:259200
.ms:192.168.170.103:a:259200
.mt:192.168.170.103:a:259200
.mu:192.168.170.103:a:259200
.mv:192.168.170.103:a:259200
.mw:192.168.170.103:a:259200
.mx:192.168.170.103:a:259200
.my:192.168.170.103:a:259200
.mz:192.168.170.103:a:259200
.na:192.168.170.103:a:259200
.nc:192.168.170.103:a:259200
.ne:192.168.170.103:a:259200
.nf:192.168.170.103:a:259200
.ng:192.168.170.103:a:259200
.ni:192.168.170.103:a:259200
.nl:192.168.170.103:a:259200
.no:192.168.170.103:a:259200
.np:192.168.170.103:a:259200
.nr:192.168.170.103:a:259200
.nu:192.168.170.103:a:259200
.nz:192.168.170.103:a:259200
.om:192.168.170.103:a:259200
.pa:192.168.170.103:a:259200
.pe:192.168.170.103:a:259200
.pf:192.168.170.103:a:259200
.pg:192.168.170.103:a:259200
.ph:192.168.170.103:a:259200
.pk:192.168.170.103:a:259200
.pl:192.168.170.103:a:259200
.pm:192.168.170.103:a:259200
.pn:192.168.170.103:a:259200
.pr:192.168.170.103:a:259200
.ps:192.168.170.103:a:259200
.pt:192.168.170.103:a:259200
.pw:192.168.170.103:a:259200
.py:192.168.170.103:a:259200
.qa:192.168.170.103:a:259200
.re:192.168.170.103:a:259200
.ro:192.168.170.103:a:259200
.rs:192.168.170.103:a:259200
.ru:192.168.170.103:a:259200
.rw:192.168.170.103:a:259200
.sa:192.168.170.103:a:259200
.sb:192.168.170.103:a:259200
.sc:192.168.170.103:a:259200
.sd:192.168.170.103:a:259200
.se:192.168.170.103:a:259200
.sg:192.168.170.103:a:259200
.sh:192.168.170.103:a:259200
.si:192.168.170.103:a:259200
.sj:192.168.170.103:a:259200
.sk:192.168.170.103:a:259200
.sl:192.168.170.103:a:259200
.sm:192.168.170.103:a:259200
.sn:192.168.170.103:a:259200
.so:192.168.170.103:a:259200
.sr:192.168.170.103:a:259200
.ss:192.168.170.103:a:259200
.st:192.168.170.103:a:259200
.su:192.168.170.103:a:259200
.sv:192.168.170.103:a:259200
.sx:192.168.170.103:a:259200
.sy:192.168.170.103:a:259200
.sz:192.168.170.103:a:259200
.tc:192.168.170.103:a:259200
.td:192.168.170.103:a:259200
.tf:192.168.170.103:a:259200
.tg:192.168.170.103:a:259200
.th:192.168.170.103:a:259200
.tj:192.168.170.103:a:259200
.tk:192.168.170.103:a:259200
.tl:192.168.170.103:a:259200
.tm:192.168.170.103:a:259200
.tn:192.168.170.103:a:259200
.to:192.168.170.103:a:259200
.tp:192.168.170.103:a:259200
.tr:192.168.170.103:a:259200
.tt:192.168.170.103:a:259200
.tv:192.168.170.103:a:259200
.tw:192.168.170.103:a:259200
.tz:192.168.170.103:a:259200
.ua:192.168.170.103:a:259200
.ug:192.168.170.103:a:259200
.uk:192.168.170.103:a:259200
.us:192.168.170.103:a:259200
.uy:192.168.170.103:a:259200
.uz:192.168.170.103:a:259200
.va:192.168.170.103:a:259200
.vc:192.168.170.103:a:259200
.ve:192.168.170.103:a:259200
.vg:192.168.170.103:a:259200
.vi:192.168.170.103:a:259200
.vn:192.168.170.103:a:259200
.vu:192.168.170.103:a:259200
.wf:192.168.170.103:a:259200
.ws:192.168.170.103:a:259200
.ye:192.168.170.103:a:259200
.yt:192.168.170.103:a:259200
.yu:192.168.170.103:a:259200
.za:192.168.170.103:a:259200
.zm:192.168.170.103:a:259200
.zw:192.168.170.103:a:259200
EOF
Now we can have handy three-way DNS filtering with no limits. Ordinary
addresses, like cyclecounters.org, will go into the PI and it will ask
OpenDNS to resolve them in the ordinary way. That way, you can still
use OpenDNS's great category-based filtering on most addresses.
To whitelist, say, gmail.com, do:
echo "8.8.8.8" > /etc/dnscache/root/servers/gmail.com
That tells dnscache to delegate requests for *.gmail.com to the 8.8.8.8
dns server. (Use your ISPs DNS here, *not* OpenDNS.)
To blacklist, say, latimes.com, do:
echo "192.168.170.103" > /etc/dnscache/root/servers/latimes.com
echo '+latimes.com:67.215.65.130' >> /etc/tinydns/root/data
That tells dnscache to delegate requests for *.latimes.com to the
instance of tinydns that is also running on the PI, and tells
that tinydns to hand out the OpenDNS "blocked address" page at
67.215.65.130 in response to any *.latimes.com request.
One last step -- after updating tinydns, we need to rebuild its
data file.
cd /etc/tinydns/root
make
You might also want to restart dnscache and tinydns:
svc -d /etc/service/dnscache
svc -u /etc/service/dnscache
svc -d /etc/service/tinydns
svc -u /etc/service/tinydns
And voila, that's all there is to it. Here's a basic shell script that reads
inputs from ~/white and ~/black and does the right thing:
#!/bin/bash
#
# Uses a list of domains in ~/white and ~/black
# to set up dnscache black and white lists.
rm -f /etc/dnscache/root/servers/*.*
#
# Whitelisted sites go to working DNS
#
SITES=`cat ~white`
DNS1="8.8.8.8"
for SITE in $SITES
do
echo "$DNS1" > /etc/dnscache/root/servers/$SITE
done
#
# Blacklisted sites go to 192.168.170.103, where they'll
# find a tinydns set up to serve them an OpenDNS block page.
#
SITES=`cat ~black`
DNS1="192.168.170.103"
cp ~adam/dns/roots /etc/tinydns/root/data
for SITE in $SITES
do
echo "$DNS1" > /etc/dnscache/root/servers/$SITE
echo +"$SITE":67.215.65.130 >> /etc/tinydns/root/data
done
cd /etc/tinydns/root
make
svc -d /etc/service/dnscache
svc -u /etc/service/dnscache
svc -d /etc/service/tinydns
svc -u /etc/service/tinydns