The article is intended for the following software versions:
- OS: Linux with
- Tested on: Debian 10
Installation and configuration steps should be mostly applicable to distros using
What is DNSCrypt and DNS-over-HTTPS?
While browsing on the web, people almost always use the domain name instead of the IP address of the requested resource. However, the domain name must first be resolved to a corresponding IP address by a DNS resolver. In most cases, the DNS resolver is assigned by the Internet Service Provider (ISP). Moreover, even if the requested website uses HTTPS, DNS queries use a different protocol and they are sent in plain-text by default.
These problems are addressed by both DNSCrypt and DNS-over-HTTPS (DoH). To start with, DNSCrypt is the name of the protocol which provides encryption and authentication between the client and the DNS resolver. It uses elliptic curve cryptography. Like DNSCrypt, DNS-over-HTTPS also encrypts the data but using HTTPS protocol, as the name suggests. By using either one of them, people can significantly lower the probability of request and/or tampering, thus preventing man-in-the-middle attacks [1,2].
Apart from DNSCrypt and DoH, DNS data can be further secured by the use of DNS Security Extensions (DNSSEC). It provides DNS data authentication, data integrity and authenticated denial of existence. As a result, attacks such as DNS cache poisoning can be mitigated .
Considering the benefits, encrypting DNS queries is an important part of Linux hardening. In order to use DNSCrypt, DoH and DNSSEC, we are going to use
dnscrypt-proxy as the client, which supports both protocols.
Install and configure dnscrypt-proxy
dnscrypt-proxyexists both in Debian and Ubuntu repositories. Thus, you can install it via:
sudo apt-get update sudo apt-get install dnscrypt-proxy
- Check the
systemdsocket file by:
You should see the listening IP and the port, similar to:
[Socket] ListenStream=127.0.2.1:53 ListenDatagram=127.0.2.1:53 NoDelay=true DeferAcceptSec=1
In this case it is listening on
127.0.2.1and port 53.
- Make sure that nothing else is listening on the same address:port pair from the previous step by:
sudo ss -lp 'sport = :domain'
Depending on the distro,
systemd-resolvedmight be using the same address:port pair. If that is the case, it can be disabled via the following:
sudo systemctl stop systemd-resolved.service sudo systemctl disable systemd-resolved.service
- Edit dnscrypt-proxy configuration in
dnscrypt_servers = true doh_servers = true require_dnssec = true
This will enable both DNSCrypt and DoH supporting servers. In addition, it requires the DNSSEC support. Optionally, if you would like to use only the no-log and no-filter (parental filters, ad blocking etc.) resolvers, you can add:
require_nolog = true require_nofilter = true
If you have a system where IPv6 is disabled and/or your ISP does not provide IPv6 connectivity, you might want to disable it also in
dnscrypt-proxy. This would result in immediate
refusedresponses, therefore you might realize faster connections.
block_ipv6 = true ipv6_servers = false
- Backup the existing
sudo cp /etc/resolv.conf /etc/resolv.conf.backup
- Remove the existing
sudo rm -f /etc/resolv.conf
- Create and edit
nameserver 127.0.2.1 # the listening address in dnscrypt-proxy.socket file options edns0
nameserver 127.0.2.1tells that DNS queries are sent to the specified address, at which
dnscrypt-proxy.socketis listening. If your socket file has a different address, you should configure
edns0is required to be able to use DNSSEC.
- Prevent network manager from changing the
sudo chattr +i /etc/resolv.conf
At least in Debian and Ubuntu, the Network manager configures the
nameserverautomatically when a connection is established. Therefore, if you do not set an immutable bit on
resolv.conf, it will be overridden.
- Start and enable the
sudo systemctl start dnscrypt-proxy.socket sudo systemctl enable dnscrypt-proxy.socket sudo systemctl start dnscrypt-proxy.service sudo systemctl enable dnscrypt-proxy.service
- Test if EDNS0 is active by:
drill rs.dns-oarc.net TXT
Look for “EDNS: version: 0” entry in the output.
- Test if the
dnscrypt-proxyselected resolvers are really using DNSSEC validation: DNSSEC Resolver Test.
- As the last thing, you need to check if there is a DNS leak. This can be done via DNSleaktest. You should only see the resolvers specified in the following list: DNSCrypt Resolvers. By default, this is the list used by
dnscrypt-proxywhen selecting the best resolver, constrained by your requirements in the
Installation and configuration sources: [4,5,6]
Using dnscrypt-proxy with captive portals
If you have applied the steps until this section, you will realize that captive portal logins, such as those in hotels, cafes and airports would not work. The reason is that usually, the hotspot needs to first redirect the client to an internal authentication page before allowing the access to the web. However, it cannot do this, because the network manager cannot override the
resolv.conf with the one from the router.
Thus, you need to temporarily remove the modifications made to
resolv.conf and restart the network manager, then after logging in into the captive portal, you can safely re-enable DNSCrypt/DoH. Below is a bash script to achieve this goal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #!/bin/bash # Exit script as soon as a command fails. set -o errexit RESOLV_CONF=/etc/resolv.conf DNSCRYPT_RESOLV=/etc/resolv.conf.dnscryptBackup sudo cp $RESOLV_CONF $DNSCRYPT_RESOLV sudo chattr -i $RESOLV_CONF sudo rm -f $RESOLV_CONF echo "Restarting the NetworkManager" sudo systemctl restart NetworkManager echo "Wait for the connection" echo "Then, login to the captive portal" while true do read -p "Did you login?(Y/N) " answer case $answer in [yY]* ) sudo rm -f $RESOLV_CONF sudo cp $DNSCRYPT_RESOLV $RESOLV_CONF sudo rm -f $DNSCRYPT_RESOLV sudo chattr +i $RESOLV_CONF echo "Final nameservers:" cat $RESOLV_CONF echo "Restarting dnscrypt-proxy..." sudo systemctl restart dnscrypt-proxy echo "Done" break;; [nN]* ) exit;; * ) echo "Enter Y or N, please.";; esac done
- DNSCrypt. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/DNSCrypt
- DNS over HTTPS. Wikipedia. Retrieved from https://en.wikipedia.org/wiki/DNS_over_HTTPS
- DNSSEC - What is it and why is it important? Internet Corporation for Assigned Names and Numbers (ICANN). Retrieved from https://www.icann.org/resources/pages/dnssec-what-is-it-why-important-2019-03-05-en
- dnscrypt-proxy. ArchWiki. Retrieved from https://wiki.archlinux.org/index.php/Dnscrypt-proxy
- DNSCrypt. InstallGentoo Wiki. Retrieved from https://wiki.installgentoo.com/index.php/DNSCrypt
- Dnscrypt-proxy Wiki. GitHub. Retrieved from https://github.com/DNSCrypt/dnscrypt-proxy/wiki