Protect Your DNS Privacy on Ubuntu 18.04 with DNS over TLS

This tutorial will be showing you how to protect your DNS privacy on Ubuntu 18.04 desktop with DNS over TLS. We will use a tool called stubby to achieve that. But first, let me tell you why DNS is not secure.

DNS Vulnerability

DNS is insecure because by default DNS queries are not encrypted, which can be exploited by middle entities. DNS cache poison is one of the DNS abuses that is widely used by the Great Firewall of China (GFW) to censor Chinese Internet. GFW checks every DNS query that is sent to a DNS server outside of China. Since plain text DNS protocol is based on UDP, which is a connection-less protocol, GFW can spoof both the client IP and server IP.  When GFW finds a domain name on its block list, it changes the DNS response. For example, if a Chinese Internet user wants to visit, the Great firewall of China returns to the DNS resolver an IP address located in China instead of Google’s real IP address. Then the DNS resolver returns the fake IP address to the user’s computer.

What is DNS over TLS? How It Protects Your Privacy?

DNS over TLS means that DNS queries are sent over a secure connection encrypted with TLS, the same technology that encrypts HTTP traffic, so no third parties can see your DNS queries. Together with HTTPS and encrypted SNI (Server Name Indication), your browsing history is fully protected from ISP spying.

Stubby is an open-source DNS stub resolver developed by the getdns team. It uses the getdns library. A stub resolver is a small DNS client on the end-user’s computer that receives DNS requests from applications such as Firefox and forward requests to a recursive resolver like or Stubby is special in that it supports DNS over TLS. By default, it will only send DNS requests encrypted. There is another open-source stub resolver called cloudflared that supports DNS over HTTPS but stubby is already in Ubuntu 18.04 repository and is very easy to use.

How to Install and Use Stubby on Ubuntu 18.04 Desktop

Stubby is in Ubuntu 18.04 repository. Open up a terminal window and run the following command to install it.

sudo apt install stubby

This will install stubby and the getdns library. Once installed, stubby runs in the background. You you check its status with:

systemctl status stubby

ubuntu stubby

Stubby listens on TCP and UDP port 53 of localhost (, as can be seen by running this command:

sudo netstat -lnptu | grep stubby

stubby dns over tls

The default stub resolver provided by systemd-resolved listens on TCP and UDP port 53 of

sudo netstat -lnptu | grep systemd-resolv

systemd-resolved stub resolver

Note: If dnsmasq is listening on TCP port 53 of, then Stubby will listen only on UDP port 53 of

The main configuration file is /etc/stubby/stubby.yml. Normally there’s no need to make changes to it unless you want to use another or your own recursive resolver. Let me explain some default configurations. You can open the file with:

sudo nano /etc/stubby/stubby.yml

The following line makes stubby run as a stub resolver instead of a full recursive resolver, which is why it’s named stubby.


The following configuration make stubby send DNS queries encrypted with TLS. It will not send quries in plain text.


This following line requires a valid TLS certificate on the remote recursive resolver.


The following lines set the listen addresses for the stubby daemon. By default, IPv4 and IPv6 are both enabled.

- 0::1

The following line make stubby query recursive resolvers in a round-robin fashion. If set to 0, Stubby will use each upstream server sequentially until it becomes unavailable and then move on to use the next.

round_robin_upstreams: 1

By default there are 3 recursive resolvers enabled in stubby configuration file. They are run by stubby developers and support DNS over TLS. You can see the full list of recommended servers on DNS Privacy website.    

There are other DNS servers in the Additional Servers section that are disabled by default. (supporting TLS1.2 and TLS 1.3)

There are also DNS servers listening on port 443. If port 853 is blocked in your network, you can uncomment them to use these servers.

Now you can exit nano text editor by pressing Ctrl+X.

Switching to Stubby

Editing the /etc/resolve.conf file to change name server is not recommended any more. Follow the instructions below to make systemd-resolved send DNS queries to stubby.

GNOME Desktop

Click the Network Manager icon on the upper-right corner of your desktop. Then select wired settings. (If you are using Wi-fi, select Wi-fi settings.)

encrypt dns

Click the gear button.

cloudflare dns over tls

Select IPv4 tab, then in DNS settings, switch Automatic to OFF, which will prevent your Ubuntu system from getting DNS server address from your router. Enter in the DNS field. Click Apply button to save your changes.

dns over tls port 853

Then restart NetworkManager for the changes to take effect.

sudo systemctl restart NetworkManager

Once you are reconnected, you can see that your Ubuntu system is now using as the DNS server in the Details tab.

stub resolver dns over tls

Unity Desktop

Recommended reading: how to install Unity desktop environment on Ubuntu 18.04.

Click the Network Manager icon on the upper-right corner of your desktop, then click edit connections.

network manager change DNS

Select your connection name and click the gear icon.

stubby systemd-resolved

Select IPv4 settings tab, change method from Automatic(DHCP) to Automatic(DHCP) addresses only, which will prevent your Ubuntu system from getting DNS server address from your router. Then specify a DNS server ( Stubby listens on

ubuntu dns over tls

Save your changes. Then restart NetworkManager for the changes to take effect.

sudo systemctl restart NetworkManager

Once you are reconnected, click the Network Manager icon again and select connection information. You can see that your Ubuntu system is now using as the DNS server.

ubuntu 18.04 dns over tls

A Desktop-Agnostic Way to Change DNS Server

You can use the method below to change DNS server as long as your desktop environment is using NetworkManager.

Open a terminal window and go to the Network Manager connections profile directory.

cd /etc/NetworkManager/system-connections/

Then list connection names available on your system.


network manager change dns server from command line

As you can see, I have several connections on my system, one of which is wired connection. Some are wireless connections and one is VPN connection. Because my desktop computer is connected to my router via an Ethernet cable, so I need to edit the wired connection profile with the nano command line text editor.

sudo nano 'Wired connection 1'

If your computer is connected via Wi-fi, then you need to edit the wireless connection profile. In this file, find the [ipv4] configurations. By default, it should look like this:


To make your system use Stubby, change the configurations to the following.


To save the file in Nano text editor, press Ctrl+O, then press Enter to confirm. Press Ctrl+X to exit. Then restart Network Manager for the changes to take effect.

sudo systemctl restart NetworkManager

You can now check your current DNS server by running the following command:

systemd-resolve --status

Sample output:

Link 2 (enp5s0)
Current Scopes: DNS
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
DNS Servers:

If is listed as the DNS server, then your system is using Stubby.

How to Check if Your DNS Traffic is Encrypted

We can use WireShark to monitor DNS traffic. Install WireShark from Ubuntu 18.04 repository.

sudo apt install wireshark

If you are asked “Should non-superusers be able to capture packets?”, answer Yes. Once it’s installed, run the following command to add your user account to the wireshark group so that you can capture packets.

sudo adduser your-username wireshark

Log out and log back in for the changes to take effect. Then open WireShark from your application menu, select your network interface in WireShark. For example, my Ethernet interface name is enp5s0. Then enter port 853 as the capture filter. This will make WireShark only capture traffic on port 853, which is the port used by DNS over TLS.

ubuntu 18.04 stubby

Click the button on the upper-left corner to start capturing. After that, in terminal window, run the following command to query domain name by using the dig utility. For instance, I can query the A record of my domain name.

dig A

Now you can see the captured DNS traffic in WireShark. As you can see, my DNS query was sent to, and, which are the 3 default DNS resolvers defined in stubby configuration file. Connections were made over TCP and encrypted with TLS, which is what I want.

secure dns

If DNS queries are sent without encryption, then the computer would contact DNS server on port 53. You can capture packets again with port 53 as the capture filter, but you won’t see any packets in WireShark, which means stubby is encrypting your DNS queries.

How to Add CloudFlare DNS to Stubby

I found that there is high latency (over 200ms) between my computer and the 3 default DNS servers, whereas CloudFlare DNS servers (, give me very low latency (below 20ms). CloudFlare also supports DNS over TLS. To add CloudFlare DNS server, edit stubby configuration file.

sudo nano /etc/stubby/stubby.yml

Scroll down to the upstream_recursive_servers: section and add the following text above other DNS servers.

#CloudFlare servers
  - address_data:
    tls_auth_name: ""
  - address_data:
    tls_auth_name: ""

Then find the following line:

round_robin_upstreams: 1

Change 1 to 0. This will make stubby always use CloudFlare DNS server. If CloudFlare is not available, stubby will use other DNS servers. Save the file and restart stubby for the changes to take effect.

sudo systemctl restart stubby

I hope this tutorial helped you protect your DNS privacy on Ubuntu 18.04 with DNS over TLS. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care.

Rate this tutorial
[Total: 40 Average: 4.4]

25 Responses to “Protect Your DNS Privacy on Ubuntu 18.04 with DNS over TLS

  • Stephen McGregor
    2 years ago

    I am on Xubuntu 16.04… as such, stubby is not in the repository. I am a relatively amateur Linux user, so I was wondering if I could get some alternative instructions for my scenario. TIA. (I’ve included what happens when I go to install stubby).

    “sudo apt-get install stubby
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    E: Unable to locate package stubby”

  • sir, what about opendns, whether it can be used as DNS over TLS. how to use stubby under Ubuntu 16.04 LTS desktop. It is not in the repository.

    • whether stubby can be installed from the following for Ubuntu 16.04 ( going for fresh install of 18.04 always there. would like to use opendns or ibm quad or googld dns or native dns provider. how to check whether native dns provider supports dns over tls?

  • Hi
    I have got Stubby install and config the file as above mention but when I issue the command “systemd-resolve –status” I got this output as below. Is my traffic DNS over TLS? I am using Linux Mint 19 Tara XFCE

    dell@dell-XPS-M1330:~$ systemd-resolve –status
    lines 1-23

    • If the output of systemd-resolve --status contains DNS Servers:, then your system is using Stubby.

    • I’m not using XFCE desktop, but I added instructions on changing DNS server from command line. Please see “A Desktop-Agnostic Way to Change DNS Server” section in this article.

  • Dear Xiao Guo
    Thank you.

  • Thank you Xiao, very useful resource.

  • Below page claims Stubby doesn’t have a cache and it provided a guide on how to enable it on dnsmasq. But what should be done in Ubuntu?

    • Omnominous
      12 months ago

      Stubby may not include any caching abilities, but I’m pretty sure systemd-resolved does.

  • Wow this so easy than install dnscrypt. I don’t know this software works like dnscrypt or not. But i tried using this software, and i can access reddit again. Thank you.

  • Marcel
    1 year ago

    Thanks, great! Now I am DNSoverTLS secured! (


    already can support some of it, but has no certificate verification, to name only one problem).

    sudo netstat -lnptu | grep systemd-resolve

    only works when the process ID has at most 3 digits. Once the PID grows to 4 (or 5) digits, 1 (or 2) letters are cut off from the end. So one should

    grep systemd-resol


  • Marcel
    1 year ago

    Chosing one of the quad-{1,8,9} DNS providers may be convenient, but we do not know for sure what they are doing with our data.

    To reduce delays, chose a trustworthy organization nearby. In Switzerland, this could be e.g. Digitale Gesellschaft, an association that merged with the Swiss Privacy Foundation. Their public DoT/DoH servers are described here:

  • I edited my yml file to just two providers and 5 addresses. 2 IPv4 for each server and one IPv6 for one server. I kept “round_robin_upstreams: 1”. My DNS is working, but how can I check that all 5 entries are working? Is there a log somewhere I can check? I have done numerous checks and have seen both of the servers in my settings be listed, but never concurrently. I just wanted to ensure all 5 addresses are correct. Thanks.

  • 兄弟,搞一篇文章 ,谈谈如何搭建‘dns-over-tls’ server吧。我搞了好久,都没搞好

    Hey bro, how to set up a dns-over-tls server? I can’t manage to configure it properly.

    • 想写一篇,但暂时有其他事。

      I intended to write an article on this, but I don’t have time right now.

    • Setting up a DNS-over-TLS server is actually very simple.

      First, you need to set up a dns resolver using BIND, unbound, or whatever DNS software you prefer. You can check out my BIND tutorial below.

      Then you can set up Nginx to act as a DNS proxy for BIND. Add the following lines in /etc/nginx/nginx.conf file. They need to be placed outside of the http context.

      stream {
          # DNS upstream pool
          upstream dns {
              zone dns 64k;
         # DoT server for decryption
         server {
              listen 853 ssl;
              ssl_certificate /etc/letsencrypt/live/;
              ssl_certificate_key /etc/letsencrypt/live/;
              proxy_pass dns;

      Nginx will terminate TLS on port 853, then it will redirect DNS requests to the local DNS resolver listening on You need to obtain your own TLS certificate from Let’s Encrypt.

      Save and close the file. Then test Nginx configuration and restart.

      sudo nginx -t
      sudo systemctl restart nginx

      Note that if you use CentOS, you need to allow Nginx to listen on port 853 with the following command.

      sudo dnf install policycoreutils-python-utils
      sudo semanage port -m -t http_port_t -p tcp 853

      Open port 853 in firewall.


      sudo ufw allow 853/tcp


      sudo firewall-cmd --permanent --zone=public --add-port=853/tcp
      sudo systemctl restart firewalld

      Since we are using DNS over TLS, there’s no need to worry about DNS amplification attack.

      Now configure Stubby to use your own DNS over TLS server.

  • Thank you, it was quite easy to do with your instructions…

    • I’ve just realized that youtube does not work… Do you have any idea why?

      • 🙂 Very sorry, it is kind of sown in my country at the moment…

  • If I used your previous tutorial when creating a local DNS server on linux, the queries from that DNS server don’t have TLS encryption by default as I understand. So using this tutorial on top of the previous one will work right?

  • Koutheir
    3 days ago

    Thank you for the detailed explanations!

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community ( for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB.
You can upload: image.