Setting Up DNS

Setup DNS with dnscrypt-proxy and dnsmasq

The first things to do is install the packages. If on Arch Linux install them first. I’m not using docker because it will be awkward to host both. Port 53 binding is annoying in docker as privileged ports from a container adds friction and on systemd/OpenRC systems systemd-resolved or another stub listener often already holds port 53.

DNSCrypt setup

Installing packages in Arch

Install both packages with sudo pacman -S dnscrypt-proxy dnsmasq. This will install both packages.

Setup DNSCrypt config

Now editing the config file in /etc/dnscrypt-proxy/dnscrypt-proxy.toml file. Add the lines inside the file or edit the changes.

# Change listen port from 53 to 5300 (avoid conflict with dnsmasq)
listen_addresses = ['127.0.0.1:5300']

# Pick resolvers — these are no-log, DNSSEC-validating
server_names = ['cloudflare', 'quad9']

# Recommended privacy options
require_dnssec = true
require_nolog = true
require_nofilter = true

The port generally is bind to 53 but as we are also using dnsmasq port should be something different. dnsmasq reads queries from port 5300.

dnsmasq configuration

The general file to edit is in /etc/dnsmasq.conf.

# Don't read /etc/resolv.conf
no-resolv

# Forward all queries to dnscrypt-proxy
server=127.0.0.1#5300

# Listen only on loopback
# Also adding waydroid interface
interface=lo,waydroid0
listen-address=127.0.0.1,192.168.240.1
bind-interfaces

# Cache size (number of entries)
cache-size=1000
# To enable negative caching
neg-ttl=60

When the user makes a query it is forwarded to port 5300 which then searches the internet and brings back results which are then cached in dnsmasq as entries.

Stop anything holding port 53

On CachyOS port 53 is generally bound to systemd-resolved. Check with

ss -tulpn | grep ':53'

If systemd-resolved is present then run

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

Fix /etc/resolv.conf

systemd-resolved manages this file as a symlink. Replace it with

sudo unlink /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

Then lock the file so that NetworkManager cannot overwrite it.

sudo chattr +i /etc/resolv.conf

(For if any reason you want to restore the file then run sudo chattr -i /etc/resolv.conf)

Enable the services and verify

Enable both service via systemctl with

sudo systemctl enable --now dnscrypt-proxy
sudo systemctl enable --now dnsmasq

Verify if it works

# Check both are listening on the right ports
ss -tulpn | grep -E ':53|:5300'

# Test resolution through the full chain
dig google.com @127.0.0.1

# Check dnscrypt-proxy is actually encrypting (should show your resolver)
sudo journalctl -u dnscrypt-proxy -n 20

In the journal you should see lines like [cloudflare] OK (DoH) or [quad9] OK (DNSCrypt) confirming encryption is active.

When using NetworkManager, it may try to overwrite the resolv.conf and try to manager DNS. To prevent that one can edit /etc/NetworkManager/NetworkManager.conf and add

[main]
dns=none

Then restart NetworkManager with sudo systemctl restart NetworkManager


Published on and updated on in Guides tagged with linux guide networking arch


© 2026 ryukamish