A couple of years ago I started using Pi-Hole installed on a Raspberry Pi to block advertisements for devices on my local network at home. It works great for laptops and mobile devices. My family members like playing mobile games which in most cases are full of ads. With Pi-Hole these are history. (most of the time)
Last year I bought a new Synology NAS (DS218+) which due to the presence of a Intel CPU has many great advantages like running docker and virtual machines. The DS218+ comes with 2GB internal memory and can be officially expanded to 6GB by placing an extra 4GB memory in the expansion slot of the DS218+.
But in spite of the official limitation an extra 8GB memory modules can be placed to beef up your diskstation to a whopping 10GB. I bought a Crucial memory module on Amazon for a few extra Euro’s over the official 4GB module. (DISCLAIMER: Use it on your own risk. I hold no responsibility).
Now back to Pi-hole: I decided to run more services on docker for obvious reasons:
- Isolation means better security
- Isolation means less conflicts with other services
- Easier deployment
- Easier updating
- Less resources/overhead in comparison to virtual machines
The main problems running Pi-Hole in a docker container on Synology is the available TCP ports. Port 80 is occupied on the Synology but needed for Pi-Hole to function properly. I serves ads as blank pages from it’s intenal webserver.
This article is all about solving this issue. I found part of the solution here. But my German is not sufficient enough so I ran it through Google translate, and wrote this tutorial in English.
Step 1. Introduce MACVLAN to your Synology
To run Pi-Hole on your Synology it needs its own IP-address in the same subnet as your Synology instead of the private Docker subnet. To accomplish that we need a so called MacVLAN.
First step, if not already done, is install Docker enable SSH access on your Synology.
Open package center:
Search for “docker” and hit “Install”. In my case the button says “Open” since it is already installed.
Now enable SSH access to your Synology, because creating a MACVLAN is a command line operation. In your Synology Control Panel tick the “Enable SSH service” checkbox and hit “Apply”. I strongly recommend SSH over Telnet because telnet lacks any form of encryption over the network.
Connect to the Synology IP through SSH (e.g. using Putty) and run the following command using your own network parameters at home/work:sudo docker network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.1 --ip-range=192.168.2.160/27 --aux-address 'host=192.168.2.160' -o parent=ovs_eth0 mac0
- –subnet=192.168.2.0/24
- This is the subnet the Synology resides in.
- –gateway=192.168.2.1
- The default gateway for my network. This is the default gateway in your network. E.g. the internet router.
- –ip-range=192.168.2.160/27
- A subrange of your ip range the dockers with dedicated IP adresses will be residing. Make sure other servers will not use addresses in this IP range and your DHCP server is not serving out these addresses. To calculate an IP-block there are several online subnet calculators available.
- This range will reserve 30 Ip adresses for use with Dockers. If you need more or less adresses you can use other values.
- –aux-address ‘host=192.168.2.160’
- This is the address that will be added to the Synology NAS. The dockers on the MACVLAN will be using this address to communicate to the Synology if needed.
- -o parent=ovs_eth0 mac0
- This is a tricky one: in my case the interface is “ovs_eth0” because I have the Virtual Machine Manager installed. Otherwise this probably will be “eth0”. To be absolutely sure run the
ifconfig
command on your Synology (in the SSH session). The interface which has your Synology IP address is the one you should use.
- This is a tricky one: in my case the interface is “ovs_eth0” because I have the Virtual Machine Manager installed. Otherwise this probably will be “eth0”. To be absolutely sure run the
Now the MACVLAN network named “mac0” is created. You can check this in your Docker configuration:
To make traffic possible between the host (Synology) and the Pi-Hole container we are about to create, we need to create an extra virtual network interface on the Synology with the ip of 192.168.2.160. (Remember the --aux-address 'host=192.168.2.160'
parameter?)
Run the following code on your Synology NAS (again replace IP and subnet to match your network:
#Create virtual NIC mac1
ip link add mac1 link ovs_eth0 type macvlan mode bridge
ip addr add 192.168.2.160/32 dev mac1
ip link set mac1 up
ip route add 192.168.2.160/27 dev mac1
Unfortunately this interface is lost at reboot. Therefore I created a scheduled task to run this script every 5 minutes. Make sure to run this under root privileges. I used the Task Scheduler in the Synology GUI
This was the first step. No worries.. This was the hard part!
Step 2. Create the Pi-Hole docker container
You can create the container with either the GUI or the command line. The downside of the GUI is you cannot control the IP adress assigned to the container. It will be assigned in order of start of the containers attached to the MACVLAN.
So I prefer to create the container using the command line:docker create --name=con-pihole --net=mac0 --ip=192.168.2.189 -it pihole/pihole:latest
- –name=con-pihole
- This is the name of your container. I use “con” as a prefix so I can distinguise the Dockers containers in my network
- –net=mac0
- The name of the in Step 1 created MACVLAN
- –ip=192.168.2.189
- The IP address for the docker container
- -it pihole/pihole:latest
- The image to be used for the container creation. “pihole/pihole” is the official container maintained by Pi-Hole. “Latest” points to the release/version. If not on the Docker host, the image will be downloaded.
Now the container is created we have to make a few changed before starting the container.
Go to your Docker GUI in Synology, select the Pi-Hole container and click “Edit” and make the following changes:
General Settings: Enable auto-restart
Volume:
Add these entries. The left side is a local path on your Synology. The right side represents the path in the container.
– dnsmasq.d and pihole are directories the Pi-Hole container stores its settings
– hosts is a host file which I use to create static DNS entries for my internal network. Ergo, a poor-mans-DNS-server 🙂
If you don’t make any mappings, settings will be lost during upgrades/updates.
The Environment and Links sections can be skipped. In Environment we have a couple of settings.
- WEBPASSWORD
- This is the obvious password for the webpage
- PUID and PGID
- These are necesarry for the container to obtain access to the local filesystem. Run the
id $user
command on your Synology to get these. The result will look likeuid=1111(admin) gid=222(users) groups=333(users),444(administrators)
. Use the number before admin for PUID and administrator for PGID.
- These are necesarry for the container to obtain access to the local filesystem. Run the
- TZ
- TimeZone: Check Wikipedia for a list of timezones.
- ServerIP
- The IP of your Docker container. In this example 192.168.2.189
Now the Pi-Hole container is ready to start.
Step 3. Make devices use Pi-Hole
There are two options to make your network use your new Pi-Hole docker container.
You can change the DNS entry in your DHCP server to point to your Pi-Hole instance. Or you can make the Pi-Hole container the DNS server for your internet router, this is probably your network clients current DNS server. I prefer the last option. This is more easy during maintenance of your Pi-Hole docker container.
Final thoughts
That’s it. You now have a advertisement blocking Docker container on your Synology.
You may want to change some settings but their optional. You can make them on the web management page (http://pi.hole/admin or http://<pi-hol ip>/admin)
- Upstream DNS: Standard set to the Google DNS servers, but there al lots of more options. I picked the Quad9 servers (9.9.9.9). Those are less privacy invasive and they have an option filtering out wel known addresses which are serving malware. Thus, better security.
- You can whitelist and/or blocklist specific entries
- When in trouble you can disable filtering for a specific time (or permanently)
Nice article!! I followed the macvlan part for other docker containers as i don’t use Pihole. And i changed a little on the script for adding the macvlan bridge network after an reboot. I created a triggered script in the synology that only runs on boot, and added a line that loops until the ovs_eth0 is up before executing the commands:
while ! ip link show ovs_eth0 | grep -q ‘state UP’; do
sleep 1
done
ip link add macvlan0 link ovs_eth0 type macvlan mode bridge
ip addr add 192.168.1.176/28 dev macvlan0
ifconfig macvlan0 up
THanks for the nice addition!
Thanks for the great instructions, sadly it did not work for me, hit a problem that a small number of others seem to have had with the pihole docker image. my logs show this:
Added ENV to php:
“ServerIP” => “10.0.0.225”,
“VIRTUAL_HOST” => “10.0.0.225”,
“PHP_ERROR_LOG” => “/var/log/lighttpd/error.log”,
“ServerIP” => “0.0.0.0”,
“VIRTUAL_HOST” => “0.0.0.0”,
and then:
FTL started!
::: Testing lighttpd config: Error: duplicate array-key: ServerIP. Please get rid of the duplicate entry.
No idea where the duplicate env entries are coming from.
In your comment the ServerIP entry appears twice. Remove the
“ServerIP” => “0.0.0.0”,
I have the same error, the entry does not appear twice. Fix unknown at this stage…..