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?
- The domain
sools.co.uk
seems not blocked and doesn’t exist. - The domain
scools.co.uk
is not blocked yetsrools.co.uk
is blocked - The
sccools.co.uk
andscccools.co.uk
and evensccccools.co.uk
and evenscccccools.co.uk
are all blocked.
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.