DNSCrypt is a protocol to authenticate and encrypt DNS traffic between your device and recursive name servers such as Google, Cloudflare, ISP/3rd party servers, or your own DoH server based upon Nginx+Bind9. The dnscrypt-proxy is a free and open-source application supporting protocols such as DNSCrypt v2 and DNS-over-HTTPS (DoH). It also prevents DNS spoofing. It uses cryptographic signatures to verify that responses originate from the chosen DNS resolver and haven’t been tampered with.
Free and DNSCrypt-enabled resolvers are available all over the world including DoH enabled resolvers. In other words, we use dnscrypt-proxy for securing communications between a client and a DNS resolver.
How to install dnscrypt-proxy
This page shows how to install dnscrypt-proxy with an adblocker on Linux with OpenVPN/WireGuard VPN server to secure communication on public WiFi or untrusted network.
Installing dnscrypt proxy on Linux
Run command as per your Linux distro as the root user:
## Debian/Ubuntu user try apt command/apt-get command ##
$ sudo apt install dnscrypt-proxy
## Alpine Linux user try apk command ##
$ sudo apk add dnscrypt-proxy
## CentOS / RHEL user:
## Enable EPEL repo on CentOS 8 or RHEL 8
## try yum command ##
$ sudo yum install dnscrypt-proxy
## Arch Linux user try pacman command ##
$ sudo pacman -S dnscrypt-proxy
## OpenSUSE/SUSE Linux user try zypper command ##
$ sudo zypper in dnscrypt-proxy
## Fedora user try dnf command ##
$ sudo dnf install dnscrypt-proxy
Configuring dnscrypt proxy
Edit the dnscrypt-proxy.toml in /etc/dnscrypt-proxy/ directory. For example:
$ ls -l /etc/dnscrypt-proxy/
$ sudo vim /etc/dnscrypt-proxy/dnscrypt-proxy.toml
First, we need to set up a list of servers to use. Let us use both google and cloudflare:
server_names = [ ‘google’ ‘cloudflare’]
I can just use cloudflare too:
server_names = [ ‘cloudflare’]
WARNING: Do not listen to WAN public IP address and port. We are not going to act as a public resolver for the world. Hence, I am going for loopback and my VPN interface IP address only.
Set up list of local addresses and ports to listen to:
listen_addresses = [‘127.0.0.1:53’, ‘[::1]:53’]
For my VPN 172.168.0.0/24 sub/net:
listen_addresses = [‘127.0.0.1:53’, ‘172.168.0.1:53’ ]
If you have IPv6 connectivity, use servers reachable over IPv6 (default is IPv4):
ipv6_servers = true
Make sure we use servers implementing the DNSCrypt and DoH protocol
dnscrypt_servers = true
doh_servers = true
Make sure we enable a DNS cache to reduce latency and outgoing traffic:
cache = true
Server must support DNS security extensions (DNSSEC):
require_dnssec = true
Adblock lists are made of one pattern per line. Example of valid patterns are:
## ## example.com ## =example.com ## ads.* ## ads*.example.* ## ads*.example[0-9]*.com
Path to the file of blocking rules
blacklist_file = ‘/etc/dnscrypt-proxy/blacklist.txt’
Save and close the file.
Installing adblocker list for dnscrypt proxy
Here is a small bash script to download and update list.
#!/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/blacklist.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}"
Run it:
# ./update-adblocker.sh
Verify it:
# more /etc/dnscrypt-proxy/blacklist.txt
Make sure you run the update-adblocker.sh script daily to get an updated list of the hosts file. Add a new cron job as follows:
@daily /path/to/update-adblocker.sh
Apart from ads and malware, you can block fake news, gambling, porn, and social media too. See this repository page.
Enable dnscrypt proxy service
Use the systemctl command to enable dnscrypt-proxy service on Linux:
$ sudo systemctl enable dnscrypt-proxy
Start the service:
$ sudo systemctl start dnscrypt-proxy
Verify the service:
$ sudo systemctl status dnscrypt-proxy
DNSCrypt status:
● dnscrypt-proxy.service - DNSCrypt-proxy client Loaded: loaded (/usr/lib/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2020-10-10 05:44:29 EDT; 4s ago Docs: https://github.com/jedisct1/dnscrypt-proxy/wiki Main PID: 5108 (dnscrypt-proxy) Tasks: 8 (limit: 11328) Memory: 13.8M CGroup: /system.slice/dnscrypt-proxy.service └─5108 /usr/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Wiring systemd TCP socket #1, dnscrypt-proxy.socket, [::1]:53 Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Wiring systemd UDP socket #2, dnscrypt-proxy.socket, 127.0.0.1:53 Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Wiring systemd UDP socket #3, dnscrypt-proxy.socket, [::1]:53 Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Source [public-resolvers] loaded Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: /etc/dnscrypt-proxy/relays.md: open sf-ux5n6prgb5kk4yzf.tmp: read-only file system Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Source [relays] loaded Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Firefox workaround initialized Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: [cloudflare] OK (DoH) - rtt: 18ms Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: Server with the lowest initial latency: cloudflare (rtt: 18ms) Oct 10 05:44:29 centos-8-cloud.sweet.home dnscrypt-proxy[5108]: dnscrypt-proxy is ready - live servers: 1
Alpine Linux user need to use the rc-update command and rc-service command:
$ sudo rc-update add dnscrypt-proxy
$ sudo rc-service dnscrypt-proxy
Test it
Use the host command/drill command/dig command $ host www.cyberciti.biz 127.0.0.1
## connect to your VPN server and run #
$ host bash.cyberciti.biz {vpn-server-ip}
$ host bash.cyberciti.biz 172.168.0.1
Using domain server:
Name: 172.168.0.1 Address: 172.168.0.1#53 Aliases: bash.cyberciti.biz has address 104.22.10.214 bash.cyberciti.biz has address 104.22.11.214 bash.cyberciti.biz has address 172.67.7.239 bash.cyberciti.biz has IPv6 address 2606:4700:10::6816:ad6 bash.cyberciti.biz has IPv6 address 2606:4700:10::6816:bd6 bash.cyberciti.biz has IPv6 address 2606:4700:10::ac43:7ef
Is adblocker working? Try:
$ host pagead2.google.com 172.168.0.1
You must see NXDOMAIN outputs:
Using domain server: Name: 172.168.0.1 Address: 172.168.0.1#53 Aliases: Host pagead2.google.com not found: 3(NXDOMAIN)
If you are using Cloudflare DoH with DNSCrypt-proxy, try the following URL to verify connectivity:
https://1.1.1.1/help/
We can verify DNS encryption with the tcpdump tool, which is left as an exercise to readers.
Conclusion
And there you have it. DNSCrypt proxy is installed with an adblocker list on Linux to increase your DNS privacy and protection. Pi-hole is excellent, too, but it requires many more resources. Here are my memory usages between two adblockers:
- DNSCrypt-Proxy with DoH + WireGuard + Alpine Linux : 68.7M
- DNSCrypt-Proxy with DoH + WireGuard + Ubuntu minimal : 155.8M
- Pi-hole with WebUI + Cloudflard with DoH + WireGuard + Ubuntu minimal : 198M