To Protect and Surf (dnsmasq and Whitelists)
Contrary to popular rumor, I am still alive and very busy – from about October of last year until last month I have been buried at work (a good thing in this economy!). Maybe now that I can see a little daylight, I can try to keep this blog updated a little more frequently. Enough with the excuses and on with the post.
The only person in this house that likes to spend more time on the computer than me is my 4 year old son. Most of the time he is content to play an old copy of Monster Truck Madness 2 that I picked up years ago, but he also likes to spend time at Dan-Dare.org, Playhouse Disney, PBS Kids, and several other sites. The problem (other than trying to limit his time on the computer) is that he also likes to explore. When he gets bored just playing the games, he's off checking out what each menu item and dialog box does. He has explored all the configuration options in the monster truck game, and he is always playing with the volume control applet – I've spent plenty of time trying to undo his changes on the kid's computer. Lately, he has also taken to checking out the various links on the websites he visits. A couple of times he has run in to inform us that we can get a free monster truck game, and when we go check on him he has wandered off to some obscure website. Well, it happened again today, and although I've always known I would have to take action, today was the day to do something about it.
Being the cheap bastard that I am, I needed a free solution that would keep him (or my 7 year old daughter) from visiting places on the web that I would rather not have them be for now. I decided that what I need for now is a DNS forwarder with a whitelist, so that only the sites on the list can be accessed. Although the following solution is fine for small kids, anyone with an 8088 for a brain can figure out how to get around this. Even so, it should work for us for the next few years.
A little surfing pointed me to dnsmasq, a very popular dns forwarding server. A little more research indicated that using it to whitelist domains was not easy – there is no built-in way to do it. I found someone who listed a source patch to make it happen, but I didn't want to go to that extreme if I could avoid it. Despite this, I went ahead and installed it on my file server (running Ubuntu, of course) using sudo apt-get install dnsmasq
. Looking at all the options in the man page and in the /etc/dnsmasq.conf file was overwhelming at first, but it didn't take too long to figure things out. One of the things I discovered was that you can assign specific outside DNS servers for specific domains. I realized that if I blocked off any other way for it to resolve domain names except for this feature, I could use it like a whitelist! A little experimenting proved that it did indeed work. Here is the dnsmask.conf that I am using right now:
domain-needed
bogus-priv
log-queries
log-facility=/var/log/dnsmasq.log
no-resolv
interface=eth0
# Add other name servers here, with domain specs if they are for
# non-public domains.
#server=/localnet/192.168.0.1
server=/google.com/192.168.0.1
server=/dan-dare.org/192.168.0.1
server=/dan-dare.net/192.168.0.1
server=/pbskids.org/192.168.0.1
server=/playhousedisney.com/192.168.0.1
server=/disney.go.com/192.168.0.1
server=/starfall.com/192.168.0.1
The first few lines do the actual configuration of dnsmasq, domain-needed & bogus-priv block Windows machines from passing noise traffic, log-queries & log-facility tell dnsmasq to log all DNS requests to the /var/log/dnsmasq.log file (useful for determining the domains required by websites, but this can be turned off to save space), no-resolv tells it to ignore the resolv.conf file which usually lists the outside DNS servers to use, and finally interface tells the service which network interface to bind to.
The rest of the “server” lines implement the whitelist, telling dnsmasq to look for the specified domain's IP address using the specified DNS server. In this case, I simply pointed to the DNS server in my local network's router (192.168.0.1). Any other domains are simply returned as being invalid. To populate this list, I simply attempted to browse to the sites my children visit, and then looked in the /var/log/dnsmasq.log file to see what domains were being requested, then entered them into the dnsmasq.conf file. After each update to the configuration file, I needed to sudo /etc/init.d/dnsmasq restart
to get the service to re-read the file.
The final step was to change the DNS server address on the kid's computer to point to the file server's IP address, and that was it – now anytime they “accidentally” try to access a domain not in the list, they get a message saying the domain was not found. Of course any computer-savvy person could simply set the DNS server to something else (like OpenDNS!), but it will probably be a few years before my kids figure that out. If they want to visit someplace new, I have to intervene (which is what I want). In a few more years, I will have to be more creative to keep ahead of the kids and to keep my workload down updating the list – but for now this works for me.
So hopefully, if there are other people like me searching for a way to add whitelisting to their dnsmasq forwarders, maybe this post will be a starting point. If you have any questions, go ahead and leave me a comment or send me an email, I'll do my best to help. And maybe if things slow down a little there will be more frequent posting around here as well.