Due to Covid-19, most of people are working at home. Nowadays, advertising consumes a lot of your bandwidth and it is not safe for non-IT people, especially for your little kids. Pi-hole is what you need for this task.

What is Pi-hole

Pi-hole is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole, intended for use on a private network. Wikipedia.

Setup pi-hole

My Pi-hole is setup under docker container inside ClearLinux VM which is also running Nginx Proxy Manager. Since you can point your domain to your home IP and if  you want to expose the Pi-hole web, you can also setup VIRTUAL_HOST that point to your domain. You can do the same with your Rasberry Pi.

Below is docker-compose.yml file and connect to nginx-network created early with Nginx Proxy Manager, so I can access to pihole at https://dns.bacnh.com.

# Domain: dns.bacnh.com
# host: pihole
# Port: 80
version: "3"

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp"
      #- "80:80/tcp"
      #- "443:443/tcp"
    environment:
      - TZ='Asia/Ho_Chi_Minh'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # Volumes store your data between container upgrades
    volumes:
       - 'etc-pihole/:/etc/pihole/'
       - 'etc-dnsmasq.d/:/etc/dnsmasq.d/'
    dns:
      - 127.0.0.1
      - 1.1.1.1
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped
    networks:
      - nginx-proxy
volumes:
  etc-pihole:
  etc-dnsmasq.d:
networks:
  nginx-proxy:
    external:
      name: nginx-network

In order to run this docker, I need to stop systemd-resolved service running inside ClearLinux which occupied port 53 (DNS port), so I need to disable this service and change the DNS local server to 127.0.0.1. By doing this, all DNS requests inside my Linux box will send to 127.0.0.1:53

sudo systemctl stop systemd-resolved

cat /etc/resolv.conf 
search lan
nameserver 127.0.0.1

Then, you can bring your Pi-hole up:

docker-compose up

As recomended by pi-hole, admin password is generated randomly, you can check Pi-hole log to get admin password:

docker logs pihole | grep random

Setup your OpenWrt router

As we managed our own router firmware using OpenWrt, you need to tell your router to send  Pi-hole IP 192.168.11.20 as DNS-server to client.

Go to Interfaces >> Lan >> DHCP Server >> Advanced Settings, inside DHCP-Options enter value: 6,192.168.11.20.

alternative way, you can use uci tool:

uci set dhcp.lan.dhcp_option='6,192.168.11.20'
uci commit dhcp
/etc/init.d/dnsmasq restart

Then, you can check from client side, that can get DNS server as 192.168.11.20.

Now I can enjoy seeing Pi-hole is blocking ads for all my home clients and the web browser is much much faster than ever. If you want to take advantage of this DNS, you can open port 53 to your pi-hole and setup your remote devices to use your WAN IP.

config redirect
	option dest_port '53'
	option src 'wan'
	option name 'DNS'
	option src_dport '53'
	option target 'DNAT'
	option dest_ip '192.168.11.20'
	option dest 'lan'

Result from pi-hole admin:

Good luck!