Securing DNS with stubby

Stubby is an application that acts as a local DNS Privacy stub resolver (using DNS-over-TLS). Stubby encrypts DNS queries sent from a client machine (desktop or laptop) to a DNS Privacy resolver increasing end user privacy. (https://github.com/getdnsapi/stubby)

The following steps will guide you through the installation and configuration of stubby on RHEL 9. These steps may be repeatable for other Linux distributions.

  1. Enable Extra Packages for Enterprise Linux (EPEL) for RHEL 9:
subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
Repository 'codeready-builder-for-rhel-9-x86_64-rpms' is enabled for this system.
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
Updating Subscription Management repositories.
Red Hat CodeReady Linux Builder for RHEL 9 x86_64 (RPMs)                                                                         3.7 MB/s | 7.1 MB     00:01    
epel-release-latest-9.noarch.rpm                                                                                                  13 kB/s |  19 kB     00:01    
Dependencies resolved.
=================================================================================================================================================================
 Package                                  Architecture                       Version                              Repository                                Size
=================================================================================================================================================================
Installing:
 epel-release                             noarch                             9-7.el9                              @commandline                              19 k

Transaction Summary
=================================================================================================================================================================
Install  1 Package

Total size: 19 k
Installed size: 26 k
Is this ok [y/N]: y
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                         1/1 
  Installing       : epel-release-9-7.el9.noarch                                                                                                             1/1 
  Running scriptlet: epel-release-9-7.el9.noarch                                                                                                             1/1 
Many EPEL packages require the CodeReady Builder (CRB) repository.
It is recommended that you run /usr/bin/crb enable to enable the CRB repository.

  Verifying        : epel-release-9-7.el9.noarch                                                                                                             1/1 
Installed products updated.

Installed:
  epel-release-9-7.el9.noarch                                                                                                                                    

Complete!
  1. Install the getdns and stubby packages:
dnf install getdns stubby
Updating Subscription Management repositories.
Last metadata expiration check: 0:04:55 ago on Wed 24 Apr 2024 23:27:39.
Dependencies resolved.
=================================================================================================================================================================
 Package                           Architecture                Version                               Repository                                             Size
=================================================================================================================================================================
Installing:
 getdns                            x86_64                      1.7.3-1.el9                           epel                                                  219 k
 stubby                            x86_64                      0.4.3-1.el9                           epel                                                   41 k
Installing dependencies:
 libev                             x86_64                      4.33-5.el9                            rhel-9-for-x86_64-baseos-rpms                          56 k
 unbound-libs                      x86_64                      1.16.2-3.el9_3.5                      rhel-9-for-x86_64-appstream-rpms                      553 k

Transaction Summary
=================================================================================================================================================================
Install  4 Packages

Total download size: 869 k
Installed size: 2.2 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): stubby-0.4.3-1.el9.x86_64.rpm                                                                                             148 kB/s |  41 kB     00:00    
(2/4): getdns-1.7.3-1.el9.x86_64.rpm                                                                                             772 kB/s | 219 kB     00:00    
(3/4): libev-4.33-5.el9.x86_64.rpm                                                                                               102 kB/s |  56 kB     00:00    
(4/4): unbound-libs-1.16.2-3.el9_3.5.x86_64.rpm                                                                                  1.3 MB/s | 553 kB     00:00    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                            173 kB/s | 869 kB     00:05     
Extra Packages for Enterprise Linux 9 - x86_64                                                                                    67 kB/s | 1.6 kB     00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                         1/1 
  Running scriptlet: unbound-libs-1.16.2-3.el9_3.5.x86_64                                                                                                    1/4   Installing       : unbound-libs-1.16.2-3.el9_3.5.x86_64                                                                                                    1/4 
  Running scriptlet: unbound-libs-1.16.2-3.el9_3.5.x86_64                                                                                                    1/4 
Created symlink /etc/systemd/system/timers.target.wants/unbound-anchor.timer → /usr/lib/systemd/system/unbound-anchor.timer.

  Installing       : libev-4.33-5.el9.x86_64                                                                                                                 2/4 
  Installing       : getdns-1.7.3-1.el9.x86_64                                                                                                               3/4 
  Running scriptlet: getdns-1.7.3-1.el9.x86_64                                                                                                               3/4 
  Installing       : stubby-0.4.3-1.el9.x86_64                                                                                                               4/4 
  Running scriptlet: stubby-0.4.3-1.el9.x86_64                                                                                                               4/4 
  Verifying        : getdns-1.7.3-1.el9.x86_64                                                                                                               1/4 
  Verifying        : stubby-0.4.3-1.el9.x86_64                                                                                                               2/4 
  Verifying        : libev-4.33-5.el9.x86_64                                                                                                                 3/4 
  Verifying        : unbound-libs-1.16.2-3.el9_3.5.x86_64                                                                                                    4/4 
Installed products updated.

Installed:
  getdns-1.7.3-1.el9.x86_64            libev-4.33-5.el9.x86_64            stubby-0.4.3-1.el9.x86_64            unbound-libs-1.16.2-3.el9_3.5.x86_64           

Complete!
  1. Edit the stubby configuration file (/etc/stubby/stubby.yml). Ensure the files has the following configuration:
dns_transport_list:
- GETDNS_TRANSPORT_TLS

tls_authentication: GETDNS_AUTHENTICATION_REQUIRED

listen_addresses:
- 127.0.0.1@8053
- 0::1@8053

Comment out the out-of-the-box enabled DNS resolvers:

### Test servers ###
# The getdnsapi.net server
#  - address_data: 185.49.141.37
#    tls_auth_name: "getdnsapi.net"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
####### IPv6 addresses ######
### Test servers ###
# The getdnsapi.net server
#  - address_data: 2a04:b900:0:100::38
#    tls_auth_name: "getdnsapi.net"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=

Uncomment the Quad9 DNS resolvers. These resolvers provide a private (an encrypted transport) and secured (safe*) DNS service:

## Quad 9 'secure' service - Filters, does DNSSEC, doesn't send ECS
  - address_data: 9.9.9.9
    tls_auth_name: "dns.quad9.net"
  - address_data: 149.112.112.112
    tls_auth_name: "dns.quad9.net"
  1. Edit the Bind server configuration file (/var/named/chroot/etc/named.conf) to use the stubby service as the upstream forwarder. The DNS flow can be visualised as Client > Bind > Stubby (TLS) > Quad9:
options {
        ...
        forwarders { 127.0.0.1 port 8053; };
        ...
};
  1. Enable and/or start the stubby service:
systemctl enable --now stubby.service
Created symlink /etc/systemd/system/multi-user.target.wants/stubby.service → /usr/lib/systemd/system/stubby.service.
systemctl status stubby.service 
● stubby.service - stubby DNS resolver
     Loaded: loaded (/usr/lib/systemd/system/stubby.service; enabled; preset: disabled)
     Active: active (running) since Thu 2024-04-25 20:18:59 AEST; 8s ago
   Main PID: 2827 (stubby)
      Tasks: 1 (limit: 10974)
     Memory: 2.5M
        CPU: 24ms
     CGroup: /system.slice/stubby.service
             └─2827 /usr/bin/stubby

Apr 25 20:18:59 rhel9 systemd[1]: Started stubby DNS resolver.
  1. Enable and/or start the Bind service:
systemctl enable --now named-chroot.service
Created symlink /etc/systemd/system/multi-user.target.wants/named-chroot.service → /usr/lib/systemd/system/named-chroot.service.
systemctl status named-chroot.service 
● named-chroot.service - Berkeley Internet Name Domain (DNS)
     Loaded: loaded (/usr/lib/systemd/system/named-chroot.service; enabled; preset: disabled)
     Active: active (running) since Thu 2024-04-25 20:06:31 AEST; 16min ago
   Main PID: 2711 (named)
      Tasks: 6 (limit: 10974)
     Memory: 20.8M
        CPU: 60ms
     CGroup: /system.slice/named-chroot.service
             └─2711 /usr/sbin/named -u named -c /etc/named.conf -t /var/named/chroot
...
  1. Test name resolution:
nslookup google.com localhost
Server:         localhost
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   google.com
Address: 142.250.204.14
Name:   google.com
Address: 2404:6800:4006:814::200e

Verify that stubby is receiving requests through a simple packet capture:

tcpdump -nnqi lo -c 4
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:14:35.320052 IP 127.0.0.1.54029 > 127.0.0.1.8053: UDP, length 48
21:14:35.422034 IP 127.0.0.1.8053 > 127.0.0.1.54029: UDP, length 52
21:14:35.426235 IP 127.0.0.1.49300 > 127.0.0.1.8053: UDP, length 48
21:14:35.540919 IP 127.0.0.1.8053 > 127.0.0.1.49300: UDP, length 92
4 packets captured
8 packets received by filter
0 packets dropped by kernel

With that, stubby receives DNS requests from bind and sends them upstream to Quad9 over TLS. In theory, no one should be able to easily intercept and interpret DNS transactions.


Posted

in

by