$ cd ../
$ cat /backups/brain/
0042
Unblock blocked DNS

Are you in a network which blocks everything besides 22,80,443? Are all public DNS blocked besides the sketchy internal one? Well, DNS over HTTPS on port 443 it is!

We will be using systemd-resolved (stub) + cloudflared (resolver) until systemd-resolved adds DoH support: https://github.com/systemd/systemd/pull/31537 but thanks cloudflare!

Average linux setup is systemd-resolved acting as DNS on 127.0.0.1:53 and there you actually configure a DNS. It’s more tweakable and has its manageable cache etc.

First let’s proxy stub DNS -> DoH with cloudflare.

Configure cloudflared as a container:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=DNS over HTTPS (Cloudflared)
Wants=network-online.target nss-lookup.target
Before=nss-lookup.target

[Container]
Image=docker.io/cloudflare/cloudflared:latest
Exec=proxy-dns --address 0.0.0.0 --port 5553
PublishPort=5553:5553/udp

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

this config is for quadlets but should be easy to port to docker-compose or plain systemd services.

Now you have a DNS 0.0.0.0:5553 which uses 1.1.1.1 via DoH.

Now let’s make systemd-resolved use the cloudflare DoH stub DNS.

Edit /etc/systemd/resolved.conf:

1
2
[Resolve]
DNS=127.0.0.1:5553

Finally, check out resolvectl dns to see if the interfaces are using a DHCP-provided DNS:

1
2
3
4
5
6
[ecomaikgolf@laptop ~/]$ resolvectl dns
Global: 127.0.0.1:5553 127.0.0.1
Link 3 (wlp2s0): 129.27.48.132 129.27.48.133
Link 4 (ecomaikgolf-DMZ):
Link 16 (enp62s0u1u4): 127.0.0.1
Link 17 (enp62s0u1u3u3c2):

See that wlp2s0 is using a custom one? Well:

1
2
nmcli con
nmcli con mod eduroam ipv4.dns "127.0.0.1"

you can also:

1
nmcli con mod eduroam ipv4.ignore-auto-dns yes

restart the interface and see how it’s using the global one:

1
2
3
4
5
6
$ resolvectl dns
Global: 127.0.0.1:5553 127.0.0.1
Link 3 (wlp2s0):
Link 4 (ecomaikgolf-DMZ):
Link 16 (enp62s0u1u4): 127.0.0.1
Link 17 (enp62s0u1u3u3c2):

which comes from the cloudflared container.

1
2
3
4
5
6
[ecomaikgolf@laptop ~/]$ resolvectl query ecomaikgolf.com
ecomaikgolf.com: 168.119.156.178

-- Information acquired via protocol DNS in 1.4ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

Now to double-check that it’s actually being used, run sudo resolvectl monitor and use the PC to connect to some websites:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
→ Q: avatars.githubusercontent.com IN A
← S: success
← A: avatars.githubusercontent.com IN A 185.199.108.133
← A: avatars.githubusercontent.com IN A 185.199.111.133
← A: avatars.githubusercontent.com IN A 185.199.109.133
← A: avatars.githubusercontent.com IN A 185.199.110.133

→ Q: avatars.githubusercontent.com IN AAAA
← S: success
← A: avatars.githubusercontent.com IN AAAA 2606:50c0:8001::154
← A: avatars.githubusercontent.com IN AAAA 2606:50c0:8000::154
← A: avatars.githubusercontent.com IN AAAA 2606:50c0:8003::154
← A: avatars.githubusercontent.com IN AAAA 2606:50c0:8002::154

you will see how it’s resolving. See also how per default, the systemd-resolved DNS is being used:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[ecomaikgolf@laptop ~/]$ dig google.com

; <<>> DiG 9.18.36 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25649
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.		204	IN	A	142.250.180.206

;; Query time: 7 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon May 12 14:50:55 CEST 2025
;; MSG SIZE  rcvd: 55

see that SERVER is 127.0.0.1:53

Your network still has two options for blocking this technique (AFAIK):

  • Denylist the DoH bootstrapping IPs
  • Denylist the cloudflare DoH IPs

You can probably proxy both from your own server with your own domain and IP. AFAIK they are configurable. Or, rent google cloud/AWS and rotate their IPs till the entire range is blocked lol.

Not sure if the bootstrapping request could be blocked, one can probably do the bootstraping manually (?) or in a trusted network (?) not sure at all about this.

$ cd ../