How to pair Pi-hole with an OpenVPN to block ads and increase privacy on Ubuntu / Debian Linux

Posted on in Categories , , , , last updated November 22, 2016

I followed your tutorial to install an OpenVPN on my Ubuntu server in the cloud. How can I install Pi-hole to block ads, reduced my 4G/3G/LTE traffic on the same Debian or Ubuntu Linux server?

Pi-hole is free and open source software to block ads and tracking domain. It is released under the GNU General Public License. The biggest advantage is ad blocking on all devices on the network from your smartphone to your tablets including all desktop computers. It even blocks in app ads on iOS and Android/Windows devices. The benefits are as follows:

  1. Blocks all advertisements using network-level DNS based blocking.
  2. Works with both apps and websites regardless of operating system.
  3. You can pair your Pi-hole with a VPN software such as OpenVPN for on-the-go ad-blocking and save on data 3G/4G/LTE costs.
  4. You can get improved privacy and security due to blocking of ads and tracking codes.

Pi-Hole
This tutorial provides step-by-step instructions for configuring an OpenVPN server on a Debian or Ubuntu Linux v14.04/16.04 LTS including Pi-hole ad blocking software. The steps are as follows.

Install OpenVPN

Type the following two commands:
$ wget https://git.io/vpn -O openvpn-install.sh
$ sudo bash openvpn-install.sh

Just follow on screen instructions to install the OpenVPN server. See our step-by-step guide for more detailed information on setting up an OpenVPN server on Linux.

Installing Pi-hole on a Linux server

At this stage I am assuming that you have a working OpenVPN server. The client is also configured to OpenVPN on OSX/Windows/Linux/FreeBSD/iOS/Andriod devices.

Note down your OpenVPN server IP address

Type the following command:
$ ip a show dev tun0
Sample outputs:

Fig.01: Finding out your OpenVPN server IP address
Fig.01: Finding out your OpenVPN server IP address

Please note down 10.8.0.1/24 IP address. You also need to provide tun0 as an interface name including your default gateway IP address such as 192.168.2.254:
$ ip r | grep default
default via 192.168.2.254 dev br0 onlin

Our sample setup

Our sample setup/network
Our sample setup/network

Pi-hole was designed for Raspberry PI hardware but works with Ubuntu and Debian based Linux distro. In this example, I am setting up on a Ubuntu 16.04 LTS server.

Install PI-HOLE

Run the install command as follows:
$ wget -O basic-install.sh https://install.pi-hole.net
$ sudo bash basic-install.sh

You will see progress on screen as follows:

Fig.02: Pi-Hole installer in action
Fig.02: Pi-Hole installer in action

This installer will transform your device into a network-wide ad blocker. The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.

Choose an interface for Pi-hole

Fig.03: Select an interface of OpenVPN server such as tun0
Fig.03: Select an interface of OpenVPN server such as tun0

Select protocols for dns server

Fig.04: You must at least select IPv4 for all dns queries
Fig.04: You must at least select IPv4 for all dns queries

Setup a static IP address (select No)

Fig.05: You must set a static IP address and it must match to tun0/OpenVPNs static IP address
Fig.05: You must set a static IP address and it must match to tun0/OpenVPNs static IP address

Next enter OpenVPN’s server IP address as follows:
Fig.06: Enter your tun0 interfaces IP address here
Fig.06: Enter your tun0 interfaces IP address here

Finally enter your default router/gateway IP address:
Fig.07: Setup default router IP
Fig.07: Setup default router IP

Confirm the settings:
Fig.08: Are static IP settings correct? Yes.
Fig.08: Are static IP settings correct? Yes.

Setup upstream DNS IP address

Fig.09: Select upstream DNS provider such as Google DNS
Fig.09: Select upstream DNS provider such as Google DNS

And you are done:
Fig.10: Installation complete
Fig.10: Installation complete

Test it

Type the following command on Pi-hole to see if DNS is working or not:
$ host cyberciti.biz 10.8.0.1
Sample outputs:

Using domain server:
Name: 10.8.0.1
Address: 10.8.0.1#53
Aliases: 

cyberciti.biz has address 75.126.153.202
cyberciti.biz mail is handled by 1 aspmx.l.google.com.
cyberciti.biz mail is handled by 10 aspmx2.googlemail.com.
cyberciti.biz mail is handled by 10 aspmx3.googlemail.com.
cyberciti.biz mail is handled by 5 alt1.aspmx.l.google.com.
cyberciti.biz mail is handled by 5 alt2.aspmx.l.google.com.

Now try to lookup ad server IP address:
$ host pagead2.googlesyndication.com 10.8.0.1
Sample outputs:

Using domain server:
Name: 10.8.0.1
Address: 10.8.0.1#53
Aliases: 

pagead2.googlesyndication.com has address 10.8.0.1

As you can see 10.8.0.1 is not a valid public IP address hence any ads coming from pagead2.googlesyndication.com will be served by our own Pi-hole.

Update OpenVPN config to push our PI-hole dns server

Type the following command:
$ sudo vi /etc/openvpn/server.conf
Delete or comment out existing DNS entries:
#Stop using Google DNS for our OpenVPN
#push "dhcp-option DNS 8.8.8.8"
#push "dhcp-option DNS 8.8.4.4"

Next add our PI-Hole DNS IP address:
push "dhcp-option DNS 10.8.0.1"
Save and close the file. Restart the OpenVPN server:
$ sudo systemctl restart [email protected]

Open port 53 and 80 for our OpenVPN subnet

Type the following commands:
$ ufw allow proto tcp from 10.8.0.0/24 to 10.8.0.1 port 80
$ ufw allow proto tcp from 10.8.0.0/24 to 10.8.0.1 port 53
$ ufw allow proto udp from 10.8.0.0/24 to 10.8.0.1 port 53

Now reconnect all OpenVPN clients and you should able to browser everything without ads on your mobile devices. You can view PI-hole stats with the following url:
http://10.8.0.1/admin/
Sample outputs:

Fig.11: Pi-Hole admin/stats area
Fig.11: Pi-Hole admin/stats area

You can white-list or blacklist certain domains.

Conclusion

And there you have it, Pi-hole installed and configured on Debian or Ubuntu Linux along with an OpenVPN server. See Pi-hole.net for more information.

11 comment

  1. Hi, great tutorial!

    Unfortunately, my Android phone (Nexus 6P, running 7.1.1 DP 2) doesn’t correctly copy the DNS server settings pushed by the OpenVPN server. Is there something I can do about this?

  2. Hello and thanks for your toturial.

    I was looking for something of this type but also solution to another problem. Is it possible to have pi-hole work with a VPN client?
    For what I have seen in google searches and and tests that I have already done with another software (script ab-solution) in conjunction with the openvpn client the ads are not blocked because of the resolution of dns in the dnsmasq file and because of the options Strick or exclusive in client configuration.
    If I put the option strick I get the ad blocking to work but I have dns leak, if I put the option in exclusive I do not have dns leak, but I do not have ad blocking.

    Can you help me?

    Thank you.

  3. Hi. Can you give the `iptables` direct command that corresponds to
    ufw allow proto udp from 10.8.0.0/24 to 10.8.0.1 port 53

    Here is my current situation:

    I have OpenVPN-2.4 running on my Ubuntu 16.04 server, and also running on my clients: dd-wrt router, Windows x64 Pro, and Android 7.1.1.

    In my Ubuntu /etc/openvpn/server.conf I have
    push “dhcp-option DNS 10.8.0.1”

    I want my clients to use the server’s iptable rules set up to block a list of IP addresses.

    I have have tried several sets of iptable rules in my Ubuntu server /etc/init.d/openvpn file, not of which work. E.g., I try
    blacklist IP:
    iptables -A INPUT -s IP -j DROP
    delete blacklisted IP
    iptables -D INPUT -s IP -j DROP
    to test an IP that I can use in one of my client browsers.

    I have tried (uncommented iptables lines are used currently):

    # iptables -A INPUT -i tun+ -j ACCEPT
    # iptables -A FORWARD -i tun+ -j ACCEPT
    # iptables -A FORWARD -i tun+ -o eth0 -m state –state RELATED,ESTABLISHED -j ACCEPT
    # iptables -A FORWARD -i eth0 -o tun+ -m state –state RELATED,ESTABLISHED -j ACCEPT
    # iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    # iptables -A OUTPUT -o tun+ -j ACCEPT

    ## from Linode doc
    /sbin/iptables -A FORWARD -m state –state RELATED,ESTABLISHED -j ACCEPT
    /sbin/iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
    /sbin/iptables -A FORWARD -j REJECT
    /sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    /sbin/iptables -A INPUT -i tun+ -j ACCEPT
    /sbin/iptables -A FORWARD -i tun+ -j ACCEPT

    Otherwise, my VPNs seem to be working fine.

    Thanks.

    Lester

  4. Hi there, i thought your tutorial was very clear and easy to get through. It worked very well…. for a few hours hahaha! Now I keep having problems connecting my openvpn. I cant ssh into my pi, but when I reboot AND restart the openvpn server it seems to be working again. For a few hours! I’ve checked out the IPtables and they seem to be messed up when I cant ssh into my pi anymore. The weird thing is it works fine for a few hours, only after reconnecting/spending some time on the vpn it stops working completely. Anybody else had this problem or knows a solution?! Thank you!

    1. That is weird. You need to make sure you are not running out of memory. Also what OS and version? What is the version Kernel? Older kernels have bugs on Ubuntu that killed process randomly. Make sure you are using latest kernel. HTH

  5. Hi would i be able to setup raspberry pi and also use openvpn to set up my paid vpn such as private intenet access for example?

Leave a Comment