DNS is an abbreviation of Domain Name Resolution. It is used to resolve IP addresses to domain names and vice-versa. This helps eliminate the complexity of memorizing specific IP addresses for the various internet sites and therefore, human beings are able to access the pages using the domain names for example google.com, computingforgeeks.com etc. There are several solutions to setting up a DNS server, the most popular ones are BIND DNS, Knot DNS, NSD, MaraDNS, YADIFA, PowerDNS e.t.c
DNSCrypt is a protocol used to improve DNS security by encrypting communications between a DNS client and a DNS resolver. It helps users communicate online privately, without security concerns by preventing DNS spoofing with authentication. DNSCrypt uses cryptographic signatures to verify that responses originate from the chosen DNS resolver and ensure that they have not been tampered with while being transmitted. DNSCrypt is available for several platforms such as macOS, Android, Linux, and Windows as well as routers.
The main features and benefits associated with DNSCrypt are:
- It reduces latency by caching responses and avoiding requesting IPv6 addresses on IPv4-only networks.
- It forces traffic to use TCP, to route it through TCP-only tunnels or Tor.
- It locally blocks ads, trackers, malware, spam, and any website whose domain names or IP addresses match a set of rules you define.
- It allows users to review the DNS traffic originating from your network in real-time, and detect compromised hosts and applications phoning home.
- It prevents queries for local zones from being leaked.
- It supports DNSCrypt v2, Anonymized DNSCrypt and DNS-over-HTTP (DoH) forwarding protocols which can be served on the same port usually port 443.
Today we will learn how to install and configure an Encrypted DNS Server (DNSCrypt)
1. Installing Encrypted DNS Server(DNSCrypt)
There are several ways to install the Encrypted DNS Server(DNSCrypt). These include:
- Using precompiled binaries
- Compiling from source
- Using Docker
In this guide, we will learn how to install an Encrypted DNS Server(DNSCrypt) using a precompiled x86_64 binary. Unfortunately, there are binaries for Linux and Windows systems
For Linux, you need a 64-bit Debian/Ubuntu system, then proceed as shown.
First, create a directory for DNSCrypt.
sudo mkdir -p /opt/encrypted-dns
In the directory, download the latest precompiled package. At the time of this documentation, the latest version was 0.9.9.
Download the binary with the command:
VER=$(curl -s https://api.github.com/repos/DNSCrypt/encrypted-dns-server/releases/latest|grep tag_name|cut -d '"' -f 4)
wget https://github.com/DNSCrypt/encrypted-dns-server/releases/download/$VER/encrypted-dns_${VER}_amd64.deb
Once downloaded, install the package:
sudo apt install -f ./encrypted-dns_*_amd64.deb
Sample Output:
Selecting previously unselected package encrypted-dns.
(Reading database ... 187584 files and directories currently installed.)
Preparing to unpack encrypted-dns_0.9.13_amd64.deb ...
Unpacking encrypted-dns (0.9.13) ...
Setting up encrypted-dns (0.9.13) ...
2. Configure Encrypted DNS Server(DNSCrypt)
Once installed, the Encrypted DNS Server(DNSCrypt) has an example configuration file stored at /usr/share/doc/encrypted-dns/. We will copy this config file to our created directory:
sudo cp /usr/share/doc/encrypted-dns/example-encrypted-dns.toml /opt/encrypted-dns/encrypted-dns.toml
We can now modify this configuration file accordingly.
sudo vim /opt/encrypted-dns/encrypted-dns.toml
Here, modify the listen_addrs
parameter to your IP address that is reachable by the clients(This can be a public IP if you are running the server on cloud)
listen_addrs = [
{ local = "0.0.0.0:443", external = "Your_ipv4_address:443" },
## { local = "[::]:443", external = "[Your_ipv6_address]:443" }
]
You might also need to modify the, upstream_addr
to point to your internal recursive DNS server or leave it as is. Set the provider_name
## Upstream DNS server and port
upstream_addr = "1.1.1.1:53"
dnscrypt]
## Provider name (with or without the `2.dnscrypt-cert.` prefix)
provider_name = "example.com"
## Does the server support DNSSEC?
dnssec = true
## Does the server always returns correct answers (no filtering, including ad-blocking)?
no_filters = true
## Set to `true` if the server doesn't keep any information that can be used to identify users
no_logs = true
3. Run DNSCrypt as a system service
Once the configurations have been made, we need to create a systemd service file for DNSCrypt. This can be done using the command:
sudo bash -c 'cat << EOF > /etc/systemd/system/encrypted-dns.service
# /etc/systemd/system/dnscrypt-server.service
[Unit]
Description=DNSCrypt v2 server
ConditionFileIsExecutable=/usr/bin/encrypted-dns
After=syslog.target network-online.target
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/bin/encrypted-dns -c /opt/encrypted-dns/encrypted-dns.toml
WorkingDirectory=/opt/encrypted-dns/
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
Start and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable --now encrypted-dns
Verify if the service is running:
$ systemctl status encrypted-dns
● encrypted-dns.service - DNSCrypt v2 server
Loaded: loaded (/etc/systemd/system/encrypted-dns.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2022-11-27 13:34:33 EAT; 5s ago
Main PID: 376198 (encrypted-dns)
Tasks: 6 (limit: 4575)
Memory: 16.6M
CGroup: /system.slice/encrypted-dns.service
└─376198 /usr/bin/encrypted-dns -c /opt/encrypted-dns/encrypted-dns.toml
Sad 27 13:34:33 dnscrypt.computingforgeeks.com systemd[1]: Started DNSCrypt v2 server.
Sad 27 13:34:33 dnscrypt.computingforgeeks.com encrypted-dns[376198]: [WARN encrypted_dns] No state file found... creating a new provider key
....
Sad 27 13:34:33 dnscrypt.computingforgeeks.com encrypted-dns[376198]: [INFO encrypted_dns] DNS Stamp: sdns://AQcAAAAAAAAADzg4Ljk5LjkyLjgxOjQ0MyBvFka8viUkAT9gkYMioJ5XjB>
From the above output, we can agree that the DNSCrypt server is set. At the end of the service status, we see the DNS Stamp of the DNSCrypt server. This encodes all the parameters required to connect to a secure DNS server as a single string.
Now allow the required ports through the firewall:
sudo ufw allow 443
sudo ufw allow 53
4. Enable secure DNS on your Local device
Once the DNSCrypt server is running, we need to use it to query DNS requests. In that case, we are required to install a DNSCrypt client. There is a long list of DNSCrypt client implementations. In this guide, we will install the DNSCrypt Proxy which can be on the local or remote system.
Download the latest version for the Client:
VER=$(curl -s https://api.github.com/repos/DNSCrypt/dnscrypt-proxy/releases/latest|grep tag_name|cut -d '"' -f 4)
wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/$VER/dnscrypt-proxy-linux_x86_64-${VER}.tar.gz
Once complete, extract the archive:
tar xvf dnscrypt-proxy-linux_x86_64-${VER}.tar.gz
cd linux-x86_64
Create a configuration file and open it for editing:
cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml
vim dnscrypt-proxy.toml
In the file, make the below adjustments and set your server names.
server_names = ['myserver']
There are several providers enabled on the list of public resolvers. For this case, we will ignore them and use the custom one.
Next, remove the ‘#‘ at the beginning of the below lines and provide the DNS Stamp of your DNSCrypt server
[static]
[static.'myserver']
stamp = 'sdns://AQcAAAAAAAAAAAAQMi5kbnNjcnlwdC1jZXJ0Lg'
Do not worry about the DNS Stamp as it can be retrieved using the sudo systemctl status encrypted-dns
command on your DNSCrypt server.
You can also set a list of domains to be blocked:
[blocked_names]
## Path to the file of blocking rules (absolute, or relative to the same directory as the config file)
blocked_names_file = 'blocked-names.txt'
....
In the directory, there is a sample file that can be copied and edited as desired:
sudo cp example-blocked-names.txt blocked-names.txt
Once the changes have been made, save the config then start the DNSCrypt proxy service:
sudo ./dnscrypt-proxy --config dnscrypt-proxy.toml
Sample Output:
[2023-10-31 14:16:36] [NOTICE] dnscrypt-proxy 2.1.5
[2023-10-31 14:16:36] [NOTICE] Network connectivity detected
[2023-10-31 14:16:36] [NOTICE] Now listening to 127.0.0.1:53 [UDP]
[2023-10-31 14:16:36] [NOTICE] Now listening to 127.0.0.1:53 [TCP]
[2023-10-31 14:16:36] [NOTICE] Service is not usable yet
[2023-10-31 14:16:36] [NOTICE] Resolving server host [raw.githubusercontent.com] using bootstrap resolvers over udp
[2023-10-31 14:16:36] [NOTICE] Source [public-resolvers] loaded
[2023-10-31 14:16:36] [NOTICE] Service is not usable yet
[2023-10-31 14:16:36] [NOTICE] Resolving server host [download.dnscrypt.info] using bootstrap resolvers over udp
[2023-10-31 14:16:36] [NOTICE] Source [relays] loaded
[2023-10-31 14:16:36] [NOTICE] Firefox workaround initialized
[2023-10-31 14:16:36] [NOTICE] [myserver] OK (DNSCrypt) - rtt: 0ms
[2023-10-31 14:16:36] [NOTICE] Server with the lowest initial latency: myserver (rtt: 0ms)
[2023-10-31 14:16:36] [NOTICE] dnscrypt-proxy is ready - live servers: 1
You are now set to send secure DNS queries from your client to the DNSCrypt server. To test if all DNS queries go through 127.0.0.1:53, you need to open a separate terminal and edit /etc/resolv.conf as shown:
$ sudo vim /etc/resolv.conf
nameserver 127.0.0.1
#options edns0 trust-ad
search .
Run the below command to see if the DNS queries are handled as expected with DNSCrypt
$ nslookup example.com
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: example.com
Address: 93.184.216.34
Name: example.com
Address: 2606:2800:220:1:248:1893:25c8:1946
That shows that traffic is being handled with the DNSCrypt server securely.
Run dnscrypt-proxy Client as a systemd service
We can also configure this service to run as a system service:
sudo bash -c 'cat << EOF > /etc/systemd/system/dnscrypt-proxy.service
# /etc/systemd/system/dnscrypt-server.service
[Unit]
Description=DNSCrypt v2 server
ConditionFileIsExecutable=/usr/local/bin/dnscrypt-proxy
After=syslog.target network-online.target
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/local/bin/dnscrypt-proxy --config /opt/dnscrypt-proxy/dnscrypt-proxy.toml
WorkingDirectory=/opt/dnscrypt-proxy/
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
Copy the files to the required directories:
sudo mkdir /opt/dnscrypt-proxy
sudo cp ~/linux-x86_64/* /opt/dnscrypt-proxy/
sudo cp ~/linux-x86_64/dnscrypt-proxy /usr/local/bin
Stop the running service:
sudo killall -9 dnscrypt-proxy
Start the dnscrypt-proxy service:
sudo systemctl enable --now dnscrypt-proxy
Check if the service is running:
$ systemctl status dnscrypt-proxy
● dnscrypt-proxy.service - DNSCrypt v2 server
Loaded: loaded (/etc/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-10-31 16:30:16 EAT; 5s ago
Main PID: 868360 (dnscrypt-proxy)
Tasks: 6 (limit: 4617)
Memory: 7.8M
CPU: 22ms
CGroup: /system.slice/dnscrypt-proxy.service
└─868360 /usr/local/bin/dnscrypt-proxy --config /opt/dnscrypt-proxy/dnscrypt-proxy.toml
Okt 31 16:30:16 computingforgeeks dnscrypt-proxy[868360]: [2023-10-31 16:30:16] [NOTICE] Network connectivity detected
Okt 31 16:30:16 computingforgeeks dnscrypt-proxy[868360]: [2023-10-31 16:30:16] [NOTICE] Now listening to 127.0.0.1:53 [UDP]
Okt 31 16:30:16 computingforgeeks dnscrypt-proxy[868360]: [2023-10-31 16:30:16] [NOTICE] Now listening to 127.0.0.1:53 [TCP]
Okt 31 16:30:16 computingforgeeks dnscrypt-proxy[868360]: [2023-10-31 16:30:16] [NOTICE] Source [relays] loaded
....
Verify if it is handling DNS queries:
$ nslookup example.com
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: example.com
Address: 93.184.216.34
Name: example.com
Address: 2606:2800:220:1:248:1893:25c8:1946
You can also see if it is able to block traffic on the set domains. For example, in my case, I have blocked traffic to computingforgeeks.com

Verdict
That marks the end of this detailed guide on how to install and configure an Encrypted DNS Server (DNSCrypt). I hope this worked for you too.
See more on this page:
- How To Secure BIND DNS Server With DNSSec Keys
- Install and Configure DNS Server on Windows Server
- Configure PowerDNS and PowerDNS Admin on Rocky Linux