How to install dnscrypt proxy with adblocker on Linux

How do I install the dnscrypt proxy application with an adblocker/malware blocker on Linux operating system with WireGuard or OpenVPN?

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.
Tutorial details
Difficulty Easy (rss)
Root privileges Yes
Requirements Linux
Time 10m
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.
Sample dnscrypt-proxy set up

ADVERTISEMENTS

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

How to install dnscrypt proxy on Linux

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

Are you using dnscrupt-proxy on Fedora Linux? See this comment below.

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/
Linux Cloudflare DNSCrypt Proxy Verification
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

I prefer DNSCrypt due to lightweight and less moving parts, but it lacks pretty reports and WebUI too.

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
8 comments… add one
  • Zebra Oct 10, 2020 @ 10:34

    How come “DNSCrypt-Proxy with DoH + WireGuard + Alpine Linux : 68.7M”? Why is memory footprint so low on Alpine Linux? I never tried, but look like an excellent solution for my tiny RPI 3 server at home.

  • Fedora's maintainer Oct 12, 2020 @ 17:35

    For Fedora, we use SystemD sockets to configure the listen address

    – *Remove* the list of local addresses and ports to listen to:
    listen_addresses = []

    – If you don’t have IPv6, edit:
    sudo vim /usr/lib/systemd/system/dnscrypt-proxy.socket

    and comment out the IPv6 address:

    [Socket]
    ListenStream=127.0.0.1:53
    # ListenStream=[::1]:53
    ListenDatagram=127.0.0.1:53
    # ListenDatagram=[::1]:53

    then use sudo systemctl daemon-reload and restart the dnscrypt-proxy.service.

    • 🐧 Vivek Gite Oct 12, 2020 @ 22:48

      Thanks for the feedback!

      • ebzero Oct 13, 2020 @ 5:09

        This is also the case for Ubuntu 20.04.

  • CentOS 7 Linux user Oct 12, 2020 @ 23:04

    Your script failed on my CentOS 7 box and blacklist.txt was always empty. I had to re-run it multiple times. So I modified it follows and it is perfect now. Sharing for other CentOS 7 users:

    #!/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_HOSTS="$(mktemp)"
    TMP_B_FILE="$(mktemp)"
    TMP_B_FILE_SORTED="$(mktemp)"
    wget --timeout=3 --tries=5 -qO "${TMP_HOSTS}" "${SRC}" 
    grep -Ev "(localhost)" "${TMP_HOSTS}"  | 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}"
    cat "${TMP_B_FILE_SORTED}" > "$DEST"
    rm -f "${TMP_B_FILE}" "${TMP_B_FILE_SORTED}" "${TMP_HOSTS}"
  • realcs Oct 13, 2020 @ 9:46

    Hi Vivek ! Thx for this tutorial ! I was wondering , for example if we have installed wireguard + pihole why we need DNSCrypt installed if wireguard it’s a vpn and encrypt the connection passing through his interface ?

    • 🐧 Vivek Gite Oct 13, 2020 @ 10:37

      You don’t need it. I use it because Pi-Hole take more resources. Wireguard may or many not available everywhere. Additional level of protection never hurts either, you know may layers of security.

    • Anonymous Oct 14, 2020 @ 8:13

      There was a bug on win10 wsl that leaked dns traffic by accident when using openvpn. In such case encrypted dns might have protected you.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.