Ad blocking with an ESP8266

I have used in the past ad blocking hosts files in order to avoid popups, spyware and different types of advertisements. I had even a microserver configured with dnsmasq in order to use as ad blocking DNS server.

There are many solutions to this, from browser plugins to ideas like pi-hole (using a Raspberry Pi as an ad black hole).

It is clear that the Raspberry Pi or any similar device is capable of ad blocking, but I was in doubt whether it would be possible to run an ad blocker on the ESP8266 and how it would behave.

What’s more, if a low-cost, low-consumption device like ESP8266 was enough for ad blocking, I could power it with the USB of the router and use as the primary DNS for devices in the home WiFi.

The bottom line is yes, you can deploy an ad blocker on the ESP8266. The performance needs to be improved, mainly when receiving a lot of DNS queries in a short period of time, so, probably is not enough for daily usage but it is interesting at least as a proof of concept.

How to Install

These are more or less the steps I followed, in case you want to replicate the ESP ad blocker:

Downloading the code

The source code can be found in https://github.com/rubfi/esphole . Clone it or download the zip file.

The source codes includes the Arduino sketch (you may need to install Arduino + ESP8266 core if you don’t have it installed yet), the DNS server library ( The library is a modified version of the DNS Server library included with the Esp8266 core for Arduino) and a script for processing the hosts files.

Once, you have the source downloaded and Arduino installed you could proceed with the next step.

Preprocess the hosts file

I needed to store the hosts file somewhere. Since ESP8266 uses a SPIFFS filesystem in order to store files in the flash, I used it to save the hosts file downloaded from https://pgl.yoyo.org/as/ or http://someonewhocares.org/hosts/

The first versions uploaded the full hosts file (around 350KB) to the SPIFFS. The performance of finding the domain in the full hosts file was really poor, so for the current version the hosts file is preprocessed and stored in smaller files based on the length of the domain.

$ cd utils
$ sh gen_block_lists.sh

gen_block_lists.sh downloads the hosts file and saves it in different files in the data directory

Upload the SPIFFS

Follow the guide of Arduino ESP8266 filesystem uploader to install the SPIFFS uploader and then select: Tools > ESP8266 Sketch Data Upload in order to upload data directory to the ESP

Upload the sketch

Open the sketch directory with Arduino IDE and edit esphole.ino in order to change the WIFI settings

#define wifi_ssid "........"
#define wifi_password "........"

Then, upload it to the ESP

Usage/Test

Open the serial monitor or minicom in order to find the IP of the ESP device (or scan your network in order to find it) and use nslookup to test some domains:

$ nslookup - 192.168.0.161
> github.com
Server: 192.168.0.161
Address: 192.168.0.161#53
Non-authoritative answer:
Name: github.com
Address: 192.30.253.112
> analytics.google.com
Server: 192.168.0.161
Address: 192.168.0.161#53
Non-authoritative answer:
Name: analytics.google.com
Address: 0.0.0.0

In the serial monitor the debug information from the ESP is shown:

WiFi connected | IP address: 192.168.0.161
DNS Server ready
Domain: github.com | IP:192.30.253.112
Resolv took 70 ms | Find took 57 ms
Domain: analytics.google.com Blocked | Find took 30 ms 

The log above shows the time took to find the domain in the hosts files (and thus deciding that github.com was not in the blocking list) and resolve the IP. The second case shows a blocked domain.

Note: Esphole was tested with a Wemos D1 mini and an Amica NodeMCU.