What I am trying to accomplish:

I have a WireGuard reverse VPN Setup that does not route my traffic, but lets me connect to my raspberry pi from within the Internet using a public server as "bridge".

I installed pihole on the raspberry pi. Now, I want to use the pi as DNS (over WireGuard) while sending the actual HTTP request from my actual device.

Basically, I want it to work like this:

192.168.0.x (wlan0@localhost) requests an URL. The DNS @192.168.66.z (pihole) resolves the URL and sends the IP back to 192.168.66.y (wg0@localhost). This answer is then used to send the HTTP request from 192.168.0.x (wlan0@localhost).

What I've tried:

Obviously, I have tried to enter the pi's VPN-IP into NetworkManager. This has given me some headache as my Ubuntu (5.4.0-42-generic #46~18.04.1-Ubuntu) was always falling back to its default DNS (what I did not want even if the VPN DNS worked). I found a workaround provided by user2427436 on a SO thread here.

What the issue is:

While I can force the DNS to use (without falling back to the routers/default DNS), I cannot manage to use the pihole as DNS. I can connect to the pi via tunnel (eg HTTP, SSH,..), and the Port 53 (for DNS) is opened in the firewall. I still cannot resolve any domainnames. Also, checking journalctl -xe on the pi does not show any hint that the device tried to connect/resolve.

I would really like to understand why this is not working and how it is supposed to work. I feel like I am missing something on how DNS works.

What would be the correct logfile to check here? Do you have any suggestions what I should try next?


DNS is setup per network device. Does my wlan0 device @\24 know about the wg0 device and it's address space @\24? May this be the cause of the problem, that I try to resolve a request from wlan0 using a DNS over wg0? If yes, how would I solve this?


There are various aspects to troubleshooting this issue.

  1. adding ip rules for correct routing
  2. testing name resolution
  3. disabling / tweaking resolved

step by step:

The first step is to see if the Pi can be reached. One needs to check which interface the routing goes over. The following tests can be used:

traceroute -i <interface name> -p 53 192.168.66.z

replace with the interfaces available on the system. Expected result: traceroute will work over the wg0 interface, but presumably not over the others.

The same test can be done using the source IP:

traceroute -s <sourceIP> -p 53 192.168.66.z

replace with a local IP on your localhost Expected result: traceroute will presumably work with the wg0's IP address but not with the IP address of the any other interface

If the above two do not work with any interface or address, then the routing part on your public "bridge" is faulty.

Assuming that you get the first step to work as expected, the next step is to tell the OS to route traffic for DNS requests through the right interface. Replace with the name of the interface that provides a working route to your pihole in the previous step.

create a new routing table for DNS requests, e.g. "dns" and tell the OS to route all DNS requests (destination port 53) to go over a different interface

echo "10 dns" >>/etc/iproute2/rt_tables
ip rule add pref 10 dport 53 table dns
ip route add default via 192.168.66.z dev <DNSInterface> table dns
ip route flush cache

First see if DNS resolution works by specifying the pihole address explicitely:

nslookup www.serverfault.com 192.168.66.z

Expected result: the DNS query goes well. If it does not, you need to double check on the interfaces and IP addresses above and on your routing rules on the VPS.

Last we need to handle resolved. My suggestion is to switch resolved off and use the pihole DNS directly:

systemctl stop systemd-resolved
systemctl disable systemd-resolved.service
mv /etc/resolv.conf /etc/resolv.conf.securitycopy



under [main] in /etc/NetworkManager/NetworkManager.conf

systemctl restart NetworkManager

Change the DNS Server IP on your network interface property to the pihole address

test DNS resolution:

nslookup www.serverfault.com

The following changes have now been made to your system:

  1. DNS requests (destination port 53) are routed over a different interface
  2. Resolved is disabled, DNS resolution goes directly to a DNS Server
  3. The DNS Server is set to be the piHole's IP

Let me know if it works.

| improve this answer | |
  • First off: Thank you for this detailed and comprehensnive answer. I will definetly work myself through it tonight and let you know if it works before the bounty expires! – randmin Sep 17 at 20:24
  • ip rule add pref 10 dport 53 table dns -> Error: argument "dport" is wrong: Failed to parse rule type. (As a result?) nslookup is not working. – randmin Sep 18 at 2:38
  • First - many thanks for the bounty. I have tried and double checked on my system and it does work. Are you doing this as root ? Please type ip rule help and see what it suggests. Maybe it's related to the distro ? What linux are you on ? – onemarcfifty Sep 18 at 8:58
  • Alternatively, if things don't work with dport (i.e. deviating traffic for the destination port) you might as well just tell linux to deviate all traffic for the DNS Server over that table - after all, the only reason you want to join it is for DNS. In this case you could replace the command with ip rule add pref 10 to <piHole's IP> table dns – onemarcfifty Sep 18 at 9:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.