Wireguard and Unbound

The Pi-hole documentation provides an excellent guide to install Wireguard VPN to allow use of Pi-hole outside of a local network and an equally excellent guide to install Unbound as a recursive DNS server. However, one issue I ran into when implementing Wireguard with a previously working Unbound implementation according to the guides was that Unbound stopped responding to DNS requests.

To solve the issue, try adding a line access-control: [local network subnet] allow into the file /etc/unbound/unbound.conf.d/pi-hole.conf and restarting unbound with sudo /etc/init.d/unbound restart . For example, if your local network hosting Pi-hole is 192.168.1.0/24, add access-control: 192.168.1.0/24 allow.

You can edit the documentation files to add anything that was missed or could be updated, if you are so inclined. The documentation will be seen by far more users than just a note here on Discourse.

1 Like

Thanks. Happy to create a pull request.

Blockhead, you just saved me a lot of headaches! I could not for the life of me figure out why enabling the masquerade rules seemed to break unbound, and this fixed the issue immediately. I hope your PR for the changes to the docs gets merged soon!

(I'm only reading this now, upon nickclyde's reply:)

This should not be required at all.
If you followed our guide, unbound can be expected to only ever receive DNS requests from Pi-hole via 127.0.0.1.

If your unbound would have to accept additional IP ranges, you may be routing DNS requests from your Wireguard network directly to unbound instead of Pi-hole.
You should verify your PostUp/PostDown rules.

And on another thought:
You wouldn't run unbound and/or Pi-hole as a Docker container, would you?

Thanks. This was a while ago and
alas, I'm not at all at the level of your understanding. I'll tell you what I remember and hopefully that will help you sort it out.

I was running Pi-hole on a Win11 hyper-V VM and wanted Wireguard. I recall the Wireguard guide leaving some things out, like not having ufw rules for example. So, I tried to find things that worked. Then, I ran into the nonrouting problem and somehow solved it, possibly with the idea being discussed.

The good news is that I put every change I made to the Wireguard documentation (at the time) to make my system work into the pull request. So if there's something wonky in what I did, it should be there to see. Happy to learn how it could be improved.

When following our guide, there is no direct communication between a client and unbound:
Any client - regardless whether connection via Wireguard or directly - should be talking to Pi-hole for DNS, and Pi-hole will then filter allowed DNS requests only to be forwarded to unbound on 127.0.0.1:5335.

Where did you install unbound then?

Our guide provides instructions on how to run unbound on the same machine as Pi-hole.

By shunning Pi-hole into a VM, you would effectively run Pi-hole and unbound on different machines, even if that machine is only virtual (unless you would install unbound on the very same VM as Pi-hole).

In such a scenario, instead of allowing 127.0.0.1, configuring unbound to accept DNS requests from your Pi-hole's IP address would be required to closely match the original configuration.

However, that requirement would be completely independent of Wireguard.

To objectively assess your solution approach, I think it would be required to also know how you have installed and configured both Pi-hole and unbound.

Weird, I'm pretty sure I'm following a pretty buck standard setup - I just flashed Raspberry Pi OS on my Raspberry Pi 4, installed pihole, installed unbound following the guide in the docs exactly, then set up wireguard following the guide in the docs exactly. It worked perfectly, until I tried the guide to make internal network devices accessible via the VPN. As soon as I added the nftables masquerade rules to my wireguard conf and restarted wireguard, DNS resolution just broke. Adding the access-control line to my unbound conf fixed it!

The VM is running Ubuntu. Pi-hole, unbound, and Wireguard are running on the Ubuntu virtual machine.

That sounds like where it went squiggly for me as well.

If they all run on the same VM, then 127.0.0.1 should be sufficient.

So there's a difference to my working installation, as I've used the iptables rules.

If you did configure Pi-hole correctly, and did verify that Pi-hole and unbound would work together before bringing Wireguard to the field, then that could suggest that your nftables rules would intercept DNS requests originating from 127.0.0.1.

Could both of you share a debug token, and also your PostUp/Postdown rules?
For the latter, e.g.:

sudo grep -E "PostUp|PostDown" /etc/wireguard/wg0.conf

Token: IDdurt99

PostUp = ufw route allow in on wg0 out on eth0
#PostUp = ufw route allow in on eth0 out on wg0
PostUp = nft add table ip wireguard; nft add chain ip wireguard wireguard_chain {type nat hook postrouting priority srcnat; policy accept;}; nft add rule ip wireguard wireguard_chain counter packets 0 bytes 0 masquerade; nft add table ip6 wireguard; nft add chain ip6 wireguard wireguard_chain {type nat hook postrouting priority srcnat; policy accept;}; nft add rule ip6 wireguard wireguard_chain counter packets 0 bytes 0 masquerade
PostDown = nft delete table ip wireguard; nft delete table ip6 wireguard

Your debug log shows you've pointed Pi-hole correctly to 127.0.0.1#5335 as upstream, and there are no stray custom dnsmasq configurations that could potentially interfere.

However, it shows that your FTL.log contains quite a few recent warnings when contacting unbound, like:

2024-09-09 09:25:43.055 EDT [474762/F391681] WARNING: Connection error (127.0.0.1#5335): failed to send TCP(read_write) packet (Connection prematurely closed by remote server)

I'm not yet sure whether that's significant for our analysis, but let's keep those in mind to return to later eventually.

Meanwhile, the obvious difference between your PostUp lines and those from our guide is that yours omits the escaping (\) before the semicolon (;) if that appears within brackets, e.g. yours reads "...policy accept;}..." where the guide has "...policy accept\;}...".

To preclude that those are not just formatting or copy&paste artifacts, could you please share your current nftables ruleset:

sudo nft list ruleset

As you are using ufw, this is probably going to be rather copious, so instead of pasting the contents here, you may also try to upload it to our servers and share its token:

sudo nft list ruleset | pihole tricorder

Token: 8Bau4EGv

(I also checked wg0.conf and each of the four slashes from the guide appeared to be there. So, I suspect it is copying/rendering artifact.)

Debug token: https://tricorder.pi-hole.net/N9VKhX7i/

Note, this debug log was generated after I added the access-control line to my unbound conf, and DNS resolution via the VPN is working. I'm happy to generate another log without that line, if it's helpful.

My PostUp and PostDown rules were just copy/pasted from the guide in the docs:

PostUp = nft add table ip wireguard; nft add chain ip wireguard wireguard_chain {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip wireguard wireguard_chain counter packets 0 bytes 0 masquerade; nft add table ip6 wireguard; nft add chain ip6 wireguard wireguard_chain {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip6 wireguard wireguard_chain counter packets 0 bytes 0 masquerade
PostDown = nft delete table ip wireguard; nft delete table ip6 wireguard

As with Blockhead, your debug log shows you've pointed your Pi-hole v5 correctly to 127.0.0.1#5335 as upstream, and there are no stray custom dnsmasq configurations that could potentially interfere.

Unrelated to the issue, your router distributes `1.1.1.1` as DNS server:
*** [ DIAGNOSING ]: Discovering active DHCP servers (takes 10 seconds)
   Scanning all your interfaces for DHCP servers
   
   * Received 305 bytes from eth0:192.168.1.1
     Offered IP address: 192.168.1.109
     DHCP options:
      Message type: DHCPOFFER (2)
      router: 192.168.1.1
      dns-server: 1.1.1.1

DHCP clients won't use Pi-hole, unless you've manually pointed a client to use Pi-hole, which your debug log suggests you have done for at least some clients.

Blockheads' nft ruleset correctly lists the wireguard tables, so the differences were likely from pasting only.

nickclyde , are you using ufw as well?
Could you also share your nft ruleset?

In the meantime, I've installed Pi-hole and unbound on RPi OS 12/bookworm on a spare Zero, and had no issues when adding the recommended nftables rules.

The resulting ruleset is much smaller than @Blockhead's (click for details)
$ sudo nft list ruleset
table ip filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
	}
}
table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
	}
}
table ip6 nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
	}
}
table ip wireguard {
	chain wireguard_chain {
		type nat hook postrouting priority srcnat; policy accept;
		counter packets 28 bytes 1858 masquerade
	}
}
table ip6 wireguard {
	chain wireguard_chain {
		type nat hook postrouting priority srcnat; policy accept;
		counter packets 54 bytes 4908 masquerade comment
	}
}

Next, I tried to apply Blockhead's ruleset to my configuration.
However, nft complained about quite a few unexpected keywords, mostly because a type wasn't declared.

I've turned those lines into comments (more):
210:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
211:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
212:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
213:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
214:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
215:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
216:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
217:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
218:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
219:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
220:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
221:#		meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
222:#		meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
223:#		meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
224:#		meta l4proto ipv6-icmp icmpv6 type  counter packets 0 bytes 0 accept
245:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
246:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
247:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
248:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
249:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 0 bytes 0 accept
250:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  counter packets 7 bytes 612 accept
251:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
252:#		meta l4proto ipv6-icmp icmpv6 type  ip6 hoplimit 255 counter packets 0 bytes 0 accept
253:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
254:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept
255:#		meta l4proto ipv6-icmp ip6 saddr fe80::/10 icmpv6 type  ip6 hoplimit 1 counter packets 0 bytes 0 accept

Applying the resulting ruleset didn't negatively impact DNS resolution:
I was able to dig @192.168.0.53 heise.de as well as dig @10.100.0.1 heise.de and dig -p 5335 @127.0.1.1 pi-hole.net successfully on the Zero.

Thus, I cannot recreate your observation of failing DNS when appyling nftables rules.

Could you share your unbound configurations?

sudo grep -v '#\|^$' -R /etc/unbound/unbound.conf.d

Also, if you remove those access-control: <private.range>/24 allow now, would you still encounter your issue?

I commented out the access-control line and the error occurred.

Here's a pihole -d token with the comment: EG27vSLl

Oddly, the debug log looks like pihole is able to resolve addresses on the VM, but if I try to use a browser on a computer on the network, I get no resolution. Also, if I dig @ the local address on the VM, I get a network timeout:

$ dig @192.168.1.150 cnn.com
;; communications error to 192.168.1.150#53: timed out
;; communications error to 192.168.1.150#53: timed out
;; communications error to 192.168.1.150#53: timed out

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> @192.168.1.150 cnn.com
; (1 server found)
;; global options: +cmd
;; no servers could be reached

Alternatively, if I re-enable the access-control, everything is happy with the local VM digging:

dig @192.168.1.150 cnn.com

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> @192.168.1.150 cnn.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60541
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;cnn.com. IN A

;; ANSWER SECTION:
cnn.com. 60 IN A 151.101.131.5
cnn.com. 60 IN A 151.101.195.5
cnn.com. 60 IN A 151.101.67.5
cnn.com. 60 IN A 151.101.3.5

;; Query time: 108 msec
;; SERVER: 192.168.1.150#53(192.168.1.150) (UDP)
;; WHEN: Tue Sep 10 12:10:17 EDT 2024
;; MSG SIZE rcvd: 100

Here are the unbound settings:

/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf:server:
/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf: auto-trust-anchor-file: "/var/lib/unbound/root.key"
/etc/unbound/unbound.conf.d/pi-hole.conf:server:
/etc/unbound/unbound.conf.d/pi-hole.conf:
/etc/unbound/unbound.conf.d/pi-hole.conf:verbosity: 0
/etc/unbound/unbound.conf.d/pi-hole.conf: interface: 127.0.0.1
/etc/unbound/unbound.conf.d/pi-hole.conf: port: 5335
/etc/unbound/unbound.conf.d/pi-hole.conf:access-control: 192.168.1.0/24 allow
/etc/unbound/unbound.conf.d/pi-hole.conf: do-ip4: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: do-udp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: do-tcp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: do-ip6: no
/etc/unbound/unbound.conf.d/pi-hole.conf: prefer-ip6: no
/etc/unbound/unbound.conf.d/pi-hole.conf: harden-glue: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: harden-dnssec-stripped: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: use-caps-for-id: no
/etc/unbound/unbound.conf.d/pi-hole.conf: edns-buffer-size: 1472
/etc/unbound/unbound.conf.d/pi-hole.conf: prefetch: yes
/etc/unbound/unbound.conf.d/pi-hole.conf: num-threads: 1
/etc/unbound/unbound.conf.d/pi-hole.conf: so-rcvbuf: 1m
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: 192.168.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: 169.254.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: 172.16.0.0/12
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: 10.0.0.0/8
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: fd00::/8
/etc/unbound/unbound.conf.d/pi-hole.conf: private-address: fe00::/10

Yeah, I had to disable network-wide Pihole due to complaints from the wife about broken sites :sweat_smile: So I'm just using the Pihole on my laptop and phone via Wireguard.

I am not using ufw - the Rpi is behind NAT, so I'm fine with no firewall.

Here is my unbound config:

/etc/unbound/unbound.conf.d/pi-hole.conf:server:
/etc/unbound/unbound.conf.d/pi-hole.conf:    logfile: "/var/log/unbound/unbound.log"
/etc/unbound/unbound.conf.d/pi-hole.conf:    verbosity: 0
/etc/unbound/unbound.conf.d/pi-hole.conf:    log-time-ascii: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    interface: 127.0.0.1
/etc/unbound/unbound.conf.d/pi-hole.conf:    port: 5335
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-ip4: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-udp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-tcp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-ip6: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    prefer-ip6: no
/etc/unbound/unbound.conf.d/pi-hole.conf:    harden-glue: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    harden-dnssec-stripped: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    use-caps-for-id: no
/etc/unbound/unbound.conf.d/pi-hole.conf:    edns-buffer-size: 1232
/etc/unbound/unbound.conf.d/pi-hole.conf:    prefetch: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    num-threads: 1
/etc/unbound/unbound.conf.d/pi-hole.conf:    so-rcvbuf: 1m
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 192.168.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 169.254.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 172.16.0.0/12
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 10.0.0.0/8
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: fd00::/8
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: fe80::/10
/etc/unbound/unbound.conf.d/pi-hole.conf:    access-control: 192.168.1.0/24 allow
/etc/unbound/unbound.conf.d/remote-control.conf:remote-control:
/etc/unbound/unbound.conf.d/remote-control.conf:  control-enable: yes
/etc/unbound/unbound.conf.d/remote-control.conf:  control-interface: /run/unbound.ctl
/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf:server:
/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf:    auto-trust-anchor-file: "/var/lib/unbound/root.key"

Here is what I get from dig on my laptop with the access-control line in my unbound.conf:

❯ dig @192.168.1.109 pi-hole.net

; <<>> DiG 9.10.6 <<>> @192.168.1.109 pi-hole.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5961
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pi-hole.net.			IN	A

;; ANSWER SECTION:
pi-hole.net.		300	IN	A	3.18.136.52

;; Query time: 54 msec
;; SERVER: 192.168.1.109#53(192.168.1.109)
;; WHEN: Tue Sep 10 10:13:01 PDT 2024
;; MSG SIZE  rcvd: 56

❯ dig @10.9.0.1 pi-hole.net

; <<>> DiG 9.10.6 <<>> @10.9.0.1 pi-hole.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64795
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pi-hole.net.			IN	A

;; ANSWER SECTION:
pi-hole.net.		261	IN	A	3.18.136.52

;; Query time: 41 msec
;; SERVER: 10.9.0.1#53(10.9.0.1)
;; WHEN: Tue Sep 10 10:13:40 PDT 2024
;; MSG SIZE  rcvd: 56

Here is what I get from dig without the access-control line in my unbound.conf:

❯ dig @192.168.1.109 cnn.com

; <<>> DiG 9.10.6 <<>> @192.168.1.109 cnn.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
❯ dig @10.9.0.1 cnn.com

; <<>> DiG 9.10.6 <<>> @10.9.0.1 cnn.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

If I try to hit unbound from my Rpi after removing the access-control line, I get this:

nick@pihole:~ $ dig @127.0.0.1 -p 5335 cnn.com

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> @127.0.0.1 -p 5335 cnn.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 57015
;; flags: qr rd ad; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Tue Sep 10 10:16:20 PDT 2024
;; MSG SIZE  rcvd: 12

That could indeed happen if unbound would be receiving requests with a source IP that doesn't match its configured interface.
In turn, that would suggest that ntftables would source-NAT requests from the loopback interface.

The remedy would then be to apply srcnat masquerading to just those inbound and outbound interfaces that involve wireguard (which was always the case with iptables).

Of course, wireguard's interface would be the inbound one, and judging by your debug logs, your outbound interface would be eth0 for both nickclyde and @Blockhead.

Please try the following (while at home, connected directly to your home network):
a. bring down your Wireguard interface:

sudo wg-quick down wg0

b. change your Wireguard's PostUp rules:

sudo nano /etc/wireguard.conf

by replacing your PostUp with the folllowing rules:

PostUp = nft add table ip wireguard; nft add chain ip wireguard wireguard_nat {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip wireguard wireguard_nat iifname %i oifname 'eth0' counter masquerade
PostUp = nft add table ip6 wireguard; nft add chain ip6 wireguard wireguard_nat {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip6 wireguard wireguard_nat iifname %i oifname 'eth0' counter masquerade

You'll note that I've separated the tables for IPv4 and IPv6 into their own PostUp lines.

c. bring Wireguard up again:

sudo wg-quick up wg0

d. verify both tables have been created

sudo nft list table ip wireguard; sudo nft list table ip6 wireguard
Output should look similar to (click for details)
table ip wireguard {
	chain wireguard_chain {
		type nat hook postrouting priority srcnat; policy accept;
		iifname "wg0" oifname "eth0" counter packets 0 bytes 0 masquerade
	}
}
table ip6 wireguard {
	chain wireguard_chain {
		type nat hook postrouting priority srcnat; policy accept;
		iifname "wg0" oifname "eth0" counter packets 0 bytes 0 masquerade
	}
}

In particular, verify that %i has been correctly replaced by your wireguard's interface name.

e. run a few test lookups to your different IP ranges:
-- to your local unbound

dig -p 5335 @127.0.0.1 pi-hole.net

-- to your Pi-hole's home network IP address

dig @<pi.ho.le.ip> pi-hole.net

-- to your Pi-hole's wireguard IP address

dig @<wg.pi.ho.le> pi-hole.net

If that doesn't work straight away, please consider a reboot, and report back whether that would allow Pi-hole/unbound/Wireguard to work for you without expanding unbound's access-control.

That works, both with and without the access-control for all three digs. Can you take on making the edit to the pull-request, if warranted? (It might take me a while to relearn how to do it, and I suspect all my credentials expired.)

1 Like