Skip to content

Instantly share code, notes, and snippets.

@buffrr
Last active March 18, 2021 01:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buffrr/546a14ebab606f8b602a9183f28b9a3a to your computer and use it in GitHub Desktop.
Save buffrr/546a14ebab606f8b602a9183f28b9a3a to your computer and use it in GitHub Desktop.
Experimental HSD root server + external dnssec resolver

This is a proof of concept branch for fixing NSEC proofs in HSD.

Here is some example configurations for running a standalone HSD root server with an external dnssec recursive resolver! You can let bind or external unbound resolver do most of the work for resolving and validating dnssec. HSD will only be responsible for serving the root zone.

Install hsd using the blacklies branch:

git clone https://github.com/buffrr/hsd
cd hsd && git checkout blacklies
npm install

You also need this PR chjj/bns#27 make sure to apply it to the installed bns library in node_modules

Notice our root server will listen on 127.0.0.56. You don't need to run as root to listen on port '53' just allow nodejs to listen on lower ports if you like (only tested on ubuntu 20.04):

sudo setcap CAP_NET_BIND_SERVICE=+eip $(which node)
./bin/hsd --ns-host 127.0.0.56 --ns-port 53 --log-level spam

Create a root hints file and save it somewhere. I have it in /etc/bind/root.hints.

;       This file holds the information on handshake root name servers needed to 
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers). 
; 
.	3600000		NS	.
.	3600000		A	127.0.0.56

Bind

You must disable sig0 first! edit server.js: Changes

diff --git a/lib/dns/server.js b/lib/dns/server.js
index 9c10c836..a15029f8 100644
--- a/lib/dns/server.js
+++ b/lib/dns/server.js
@@ -209,11 +209,11 @@ class RootServer extends DNSServer {
   }
 
   signSize() {
-    return 94;
+    return 0;
   }
 
   sign(msg, host, port) {
-    return hsig.sign(msg, this.key);
+    return msg;
   }
 
   async lookupName(name) {

Run named -V to see where everything is:

default paths:
  named configuration:  /usr/local/etc/named.conf
  rndc configuration:   /usr/local/etc/rndc.conf
  DNSSEC root key:      /usr/local/etc/bind.keys
  nsupdate session key: /usr/local/var/run/named/session.key
  named PID file:       /usr/local/var/run/named/named.pid
  named lock file:      /usr/local/var/run/named/named.lock

in this case it's in /usr/local/etc/named.conf here's my configuration: It has HSD ksk hard coded ksk already added for now: copy the same root hints as above change the path if different:

##include "/etc/bind/named.conf.options";
##include "/etc/bind/named.conf.local";
##include "/etc/bind/named.conf.default-zones";

options {
     dnssec-validation yes; 
};

trust-anchors { . static-ds 35215 13 2 "7C50EA94A63AEECB65B510D1EAC1846C973A89D4AB292287D5A4D715136B57A3"; };

zone "." {
    type hint;
    file "/etc/bind/root.hints"; 	
};

make sure root.hints is readable by bind!

Run named i like to run it this way so i can see logs easier but this depends on your setup. Check the logs if it's not working (don't forget to disable sig0)

sudo named -g -d 11

Start digging!

dig @127.0.0.1 . NS
dig @127.0.0.1 letsdane a
dig @127.0.0.1 google.com a
dig @127.0.0.1 dnssec-failed.org a
dig @127.0.0.1 howtomakepancakes. ds +dnssec
dig @127.0.0.1 welcome.nb a
dig @127.0.0.1 . TLSA +dnssec

External unbound example:

Assuming you have HSD ksk stored in /var/lib/unbound/root.key Since hsd has a hardcoded KSK for now here we go:

;; HSD KSK
.			9471	IN	DNSKEY	257 3 13 T9cURJ2M/Mz9q6UsZNY+Ospyvj+Uv+tgrrWkLtPQwgU/Xu5Yk0l02Sn5 ua2xAQfEYIzRO6v5iA+BejMeEwNP4Q==

This is just an example config file not all of these settings really matter for testing this. Also, make sure to specify path for root.hints you created.

server:
    # Add HSD KSK in this path
    trust-anchor-file: "/var/lib/unbound/root.key"

    # Specify path to root hints
    root-hints: "/path/to/root.hints"  
    do-not-query-localhost: no


    # If no logfile is specified, syslog is used
    # logfile: "/var/log/unbound/unbound.log"
    verbosity: 0

    auto-trust-anchor-file: ""
    trust-anchor-signaling: no
   
    local-zone: "." nodefault
    local-zone: "." transparent  
	
    interface: 127.0.0.1
    port: 53
    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    # May be set to yes if you have IPv6 connectivity
    do-ip6: no

    # You want to leave this to no unless you have *native* IPv6. With 6to4 and
    # Terredo tunnels your web browser should favor IPv4 for the same reasons
    prefer-ip6: no

    # Use this only when you downloaded the list of primary root servers!
    # If you use the default dns-root-data package, unbound will find it automatically
    #root-hints: "/var/lib/unbound/root.hints"

    # Trust glue only if it is within the server's authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes

    # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
    # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
    use-caps-for-id: no

    # Reduce EDNS reassembly buffer size.
    # Suggested by the unbound man page to reduce fragmentation reassembly problems
    edns-buffer-size: 1472

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
    num-threads: 1

    # Ensure kernel buffer is large enough to not lose messages in traffic spikes
    so-rcvbuf: 1m

    # Ensure privacy of local IP ranges
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8
    private-address: fd00::/8
    private-address: fe80::/10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment