Back

Setting Up Pihole on CentOS 7

2020-12-08

Table of Contents
  1. Set Up
  2. Installing Pihole
  3. Web Interface
  4. Adding to the Block Lists

Pihole is a network wide ad blocker. It basically uses a blacklist of domains so that no requests will go out from your network from those domains. A very cool feature though it doesn't have some privacy issues. I don't want to know what people on my network are doing.

But I wanted to try it out, unfortunately it was a bit of a pain to get installed on centos 7 so I'll outline my steps below.

Pihole has 2 parts to it, the first is the command line utility which I think is straightforward to install and use. The second part is the web interface that gives access to pihole. This was a little finicky and these steps are for the web interface specifically.

Pihole uses php and sqlite. This is in contrast to the UniFi Server which uses java and mongodb!

Pihole has the option of using lighthttpd as it's webserver but I already have nginx set up so we'll use that.

Let's get started!

Set Up

We first need to install sqlite3 as this is the database that pihole uses.

bash
yum install sqlite3

Next we need to install php and some extensions.

bash
# yum install php-fpm php-xml php-sqlite3 php-intl

php-fpm is a php processor that nginx can use to start php processes. php-xml isa package to let php manipulate xml easily. php-sqlite3 is the connector to sqlite3, really it is installing php-pdo which is a wrapper orm for multiple sql databases. php-intl is a package to handle internationalization.

Now we have everything ready for our pihole installation!

Installing Pihole

# curl -sSL https://install.pi-hole.net | bash

This will start the installer and for the most part it is straightforward to follow along with. Make sure to skip installing lighthttpd as we will be using nginx.

Once the installer is finished we will have a few different things set up.

We will now have access to the pihole command which will let interact with pihole via the commandline

bash
# pihole -g -r 
# pihole -b "googleadservices.com"
# pihole restartdns

Here we have a rebuild of the pihole database, called gravity. We also have an blacklist addition and a full restart of pihole.

We will also have the pihole configuration files located in /etc/pihole. This is also where the pihole database is stored.

We also have installation files located at /opt/pihole. I had to make a small change to gravity.sh in this folder as gravity was trying to set up 6 columns for 7 pieces of data.

bash
...
elif [[ "${table}" == "adlist" ]]; then
         # Adlist table format
         echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${source}\"," >> "
...

I added one more comma after the Migrated From column.

bash
# pihole -g -r

With that I rebuild the pihole database and away we go!

Now we have pihole installed. Now we need to allow it to talk over port 53 as that is the DNS port.

bash
# firewall-cmd --permanent --zone=public --add-service=dns
# firewall-cmd --reload

We have now updated our firewall so that pihole can begin working!

We can update /etc/resolv.conf and add our DNS IP as the first line.

bash

# Generated by NetworkManager
search localdomain
nameserver 192.168.7.41
nameserver 1.1.1.1
nameserver 1.0.0.1
# service NetworkManager restart
bash
# nslookup google.ca
Server:         192.168.7.41
Address:        192.168.7.41#53

Non-authoritative answer:
Name:   google.ca
Address: 172.217.1.3
Name:   google.ca
Address: 2607:f8b0:400b:80f::2003

We added a new DNS server to our server and then we restart the network and voila! We can use nsloop and see that we are using our new DNS server to do lookups!

Web Interface

Now that we have pihole up and running, we just need to wire it up to nginx.

Another folder that the pihole installation created is under /var/www/html/pihole. This is where the web interface files are located.

Let's update our nginx configuration.

/etc/nginx/sites-available/pihole.conf

server {
    listen 7082;
    listen [::]:7082;

    root /var/www/html;
    server_name _;
    autoindex off;

    index pihole/index.php index.php index.html index.htm;

    location / {
        expires max;
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param FQDN true;
        auth_basic "Restricted"; # For Basic Auth
        auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location /*.js {
        index pihole/index.js;
        auth_basic "Restricted"; # For Basic Auth
        auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location /admin {
        root /var/www/html;
        index index.php index.html index.htm;
        auth_basic "Restricted"; # For Basic Auth
        auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location ~ /\.ht {
        deny all;
    }
}

The key lines in this configuration is the port to listen on as we'll need to allow this in the firewall and the fastcgi_pass option as we'll need to make sure that matches what's php-fpm is configured for.

Let's update our php-fpm configuration.

/etc/php-fpm.d/www.conf

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9000

Here we want php-fpm to be listening on port 9000 on localhost. This is what is in the nginx configuration as well.

bash
# systemctl enable php-fpm
# service php-fpm start

Now we enable php-fpm to start on boot and start it now.

bash
# service nginx restart

Now we have our pihole web interface working!

We just have one more step, we need to allow the firewall to allow the web interface to be accesible from outside localhost.

/etc/firewalld/zones/public.xm

...
<port protocol="tcp" port="7082"/>
...
bash
# firewall-cmd --reload

We add the port we specified in our nginx configuration and we restart the firewall and voila! We are done!

We now have our web interface wired up.

One last thing we need to do is set up a password as pihole password protects the directories.

bash
# yum install httpd-tools
bash
# htpasswd -c /etc/nginx/.htpasswd nivethan

We create a password and now we can navigate to 192.168.7.41:7082/admin and login to the web interface monitor our pihole!

We are now done and have our pihole set up!

Adding to the Block Lists

Pihole by default has 2 blocklists.

We're going to add some blocklists from:

https://firebog.net/

We can add the links directly to /etc/pihole/adlists.list.

/etc/pihole/adlists.list

bash
https://raw.githubusercontent.com/PolishFiltersTeam/KADhosts/master/KADhosts_without_controversies.txt
https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Spam/hosts
https://v.firebog.net/hosts/static/w3kbl.txt
bash
# pihole -g

We now rebuild the pihole database and with that we have our new blocklists working!

With that we are now done setting up pihole!