Setting up your own DNSSEC-aware resolver using Unbound


Now that the root DNS servers are signed, I thought it was time I started using DNSSEC on my own PC. However, not wanting to wait for my ISP to enable it, I decided to setup a private recursive DNS resolver for myself using Unbound . Instal...



Onion Details



Page Clicks: 0

First Seen: 03/11/2024

Last Indexed: 10/21/2024

Domain Index Total: 195



Onion Content



Now that the root DNS servers are signed, I thought it was time I started using DNSSEC on my own PC. However, not wanting to wait for my ISP to enable it, I decided to setup a private recursive DNS resolver for myself using Unbound . Installing Unbound Being already packaged in Debian and Ubuntu , unbound is only an apt-get away: apt install unbound ca-certificates Optional settings In /etc/unbound/unbound.conf.d/francois.conf , I enabled the following security options: server: harden-below-nxdomain: yes harden-referral-path: yes harden-algo-downgrade: no # false positives with improperly configured zones use-caps-for-id: no # makes lots of queries fail hide-identity: yes hide-version: yes private-address: 10.0.0.0/8 private-address: 100.64.0.0/10 private-address: 127.0.0.0/8 private-address: 169.254.0.0/16 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: fc00::/7 private-address: fe80::/10 private-address: ::ffff:0:0/96 module-config: "validator iterator" # disable EDNS client subnet support and turned on prefetching to hopefully keep in cache the sites I visit regularly: server: prefetch: yes prefetch-key: yes msg-cache-size: 128k msg-cache-slabs: 2 rrset-cache-size: 8m rrset-cache-slabs: 2 key-cache-size: 32m key-cache-slabs: 2 cache-min-ttl: 3600 num-threads: 2 Finally, I also restricted the server to the local machine: server: interface: 127.0.0.1 access-control: 0.0.0.0/0 refuse access-control: 127.0.0.1/32 allow and increased the amount of debugging information: server: val-log-level: 2 use-syslog: yes verbosity: 1 before running sudo unbound-control-setup to generate the necessary keys. Once unbound is restarted ( sudo service unbound restart ) stats can be queried to make sure that the DNS resolver is working: unbound-control stats Overriding DHCP settings In order to use my own unbound server for DNS lookups and not the one received via DHCP , I added this line to /etc/dhcp/dhclient.conf : supersede domain-name-servers 127.0.0.1; and restarted dhclient: sudo killall dhclient sudo /etc/init.d/network-manager restart If you're not using DHCP, then you simply need to put this in your /etc/resolv.conf : nameserver 127.0.0.1 or on more recent distros, the following in /etc/systemd/resolved.conf : [Resolve] DNS=127.0.0.1 DNSSEC=no Yes, you need DNSSEC=no because otherwise it will break insecure delegations and you'll see messages like this one in your logs: systemd-resolved[1161]: DNSSEC validation failed for question dyn.fmarier.org IN SOA: no-signature You can test that systemd-resolved is configured properly using: systemd-resolve --status Testing DNSSEC resolution Once everything is configured properly, the best way I found to test that this setup was actually working is to use a web browser to visit these sites: http://www.dnssec.cz/ should show a green key http://www.rhybar.cz/ should not be reachable https://wander.science/projects/dns/dnssec-resolver-test/ and using dig: $ dig +dnssec A www.dnssec.cz | grep ad ;; flags: qr rd ra ad ; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 1 Are there any other ways of making sure that DNSSEC is fully functional? Using DNS-over-TLS using Cloudflare's 1.1.1.1 In order to make use of DNS over TLS and effectively hide DNS queries from anybody looking at your network traffic, one option is to forward your queries to Cloudflare's 1.1.1.1 : server: tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt forward-zone: name: "." forward-tls-upstream: yes # Cloudflare DNS forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com forward-addr: 1.1.1.1@853#cloudflare-dns.com forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com forward-addr: 1.0.0.1@853#cloudflare-dns.com While Unbound appears to support DNS over TLS natively, it's not clear to me that it will connect to DNS servers over TLS while doing a recursive name resolution. Additionally, it will leak queries to non-encrypted servers to your ISP and other potential on-path attackers. Therefore, forwarding traffic to a non-logging trusted recursive resolver appears to be the best solution at the moment. To test that DNS queries are being correctly forwarded to Cloudflare, use their official test page . Integration with OpenVPN If you are running your own OpenVPN server , you can tell clients to connect to the local unbound DNS client by putting the following in /etc/unbound/unbound.conf.d/openvpn.conf : server: interface: 127.0.0.1 interface: 10.8.0.1 interface: 10.8.0.1@853 access-control: 127.0.0.1 allow access-control: 10.8.0.1/24 allow tls-service-key: /etc/letsencrypt/live/hafnarfjordur.fmarier.org/privkey.pem tls-service-pem: /etc/letsencrypt/live/hafnarfjordur.fmarier.org/fullchain.pem tls-port: 853 and acquiring the necessary Let's Encrypt TLS certificates using Certbot . The DNS over TLS option is used automatically by certain VPN clients (e.g. Android) who will try to upgrade to secure DNS automatically. If you are using AppArmor, then you'll need to put the following in /etc/apparmor.d/local/usr.sbin.unbound to ensure that Unbound can read the TLS cert it needs: /etc/letsencrypt/archive/** r, /etc/letsencrypt/live/** r, and then run this: apparmor_parser --replace /etc/apparmor.d/usr.sbin.unbound Then put the following in /etc/openvpn/server.conf : push "dhcp-option DNS 10.8.0.1" push "register-dns" and open the following ports on your firewall (typically /etc/network/iptables.up.rules on Debian): A INPUT -p udp --dport 53 -s 10.8.0.0/24 -d 10.8.0.1 -j ACCEPT -A INPUT -p tcp --dport 53 -s 10.8.0.0/24 -d 10.8.0.1 -j ACCEPT -A INPUT -p tcp --dport 853 -s 10.8.0.0/24 -d 10.8.0.1 -j ACCEPT before restarting both services: systemctl restart unbound.service openvpn.service Work-around for systemd-networkd If you're having problems with unbound attempting to start before systemd-networkd has finished bringing up the network interfaces, then you may find this work-around useful. Start by installing these packages: apt install networkd-dispatcher moreutils and then put the following script in /etc/networkd-dispatcher/routable.d/unbound-local : #!/bin/sh LOGFILE=/var/log/unbound-local.log if [ "$IFACE" = lo ]; then echo "$0: ignoring $IFACE for \`$STATE'" | ts >> $LOGFILE exit 0 fi case "$STATE" in routable) echo "$0: restarting unbound because of $IFACE" | ts >> $LOGFILE systemctl stop unbound.service 2>&1 | ts >> $LOGFILE sleep 5 # hack around unbound's rate limiter systemctl start unbound.service 2>&1 | ts >> $LOGFILE ;; *) echo "$0: nothing to do with $IFACE for \`$STATE'" | ts >> $LOGFILE ;; esac exit 0 before making it executable: chmod a+x /etc/networkd-dispatcher/routable.d/unbound-local Finally, create a new /etc/logrotate.d/unbound-local file to ensure that the log file does not grow unbounded: /var/log/unbound-local.log { monthly rotate 1 nocreate nomail noolddir notifempty missingok } RSS Atom First, Thank You for posting this. There is one more thing that needs to be done. After following: http://www.unbound.net/documentation/howto_anchor.html I was getting this error in /var/log/daemon.log: error: Could not open autotrust file for writing, /etc/unbound/root.key: Permission denied I changed the group to unbound and made it writable. # cd /etc/unbound # chgrp unbound root.key # chmod g+w root.key # ls -la root.key -rw-rw-r-- 1 root unbound 758 Sep 21 16:46 root.key After restarting unbound, no more errors. The root.key should look like the following: ; autotrust trust anchor file ;;id: . 1 ;;last_queried: 1285101992 ;;Tue Sep 21 16:46:32 2010 ;;last_success: 1285101992 ;;Tue Sep 21 16:46:32 2010 ;;next_probe_time: 1285141647 ;;Wed Sep 22 03:47:27 2010 ;;query_failed: 0 ;;query_interval: 43200 ;;retry_time: 8640 . 86400 IN DNSKEY 257 3 8 AwEAAagAI...... Again Thank You, for this post. "Are there any other ways of making sure that DNSSEC is fully functional?" The following will give some info on dnssec. Install unbound-host, then try the following: $ unbound-host rhybar.cz -f /etc/unbound/root.key -v Output: rhybar.cz has no address (BOGUS (security failure)) validation failure : no keys have a DS with algorithm RSASHA1 from 194.0.12.1 for key rhybar.cz. while building chain of trust Or: $ unbound-host rhybar.cz -C /etc/unbound/unbound.conf -v Also: $ unbound-host dnssec.cz -C /etc/unbound/unbound.conf -v Output: dnssec.cz has address 217.31.205.50 (secure) dnssec.cz has IPv6 address 2001:1488:0:3::2 (secure) dnssec.cz mail is handled by 10 mail.nic.cz. (secure) dnssec.cz mail is handled by 15 mail4.nic.cz. (secure) dnssec.cz mail is handled by 20 mx.cznic.org. (secure) Or: $ unbound-host dnssec.cz -f /etc/unbound/root.key -v Add a comment