-
-
Save xirixiz/ecad37bac9a07c2a1204ab4f9a17db3c to your computer and use it in GitHub Desktop.
#!/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! |
Thank bro,
We can use DNS server app on DMS and Pihole. :D
But on router -> Active DHCP Leases not show pihole IP
Can i add 02:42:c0:a8:01:d7 ,192.168.1.210 to static DHCP ?
Hi xirixiz. I'm stuck trying to get pihole working concurrently with a node.js server on Raspberry Pi 4. I want to avoid port conflicts and thought macvlan would be the best solution. Could you have a look and see if you can help?
I've got a node.js server running on wlan0, port 80, ip 192.168.0.51. Then, I do the following:
docker network create --driver=macvlan --gateway=192.168.0.1 --subnet=192.168.0.51/24 -o parent=wlan0 piholenet
sudo ip link add piholenet0 link wlan0 type macvlan mode bridge
sudo ip addr add 192.168.0.208/28 dev piholenet0
sudo ifconfig piholenet0 up
docker run --net=piholenet -d --ip=192.168.0.208 -p 80:80 nginx
So far so good, I have both interfaces up and running with different IP and MAC addresses:
piholenet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.208 netmask 255.255.255.240 broadcast 0.0.0.0
inet6 fe80::3257:c36e:cf43:8c9c prefixlen 64 scopeid 0x20
ether 3e:9b:6e:26:e8:83 txqueuelen 1000 (Ethernet)
RX packets 226 bytes 15635 (15.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 134 bytes 22827 (22.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.51 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::291a:bf94:ff88:f094 prefixlen 64 scopeid 0x20
ether dc:a6:32:3c:62:c8 txqueuelen 1000 (Ethernet)
RX packets 42672 bytes 4612986 (4.3 MiB)
RX errors 0 dropped 76 overruns 0 frame 0
TX packets 13875 bytes 4097060 (3.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
However, when I go to 192.168.0.51 or 192.168.0.208 they both show the website I am hosting on node.js. I also can't see piholenet0 listed on my router. What am I doing wrong?
It's been a while since I used macvlan, but can you try it like this:
Cleanup first (remove containers using piholenet first!):
sudo ip link set piholenet0 down
sudo ip link delete piholenet0
docker network rm piholenet
Create a 'fresh' macvlan and run a nginx container:
sudo ip link add piholenet0 link wlan0 type macvlan mode bridge
sudo ip addr add 192.168.0.210/28 dev piholenet0
sudo ip link set piholenet0 up
docker network create --driver=macvlan --gateway=192.168.0.1 --subnet=192.168.0.0/24 -o parent=wlan0 piholenet
docker run --net=piholenet -dit --name nginx-test-01 --ip=192.168.0.211 nginx:alpine nginx-debug -g 'daemon off;'
Thanks so much for the response!
I've tried the above but no luck, ended up with piholenet0 with ip 192.168.1.210. Neither 192.168.1.210 nor 192.168.0.210 show any nginx welcome page - connection times out.
I retried the above changing this line:
sudo ip addr add 192.168.1.210/28 dev piholenet0
to:
sudo ip addr add 192.168.0.210/28 dev piholenet0
Exactly the same thing as before happens - my node.js website is accessible from both wlan0 192.168.0.51 and piholenet0 192.168.0.210.
If you have any more ideas - great, I'll try them out, if not - don't worry about it. It's already taken me over a day of trying and it's not really worth any extra effort.
I'm a bit surprised about how little there is online about macvlan and port conflict workarounds. Your guide is pretty much the best one around.
I had the same struggle back then :). It was indeed hard to find proper documentation, so thanks for the compliment! I can try to simulate it on my nas, it won't take much time, so I'll do that Today. I`ll get back to you later.
I've updated the gist based. I followed all steps as described in the gist, and that's working fine now. I noticed port mapping doesn't work with macvlan for example, so I removed it. Anyway, hope you manage to get it working now. I've updated my previous comment as well, please try again.
Cleanup first and follow the order I specified (docker network create after the virtual adapter creation, as I've had some issues doing it in a different order).
Still no luck. I've also tried to change a few things here and there to narrow down the problem. If I stop the node.js service and simply run
docker run --rm -d --network host --name my_nginx nginx
I can see the nginx start page. If I run the same with
docker run --rm -d --network piholenet --name my_nginx --ip=192.168.0.211 nginx
I can't ping 192.168.0.211 at all. If I run
docker run --rm -d --network piholenet --name my_nginx --ip=192.168.0.210 nginx
and enable node.js service on host, I get back to seeing the node.js website at 192.168.0.210, otherwise I get connection timed out.
Thanks a lot for your help, I think I'll give up at this point. It's really not worth any more of our time.
Good news! There is nothing wrong with the setup we've been trying to do. It's apparently an ARP issue in the Linux Kernel version used in Raspbian. Solved with a simple
sudo rpi-update
as per Docker MACVLAN only works Outbound
After this, following your guide has worked perfectly fine:
sudo ip link add piholenet0 link wlan0 type macvlan mode bridge
sudo ip addr add 192.168.0.210/28 dev piholenet0
sudo ip link set piholenet0 up
docker network create --driver=macvlan --gateway=192.168.0.1 --subnet=192.168.0.0/24 -o parent=wlan0 piholenet
docker run --net=piholenet -dit --name nginx-test-01 nginx:alpine nginx-debug -g 'daemon off;'
nginx is available at 192.168.0.210 while my node.js server is available at 192.168.0.51
Now I will simply put together a docker-compose file and run pihole in a container.
EDIT:
Never mind. It worked for a couple of minutes and then went back to showing my node.js website on both.
After removing docker networks (docker network rm piholenet) and killing all docker processes, I have narrowed the problem down to:
sudo ip link add piholenet0 link wlan0 type macvlan mode bridge
sudo ip addr add 192.168.0.210/28 dev piholenet0
sudo ip link set piholenet0 up
Which makes my node.js website appear on both wlan0 IP (192.168.0.51) and piholenet0 IP (192.168.0.210). I'll have to do some reading on network bridging.
Did not think of that either, but great job finding it out! 👍 🥳
Was struggling to do with with protainer Pihole container, just followed your commands and boom i now have a working pihole container that is on the local network as if it was a physical computer connected to my main network!
So much for using Portainers GUI to do this it was forever causing ARP'ing issues. Always said CLI was better this proves it.
Thank you
Hi Bram. I signed up to GitHub specifically so I could thank you for posting this! Extremely helpful! I did a lot of research on this topic (Pihole in Docker on Synology with macvlan). This is by far the best resource I've found! Thanks!
Hi @canadadanac, how nice to specially register to tell me this! Thanks, much appreciated! Glad it helped you out a lot! 👍
Hi Bram, great gist, very helpful! I created a script inspired by your guide here, it might help others too. I added a static route from the host to the Pi-hole container to get it to work for my particular Synology setup (which uses a custom Docker installation). It should also persist reboots and DSM updates.
Hi @markdumay, good job! I hope it'll help people.
Currently I`m not using Pi-Hole anymore as adguard has a much better way of solving this. So per client I can specify the upstream dns servers, block specific services, and enable/enforce other stuff. This works out great to separate rules for our kids and us as parents!
Thanks! AdGuard Home looks promising indeed, especially when looking at this comparison. It seems Home Assistant provides integration support too. Out of curiosity, are you running a containerized version of AdGuard yourself?
Yes, I run everyting in Docker (when possible :))
Hi! Thank you very much for your work. Let's see if you can help me, this error gives me when I try to create the network in docker:
Error response from daemon: Pool overlaps with other one on this address space.
I have followed these steps:
#iPhone NAS 192.168.10.251
ip link add macvlan0 link ovs_eth0 type macvlan mode bridge
ip addr add 192.168.10.100/28 dev macvlan0
ip link set macvlan0 up
Ifconfig
docker network create --driver=macvlan --gateway=192.168.10.1 --subnet=192.168.10.0/24 -o parent=ovs_eth0 macvlan
Might be easy, try service docker restart
first. Most of the times this solves it for these kind of errors
Or:
docker-compose down
docker network prune
Also check the existing Docker network config:
docker network ls
Maybe there's a duplicate network specified.
Solved. Thank you!
Thanks for this.
I see you cleanup macvlan at the end of the script. I suppose it's just to show how to delete it, if needed. However, we shouldn't do that if piHole must be running right ?
Correct! It's indeed only some info if you need to remove macvlan. However, as you're mentioning Pi-Hole, I swtiched to Adguard. Adguard has the ability to specify rules and upstream DNS servers per subnet. So I now have a single instance of Adguard running, serving multiple subnets, all with their own configuration so f.e. the subnet of the kids has many limitiations. Pi-Hole is not going to add such a feature unfortunatly and I don't wan't to manage multiple Pi-Hole instances.
Hello everyone!
Really like it! :-)
I feel that I am almost finished with a running pihole in docker on a synology nas. But the DNS is not working.
If I use it, the browser outputs an DNS ERROR:
DNS_PROBE_FINISHED_BAD_CONFIG
My router has the ip 192.168.0.1.
The nas has 192.168.0.100
DHCP (running on the nas) ip range: 192.168.0.100 - 192.168.0.199
All the commands that I uses are:
ip link add macvlanpihole link eth0 type macvlan mode bridge
ip addr add 192.168.0.200/28 dev macvlanpihole
ip link set macvlanpihole up
ifconfig
Output:
...
macvlanpi Link encap:Ethernet HWaddr 82:08:AC:9D:26:77
inet addr:192.168.0.200 Bcast:0.0.0.0 Mask:255.255.255.240
inet6 addr: fe80::8008:acff:fe9d:2677/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:28208 errors:0 dropped:0 overruns:0 frame:0
TX packets:1301 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:3215747 (3.0 MiB) TX bytes:173829 (169.7 KiB)
docker network create --driver=macvlan --gateway=192.168.0.1 --subnet=192.168.0.0/24 --ip-range=192.168.0.200/28 -o parent=eth0 macvlan
docker run --net=macvlan -dit --name nginx-test-01 --ip=192.168.0.215 nginx:alpine nginx-debug -g 'daemon off;'
192.168.0.215 is shown in the router as connected client.
browsing to 192.168.0.215 shows nginx page.
ssh into the container, executing ping google.de is successful.
docker rm nginx-test-01 --force
NAME=pihole-macvlanpihole
IMAGE=pihole/pihole
docker run --detach \
--name ${NAME} \
--restart always \
--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.0.201" \
--env "DNSMASQ_LISTENING=all" \
--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}
I can browse to the pihole gui by visiting 192.168.0.201 with my browser.
The query log is showing all the request. So they are there, that's fine.
But browsing to google.com with my browser leads to DNS_PROBE_FINISHED_BAD_CONFIG.
I noticed the following: Ssh into the container, executing ping google.com leads to:
ping: google.com: Temporary failure in name resolution
I think that's a problem?
So my container does "not have" an internet connection?
Hi, nice work! A couple of questions:
- Is the DHCP server set to use 192.168.0.201 as a DNS server for all clients?
- I believe the config of pihole might have changes slightly, can you try it like this:
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}
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
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:
Cheers and thanks
titanbird
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.
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.
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. 👍
Great! Good you managed to fix it! 🚀
What about:
route add -net 192.168.0.212 netmask 255.255.255.254 dev macvlan0
?
I think I solved it :) Didn't have anything to do with Macvlan after all. I misconfigured Policy Based Routing on my Asus router (Asuswrt-Merlin). Apparently it routed local destinations (other LAN subnets) through my VPN provider. This caused issues when trying to access devices on my main LAN subnet from other subnets, like a WiFi network on another subnet or VPN TUN clients on another subnet. Still need to investigate the Policy Based Routing settings a bit more, but at least it wasn't a Macvlan limitation and there's nothing wrong with your instructions 😄