eco/CENTR Workshop - DoH/DoT: How to upgrade existing DNS Resolver

1 Installing DNSDIST as an DoT/DoH Proxy for an existing DNS Resolver

The slides for this workshop can be found at https://doh.defaultroutes.de/eco-doh-proxy/

The Ansible scripts used to create the virtual machine environment for this workshop can be found at https://github.com/sys4/ansible-doh-proxy

1.1 Installing DNSDIST

  • DNSDIST is a DNS load-balancer and DNS-over-TLS and DNS-over-HTTPS proxy from PowerDNS B.V.
  • From the product website https://dnsdist.org/index.html:
    dnsdist is a highly DNS-, DoS- and abuse-aware load-balancer. 
    Its goal in life is to route traffic to the best server, delivering 
    top performance to legitimate users while shunting or blocking abusive traffic.
    
    dnsdist is dynamic, its configuration language is Lua and it can be 
    changed at run-time, and its statistics can be queried from a 
    console-like interface or an HTTP API.
    
  • In this workshop we will only use the DoH/DoT functions of DNSDIST
  • DNSDIST is open source software under the GPL V2
  • The virtual machines are CentOS 8 Linux machines.
  • Become the root user for the installation and configuration (Password DNSandBIND)
    sudo -s
    
  • check that the BIND 9 DNS server is up and running (our pre-installed DNS resolver serving classic DNS over Port 53):
    dig @localhost eco.de
    
  • the response should look like this
    ; <<>> DiG 9.11.20-RedHat-9.11.20-5.el8 <<>> @localhost eco.de
    ; (2 servers found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33741
    ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ; COOKIE: a5a408f40adb4d65728f85806022562da510a81f97544ac0 (good)
    ;; QUESTION SECTION:
    ;eco.de.                                IN      A
    
    ;; ANSWER SECTION:
    eco.de.                 85035   IN      A       46.31.121.137
    
    ;; Query time: 2 msec
    ;; SERVER: ::1#53(::1)
    ;; WHEN: Tue Feb 09 09:30:21 UTC 2021
    ;; MSG SIZE  rcvd: 79
    
  • Now we install dnsdist from the PowerDNS software repository for CentOS 8:
    dnf install -y epel-release
    dnf install -y 'dnf-command(config-manager)'
    curl -o /etc/yum.repos.d/powerdns-dnsdist-16.repo https://repo.powerdns.com/repo-files/centos-dnsdist-16.repo
    dnf install -y dnsdist
    

1.2 TLS x509 certificates

  • Our server already has x509 certificates for TLS from Let's Encrypt. We need to copy the certificate file and the private key file into the dnsdist configuration directory and adjust the file permissions, so that dnsdist can read the files (replace XXX with your participant number):
    cp /root/.acme.sh/dohXXX.dane.onl/dohXXX.dane.onl.* /etc/dnsdist/
    chown dnsdist: /etc/dnsdist/*
    

1.3 Configuration for the "upstream" DNS resolver

  • first we need to tell dnsdist where to find the upstream (existing) DNS resolver. In our case, it is the BIND 9 instance running on the same machine.
    • in dnsdist, you can specify any number of upstream servers with load-balancing parameters, please see the dnsdist website for documentation.
  • we create the file /etc/dnsdist/dnsdist.conf with one line of configuration that defines one upstream DNS resolver (use your favorite text editor nano, emacs, vim):
    newServer({address="127.0.0.1"})
    

1.4 Configuration for DNS-over-TLS (DoT)

  • our DNS-over-TLS service will run on the (loop-back) IP-Address 127.0.0.10. In an production environment, this would be one of the external addresses of the proxy machine that is reachable from DNS clients.
    • the new configuration line for DoT defines the listen address, the x509 certificate and the private key matching the certificate
  • our configuration file /etc/dnsdist/dnsdist.conf should now look like this:
    newServer({address="127.0.0.1"})
    addTLSLocal('127.0.0.10', '/etc/dnsdist/dohXXX.dane.onl.cer', '/etc/dnsdist/dohXXX.dane.onl.key')
    

1.5 Starting dnsdist

  • check the configuration of dnsdist for syntax errors
    /usr/bin/dnsdist -u dnsdist -g dnsdist --check-config
    Configuration '/etc/dnsdist/dnsdist.conf' OK!
    
  • enable and start the dnsdist service
    systemctl enable --now dnsdist
    
  • check that the service has been started without errors:
    # systemctl status dnsdist
    ● dnsdist.service - DNS Loadbalancer
       Loaded: loaded (/usr/lib/systemd/system/dnsdist.service; enabled; vendor preset: disabled)
       Active: active (running) since Tue 2021-02-09 09:05:34 UTC; 17s ago
         Docs: man:dnsdist(1)
               https://dnsdist.org
      Process: 111443 ExecStartPre=/usr/bin/dnsdist -u dnsdist -g dnsdist --check-config (code=exited, status=0/SUCCESS)
     Main PID: 111445 (dnsdist)
        Tasks: 19 (limit: 8192)
       Memory: 28.2M
       CGroup: /system.slice/dnsdist.service
                └─111445 /usr/bin/dnsdist -u dnsdist -g dnsdist --supervised --disable-syslog
    
    Feb 09 09:05:34 doh01 systemd[1]: Stopped DNS Loadbalancer.
    Feb 09 09:05:34 doh01 systemd[1]: Starting DNS Loadbalancer...
    Feb 09 09:05:34 doh01 dnsdist[111445]: Added downstream server 127.0.0.1:53
    Feb 09 09:05:34 doh01 dnsdist[111445]: Listening on 127.0.0.10:853 for TLS
    Feb 09 09:05:34 doh01 dnsdist[111445]: dnsdist 1.6.0-alpha1 comes with ABSOLUTELY NO WARRANTY. This is free software, and you are we>
    Feb 09 09:05:34 doh01 dnsdist[111445]: ACL allowing queries from: 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0>
    Feb 09 09:05:34 doh01 dnsdist[111445]: Console ACL allowing connections from: 127.0.0.0/8, ::1/128
    Feb 09 09:05:34 doh01 dnsdist[111445]: Marking downstream 127.0.0.1:53 as 'up'
    Feb 09 09:05:34 doh01 systemd[1]: Started DNS Loadbalancer.
    Feb 09 09:05:35 doh01 dnsdist[111445]: Polled security status of version 1.6.0-alpha1 at startup, no known issues reported: OK
    

1.6 Testing the DoT setup

  • we use kdig, the DNS query tool from the Knot DNS Server, to send DNS over TLS queries to our server. But first we install kdig
    dnf install knot-utils
    
  • and now we test DNS-over-TLS
    # kdig @127.0.0.10 eco.de +tls
    ;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
    ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 27271
    ;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 2; ADDITIONAL: 3
    
    ;; EDNS PSEUDOSECTION:
    ;; Version: 0; flags: ; UDP size: 4096 B; ext-rcode: NOERROR
    
    ;; QUESTION SECTION:
    ;; eco.de.                      IN      A
    
    ;; ANSWER SECTION:
    eco.de.                 86385   IN      A       46.31.121.137
    
    ;; AUTHORITY SECTION:
    eco.de.                 86385   IN      NS      dns01.cix.de.
    eco.de.                 86385   IN      NS      dns02.cix.de.
    
    ;; ADDITIONAL SECTION:
    dns02.cix.de.           86385   IN      A       78.47.156.210
    dns01.cix.de.           86385   IN      A       46.31.121.131
    
    ;; Received 127 B
    ;; Time 2021-02-09 09:07:51 UTC
    ;; From 127.0.0.10@853(TCP) in 44.5 ms
    
  • kdig will print information on the TLS connection in the first line:
    ;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
    

1.7 Configuration for DNS-over-HTTPS (DoH)

  • the configuration for DNS-over-HTTPS is very similar to the DoT configuration. Please add the following line (replace the XXX with your participant number) to the file /etc/dnsdist/dnsdist.conf:
    addDOHLocal('127.0.0.10', '/etc/dnsdist/dohXXX.dane.onl.cer', '/etc/dnsdist/dohXXX.dane.onl.key')
    
  • check the configuration file for errors
    /usr/bin/dnsdist -u dnsdist -g dnsdist --check-config
    
  • and if no errors are reported, restart the dnsdist service
    systemctl restart dnsdist
    
  • check that the service has been (re-)started
    # systemctl status dnsdist
    ● dnsdist.service - DNS Loadbalancer
       Loaded: loaded (/usr/lib/systemd/system/dnsdist.service; enabled; vendor preset: disabled)
       Active: active (running) since Tue 2021-02-09 09:12:03 UTC; 5s ago
         Docs: man:dnsdist(1)
               https://dnsdist.org
      Process: 112038 ExecStartPre=/usr/bin/dnsdist -u dnsdist -g dnsdist --check-config (code=exited, status=0/SUCCESS)
     Main PID: 112040 (dnsdist)
        Tasks: 21 (limit: 8192)
       Memory: 31.2M
       CGroup: /system.slice/dnsdist.service
               └─112040 /usr/bin/dnsdist -u dnsdist -g dnsdist --supervised --disable-syslog
    
    Feb 09 09:12:02 doh01 systemd[1]: Starting DNS Loadbalancer...
    Feb 09 09:12:03 doh01 dnsdist[112040]: Added downstream server 127.0.0.1:53
    Feb 09 09:12:03 doh01 dnsdist[112040]: Listening on 127.0.0.10:853 for TLS
    Feb 09 09:12:03 doh01 dnsdist[112040]: Listening on 127.0.0.10:443 for DoH
    Feb 09 09:12:03 doh01 dnsdist[112040]: dnsdist 1.6.0-alpha1 comes with ABSOLUTELY NO WARRANTY. This is free software, and you are we>
    Feb 09 09:12:03 doh01 dnsdist[112040]: ACL allowing queries from: 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0>
    Feb 09 09:12:03 doh01 dnsdist[112040]: Console ACL allowing connections from: 127.0.0.0/8, ::1/128
    Feb 09 09:12:03 doh01 dnsdist[112040]: Marking downstream 127.0.0.1:53 as 'up'
    Feb 09 09:12:03 doh01 systemd[1]: Started DNS Loadbalancer.
    Feb 09 09:12:03 doh01 dnsdist[112040]: Polled security status of version 1.6.0-alpha1 at startup, no known issues reported: OK
    

1.8 Testing DNS-over-HTTPS

  • Again we use the kdig tool to test our new DNS-over-HTTPS service:
    # kdig @127.0.0.10 eco.de +https
    ;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
    ;; HTTPS session (HTTP/2-POST)-(127.0.0.10/dns-query)-(status: 200)
    ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
    ;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 2; ADDITIONAL: 3
    
    ;; EDNS PSEUDOSECTION:
    ;; Version: 0; flags: ; UDP size: 4096 B; ext-rcode: NOERROR
    
    ;; QUESTION SECTION:
    ;; eco.de.                      IN      A
    
    ;; ANSWER SECTION:
    eco.de.                 86097   IN      A       46.31.121.137
    
    ;; AUTHORITY SECTION:
    eco.de.                 86097   IN      NS      dns02.cix.de.
    eco.de.                 86097   IN      NS      dns01.cix.de.
    
    ;; ADDITIONAL SECTION:
    dns02.cix.de.           86097   IN      A       78.47.156.210
    dns01.cix.de.           86097   IN      A       46.31.121.131
    
    ;; Received 127 B
    ;; Time 2021-02-09 09:12:39 UTC
    ;; From 127.0.0.10@443(TCP) in 41.7 ms
    
  • kdig print information about the TLS and HTTPS connection in the first two lines:
    ;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
    ;; HTTPS session (HTTP/2-POST)-(127.0.0.10/dns-query)-(status: 200)
    

1.9 FIN

  • Congratulations, you've configured a DNS-over-TLS and DNS-over-HTTPS service
  • please "raise your hand" in the zoom meeting to indicate that you are done with the workshop part, so that the host gets feedback and knows when to continue with the next session of the webinar.
  • Questions can be asked in the chat or during the panel discussion