How to Block Advertisements at the DNS Level using Pi-hole and OpenVPN

Online ads are not only irritating but also potential sources of malware on your devices. While there are plugins designed to block ads on a per-application/per-device basis. However, stopping advertisements at the DNS level provides a much more complete solution across all of your applications and devices at once.

Pi-hole — a DNS server originally created to filters out requests to ad-serving domains, blocking ads and improving network performance. With Pi-hole, you can actively monitor every DNS request made on your network and block requests on the fly. This functionality also extends beyond web browsers, allowing you to filter out ads within other applications by targeting the appropriate DNS query.

In this guide, we will install and configure OpenVPN and Pi-hole on an Ubuntu 17.10 server to act as your own private, network-wide, DNS-based, ad-blocking filter for all of the devices connected to your network.

Note: For this set up, we will use network information i.e. ip addresses, hostnames according to our environment. You will need to replace these information accordingly.


To complete this guide, you will need:

Gathering Network Information

Before we begin installation, you need to gather the network information Pi-hole uses to communicate with the VPN. As Pi-hole's installation process takes over your terminal session, having this information on hand before you start will make the whole process go much more smoothly.

First, use the ip command with the addr and show subcommands to identify the IP address of tun0, the network interface that your VPN tunnel is active on.

sudo ip addr show tun0

The output provides in-depth information about the interface.

Output from ip addr show tun0
1: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    inet peer scope global tun0
       valid_lft forever preferred_lft forever

Make note of the IP address following inet, as this is the address of your VPN server. You will need to know this when installing Pi-hole.

In addition to your VPN server's IP address, Pi-hole also needs to know the gateway to use for IPv4 traffic. You can think of a gateway as an access point between different networks.

Use the ip command again, this time with the route and show subcommands, to get your server's routing table information. Pipe the routing table information to grep which will parse and search the output for the string, default. default indicates the default gateway used by the server.

sudo ip route show | grep default

In the following example, the output tells you that the default gateway's IP address is, that the gateway is reachable on the eth0 interface, and that the gateway's onlink option is turned on, which is the default with tunneled connections.

Output from ip addr | grep default
default via dev eth0 onlink

Make note of the IP address following via, as this is your server's default gateway address. You will need to know this when installing Pi-hole.

With the network information in hand, you're ready to download and install Pi-hole.

Downloading Pi-hole

As per the official installation instructions, use Git to clone the Pi-hole repository on GitHub into ~/Pi-hole, a directory that will automatically be created during the cloning process. Use the --depth 1 option to create a clone with a history truncated to the last revision; this will give you the latest version of Pi-hole without all the extra historical revisions.

Change to your home directory and clone the repository.

cd ~
sudo git clone --depth 1 Pi-hole

The output confirms the location you're cloning into and then provides a real-time report of the process, including a count of the objects Git expected to copy as well as the number it actually did copy.

Output from git clone
Cloning into 'Pi-hole'...
remote: Counting objects: 65, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 65 (delta 5), reused 26 (delta 1), pack-reused 0
Unpacking objects: 100% (65/65), done.
Checking connectivity... done.

Now, go into to the newly created Pi-hole/automated\ install/ directory where you'll find Pi-hole's installation script.

cd Pi-hole/automated\ install/

Open the installation script to make sure that you're comfortable with what it does or modify it as necessary.

sudo nano

Save and close the file to continue.

You now have a copy of the most up-to-date version of Pi-hole, and you've examined the automated installation script for potential problems. It's time to install and configure Pi-hole.

Executing the Installation Script

Pi-hole installation and configuration takes place with the help of a terminal-based wizard. Start the wizard with the following command:


First, the installation script tells you that it's Installing packages and that it's retrieving additional files needed for installation.

The next screen is a message from the Pi-hole automated installer informing you that you are installing a network-wide ad blocker.

Press ENTER to proceed.

Next, the installation wizard tells you that Pi-hole is Free and open source and lets you know how you can donate to the Pi-hole project.

Press ENTER to continue the installation.

The installation script will then inform you that a Static IP Address is required for the service to function properly.

Again, press ENTER to continue.

The next screen asks you to Choose An Interface for Pi-hole to listen on. Because you need Pi-hole to monitor the VPN's network interface, use the arrow keys on your keyboard to highlight tun0 and then press SPACE to make the selection. Next, press TAB to jump to the options at the bottom of screen. With highlighted, press ENTER to save the settings and continue.

The wizard now asks you to specify the Upstream DNS Provider. This is the service Pi-hole will use to resolve domain names. For simplicity's sake, you can leave this set to the default value, Google.

Press TAB to jump to the bottom of the screen, then press ENTER when is highlighted.

On the following screen, Pi-hole prompts you to select which internet protocols to filter. Protocols — like IPv4 and IPv6 — specify the technical format of packets and the addressing scheme for computers to communicate over a network. IPv4 is the most widely adopted internet protocol for connecting devices to a network.

Filtering of both IPv4 and IPv6 is needed for Pi-hole to perform effectively, so leave both protocols selected and press TAB to jump to the options at the bottom of the screen. Select and then press ENTER.

Pi-hole now asks if you want to use the current network settings as the Static IP Address. Because you need Pi-hole to make use of the VPN, you'll enter this information manually on the next screen.

Use your arrow keys to select and then press ENTER.

Pi-hole will now prompt you for an IPv4 address. Enter your VPN server's address here. This is the IP address that came after inet in the output you received the first time you ran the ip command.

Select and press ENTER to continue.

The next screen requires you to enter the IPv4 gateway (router) that Pi-hole should use to access the internet. Enter the IP address of your server's default gateway here. This is the IP address that came after via in the output you received the second time you ran the ip command.

Select and press ENTER after you've entered the information.

On the next screen, confirm that the IP address and Gateway are correct before they are applied to Pi-hole's configuration. If you need to make a change, select and press ENTER. Otherwise, select and press ENTER to continue with the installation.

In addition to a command-line interface, you can also manage Pi-hole through its web admin interface. One of the web interface's main advantages is its ability to view live DNS queries and blocking statistics.

By default, the web admin interface is set to On.

Use TAB to select and then press ENTER.

In order to make use of the web admin interface's ability to view live DNS queries and blocking statistics, you have to configure Pi-hole to log queries.

This is both the default and recommended setting, so use TAB to select and then press ENTER. 

At this stage, Pi-hole will download and install the remaining dependencies along with the default data for the block- and blacklist. From there, Pi-hole will apply all of the network configuration settings you entered in the previous screens.

During this step, Pi-hole will tell you that there is a Firewall in use and then the installer will prompt you to accept the firewall settings required for the service to function properly.

Use TAB to select and then press ENTER.

From here, Pi-hole will continue with the installation on its own. When finished, the dialogue title will change to, Installation Complete!, and Pi-hole will start automatically and begin filtering all DNS queries on the network.

Press ENTER to exit the installation wizard.

Pi-hole is now installed and configured, but before moving on, let's test that everything is working as expected.

Testing DNS Filtering

When both OpenVPN and Pi-hole are completely set up and working together, every DNS request made on your network will get forwarded to Pi-hole, which will then check to see whether the requested domain matched any other domain in either the block lists or blacklist. If so, the filter will drop the domain altogether; if not, the filter will allow the domain to pass through.

Even though Pi-hole isn't yet configured to work with OpenVPN, you can still verify the current installation by testing Pi-hole's ability to filter ad-serving domains right from your server.

To perform the test, use the host command to do a DNS lookup on, specifying the default gateway,, as the name server to query. This will cause the request to pass through Pi-hole's filters.


Because the output includes the domain's public IP address, you know that did not match any domains on the block lists or blacklist.

Output from host has address

Now, try the host command again, this time passing it, a known ad-serving domain.


Rather than the domain's public IP address, this time you get back the default gateway's address. This means that Pi-hole successfully identified the ad-serving domain and then responded by dropping the request.

Output from host has address

If you don't see the default gateway's address in the output, double check that you've included as the name server to query and then review the terminal for messages indicating there was a problem either installing or starting Pi-hole.

Pi-hole is now correctly installed and filtering requests, so it's time to configure OpenVPN to point DNS requests to Pi-hole.

Configuring OpenVPN

OpenVPN is currently configured to direct all DNS traffic to the DNS server you specified during installation in the Prerequisites. To make use of Pi-hole as an ad-blocker, you now need to reconfigure OpenVPN to point DNS traffic to Pi-hole instead.

First, open OpenVPN's main configuration file for editing.

sudo nano /etc/openvpn/server.conf

Find the following lines:

;push "dhcp-option DNS"
;push "dhcp-option DNS"

These settings allow you to push DHCP options — including DNS settings — to clients connected to the VPN.

As the two dhcp-option settings included in server.conf are commented out by default, leave them in place in case you need to refer to them again in the future.

Now, add the new setting telling OpenVPN to direct clients to use Pi-hole, located at, for all DNS requests.

;push "dhcp-option DNS"
;push "dhcp-option DNS"
push "dhcp-option DNS"

Save and close the file to continue.

To apply the changes, reload OpenVPN.

sudo systemctl restart openvpn@server

Finally, test that OpenVPN successfully started back up.

sudo systemctl status openvpn@server

If everything worked, the output will tell you that OpenVPN is active (running).

Output from systmctl
Active: active (running) since Mon 2017-12-04 22:08:43 UTC; 1 day 23h ago

If the service failed to start, retrace the previous steps to resolve the problem.

OpenVPN is now configured to direct DNS requests to Pi-hole, but you still have to adjust the firewall to make everything work.

Adjusting Firewall Rules

Now that Pi-hole and OpenVPN are both configured and running, open port 53 to allow DNS requests that passed Pi-hole's filters to continue on to the upstream DNS server.

sudo ufw allow 53

For web browsing to work correctly, open up the firewall for HTTP and HTTPS traffic.

sudo ufw allow http
sudo ufw allow https

Next, tell UFW to allow all udp and tcp transmissions originating in the to IP range on port 53. This will allow DNS queries from the VPN's IP range to pass to Pi-hole for filtering.

sudo ufw allow proto udp from to port 53
sudo ufw allow proto tcp from to port 53

Similarly, allow web traffic originating in the IP range to pass through the VPN server at on port 80.

sudo ufw allow proto tcp from to port 80

To apply the changes, reload UFW.

sudo ufw reload

If successful, the output will read:

Output from ufw reload
Firewall reloaded

If you run into a problem, follow the on-screen messages to resolve the issue.

Now that the firewall is configured for OpenVPN and Pi-hole, you can log into the web admin interface to explore Pi-hole's filtering capabilities.

Filtering with Block Lists

Pi-hole ships with a set of default block lists that are maintained by the project's development team; however, these lists alone are not always sufficient. Ideally, you should tailor the block lists to fit your specific browsing habits and the applications you use. You can manage block lists and more with Pi-hole's admin web interface.

To manage Pi-hole through its web interface, you need to connect to your OpenVPN network first. Once you're connected, navigate your web browser to the web interface's default homepage at

You'll be greeted by a screen that includes widgets reporting the number of Queries Blocked Last 24 Hours, number of Queries Last 24 Hours, percent of Queries Blocked Last 24 Hours, and number of Domains on Blocklists. You'll also see a chart of the Queries over last 24 hours, a Pi-hole Status indicator, and navigation options for the Dashboard, Login screen, and Donate page on PayPal.

Click Login to access the full interface. When prompted, enter the password you received on the final Pi-hole installation screen in above step.

After you've logged in, the interface's general layout will remain the same, but it will now include more menu options on the left-hand side of the screen and additional widgets for Query Types over Time and Forward Destinations over Time.

Before adding additional block lists to Pi-hole, you should first update the official block list data from the project's maintainers, as it's possible that the most recent update includes some or all of the data sources you're about to add manually.

On the left-hand side of the screen, click Tools to expand the navigation menu and then select Update Lists.

On the next screen, click the blue Update Lists button in the middle of the screen to fetch the latest version of official block list sources.

As Pi-hole performs the update, it will show you the sources it's pulling the list data from, whether the sources have been modified since your last update, and whether any data was imported into your installation. When complete, the green bar at the top of the screen will read, Success!.

With the official block list data updated, you're ready to add your own additional block lists.

Click Settings in the navigation menu on the left-hand side of the screen for Pi-hole's main configuration options.

On the next screen, click the + symbol in the box labeled Pi-Hole's Block Lists to view the current block list data.

By default, Pi-hole uses the following block lists for filtering:

To add a new list to your installation, enter the list's source URL in the input field at the bottom of the pane, then press the Save and Update button to save your addition and re-run the Update Lists function. This will automatically pull in the data associated with the new block list source.

For additional block lists broken down into categories, like Suspicious Lists, Advertising Lists, and Tracking & Telemetry Lists, see The Big Blocklist Collection here.

Now that you've updated the default block lists and learned how to manually add more, let's take a look at filtertering requests with black- and whitelists.

Filtering with Blacklists and Whitelists

Alongside the block lists that Pi-hole uses to filter DNS requests, you can also target individual domains with blacklists. Blacklists automatically drop outgoing and incoming requests to and from specific domains. This can be particularly useful to businesses and other organizations who need to block domains that contain content that isn't appropriate for work or are known for hosting viruses and other malware.

To blacklist a domain, click Blacklist in the main navigation on the left-hand side of the screen.

On the next screen, you can either add exact or wildcard blocking to a domain.

With exact blocking, only those domains that perfectly match the values you enter in the Add a domain input field will be blocked. In other words, if you enter in the input field, then requests made to and from will be blocked, but requests made to and from will not.

With wildcard blocking, both the domain you enter and any related subdomains will be blocked. In this case, that means both and will be blocked.

Test the blacklist functionality by entering into the Add a domain input field, then click on the Add (exact) button. is now listed under Exact blocking on the Blacklist screen.

Any request made to or from will now be blocked by Pi-hole's blacklist filter. Try navigating your web browser to Although the error message differs from browser to browser, you will no longer be able to reach this address.

To remove from Exact blocking, click the red button with the white trashcan icon to the right of the domain.

At the opposite end of the spectrum, the whitelist tells Pi-hole to always allow all requests to and from specific domains to pass through its filters. Whitelisting can be useful when legitmate domains end up in a block list you're using or when you want to allow traffic to and from domains that contain a mix of ad-based and non-ad content.

To whitelist a domain, click Whitelist in the main navigation on the left-hand side of the screen.

On the next screen, you can add new domains to be whitelisted and see which domains already are whitelisted.

Even though you haven't yet whitelisted any domains yourself, by default, Pi-hole whitelists the domains it uses for updating block lists. This is to prevent one block list from blocking another block list.

Additionally, notice the Note that explains you cannot whitelist a subdomain of a wildcard-blocked domain. This means that if you already have a wildcard block on, whitelisting still won't give you access to the subdomain. In order to blacklist but whitelist, you need to apply an exact block to instead.

To whitelist a domain, enter the domain in the Add a domain input field and then press the Add button. Pi-hole will briefly flash one message that says, Adding to the Whitelist ..., followed by a second message saying, Success! The list will refresh. Both messages will then disappear and the list of whitelisted domains will contain the domain you just entered.

To remove a domain from the whitelist, click the red button with the white trashcan icon to the right of the domain you no longer want whitelisted.

Finally, to test your installation's black- and whitelisting abilities, see Pi-hole's official list of pages to test your setup's ad-blocking performance.


You now have a simple yet effective way of filtering any DNS request on your network, but keep in mind that you might need to customize your block lists a bit to suit your environment.
Powered by Blogger.