Running PiHole on OpenWrt (x86) using Docker - Tutorial/Experiences

I have recently been able to run PiHole on OpenWrt x86 using Docker. Before OpenWrt I had an Ubuntu Docker host which was running the PiHole container. The PiHole container was attached to the LAN network using Linux/Docker macvlan. Also for the Ubuntu Host to be able to ping the PiHole container, a workaround posted on stackoverflow was applied which creates a linux macvlan that the container uses. Giving PiHole an IP Address different than the IP Address of the host greatly simplifies the setup and prevents any conflict with DNS/DHCP/HTTP ports overlapping.

The idea for setting this up on OpenWrt is very similar and so would like to share it with rest of the community and get some feedback. Bear in mind that this was tested on OpenWrt x86 and may differ or otherwise be unsupported for other targets. The goal of this tutorial is to setup PiHole as an AdBlock DNS server only without using it's DHCP capabilities (DHCP is handled by OpenWrt).

Install Docker and Docker-Compose on OpenWrt

opkg update && opkg install docker luci-app-dockerman docker-compose

Setup MACVLAN interface in OpenWrt

Here the MACVLAN interface will be created which is a virtual interface bridged to current LAN interface. This interface will later be used by Docker and PiHole.

vi /etc/config/network

Look for the config interface 'lan' section and note down the device from the option device line. In my case it is br-lan.

Add the following at the end of the file. The key part here is option device and option name which is the same device as in the lan section with .20 suffix.

config interface 'macvlan'
        option proto 'static'
        option defaultroute '0'
        option netmask '255.255.255.255'
        option device 'br-lan.20'
        option ipaddr '192.168.1.2'

config device
        option type 'macvlan'
        option ifname 'br-lan'
        option mode 'bridge'
        option name 'br-lan.20'
        option acceptlocal '1'

config route
        option interface 'macvlan'
        option target '192.168.1.3'
        option netmask '255.255.255.255'

Modify the firewall adding the new interface to the lan zone

vi /etc/config/firewall

Look for section similar to below:

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

Then add the following line to it:

        list network 'macvlan'

Restart the network and firewall services

/etc/init.d/network restart 
/etc/init.d/firewall restart

Setup docker-compose.yml and PiHole

cd ~
vi docker-compose.yml

Copy and paste the following and save. The following was retrieved from PiHole docs and slightly modified to fulfill our purpose. In the netowrk section at the bottom, the parent is set to the new macvlan interface created in the previous step from the option device line (the one with suffix .20). Also, the PiHole container will have a static IP which I've set to 192.168.1.3.

version: "3.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
    hostname: pihole.lan
    environment:
      # TZ: 'set timezone'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # Volumes store your data between container upgrades
    volumes:
      - './pihole/etc-pihole/:/etc/pihole/'
      - './pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/'
      - './pihole/var-log/:/var/log'
      - './pihole/etc-cont-init.d/10-fixroutes.sh:/etc/cont-init.d/10-fixroutes.sh'
    # 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:
      internal:
      lan:
        ipv4_address: 192.168.1.3

networks:
  internal:
  lan:
    name: lan
    driver: macvlan
    driver_opts:
      parent: br-lan.20
    ipam:
      config:
        - subnet: 192.168.1.0/24

Create the folders for the volumes:

mkdir -p ./pihole/etc-pihole/
mkdir -p ./pihole/etc-dnsmasq.d/
mkdir -p ./pihole/var-log/
mkdir -p ./pihole/etc-cont-init.d/

Create 10-fixroutes.sh.

echo '#!/usr/bin/with-contenv bash
set -e

echo "fixing routes"
ip route del default
ip route add default via 172.18.0.1
echo "done fixing routes"' >> ./pihole/etc-cont-init.d/10-fixroutes.sh

Start PiHole and finalize its setup

cd ~
docker-compose up -d pihole
docker logs -f pihole

Wait for PiHole to finish starting up and then hit CTRL+C. Then run the following:

cd ~/pihole/etc-pihole
sed -i -e 's/REV_SERVER.*//; s/REV_SERVER_CIDR.*//; s/REV_SERVER_TARGET.*//; s/REV_SERVER_DOMAIN.*//; s/PIHOLE_INTERFACE.*//' setupVars.conf
echo 'REV_SERVER=true
REV_SERVER_CIDR=192.168.1.0/24
REV_SERVER_TARGET=127.0.0.11
REV_SERVER_DOMAIN=lan
PIHOLE_INTERFACE=eth0' >> setupVars.conf

Restart PiHole container

docker restart pihole

Test

You could do some testing and see if it works. From another machine connected to the LAN network or WiFi:

ping 192.168.1.3
nslookup openwrt.org 192.168.1.3
nslookup $(hostname).lan 192.168.1.3

Open PiHole admin: http://192.168.1.3/admin

If all of the above works then PiHole container is ready to be the DNS server for your devices on the LAN network.

Configure DNS settings in OpenWrt and Profit!

vi /etc/config/dhcp

Look for the following section:

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'

Then add the following line to it:

        list dhcp_option '6,192.168.1.3'

Restart dhcp service:

/etc/init.d/dhcp restart

Disconnect and reconnect your devices (or wait for the DHCP leases to expire) and enjoy ad blocking!

Troubleshooting

Pinging PiHole IP is not working or opening the PiHole admin is not working

This would mean that something is wrong with macvlan interface or the docker-compose.yml network related section. Check again these two steps from before.

nslookup openwrt.org 192.168.1.3 is not working

Check the interfaces in the PiHole container:

docker exec -it pihole ip a

Look for an interface with the IP Address that starts with 172. Is it having the same first three numbers 172.18.0 (the subnet) same as in the 10-fixroutes.sh script? If not then modify 10-fixroutes.sh and fix the subnet to be matching (keeping the last number .1 as is) and then restart the container.

nslookup $(hostname).lan 192.168.1.3 is not working

There could be multiple reasons for this, but the basic idea from this test is to ensure that PiHole is forwarding any lookup with .lan suffix to OpenWrt DNS. OpenWrt creates DNS entries for the devices connecting to the LAN network on the fly with .lan suffix (as in belonging to the lan domain). Check again setupVars.conf, make sure of REV_SERVER_TARGET=127.0.0.11 in there (notice the extra 1 in the end, that is because 127.0.0.11 is the embedded Docker DNS which eventually forwards to OpenWrt local DNS).

4 Likes

Thanks for this great tutorial ! :+1:

1 Like

Thank you, and thanks to the devs and community for getting us there!

1 Like

hi,

thanks for the guide! could you please elaborate why you decided to use pihole over "native" adblock (i.e. no docker wrap is required)? what are the benefits you see with pihole please? can you setup pihole to provide service to multiple subnets (e.g. lan less restrictive, guest restrictive, IoT most restrictive)? can you integrate pihole UI with LuCI?

thanks in advance.

1 Like

Hi, and thank you for your message

Do you mean running pihole without using docker? If so then one reason for running it with docker is that currently OpenWrt by default runs dnsmasq and dhcp service which reserve ports 53 and 67 on all of its interfaces. Running it without using docker would require to disable/modify one or both services, I find that unnecessary and complicated compared to docker setup I've done because docker can give me network isolation between container and host hence avoiding any conflicts. It not impossible to run pihole without using docker, just has extra work.

Benefits of PiHole compared to what? Generally speaking its a great AdBlock DNS service, I didn't do too much comparison between it and other AdBlock DNS services available and just went with it and so far did not find any shortcomings in using it.

Its definitely possible, in theory I would setup multiple macvlan interfaces in OpenWrt and have PiHole container attached to them. There might be some extra configuration needed to be done on PiHole which I recall reading about in its release notes and I have a feeling that it would work.

What's the end goal here? Honestly I consider setting up something like heimdall on an Ubuntu Docker host and adding links to PiHole admin and OpenWrt luci. If its for statistics I currently rely on HomeAssistant which has an integration with PiHole but any other solution could work.

1 Like

sorry maybe was not clear enough:

dnsmasq + adblock are providing similar services (i.e. DHCP, DNS filtering), am wondering what are the benefits using docker + pihole? i understand that docket is a workaround here for the reason you mentioned.

am not familiar with pihole to be honest hence wondering is it worth to replace my current setup (dnsmasq + adblock). looks it is just a matter of choice, right?

1 Like

give it a try...
There is also AdGuard Home, as alternative to AdBlock !

Not at all. With dnsmasq + adblock setup, as far as I understood its done by editing the dnsmasq.conf file and downloading one of the adblock txt lists for dnsmasq to use for blocking. PiHole has that and adds to it periodic adblock list updates, query logs, statistics, per client configuration, and a nice UI to manage all of that and more. Definitely worth a try.

@ahasbini . @erdoukki - thanks, yes probably i will give a try. the per client setup sounds interesting.

edit: i have checked pihole. couple of comments:

  1. i found the guide above missing installation of dockerd, kmod-macvlan, without it i could not start docker.
  2. according to https://docs.pi-hole.net/main/origins/ it is using dnsmasq too under the hood :slight_smile:
  3. indeed looks very fancy with a nice web gui, i can understand why to use it.
2 Likes

Congrats!

You're right I totally missed those two packages. I'll mark your post as the solution as it seems the time window for editing the original post has expired.

I think it's always good to be able to learn and compare new and different ways to achieve desired goals with existing known solutions. While I don't use either PiHole, nor AdBlock as I do prefer AdGuard Home, I understand different people may prefer different things. After all, this is not Ford in the early days, when you could have any car color, as long as it was black...

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.