Building a secure website on your Handshake TLD

Put those names to good use and add value to the ecosystem!

Matthew Zipkin
7 min readJul 11, 2020

If you’ve ever launched a website on the “legacy” internet, the process probably went something like this:

  1. Search for an available, memorable name on GoDaddy and rent it from them
  2. Launch a Digital Ocean Droplet (or other cloud server) and get an IP address
  3. Go back to GoDaddy and paste the IP address into your dashboard under DNS
  4. On your server, run the Let’s Encrypt certbot to obtain an SSL certificate
  5. Set up Apache, add content, profit :-)

In this system, your domain name (from step 1) and SSL certificate (from step 4) don’t really belong to you. Both digital assets can be revoked at any time. Handshake solves this problem by putting the user in control of everything, the same way Bitcoin puts users in control of their money: personal responsibility of unique cryptographic keys.

The legacy process also conceals a lot of the DNS stuff that is actually required to find a website on the internet. You trust GoDaddy to host a nameserver for you to serve DNS records. In Handshake you have to (/get to) do this yourself, but it is just as easy as hosting that webserver you set up in step 5.

Handshake replaces the DNS root of trust AND the certificate authority root of trust by combining them into one thing (DANE) and then securing that with proof-of-work. To make a short story long, the entire chain looks like this:

  • The Handshake blockchain proof-of-work secures the relationship between a domain name and two important data: An NS record (with the IP address of your nameserver) and a DS record (with the hash of a public key-signing-key, or KSK).
  • The nameserver lives at that IP address and serves a series of data: First, another public key is signed by the KSK. This is called the zone-signing-key, or ZSK. The ZSK is used to sign A/AAAA records (with the IP address of your actual webserver) and also TLSA records (with the hash of your SSL certificate).
  • The webserver can live on the same machine with the same IP address as the nameserver. It can be configured with a self-signed SSL certificate. Because the certificate is cryptographically committed to by the TLSA record, everything tiesback up to the blockchain’s proof-of-work and no trusted authority is needed! This is why the certificate may be self-signed.

To securely visit a website configured this way, a user must have a Handshake resolver, and some mechanism to verify DANE. The user’s computer looks up the nameserver from the HNS root zone, then looks up the A record for the website. It gets the SSL certificate from the webserver as part of the TLS handshake, then verifies the certificate matches the hash in the TLSA record provided by the authenticated nameserver. Green lights! It is safe to trust the content on this website, or enter private details into forms on the website.

The Holy Grail of Handshake: A web browser with a green lock icon!

Currently there are two decent ways I know of to verify DANE and access secure HNS websites: my own guide on manually verifying and installing certificates, and Mike Carson’s guide on using godane middleware.

So, let’s revisit the list from the top of the article now and write a new list for launching a secure Handshake website:

  1. Obtain a Handshake domain name either by winning an auction or on a secondary market. Your private key, your name!
  2. Launch a server and get an IP address
  3. Generate DNSSEC keys (the ZSK and KSK mentioned above)
  4. Add DNS records to the blockchain identifying the IP address and KSK
  5. On your server, generate a self-signed SSL certificate. From this certificate, generate TLSA record and A record, sign everything with the ZSK. Sign the ZSK with the KSK and add all that junk to your nameserver
  6. Launch the nameserver with those DNS records and the webserver with the SSL certificate
  7. Add content, profit ;-)

Introducing: Handout

I put together a nodejs package that handles steps 3–6 for you, reducing this process to:

  1. Obtain a Handshake name
  2. Launch a server and get an IP address
  3. Install handout and run the hnssec-gen.js script
  4. Add content, profit :-)

Here it is:

Handout is built from JJ’s bns and bcrypto packages. I added extra features to both to streamline the interface so handout actually installs my own branches. These new features are open pull requests — review would be appreciated! Handout also deploys JJ’s bweb package for the web server, but you could replace that with Apache if you want. You could also use BIND9 and OpenSSL to generate all the keys and DNS records but Handout makes it a lot easier. bns, bweb, and bcrypto are all used in bcoin and hsd and so I’m already familiar with them.

Get the IP address (bottom left) for your server to enter into hnssec-gen.js

Let’s run the script and see what we get! It requires two command line arguments: a domain name and an IP address.

$ node scripts/hnssec-gen.js proofofconcept SSL key and self-signed certificate...Generating DNSSEC keys...Writing new conf/handout.conf...DS record for root zone:
proofofconcept. 172800 IN DS 23440 8 2 BBBE70AF5CD965360442CBEF40E3299344AF493D339592B93DAA29F7 839C1D58; alg = RSASHA256 ; hash = SHA256
GLUE4 record, Bob format:
DS record, Bob format:
17552 8 2 bbbe70af5cd965360442cbef40e3299344af493d339592b93daa29f7839c1d58
All records, hsw-rpc sendupdate format:

Handout generates a GLUE4 record, which is a special type of NS record specifically optimized for Handshake. The DS record is also output to the console. Both record types are printed out in a variety of formats to make it easy for users of hsd, Bob Wallet, or Namebase to add these records to the blockchain.

Entering the DNS data from hnssec-gen.js into Bob Wallet… plus a few extra TXTs for fun

Handout saves several files to a directory inside the repository called conf/. Take a look at what’s in there — you’ll want to back up everything!

$ ls conf/*
conf/handout.conf conf/hsw-rpc_sendupdate.txt
Kproofofconcept.+008+23440.key Kproofofconcept.+008+23440.private
proofofconcept.crt proofofconcept.key
Kproofofconcept.+008+28183.key Kproofofconcept.+008+28183.private

If you’ve been following along, you should be able to identify and understand what all these files are. When you run the Handout combination server, the built-in authoritative nameserver will collect all the key data, generate all the records for the zone (including signing all records), and store everything in memory so it can be served to users.

Now run the combination name+web server and take a look:

$ sudo node lib/handout.js
[debug] (webserver) Webserver opened at host
[debug] (authns) Authoritative Nameserver opened for domain proofofconcept.

Handout runs a nameserver on port 53, and an HTTPS webserver on port 443. It also runs an HTTP (unencrypted) webserver on port 80, but all this does is redirect users to the HTTPS website. When users browse to your website you will see log output from both the webserver and the nameserver:

[debug] (authns) req: _tcp.proofofconcept. IN A
[debug] (authns) req: _443._tcp.proofofconcept. IN A
[debug] (authns) req: _443._tcp.proofofconcept. IN TLSA
[debug] (authns) req: proofofconcept. IN A
[debug] (authns) req: proofofconcept. IN A
[debug] (webserver) req: /index
[debug] (webserver) req: /css/normalize.css (200)
[debug] (webserver) req: /img/kitty.png (200)
[debug] (webserver) req: /favicon.ico (404)

Notice the nameserver serving the A and TLSA records to the DANE validator! Then the webserver gets queried like usual for HTML files.

In the Handout repository is a directory called html/ and this is where your website content lives. An ugly holding page lives there now — what will you build?

Proof Of Concept: A proof of concept

I built https://proofofconcept: A social network built for Handshake where every user gets their own subdomain and the entire website is secured by DANE. I built a lot more features into Handout to accomplish this, including adding extra records in the authoritative nameserver (for the subdomains) and customizing the webserver to build pages dynamically, as well as responding to HTTP POST API requests. (bweb has an interface much like ExpressJS, if you’re familiar). I also added a database to save user data.

If you want to see how I expanded Handout for Proof Of Concept, that code is also open source on a different branch:

Best practices for running a public nameserver

This is a bit out of scope for this article, but public nameservers can be hard to secure and you should read up on amplification attacks and best practices for running a nameserver. On my server I added a firewall rule to drop DNS packets (port 53) with the “recursion bit” set:

$ iptables -I INPUT 1 -p udp --dport 53 -m u32 --u32 '0x1b&0x01=0x01' -j DROP

So far, this has blocked amplification attackers from abusing my server.

Are TLD-only URLs good practice?

Probably not, read more here:

It’s easy to add subdomains to your handout server and secure them all with the same SSL certificate.

Happy Handshaking! 🚀🚀🚀