How to install dnscrypt-proxy on Debian Linux 11/12

See all Debian/Ubuntu Linux related FAQ
DNSCrypt-proxy is an open-source and free software designed to encrypt DNS traffic, thus protecting it from eavesdropping and manipulation. This is also useful to evade DNS censorship when DNSCrypt-proxy is configured correctly with Wireguard or OpenVPN. Further, DNSCrypt-proxy can configured to block malware, trackers, and internet ads. In Debian 11 and 12, using DNSCrypt-proxy can enhance privacy and security by preventing DNS spoofing attacks, DNS hijacking, and surveillance of DNS traffic. It ensures that DNS queries are encrypted, authenticated, and secure, thereby safeguarding users’ browsing activities and sensitive information. Let us see how to install dnscrypt-proxy on Debian Linux 11 and 12.

Tutorial details
Difficulty level Intermediate
Root privileges Yes
Requirements Linux terminal
Category DNS Server
OS compatibility Debian Mint Pop!_OS Ubuntu
Est. reading time 5 minutes

Step 1 – Installing dnscrypt-proxy on Debian Linux

First, update your repos and install dnscrypt-proxy as follows using the apt command or apt-get command:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install dnscrypt-proxy

Installing dnscrpt proxy server on a Debian Linux using APT

Installing dnscrpt proxy server on a Debian Linux version 11 using APT {click to enlarge}

Debian 12 install dnscrypt-proxy

Due to technical issues in the last few minutes, the dnscrypt-proxy package is not currently available in the default Debian Linux 12 (Bookworm) repositories. However, you can install it from the ‘sid’ with some care. Create a new file as follows:
$ sudo vim /etc/apt/sources.list.d/sid.list
Append the following config:
deb http://deb.debian.org/debian sid main
Save and close the file. You must configure Pinning to avoid upgrading all packages from Debian Linux unstable (sid) to stable 12 (bookworm) release as follows:
$ sudo vim /etc/apt/preferences.d/99-sid-repository-pinning
Append the following config:
Package: *
Pin: release a=unstable
Pin-Priority: -10

Save and close the file. Verify pinning policy and ensures that Debian unstable including dnscrypt-proxy is at -10 priority:
$ sudo apt update
$ sudo apt-cache policy
$ sudo apt-cache policy dnscrypt-proxy

Finally install the package:
$ sudo apt install -t sid dnscrypt-proxy

Installing dnscrypt-proxy on a Debian Linux 12 using APT

Installing dnscrypt-proxy on a Debian Linux 12 using APT {Click to enlarge}

The configuration file is at /etc/dnscrypt-proxy/dnscrypt-proxy.toml location.

Step 2 – Start/Stop/Restart the dnscrypt-proxy service

The systemd service name is dnscrypt-proxy.service and the syntax is as follows to control it:
$ sudo systemctl start dnscrypt-proxy.service
$ sudo systemctl stop dnscrypt-proxy.service
$ sudo systemctl restart dnscrypt-proxy.service
$ sudo systemctl status dnscrypt-proxy.service

Please note that IP address binding for the dnscrypt-proxy.service is managed by the dnscrypt-proxy.socket service. If you want to make changes to the default IP address 127.0.2.1, you can control it as described below. It’s important to note that you cannot set IP binding in the /etc/dnscrypt-proxy/dnscrypt-proxy.toml file.
$ sudo systemctl cat dnscrypt-proxy.socket
$ sudo systemctl start dnscrypt-proxy.socket
$ sudo systemctl stop dnscrypt-proxy.socket
$ sudo systemctl restart dnscrypt-proxy.socket
$ sudo systemctl status dnscrypt-proxy.socket

The systemd also controls and resolves domain names, IPV4 and IPv6 addresses, DNS resource records, and services. A service controls resolvconf or system-resolve via the dnscrypt-proxy-resolvconf.service. You don’t have to edit or touch this service. Just left is running alone:
$ sudo systemctl cat dnscrypt-proxy-resolvconf.service
$ sudo systemctl start dnscrypt-proxy-resolvconf.service
$ sudo systemctl stop dnscrypt-proxy-resolvconf.service
$ sudo systemctl restart dnscrypt-proxy-resolvconf.service
$ sudo systemctl status dnscrypt-proxy-resolvconf.service

Using dnscrypt-proxy.socket systemd unit file to set or change IPv4 and IPv6 address binding

The dnscrypt-proxy server will listen on TCP and UDP 127.0.2.1:53 for DNS queries by default. But, say you have additional IPv4 and IPv6 for your VPC or, VPN or VLAN configured. You can force the dnscrypt-proxy to listen on those additional IP addresses as follows:

  • IPv410.8.0.1/24
  • IPv6fd5a:dadf:8d6d::1/48 ([fd5a:dadf:8d6d::1]/48)
WARNING! Do not listen to the WAN public IPv4/IPv6 address and port. We are not going to act as a public resolver for the world. Hence, I am opting for my VPN/VPC/VLAN interface IP address only.

Edit the dnscrypt-proxy.socket to add overrides:
$ sudo systemctl edit dnscrypt-proxy.socket
You will get config file as follows:

### Editing /etc/systemd/system/dnscrypt-proxy.socket.d/override.conf
### Anything between here and the comment below will become the new contents of the file
 
 
### Lines below this comment will be discarded
 
### /lib/systemd/system/dnscrypt-proxy.socket
# [Unit]
# Description=dnscrypt-proxy listening socket
# Documentation=https://github.com/DNSCrypt/dnscrypt-proxy/wiki
# Before=nss-lookup.target
# Wants=nss-lookup.target
# Wants=dnscrypt-proxy-resolvconf.service
# 
# [Socket]
# ListenStream=127.0.2.1:53
# ListenDatagram=127.0.2.1:53
# NoDelay=true
# DeferAcceptSec=1
# 
# [Install]
# WantedBy=sockets.target

Add your config after the ### Anything between here as follows:

[Socket]
ListenStream=10.8.0.1:53
ListenDatagram=10.8.0.1:53
ListenStream=[fd5a:dadf:8d6d::1]:53
ListenDatagram=[fd5a:dadf:8d6d::1]:53

It should look as follows:

### Editing /etc/systemd/system/dnscrypt-proxy.socket.d/override.conf
### Anything between here and the comment below will become the new contents of the file
 
[Socket]
ListenStream=10.8.0.1:53
ListenDatagram=10.8.0.1:53
ListenStream=[fd5a:dadf:8d6d::1]:53
ListenDatagram=[fd5a:dadf:8d6d::1]:53
 
### Lines below this comment will be discarded
 
### /lib/systemd/system/dnscrypt-proxy.socket
# [Unit]
# Description=dnscrypt-proxy listening socket
# Documentation=https://github.com/DNSCrypt/dnscrypt-proxy/wiki
# Before=nss-lookup.target
# Wants=nss-lookup.target
# Wants=dnscrypt-proxy-resolvconf.service
# 
# [Socket]
# ListenStream=127.0.2.1:53
# ListenDatagram=127.0.2.1:53
# NoDelay=true
# DeferAcceptSec=1
# 
# [Install]
# WantedBy=sockets.target

Now just restart the services:
$ sudo systemctl daemon-reload #<--reload config changes
$ sudo systemctl restart dnscrypt-proxy.socket
$ sudo systemctl restart dnscrypt-proxy.service

Verify listing port using the ss command or netstat command:
$ sudo ss -tulpn 'sport = :53 or dport = :53'
OR use the grep command/egrep command for simplified syntax:
$ sudo ss -tulpn | grep ':53'
Outputs:

Netid                 State                  Recv-Q                 Send-Q                                       Local Address:Port                                  Peer Address:Port                 Process                                                                            
udp                   UNCONN                 0                      0                                                 10.8.0.1:53                                         0.0.0.0:*                     users:(("dnscrypt-proxy",pid=1019,fd=15),("systemd",pid=1,fd=71))                 
udp                   UNCONN                 0                      0                                                127.0.2.1:53                                         0.0.0.0:*                     users:(("dnscrypt-proxy",pid=1019,fd=13),("systemd",pid=1,fd=66))                 
udp                   UNCONN                 0                      0                                      [fd5a:dadf:8d6d::1]:53                                            [::]:*                     users:(("dnscrypt-proxy",pid=1019,fd=17),("systemd",pid=1,fd=73))                 
tcp                   LISTEN                 0                      4096                                              10.8.0.1:53                                         0.0.0.0:*                     users:(("dnscrypt-proxy",pid=1019,fd=14),("systemd",pid=1,fd=70))                 
tcp                   LISTEN                 0                      4096                                             127.0.2.1:53                                         0.0.0.0:*                     users:(("dnscrypt-proxy",pid=1019,fd=12),("systemd",pid=1,fd=64))                 
tcp                   LISTEN                 0                      4096                                   [fd5a:dadf:8d6d::1]:53                                            [::]:*                     users:(("dnscrypt-proxy",pid=1019,fd=16),("systemd",pid=1,fd=72))

Verify with the “dig,” “host,” “nslookup,” or drill command as follows:
$ dig cyberciti.biz @10.8.0.1
$ dig -6 cyberciti.biz @fd5a:dadf:8d6d::1

Step 3 – Configuring dnscrypt-proxy server

Edit the /etc/dnscrypt-proxy/dnscrypt-proxy.toml as follows:
$ sudo vim /etc/dnscrypt-proxy/dnscrypt-proxy.toml
Here is the default config:

# Empty listen_addresses to use systemd socket activation
listen_addresses = []
server_names = ['cloudflare']
 
[query_log]
  file = '/var/log/dnscrypt-proxy/query.log'
 
[nx_log]
  file = '/var/log/dnscrypt-proxy/nx.log'
 
[sources]
  [sources.'public-resolvers']
  url = 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md'
  cache_file = '/var/cache/dnscrypt-proxy/public-resolvers.md'
  minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
  refresh_delay = 72
  prefix = ''

Setting DNS server names

You can set trusted DNS server to use. It can be Google, Cloudlfare or your own DNS server:

server_names = ['cloudflare', 'cloudflare-ipv6']

Use servers reachable over IPv4

ipv4_servers = true

Use servers reachable over IPv6 when you’ve IPv6 connectivity

ipv6_servers = true

Use servers implementing the DNSCrypt protocol

dnscrypt_servers = true

Use servers implementing the DNS-over-HTTPS protocol

doh_servers = true

Server must support DNS security extensions (DNSSEC)

require_dnssec = true

Server must not enforce its own blocklist (for parental control, ads blocking etc

require_nofilter = true

Enable a DNS cache to reduce latency and outgoing traffic

cache = true

Installing adblocker list for dnscrypt proxy

Add the following to block Ads and make it as a sinkhole adblocker:

[blocked_names]
blocked_names_file = '/etc/dnscrypt-proxy/blocked_names.txt'

Create a new shell script named “update-adblocker.sh” as follows:

#!/bin/bash
# Name: update-adblocker.sh
# Purpose: Download and update adblocker list for dnscrypt proxy
# Usage: Call it from the CLI or cron job https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
DEST="/etc/dnscrypt-proxy/blocked_names.txt"
#
# Blocks both adware + malware 
# See for other lists https://github.com/StevenBlack/hosts
SRC="https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
TMP_B_FILE="$(mktemp)"
TMP_B_FILE_SORTED="$(mktemp)"
wget --timeout=10 --tries=5 -qO- "${SRC}" | grep -Ev "(localhost)" | grep -Ev "#" | sed -E "s/(0.0.0.0 |127.0.0.1 |255.255.255.255 )//" >> "${TMP_B_FILE}"
awk '/^[^#]/ { print $1 }' "${TMP_B_FILE}" | sort -u > "${TMP_B_FILE_SORTED}"
cp -f "${TMP_B_FILE_SORTED}" "$DEST"
rm -f "${TMP_B_FILE}" "${TMP_B_FILE_SORTED}"
chmod 0644 "$DEST"
Run .sh file as follows:
# chmod -v +x update-adblocker.sh
# ./update-adblocker.sh

Verify it using “bat,” “cat,” “less,” or “more” commands:
# less /etc/dnscrypt-proxy/blocked_names.txt
Make sure you run the update-adblocker.sh script daily to get an updated list of the hosts file. Set a new cron job for Linux as follows:

@daily /path/to/your/update-adblocker.sh

Apart from ads and malware, you can block fake news, gambling, porn, and social media too. See this repository page for info to adjust your script. Restart the dnscrypt service again:
$ sudo systemctl restart dnscrypt-proxy.service
$ sudo systemctl status dnscrypt-proxy.service

● dnscrypt-proxy.service - DNSCrypt client proxy
     Loaded: loaded (/lib/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-05-13 12:01:18 UTC; 2s ago
TriggeredBy: ● dnscrypt-proxy.socket
       Docs: https://github.com/DNSCrypt/dnscrypt-proxy/wiki
   Main PID: 2164 (dnscrypt-proxy)
      Tasks: 7 (limit: 519)
     Memory: 34.8M
        CPU: 512ms
     CGroup: /system.slice/dnscrypt-proxy.service
             └─2164 /usr/sbin/dnscrypt-proxy -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml

May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] Source [public-resolvers] loaded
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] Firefox workaround initialized
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] Loading the set of blocking rules from [/etc/dnscrypt-proxy/blocked_names.txt]
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] [cloudflare-ipv6] OK (DoH) - rtt: 43ms
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] [cloudflare] OK (DoH) - rtt: 38ms
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] Sorted latencies:
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] -    38ms cloudflare
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] -    43ms cloudflare-ipv6
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] Server with the lowest initial latency: cloudflare (rtt: 38ms)
May 13 12:01:18 ip-172-26-13-206 dnscrypt-proxy[2164]: [2024-05-13 12:01:18] [NOTICE] dnscrypt-proxy is ready - live servers: 2

Step 4 – Troubleshooting dnscrypt-proxy service

You can check the configuration file for errors and exit. For example:
$ sudo dnscrypt-proxy -check
Here is how to set path to the configuration file /etc/dnscrypt-proxy/dnscrypt-proxy.toml:
$ sudo dnscrypt-proxy -check -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml
Apart from that, use the journalctl command as follows:
$ sudo journalctl -u dnscrypt-proxy.service

Step 5 – Configure client computers or mobile devices

Ensure your DHCP server is configured to hand over your DNSCrypt-proxy server’s IP address as the DNS resolver. Sometimes, it’s as simple as editing the /etc/resolv.conf file and adding the IP address:
$ cat /etc/resolv.conf
Outputs:
nameserver 10.8.0.1
nameserver fd5a:dadf:8d6d::1

Other times, you may need to work with resolvctl or systemd-resolved to set the correct DNS server IPs. When using OpenVPN and Wireguard, you can force clients to use the DNSCrypt-proxy server’s IP address as the DNS resolver and block all other DNS queries for public or ISP DNS servers using ufw command or iptables command.

Related
Also, check all our complete firewall tutorials for Alpine Linux Awall, CentOS 8, OpenSUSE, RHEL 8, Debian 12/11, Ubuntu Linux version 16.04 LTS/18.04 LTS/20.04 LTS, and 22.04 LTS.

Wrapping up

There you have it, DNSCrypt-proxy installed successfully on Debian 11 or 12, with the optional Adblocker feature to block tracking and harmful content from the Internet. For more information, visit the DNSCrypt-proxy project homepage and documentation site here.

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.