Site icon GetPageSpeed

Secure your DNS with dnsmasq, dnscrypt-proxy and Cloudflare

DNS

DNS

DNS is a plain-text protocol, and many countries have employed censorship on their citizens by simply hijacking the standard DNS port 53 and inspecting it while denying much of what is being accessed.

Cloudflare provides a secure DNS system via several protocols. In this guide, we’re picking up our previous article on DNS caching for your Linux machine and iteratively improve that setup by switching from plain insecure DNS to secure DNS.

This guide is useful for both workstation and server RHEL-based systems.

Internet censorship via DNS. Indonesia example

An example of such a country that practices censorship on its Internet space is Indonesia. Many quite legitimate websites are blocked on a DNS level, and the bypass is as easy as setting a hosts file entry, or a proxy.

There are many questions about that system. The block list is downloadable and publicly accessible.

Let’s review how this system works on a sample entry s****ools.co.uk. What does it mean in practice?

In fact, such severe blocking varies per particular domain, but it can be observed that Internet access is very degraded with this wildcard blocking.

Even if there wouldn’t be any blocking in the first place, this clearly shows what the open DNS protocol allows for.
It provides the ability to inspect and block your requests to any website.
It is a high breach of your privacy, in that it allows anyone with the appropriate access levels, to see your actual website visit history, on a domain basis.

And that is, whether those websites employ TLS encryption or not.

Making your DNS secure

The best solution, for performance, and privacy-wise is to set up your DNS requests to be encrypted. There are currently few protocols and services allowing you to do it.

In this article, we will review how to make your existing RHEL machine setup with dnsmasq and NetworkManager use secure DNS communication.

Here’s our current setup: <your browser> -> <dnsmasq> -> <Cloudflare DNS servers>.
In the case of severely censored locations like the above, it actually works as <your browser> -> <dnsmasq> -> <ISP nameservers>, due to ISPs hijacking the DNS port on the network level.

And here’s what our new setup will look like:

<your browser> -> <dnsmasq> -> <dnscrypt-proxy> -> <Cloudflare secure DNS servers>.

Set up and configure dnscrypt-proxy

The dnscrypt-proxy is a software that acts as a standard DNS resolving nameserver, but is capable of talking to upstream DNS servers which support secure protocols like “DNS over HTTPS” or “DNS over TLS”. This is what we install on our machine, in order to configure it later to resolve all domains through it.

To install it, you can use the GetPageSpeed subscription-based repository or EPEL:

On CentOS/RHEL 7:

yum -y install dnscrypt-proxy2

On CentOS/RHEL 8+

dnf -y install dnscrypt-proxy

Then edit the configuration file /etc/dnscrypt-proxy/dnscrypt-proxy.toml with the following changes.

Replace

listen_addresses = ['127.0.0.1:53']

with

listen_addresses = ['127.0.0.53:53']

That’s right. NetworkManager does not have the ability to specify the port 53, so we are actually making our dnscrypt-proxy listen on a separate loopback address 127.0.0.53.

Next, ensure these settings:

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

By this, we use Cloudflare’s secure DNS.

Now you can start the service by running:

systemctl enable --now dnscrypt-proxy.service

Check that your configuration is valid, by running a query against DNS:

dnscrypt-proxy -resolve cloudflare-dns.com -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml

Sample results would be:

Resolving [cloudflare-dns.com] using 127.0.0.53 port 53

Resolver      : 162.158.161.89

Canonical name: cloudflare-dns.com.

IPv4 addresses: 104.16.249.249, 104.16.248.249
IPv6 addresses: 2606:4700::6810:f9f9, 2606:4700::6810:f8f9

Name servers  : ns1.cloudflare-dns.com., ns2.cloudflare-dns.com., ns3.cloudflare-dns.com.
DNSSEC signed : yes
Mail servers  : no mail servers found

HTTPS alias   : -
HTTPS info    : [alpn]=[h3,h3-29,h2], [ipv4hint]=[104.16.248.249,104.16.249.249], [ipv6hint]=[2606:4700::6810:f8f9,2606:4700::6810:f9f9]

Host info     : -
TXT records   : xys2vzh7bp5r11pxl363wl8skcv8k2ss

Modify NetworkManager and dnsmasq configuration

Now to the most interesting part. We already have a secure DNS available at 127.0.0.53.
Now we need dnsmasq which is managed by NetworkManager, make sure to forward DNS requests over to our secure DNS proxy.

For this, we can use nmcli, like so:

nmcli connection modify eth0 ipv4.dns 127.0.0.53
nmcli connection modify eth0 ipv4.ignore-auto-dns yes

This tells NetworkManager to set upstream DNS server to 127.0.0.53.
We also make NetworkManager ignore the DNS nameservers obtained via DHCP, since in this case, we want to explicitly use dnscrypt-proxy.
The dnsmasq which is run by NetworkManager, will forward requests appropriately to dnscrypt-proxy.

Also, you must explicitly tell Networkmanager’s dnsmasq about the upstream DNS server. Without this, things wouldn’t work as expected.

Open the file /etc/NetworkManager/dnsmasq.d/custom.conf and add:

server=127.0.0.53

Finally, you can apply all the changes by restarting NetworkManager:

service NetworkManager restart

Now NetworkManager restarts the dnsmasq instance that it manages and that instance will cache your DNS requests while routing them securely through dnscrypt-proxy.
This ensures that your DNS requests never leave your machine unsecured. From now on, they are always encrypted. The censored websites are working and your privacy is improved.

Exit mobile version