As everyone in the networking field knows, DNS is one of the most important things on the internet, the one that resolves the names of the IP addresses. But if you are working in a server or a service that requires fetching other domains and not just serving content (Like Invidious and Matrix) you don’t really want to make a DNS request EVERY TIME right?
This leads to latency problems and redundancy because you don’t really need to ask the DNS server: “HEY FUCKER, GIVE ME THE IP ADDRESS OF youtube.com
” everytime you access youtube, the DNS server will respond like this: “TAKE THIS, THIS IS THE IP ADDRESS AND STOP REQUESTING ME SHIT PLEASE, I NEED TO SERVE MORE CLIENTS”.
So that is where DNS Caching comes in, you just ask the DNS server the IP of the domain name that you are requesting, the DNS server replies with the IP address and you save that IP for a period of time so you don’t make a thousand of DNS requests with the risk of being rate limited of if the DNS server works like shit (It is slow or down, etc, etc…).
DNS Proxy is one of the many DNS clients that are capable of doing DNS Caching but this one comes with really handy features like being compatible with almost any protocol of DNS: DNS-over TLS, HTTPS, QUIC, and DNSCrypt (For HTTPS only if I remember well. I never tested in depth…)
How to install DNS Proxy
This will depend of your linux distro, on Arch Linux you can install it from the AUR with an AUR helper searching for dnsproxy-git (My package lol) or the binary dnsproxy
In any other distro you need to download the latest release from dnsproxy GitHub and download the correct one, if you don’t know which one you need to download, click on the one which contains arm64
in the name. For example: dnsproxy-linux-amd64-v0.54.0.tar.gz
.
Then just use this commands in the console:
tar -xvf dnsproxy-linux-amd64-v0.54.0.tar.gz
(Replace the name of the tar.gz if the version is different obviously)sudo mv linux-amd64/dnsproxy /usr/bin/dnsproxy
Creating a SystemD service.
If you use the AUR package you can skip this step
Other thing you would want to do is keeping DNSProxy running in background, starting on startup and restarting itself if something goes wrong. For that you would need a systemd service for it making it more easy to manage
Put this into a file named /usr/lib/systemd/system/dnsproxy.service
:
[Unit]
Description=Simple DNS proxy with DoH, DoT, and DNSCrypt support
Documentation=https://github.com/AdguardTeam/dnsproxy#readme
After=network.target
Before=network-online.target
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/bin/dnsproxy --config-path=/etc/dnsproxy/dnsproxy.yaml
[Install]
WantedBy=multi-user.target
And done. DNS Proxy has been installed but you will need to update it manually, redownloading the tar.gz and copying the dnsproxy
binary into /usr/bin/dnsproxy
. If you use Arch Linux with just update it using your preferred AUR helper.
DNSProxy configuration
This is really easy to do, the config syntax is really simple. Create /etc/dnsproxy/dnsproxy.yaml
and paste this into the file (If you installed it via an AUR helper you don’t need to paste anything, you just have to modify it a little bit):
# Any command-line options specified will override the values from the
# config file
---
## Required
upstream: # At least one upstream is required
- 76.76.2.0:53
## Recommended
tls-min-version: 1.2
http3: true # dnsproxy automatically picks the fastest HTTP(S) protocol
refuse-any: true
## Optional
listen-addrs:
- 127.0.0.1
cache: true # THIS ENABLES DNSCACHING
verbose: true # Increase verbosity for debugging
This config enables you to use 76.76.2.0
(ControlD DNS) and listen in the loopback address with DNS Caching. Now start the dnsproxy service using systemctl start dnsproxy
.
To test if it works, use this command in the console: dig @127.0.0.1 zzls.xyz
You should get a response like this:
; <<>> DiG 9.18.18 <<>> zzls.xyz
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7183
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;zzls.xyz. IN A
;; ANSWER SECTION:
zzls.xyz. 600 IN A 199.195.254.68
;; Query time: 97 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Wed Aug 23 13:33:46 -04 2023
;; MSG SIZE rcvd: 53
If it resolves the IP address without any problems you now can edit the /etc/resolv.conf
and include this line:
nameserver 127.0.0.1
That line should be at the start of the file or above of any other nameserver
option. Here is an example:
# Primary
nameserver 127.0.0.1
# Secondary / Backup
nameserver 76.76.2.0
And now your system will talk directly to DNSProxy but with the advantage of being more fast resolving domains that were resolved previously.
Remember to enable the dnsproxy systemd service so it starts automatically at startup (Or you will get a lot of DNS errors…)
You can see more detailed info here: https://github.com/AdguardTeam/dnsproxy
https://github.com/AdguardTeam/dnsproxy/blob/master/config.yaml.dist
Example configs
---
## Required
upstream: # At least one upstream is required
- https://cloudflare-dns.com/dns-query
- https://mozilla.cloudflare-dns.com/dns-query
- https://dns9.quad9.net/dns-query
#- quic://p0.freedns.controld.com
bootstrap: # This fetches the domains of the upstreams
- "9.9.9.9:53"
- "1.0.0.1:53"
## Recommended
tls-min-version: 1.2
http3: true # dnsproxy automatically picks the fastest HTTP(S) protocol
listen-addrs:
- 127.0.0.1
listen-ports:
- 53
cache: true
cache-size: 1024
verbose: false
ipv6-disabled: true
This one is what I used to use on my server, using DNS-over-HTTPS because of security.
---
## Required
upstream: # At least one upstream is required
- quic://dns.nextdns.io
bootstrap:
- "1.0.0.1:53"
- "9.9.9.9:53"
listen-addrs:
- 127.0.0.1
cache: true
verbose: false
cache-min-ttl: 600
fastest-addr: true
And this one is one that I use on my PC using DNS-over-QUIC
Troubleshoot
My resolv.conf is being overwritten!!!
Some programs “manage” the /etc/resolv.conf
changing the contents of it when there is a change on the network.
DHCPC
If you are using dhcpc
as your DHCP client for your server of your PC, you will notice that the resolv.conf
file is being overwritten without you knowledge. To solve this add this line to your /etc/dhcpcd.conf
nohook resolv.conf
Then restart the dhcpcd
service and done.
NetworkManager
If you use NetworkManager
you will notice that the resolv.conf
has a line that says something like this # Managed by NetworkManager
. This means NetworkManager will overwrite the resolv.conf
file depending of your actual network connection (E.g: It will use your ISP DNS server if you are connected to your router).
To prevent this, add these two lines into the file /etc/NetworkManager/conf.d/dns.conf
(If the file and folder doesn’t exists, just create them xd):
[main]
dns=none
Others
See https://wiki.archlinux.org/title/Domain_name_resolution#Overwriting_of_/etc/resolv.conf