Skip to content

Instantly share code, notes, and snippets.

@xirixiz
Last active June 10, 2024 08:44
Show Gist options
  • Save xirixiz/ecad37bac9a07c2a1204ab4f9a17db3c to your computer and use it in GitHub Desktop.
Save xirixiz/ecad37bac9a07c2a1204ab4f9a17db3c to your computer and use it in GitHub Desktop.
Add a PiHole instance on a macvlan enabled Docker network (Synology eth0 example)
#!/bin/bash
# NAS IP: 192.168.1.10 in this example
# DHCP scope reservation for macvlan: 192.168.1.210/28 (Details below)
## Network: 192.168.1.210/28
## HostMin: 192.168.1.211
## HostMax: 192.168.1.224
## Hosts/Net: 14
# Create a Synology macvlan0 bridge network attached to the physical eth0, and add the ip range scope (sudo)
ip link add macvlan0 link eth0 type macvlan mode bridge
# Specify part of the eth0 scope you'd like to reserve for macvlan0
ip addr add 192.168.1.210/28 dev macvlan0
# Bring up the macvlan0 adapter
ip link set macvlan0 up
# Check virtual adapter status with ifconfig
ifconfig
# Output should be something like this:
macvlan0 Link encap:Ethernet HWaddr 92:8D:43:0E:E2:D8
inet addr:192.168.1.210 Bcast:0.0.0.0 Mask:255.255.255.240
inet6 addr: fe80::908d:43ff:fe0e:e2d8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:79 errors:0 dropped:0 overruns:0 frame:0
TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:34863 (34.0 KiB) TX bytes:16322 (15.9 KiB)
# Create a macvlan Docker network using eth0
docker network create --driver=macvlan --gateway=192.168.1.1 --subnet=192.168.1.0/24 --ip-range=192.168.1.210/28 -o parent=eth0 macvlan
# It's also possible to create a scheduled task at startup as the root user, it's wise to append the following in front of the above commands
while ! ip link show eth0 | grep -q 'state UP'; do
sleep 1
done
# Perform a basic test with NGINX
docker run --net=macvlan -dit --name nginx-test-01 --ip=192.168.1.211 nginx:alpine nginx-debug -g 'daemon off;'
# Browse to http://192.168.1.211 in your local network, you should see the nginx welcome page! ...Don't forget to remove the container afterwards...
docker rm nginx-test-01 --force
# Now start PiHole on a macvlan enabled IP address f.e.
# Also I've added a fake mac address so the container always uses the samen mac, handy to make a reservation in your DHCP scope or do whatever you like to do with it.
DOCKERHOME=<some path>
NAME=pihole-macvlan
IMAGE=pihole/pihole
docker run --detach \
--name ${NAME} \
--restart always \
--volume /etc/localtime:/etc/localtime:ro \
--volume ${DOCKERHOME}/data/${NAME}/config:/etc/pihole \
--volume ${DOCKERHOME}/data/${NAME}/dnsmasq.d:/etc/dnsmasq.d \
--cap-add NET_ADMIN \
--dns=127.0.0.1 \
--dns=1.1.1.1 \
--env "DNS1=1.1.1.1" \
--env "DNS2=1.0.0.1" \
--env "ServerIP=192.168.1.212" \
--env "DNSMASQ_LISTENING=all" \
--env "WEBPASSWORD=<secret>" \
--env "TZ=Europe/Amsterdam" \
--network macvlan \
--ip "192.168.1.212" \
--mac-address "02:42:c0:a8:01:d7" \
${IMAGE}
# Cleanup macvlan
ip link set macvlan0 down
ip link delete macvlan0
docker network rm macvlan
# Happy days!
@titanbird
Copy link

titanbird commented Feb 14, 2022

Hi xirixiz.

Is the DHCP server set to use 192.168.0.201 as a DNS server for all clients?

Nope. For my tests, I change my desktop computer's connection settings to static and I set there 192.168.0.201 as the dns value.

I believe the config of pihole might have changes slightly, can you try it like this:

Oh okay. I will give it a try tomorrow. Which of the parameters do you think could lead now to success?

Best
titanbird

@titanbird
Copy link

Hi again :-)

No success yet. I deleted the pihole container and created a new one with

NAME=pihole-macvlanpihole
IMAGE=pihole/pihole
docker run --detach \
           --name ${NAME} \
           --restart always \
           --cap-add NET_ADMIN \
           --dns=1.1.1.1 \
           --env "DNSMASQ_USER=root" \
           --env "WEBPASSWORD=cVJNKQyYrJ7e" \
           --env "TZ=Europe/Amsterdam" \
           --network macvlan \
           --ip "192.168.0.201" \
           --mac-address "02:42:c0:a8:01:d7" \
           ${IMAGE}

But the same error happens (DNS_PROBE_FINISHED_BAD_CONFIG or DNS_PROBE_STARTED).
From inside the new container, ping google.com still leads to the same error as yesterday.

Very confusing because I can see all the queries within the pihole management gui:

grafik

grafik

Cheers and thanks
titanbird

@xirixiz
Copy link
Author

xirixiz commented Feb 15, 2022

I switched to AdGuard a while ago as AdGuard has an intergrated solution to handle different upstream DNS servers per subnet/client.
However, can you validate the upstream DNS servers in PiHole. Maybe set those to a basic non-tls upstream just to validate whether it's working.

https://discourse.pi-hole.net/t/how-do-i-choose-an-upstream-dns-server/258/10

Could also be the settings on the listening part of the interfaces (allowed list). Please validate that as well. Must be something like that.

image

@titanbird
Copy link

titanbird commented Feb 15, 2022

Thanks for the helpful stuff.

The interface listening behavior was already fine and the dns settings were also fine.
No success.

I retried everything from scretch. Now it is working... Somehow?! :-))

Here is all I had to do in short (please note the little ip changes, maybe there is the key to success in my case):

docker network create --driver=macvlan --gateway=192.168.0.1 --subnet=192.168.0.100/24 --ip-range=192.168.0.200/28 -o parent=eth0 macvlan0

ip link add macvlan-shim link eth0 type macvlan mode bridge

ip addr add 192.168.0.205/28 dev macvlan-shim

ip link set macvlan-shim up

I thought maybe i have to set this one for eth0:
sudo ip link set eth0 promisc on
But in the end, it's not needed.
So I restored it to off in my case:
sudo ip link set eth0 promisc off

ifconfig macvlan-shim
Output:

macvlan-s Link encap:Ethernet  HWaddr A2:CA:BE:14:B5:3B
          inet addr:192.168.0.205  Bcast:0.0.0.0  Mask:255.255.255.240
          inet6 addr: fe80::a0ca:beff:fe14:b53b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:21169 errors:0 dropped:0 overruns:0 frame:0
          TX packets:987 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:2407069 (2.2 MiB)  TX bytes:133060 (129.9 KiB)
NAME=pihole-vlan
IMAGE=pihole/pihole
docker run --detach \
           --name ${NAME} \
           --restart always \
           --cap-add NET_ADMIN \
           --dns=1.1.1.1 \
           --env "DNSMASQ_USER=root" \
           --env "WEBPASSWORD=cVJNKQyYrJ7e" \
           --env "TZ=Europe/Amsterdam" \
           --network macvlan0 \
           --ip "192.168.0.200" \
           --mac-address "02:42:c0:a8:01:d7" \
           ${IMAGE}

I tried a ping command within the freshly created docker container to test if the gateway is accessible:
docker exec -ti pihole-vlan ping -c 4 192.168.0.1
Output:

PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=1.28 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=0.989 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=1.12 ms
64 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=1.75 ms

--- 192.168.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 0.989/1.281/1.745/0.288 ms

I tested it on my notebook right beside me.
Static DNS setting:
dns=192.168.0.200
It works.

grafik
grafik

I did not make any settings in the pihole gui itself, it worked out of the box this way.
Off course, you need a system startup script to execute the ip-commands above once a boot. 👍

@xirixiz
Copy link
Author

xirixiz commented Feb 15, 2022

Great! Good you managed to fix it! 🚀

@donluca87
Copy link

What about:
route add -net 192.168.0.212 netmask 255.255.255.254 dev macvlan0 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment