Introduction
In my previous article/tutorial, I’ve explained how to setup your own DNS-over-HTTPS (DoH) server using Nginx, Certbot, and dns-over-https. In this article I’ll explain to you how to add Pi-Hole into the mix to block the unwanted advertising.
Pi-Hole
Pi-Hole is made of 2 components: a PHP web interface and a DNS server. Both are open-source. The web interface let you add blacklist, whitelist and configure the DNS server. The DNS server is the one doing the heavy lifting, responding to the queries according to its configuration generated by the interface.
The name comes from the lightness of the application, it can run without problem on a raspberry pi in your own network.
Install
Installing Pi-Hole couldn’t be easier, you need to download their installer and run it.
Check the screenshots before running the command, or simply, be sure to disable lighttpd.
sudo apt install dialog curl -sSL https://install.pi-hole.net | bash
If you don’t want to use their installer, you try their docker image.
Configuration
This section will mostly contain screenshot showing you what to do to configure your Pi-Hole for it to works with the currently installed dnscrypt-proxy.
Steps
First select your favorite DNS Server (I choose OpenDNS with ECS)
Choose which blacklist you want. You’ll be able to add your own in the UI later.
You can keep this as default. If your machine doesn’t have IPv6, Pi-Hole will detect it.
We don’t want Lighttpd, since we already have Nginx. We’ll configure Nginx to serve the admin website.
Continue the installation until the last screen where it shows you the full config and admin password.
Before connecting to the UI, we’ll run a configuration command to set the password to what we want.
sudo pihole -a -p
This will ask you to set a new password.
Nginx
Since we don’t want to use lighttpd as webserver, we’ll have to configure Nginx.
Install
First we need to install PHP-fpm to take care of running the PHP website.
sudo apt install php7.2-fpm php7.2-zip
Configuration
Put the content of this file into /etc/nginx/sites-available/pihole
.
server { listen 80; listen [::]:80; root /var/www/html; server_name blocker.example.com; autoindex off; index pihole/index.php index.php index.html index.htm; location / { expires max; try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.2-fpm.sock; } location /*.js { index pihole/index.js; } location /admin { root /var/www/html; index index.php index.html index.htm; } location ~ /\.ht { deny all; } }
Don’t forget to change the server_name
for your domain name.
Then do a symlink to the enabled folder. Ask nginx to check that to configuration works, and reload nginx.
sudo ln -s /etc/nginx/sites-available/pihole /etc/nginx/sites-enabled/pihole sudo nginx -t sudo systemctl reload nginx
Certbot
As before, let’s make this domain an HTTPS one.
sudo certbot --nginx -d blocker.example.com
And Voila, the full UI is HTTPS and accessible with Nginx.
UI
There are 2 UI, a public one containing all the stats of the server and the Admin one letting you administrate your Pi-Hole.
Accessible at https://blocker.example.com/admin
. (Of course, the domain name need to be replaced by the one you are using).
Public
This is the basic UI. Right now everybody can see this but only the Admin can add new blacklist/whitelist and configure the whole solution.
Admin
Once you click on Login, you’ll see something different.
You have more detailed statistics about the different requests done on your DNS Server.
As you can see, I’ve just spawn the instance on GCP and I’m already getting scanned for DNS Server. There is a section about firewalling later in this guide. Basically we’re going to block the public port 53, since we don’t need everybody to do request to our Pi-Hole, only doh-server.
Double check the settings to see if the installer did select the right DNS server.
This what it supposed to look like. If it’s not the case, you can correct it.
Test
You can easily test your Pi-Hole server using dig
.
dig test.com @127.0.0.1 ; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> test.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18636 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;test.com. IN A ;; ANSWER SECTION: test.com. 2 IN A 0.0.0.0 ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Wed Oct 03 17:32:34 UTC 2018 ;; MSG SIZE rcvd: 53
This well check for the domain test.com
which is in one of the default blacklist.
As you can see the answer for it is 0.0.0.0
which is the default answer for blocked domains.
Blocked Answer Type
By default, Pi-Hole will return 0.0.0.0
for blocked domains. You can change this behaviour as documented on the official website.
Personally I prefer to return NXDOMAIN
for blocked domains, making the DNS clients think the domain doesn’t exists.
If you want NXDOMAIN
, do this command.
echo "BLOCKINGMODE=NXDOMAIN" | sudo tee /etc/pihole/pihole-FTL.conf sudo systemctl restart pihole-FTL
DoH-Server
Now that you have your Pi-Hole working, we need to reconfigure DoH-Server to use Pi-Hole as a source of DNS instead of dnscrypt-proxy.
# HTTP listen port listen = [ "127.0.0.1:8053", "[::1]:8053", ] # TLS certification file # If left empty, plain-text HTTP will be used. # You are recommended to leave empty and to use a server load balancer (e.g. # Caddy, Nginx) and set up TLS there, because this program does not do OCSP # Stapling, which is necessary for client bootstrapping in a network # environment with completely no traditional DNS service. cert = "" # TLS private key file key = "" # HTTP path for resolve application path = "/dns-query" # Upstream DNS resolver # If multiple servers are specified, a random one will be chosen each time. upstream = [ "127.0.0.1:53", ] # Upstream timeout timeout = 60 # Number of tries if upstream DNS fails tries = 10 # Only use TCP for DNS query tcp_only = false # Enable logging verbose = false
Change the upstream
servers to 127.0.0.1:53
.
Then restart the service.
sudo systemctl restart doh-server
There you go you now have a DoH server with Pi-Hole.
Firewalling
This is great, you have a fully working DoH server. But Pi-Hole like to listen on all interfaces. This is normal since it’s made to be installed on a Raspberry Pi in your own network with only a LAN interface.
But with a server on internet, that can be more than problematic. Your server could be used to DNS Flood other servers. We don’t want that.
UFW
We’re going to configure UFW to take care of the firewalling.
HTTP(s)
First we want all the HTTP and HTTPS traffic to be open on our machine. HTTP is used for by Certbot when validating that the domain belongs to you.
sudo ufw allow http sudo ufw allow https
SSH
Obviously we want to be able to administrate the server.
sudo ufw allow ssh
Default
And now everything else should be blocked on Inbound.
Final Touches
Enabling the firewall
sudo ufw enable
Checking that the rules are set correctly
sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 22/tcp ALLOW IN Anywhere 80/tcp (v6) ALLOW IN Anywhere (v6) 443/tcp (v6) ALLOW IN Anywhere (v6) 22/tcp (v6) ALLOW IN Anywhere (v6)
Now your server is firewalled correctly. Only HTTP, HTTPS and SSH traffic is accepted.
Conclusion
You have now a DoH server that blocks advertisings. You can use the admin interface of the Pi-Hole to change the whitelist and the blacklists. There are a lot of tutorial online on how to add new blacklist, etc .
Original Post by : aaflalo.me
Leave a Reply