DNS over HTTPS with cloudflared and IPv6!

I figured it out.

For IPv4 follow cloudflared (DoH) - Pi-hole documentation

For IPv6 follow that link with a couple modifications, because I couldn't get one instance of cloudflared to listen on IPv4 and IPv6 so I spun up another instance for IPv6:

Proceed to create a configuration file for cloudflaredv6 :

sudo nano /etc/default/cloudflaredv6

Edit configuration file by copying the following in to /etc/default/cloudflaredv6 . This file contains the command-line options that get passed to cloudflared on startup:

# Commandline args for cloudflared, using Cloudflare DNS
CLOUDFLARED_OPTS=--address :: --port 5053 --upstream https://[2606:4700:4700::1111]/dns-query --upstream https://[2606:4700:4700::1001]/dns-query

Then create the systemd script by copying the following into /etc/systemd/system/cloudflaredv6.service . This will control the running of the service and allow it to run on startup:

sudo nano /etc/systemd/system/cloudflaredv6.service
[Unit]
Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target

[Service]
Type=simple
User=cloudflared
EnvironmentFile=/etc/default/cloudflaredv6
ExecStart=/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

Enable the systemd service to run on startup, then start the service and check its status:

sudo systemctl enable cloudflaredv6
sudo systemctl start cloudflaredv6
sudo systemctl status cloudflaredv6

And the upstream DNS settings for your Pi-hole:
image

In order to test IPv4 and IPv6:

dig @127.0.0.1 google.com A
dig @127.0.0.1 google.com AAAA
dig @::1 google.com A
dig @::1 google.com AAAA

In your router settings if you can set the IPv6 address for your DNS server, run ifconfig | grep fe80. The IPv6 address block your ISP hands you may change, but this address is local to your network and should never change.

2 Likes

Just curious - why do you need IPv6 with Cloudflared? Both A and AAAA queries can be resolved over IPv4 DNS.

The IPv4 and IPv6 loop back addresses lead to the same place.

Maybe to deploy this in a IPv6 environment ?

I know I could run one instance of cloudflared that connects out to v4 and v6 DoH servers and have that one instance listen on v4. I chose to run two as I have had one crash before.

Sometimes someone might not have v4 externally or their v4 connectivity sucks for some reason compared to v6. I have also had v4 service fail while v6 stays fine.

The really important thing with v6 servers in cloudflared though - put them in square brackets. If you don't put them in square brackets cloudflared won't know they're IP addresses, will think they're hostnames, and won't know how to get there.

Any measurable performance difference between running cloudflared v4 and v6?

Only when my ISP gets in the way.

Just what I needed. This really should be appended to the Cloudflared (DoH) Guide. Thank you!!

I followed the v6 instructions after having Cloudflared v4 set up and running for a couple of days. I have no problem creating the files, starting the services, and testing the addresses using dig, however, when I use the localhost ipv6 address with the 5053 port as the upstream DNS server, I get no address resolution. Do I need to use a different port if I'm running v4 and v6 on the same RBP or does it not matter since it's using the same service?

Firewall is the first thing that comes to mind. I had a rule, ip6tables -i lo - j ACCEPT

I use an Eero wifi system so I don't have a separate firewall. I do have IPV6 enabled there and on the piOS. Does your suggestion still apply to my situation? If so, where does that rule go?

One of the things I noticed is my server in the dig command is localhost and port 53, not 5053 for either v4 or v6.

I have 127.0.0.1#5053 as my v4 upstream DNS server so I'm not sure where it's getting 53 from.

I've verified both config files and 5053 is defined in both files. Here is the output of the command.

(Needed to remove all of the "AT's" as my account is too new and it thinks I'm trying to mention a user)

dig 127.0.0.1 google.com A
dig 127.0.0.1 google.com AAAA
dig ::1 google.com A
dig ::1 google.com AAAA

; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65229
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.             49      IN      A       172.253.124.100
google.com.             49      IN      A       172.253.124.139
google.com.             49      IN      A       172.253.124.138
google.com.             49      IN      A       172.253.124.113
google.com.             49      IN      A       172.253.124.102
google.com.             49      IN      A       172.253.124.101

;; Query time: 30 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 135


; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10691
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 22e7757d547d71fe (echoed)
;; QUESTION SECTION:
;google.com.                    IN      AAAA

;; ANSWER SECTION:
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::71
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::66
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::8b
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::65

;; Query time: 40 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 203


; <<>> DiG 9.16.44-Raspbian <<>> ::1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2697
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.             49      IN      A       172.253.124.101
google.com.             49      IN      A       172.253.124.100
google.com.             49      IN      A       172.253.124.139
google.com.             49      IN      A       172.253.124.138
google.com.             49      IN      A       172.253.124.113
google.com.             49      IN      A       172.253.124.102

;; Query time: 30 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 135


; <<>> DiG 9.16.44-Raspbian <<>> ::1 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6183
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::71
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::66
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::8b
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::65

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 151

rootrbp01:~# ; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65229
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.             49      IN      A       172.253.124.100
google.com.             49      IN      A       172.253.124.139
google.com.             49      IN      A       172.253.124.138
google.com.             49      IN      A       172.253.124.113
google.com.             49      IN      A       172.253.124.102
google.com.             49      IN      A       172.253.124.101

;; Query time: 30 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 135


; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10691
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 22e7757d547d71fe (echoed)
;; QUESTION SECTION:
;google.com.                    IN      AAAA

;; ANSWER SECTION:
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::71
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::66
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::8b
google.com.             62      IN      AAAA    2607:f8b0:4002:c08::65

;; Query time: 40 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 20 15:29:15 CST 2023
;; MSG SIZE  rcvd: 203


; <<>> DiG 9.16.44-Raspbian <<>> ::1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2697
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

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

;; MSG SIZE  rcvd: 135:29:15 CST 2023   A       172.253.124.102

Nah go in the PI and do "ip6tables-save" and show me the output please

I am running this on a RBP3b using DietPi. When I run ip6tables, I get "command not found." The only things I have installed on here outside of the default DietPi setup is PiHole, Cloudflared (v4) and now Cloudflared (v6). I've not set up a firewall to run on DietPi. I am not using my PiHole for DHCP only DNS if that makes a difference.

Did you see my other message about the localhost resolving over port 53 on both ipv4 and ipv6 in the dig command?

Been thinking about this on and off and I'm not sure what's up.

I have an Asus router so I replaced my pihole with Asuswrt-Merlin and Diversion so I can't do much testing...

Please post back if you figure it out, or hopefully someone else is more helpful than I. Good luck!

What os are you running on your pi? Did you setup a firewall or are you using the default install of the OS?

Dumb question but do you have the cloudflared service actually running? I've disabled or stopped it before and never realized it...

I double-checked the services and they are running.

I tried the dig commands again and all resolutions came back using port 53 (ipv4 and 6) even though both of my upstream DNS servers specifically use port 5053. I added an attachment of my DNS settings. My query log shows port 5053 being used to answer requests, at least for ipv4, I don't see any ipv6 addresses trying to be resolved in my query list at the moment so I cant tell if that's working as expected or not.

dig 127.0.0.1 google.com A
dig 127.0.0.1 google.com AAAA
dig ::1 google.com A
dig ::1 google.com AAAA

; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21332
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 3861aead92819320 (echoed)
;; QUESTION SECTION:
;google.com. IN A

;; ANSWER SECTION:
google.com. 271 IN A 142.250.105.101
google.com. 271 IN A 142.250.105.100
google.com. 271 IN A 142.250.105.139
google.com. 271 IN A 142.250.105.138
google.com. 271 IN A 142.250.105.113
google.com. 271 IN A 142.250.105.102

;; Query time: 70 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Feb 09 09:26:56 CST 2024
;; MSG SIZE rcvd: 207

; <<>> DiG 9.16.44-Raspbian <<>> 127.0.0.1 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60566
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 61dba3311c3f9c9a (echoed)
;; QUESTION SECTION:
;google.com. IN AAAA

;; ANSWER SECTION:
google.com. 55 IN AAAA 2607:f8b0:4002:c08::8b
google.com. 55 IN AAAA 2607:f8b0:4002:c08::66
google.com. 55 IN AAAA 2607:f8b0:4002:c08::64
google.com. 55 IN AAAA 2607:f8b0:4002:c08::71

;; Query time: 40 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Feb 09 09:26:57 CST 2024
;; MSG SIZE rcvd: 203

; <<>> DiG 9.16.44-Raspbian <<>> ::1 google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28823
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com. 270 IN A 142.250.105.101
google.com. 270 IN A 142.250.105.100
google.com. 270 IN A 142.250.105.139
google.com. 270 IN A 142.250.105.138
google.com. 270 IN A 142.250.105.113
google.com. 270 IN A 142.250.105.102

;; Query time: 20 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Feb 09 09:26:57 CST 2024
;; MSG SIZE rcvd: 135

; <<>> DiG 9.16.44-Raspbian <<>> ::1 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28700
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com. 55 IN AAAA 2607:f8b0:4002:c08::8b
google.com. 55 IN AAAA 2607:f8b0:4002:c08::66
google.com. 55 IN AAAA 2607:f8b0:4002:c08::64
google.com. 55 IN AAAA 2607:f8b0:4002:c08::71

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Feb 09 09:26:57 CST 2024
;; MSG SIZE rcvd: 151


You're adding the @ sign before 127.0.0.1 as @127.0.0.1 for the dig command? without @ I get port 53. With @ I get 5053.

Yes I am, I just cant use that symbol in my post since my account is newer, it thinks I'm trying to tag someone.

Here is a screenshot of the first dig command showing the symbol.

2024-02-09 15_49_23-192.168.4.148 - PuTTY

You can use @ even with a new account using 2 different techniques:

  1. Post inline code using code blocks:
    On the editor window, type your line of code inside backticks (`) to create a block, like this:
    `text with @`, will be shown as: text with @.
    You can achieve the same result selecting the text and clicking on the code block button: </>
    (or pressing CTRL+E).

  2. You can "escape" the symbol, adding a single backslash (\) before the symbol:
    \@ will be shown as @.