Advertising sucks. Well, some of it does.
Aggressive monetization is killing the mobile web. I find mobile advertising to be the most excruciating form of advertising due to the sheer volume of ads served, coupled with their obtrusiveness. You start reading an article only to find the screen go unresponsive as an interstitial ad fades in, blocking your content. Tap the impossibly small dismiss icon to go back to reading your article. Attempt to tap a legitimate link only to find that a new ad loads directly under your finger, sending you off to a random location, possibly to get caught in a loop of “your phone is infected with a virus” phishing attack. “Sponsored content” and clickbait are gentler and more insidious forms of mobile advertising: “You won’t believe what this famous actress looks like now!”
“Install an ad blocker,” goes the rallying cry. In my household, we have 5 laptop computers, 2 iPods, 3 iPhones, 2 Android phones, 2 Android tablets, 1 iPad, and 3 Kindles. Each of these devices has multiple ad-serving platforms. A mobile phone, for example, has 1 or 2 commonly used web browsers along with dozens of apps that also serve advertising. Installing, configuring, and updating ad blockers for all those access methods on all those devices doesn’t sound like a fun task.
Instead of blocking ads in an app or browser, a more robust solution is to block requests for ads from ever leaving your home network. When you view a page in your browser of choice, the browser is tasked with interpreting the layout of the page to display what you see, including downloading all resources referenced in the page (e.g. images, scripts, and ads). Some of these are downloaded serially during loading, and some are downloaded as you scroll through pages. This is why pages jump as you view them: content is being displayed as it’s downloaded, causing you to tap in all the wrong places. If you can isolate those requests to ad networks and block them, you should be able to view all of the good content, without seeing the ads. That requires a mechanism to sit between you and the network to intercept those requests, and a way to inspect the requests and only block the bad ones. That’s the objective of this project.
The Problem with Generalized Ad-blocking
This approach isn’t without issues, however. There are many legitimate reasons why you might want to permit these outbound requests. The biggest one is that ads support the businesses and publications you love. For many apps and online publications, ads are what keep the lights on and the doors open. If you like the content supplied by an online publication, you absolutely want them to deliver ads to you. That’s your patronage in return for what they provide to you. Some apps offer a great experience and feature reasonable, unobtrusive ads. By all means, support the developers and permit their ads. Clearly, there are reasons why you might want to allow some ads through your defenses.
This project uses a newer-model Raspberry Pi along with Pi-hole software to create a network-wide filter to suppress ads at the source.
Materials List for Your Ad-Blocking Server
- Raspberry Pi: you’ll want to choose one of the latest models, which will be the Raspberry Pi 3 Model B or the Raspberry Pi 2 Model B as of this writing. Both are quad-core with 1 GB RAM. For performance reasons, I wouldn’t want to implement this with any of the older models. $39.95 from adafruit
- Power supply for the Pi with a MicroUSB cable: $7.50 from adafruit
- MicroSD card, 8 GB Class 10: technically, class doesn’t matter much, as it measures a sustained write rate, which doesn’t correlate well to requirements of a Pi. But as a rule of thumb, spring for a name brand, class 10 card to increase your confidence level. $9.95 from adafruit, but find it anywhere
- Raspberry Pi case: optional, but highly recommended; this will sit near your router, so you should enclose it. Here’s a simple one for $5.00 from adafruit.
- Ethernet cable
Materials List for the Server Build
- HDMI cable
- USB keyboard and mouse (wireless sets will also work)
- Wifi: if using a Pi 3, you have wireless already. For older models, you’ll need a dongle if you want to use wireless, but it’s not a requirement. $11.95 from adafruit
- MicroSD card reader
Building the Pi Hole
1. Install Raspbian on your MicroSD Card
Raspbian is the Raspberry Pi Foundation’s officially supported operating system. There are plenty of other distributions you can use, but Raspbian is well supported, updated frequently, and contains many additional tools to make your Pi experience smooth.
- Download the latest Raspbian version. As of this writing, it’s Jessie, released in November 2016.
- Unzip the archive you downloaded. Decompressed, this is a large file at over 4 GB.
- If you haven’t installed Win32DiskImager, do so now.
- Insert your SD card into your card reader, and insert your card reader into your computer. A limitation of Win32DiskImager is that it cannot read or write to an SD card that is inserted directly into an onboard card reader on your PC, which is why you need to use an external reader.
- Open Win32DiskImager, browse your computer to select the image file you just unzipped, and select the drive letter where your SD card reader is inserted. For the love of all things holy, make sure that you select your SD card, and not any other drive. When you’re certain that you have the SD card selected, click the “Write” button to begin writing the image. This process will take several minutes to complete (10 for me).
- Exit Win32DiskImager and safely eject your SD card reader.
2. Configure your Raspberry Pi
- Place your Pi in a case, if you have one. This is only a precaution. If you’re not using a case, just be careful where you set your Pi; you don’t want to set it on conductive materials that will create a short.
- Insert your Raspbian-imaged microSD card into the card slot. It will look like it’s upside down if you look at your Pi from above.
- Connect an HDMI cable from your Pi to your monitor; plug in your keyboard and mouse via USB, and then connect and plugin your Pi’s power supply.
- Allow your Pi to go through it’s setup and startup procedure until you see the desktop wallpaper.
- After it’s finished booting, in the upper right hand corner, you will select your wifi network if you’re using wireless. If you’re directly connected via an ethernet cable, you should see your network recognized.
While you’re here, you should update a few settings to make your Pi a little more usable.
- In the upper-left hand corner of the screen, click the Raspberry icon, and select Preferences | Raspberry Pi Configuration.
- In the resulting dialog, click the “Change Password” button and change your Pi’s password. Your default username / password is pi / raspberry.
- Select the Interfaces tab, and select the “Enabled” radio button for SSH. This will enable you to use a tool like Putty to remotely login to your Pi at a later time.
- Select the Localisation tab, and update the Locale and Timezone to whatever is most appropriate for you.
3. Install Pi-hole
Begin the installation by opening the Pi console. It’s the icon in the upper left that looks like a greater than sign followed by an underscore. Enter the below command:
curl -L https://install.pi-hole.net | bash
If you’re worried about piping anything to your bash, you can view the contents of the file before installing it. Enter the below lines in turn: the first downloads the target file, the second opens it for viewing, the third grants execution privileges, and the final performs the install.
wget -O basic-install.sh https://install.pi-hole.net nano basic-install.sh chmod +x basic-install.sh ./basic-install.sh
Installation will take several minutes as all required components are added to your Pi. When the system is ready to proceed, the “Pi-hole automated installer” dialog will display. When working through these dialogs, use your spacebar to select/deselect whatever is under the cursor, and use the enter key to accept the selection. After advancing through a few informational screens (see gallery for the sequence), you’ll be asked to make some choices. Here are the important ones:
- Choose an Interface: Choose eth0. Due to latency, wifi is not suitable for use with Pi-hole; you will plug your Pi directly into an Ethernet cable.
- Select Protocols: select (spacebar) both IPv4 and IPv6.
- Static IP address: either accept the suggested static address or enter your own. Whatever you choose, write this address down.
- Default gateway: leave this alone and accept the default.
- Upstream DNS Provider: Google is the default, but you can select any of the other providers. Some of the other providers will offer additional filtering, e.g. blocking adult content, blocking malicious sites, etc. My goal is to block ads only, so I selected Google as my provider.
Once you enter the above and confirm that you’d like to proceed, the Pi-hole installation will complete. You can shutdown your Pi and prepare to move it to your router, if you’re not nearby already.
4. Configure your Home Router
I’m using a Google OnHub router, so my settings will not look like yours, but the procedure is the same for most routers.
- Find your DNS settings. Mine are located at Advanced Networking | DNS.
- Your DNS is probably set to automatic right now, but you will have an option to set a static DNS. For static DNS 1, enter the IP address of your Pi-hole (the number you wrote down above). Then set your secondary DNS to a server of your choice. If you want to fall back to Google DNS, enter 18.104.22.168. This is your backup DNS in the event that your Pi-hole fails.
- Connect your Pi to your home router using an Ethernet cable.
- Plugin in your Pi and allow it to boot.
5. View the Results
Once Pi-hole is installed and running, you will have access to an administrative panel where you can monitor what the Pi-hole is doing for you. You can find this panel at http://192.168.86.xx/admin/index.php, replacing the “xx” with the number specific to your network.
You might as well also test your SSH connection before you get too comfortable. If you don’t have it, download Putty, open it and point it to your Pi’s IP address. You’ll be prompted to login: use “pi” as the username, and enter the password that you configured earlier. If you didn’t change your default password (shame on you), enter “raspberry”as the password.
Updating the Pi-hole
The latest update to Pi-hole added an improved administrative interface. Staying up-to-date is simple: login to your Pi via SSH, and enter the below on the command line:
Common Questions and Concerns
Q: Am I creating a bottleneck in my home network?
It should have the opposite effect. It’s not blocking inbound ad pushes, it’s blocking outbound requests for them. So it should result in less for your browser or app to load, which translates to faster loading of content and less bandwidth usage. As an added bonus, if you’re using a mobile device, this should have the benefit of preserving your battery. Additionally, it caches DNS queries, which makes your lookups faster for those locations you visit or request more than once.
Q: Will this increase my network usage?
The Pi-hole will send thousands of DNS requests a day, but they are very tiny, so the traffic shouldn’t even be noticeable. You should be able to easily share even the slowest of broadband connections with an entire house filled with guests. And those thousands of requests will likely be more than offset from the ads that you won’t be downloading.
Q: Will this negatively impact other sites that I visit?
It might. For the Android apps I’ve built that serve responsible ads, I wait for a response back from the app before I proceed. Other apps built like this will get stuck waiting for the response. There are also some cases where a server on the blacklist might serve up legitimate content, in addition to ads. This content could be blocked. If you’re using any referral or cashback sites, the Pi-hole could interfere with them. Finally, it could impact streaming services you use. That said, there is a mechanism around this: the whitelist.
Q: I don’t want to block ads from sites and apps that I support.
On the left-hand side of the Pi-hole admin panel (http://192.168.86.xx/admin/index.php), click the “Whitelist” link, and add the domain you would like to bypass the Pi-hole. You might need to view the “Query Log” (also in the menu) to make sure you whitelist related domains serving content on behalf of your targeted domain.