Total Pageviews

Friday, 30 September 2016

Host your own DNS

One of your essential addons for your web browers is almost definitely some sort of ad blocker. Resources like bandwidth are a precious resource, especially when your ISP is of the many that limit it on a monthly basis. Another great benefit of having ad blocking software is that you risk a much lower chance of being infected by drive by malware, served by ads themselves. Not loading ads also means.. less loading! Why don’t we take the load off our machines even less by removing our ad block extensions?

For what you’ll see in this tutorial, it is assumed you’re working with a clean Debian 8.0 template. First off, we’ll use apt to install dnsmasq, the only requirement for this to work, and tell it to start by default.
apt-get update && apt-get install dnsmasq -y
update-rc.d dnsmasq enable
We’re going to delete dnsmasq’s default configuration file, as it’s way too cluttered for what we’re using it for. After that, we’ll be making our own, much simpler version.
rm /etc/dnsmasq.conf
nano /etc/dnsmasq.conf
For options like _interface_, you’ll need to use ifconfig to see what interface lists the IP you want it to be setup on. For _host-record_, simply run `hostname` to know what you should put. What is pihole you might ask? is an open source project written by Jacob Salmela to do the exact same thing we’re doing, but for Raspberry Pi’s on your local network. Creating a blacklist for ads would take ages, so we’re going to take advantage of Pi-Hole’s already created list.
chmod +x
./ will start populating an extensive blacklist for ad networks, but it shouldn’t take long. Finally, we’ll use sed to change every instance of our virtual machine’s IP with a blackhole, and restart dnsmasq.
sed -i “s/^[0-9\.]\+\s/ /g” /etc/pihole/gravity.list
service dnsmasq restart
You’re done! I like to take it a step further though, and automate the updating of our blacklist.
apt-get install cron -y
crontab -e
At the bottom of our crontab, enter the following, which will set our blacklist to be updated once every day.
0 5 * * * bash /root/
Inspired, but modified version of David Anson’s tutorial.

Pie in the Sky-Hole [A Pi-Hole in the cloud for ad-blocking via DNS]
Monday, August 24th 2015
Inspired by Marco Arment's recent post about blocking advertisements on the web, I decided to explore the same idea. However, while Marco focuses on the annoyance of advertisements, I am interested in the security benefits of removing them. There have been numerous incidents of otherwise respectable websites compromising the security of their users due to the advertisements they include. Searches for "web site hacked 'ad network'" on Google and Bing provide some examples; another is this XSS attack on Troy Hunt's site, which is interesting thanks to the detailed analysis Troy provides. Popular sites of all kinds have been compromised in this way, and one might argue they should be treated as attackers because of the approach used to serve third-party ads.
Marco's article describes an in-browser solution for ad-blocking, but I prefer something that automatically protects all the machines on my network (at least, while they're using the network; see below). So I set out looking for something that works at the network level and came across Pi-Hole, a DNS-based ad-blocker for the Raspberry Pi. Aside from the fact that I don't own a Pi, this seemed like exactly what I wanted. ;)
Fortunately, there are no actual dependencies on Pi hardware, so I decided to create my own Pi-Hole on a server in the cloud - thus the name "Sky-Hole". To do so, I opened the Microsoft Azure Portal, created a small virtual machine running Ubuntu Server 15.04, and configured it according to the manual instructions for Pi-Hole (with a few customizations outlined below). Then I updated my wireless router to use Sky-Hole as the DNS server for my home network - and all my devices stopped showing advertisements!


I used a minimal set of steps to configure the Sky-Hole and list them below so they're easy to reproduce. I made a couple of tweaks to the Pi-Hole process along the way and explain them in turn.
First, create a virtual machine to run everything on (I've used both Microsoft Azure and Amazon Web Services, but any provider should do). Then, install dnsmasq:
sudo apt-get -y install dnsmasq
sudo update-rc.d dnsmasq enable
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.orig
sudo nano /etc/dnsmasq.conf
Configure dnsmasq.conf as follows (replacing "sky-hole" on the last line with the host name of your virtual machine):
The addn-hosts option is meant to be optional, but I needed it because /etc/hosts was not updated by The host-record option was necessary to avoid a "sudo: unable to resolve host" error which showed up whenever I enabled dnsmasq. (Though this may be an artifact of the default virtual machine configuration under Azure.)
Update 2015-08-30host-record was similarly necessary on AWS, where the automatically-assigned host name was of the form ip-123-123-123-123.
Now, download the Pi-Hole script and run it to generate the list of domain names to block:
sudo curl -o /usr/local/bin/
sudo chmod 755 /usr/local/bin/
sudo /usr/local/bin/
sudo sed -i "s/^[0-9\.]\+\s/ /g" /etc/pihole/gravity.list
The last line is my own and replaces the virtual machine's IP address with an unusable address when redirecting undesirable sites. Because I'm not running a web server on the Sky-Hole, this seems like a more appropriate way to block unwanted domain names. (Besides, hostname -I in Azure reports the virtual machine's internal address which is on a private network.)
Restart dnsmasq to apply the changes:
sudo service dnsmasq restart
Now, test things locally via pingdignslookup (or similar) to verify that desirable domain names are returned as-is and undesirable ones are blocked by returning the IP. Assuming that's the case, update the virtual machine to accept incoming UDP traffic on port 53 (per the DNS specification) and test again from a different machine. If everything is working as expected, configure your router to use the Sky-Hole's public IP address for DNS resolution. This automatically applies to all devices on the local network and avoids the need to update each one manually.
Update 2015-08-30: You may also want to enable TCP traffic on port 53 (per RFC 5966).
Congratulations, you're done!


  • The nice thing about this approach is that it covers all the machines on your network. However, it can only protect machines when they're connected to that network. Taking a phone or tablet elsewhere or using cellular data exempts a device from this kind of protection.
    • So this may be an argument in favor of per-device ad-blocking - though perhaps as a strategy to be used in addition to (rather than instead of) a network-wide approach.
  • When creating the virtual machine, I used the Basic A1 size which would cost about $34.97 per month on Azure (though I don't plan to leave it running very long).
    • I tried the A0 size first (which would have cost $13.39 per month on Azure), but it ran out of memory building the domain list, seemingly due to this known issue.
  • As I note above, I chose not to configure a local web server on my Sky-Hole. While doing so offers interesting benefits, it didn't seem compelling for the purposes of this experiment and I preferred to keep thing simple. Should you choose to, directions are available in the Pi-Hole documentation.
  • If you end up using Pi-Hole like this (or on its own) please consider donating to the author, Jacob Salmela, to help support his work.


I'm only been running Sky-Hole for a couple of days, but the usability and performance improvements for some sites are quite noticeable. More importantly, it seems to me the browsing experience is necessarily safer by virtue of removing not just asubset of traffic, but the subset which is most likely to contain unwanted content.
As an experiment and a learning experience, Sky-Hole has been a successful side-project. I hope others find it interesting or thought-provoking and I welcome comments on improving or enhancing the approach!