Guide

Author
Leo Vandewoestijne
Original Publication date
Feb 22, 2024

DANE + SSH (TLSA)

Introduction

Below is a step-by-step tutorial on how to implement DANE for SSH using TLSA records.

It's targeted to RSA as well as ECDSA and ED25519 type of hostkeys.

1: Prerequisites

2: Preparing your SSH HostKeys for TLSA

a. Export the HostKey in PKCS#8 format

Assuming your SSH server's public key are in /etc/ssh/ssd_host_ *type* _key.pub, you need to convert those to a PKCS#8 (or similar DER) format that contains the SPKI.


ssh-keygen -f /etc/ssh/ssd_host_rsa_key.pub     -e -m PKCS8 > rsa_spki.pem
ssh-keygen -f /etc/ssh/ssd_host_ecdsa_key.pub   -e -m PKCS8 > ecdsa_spki.pem
ssh-keygen -f /etc/ssh/ssd_host_ed25519_key.pub -e -m PKCS8 > ed25519_spki.pem

b. Convert the PEM to DER format

Most TLSA records expect the raw DER encoding. Convert the PEM into DER:


openssl pkey -pubin -i rsa_spki.pem     -outform DER out rsa_spki.der
openssl pkey -pubin -i ecdsa_spki.pem   -outform DER out ecdsa_spki.der
openssl pkey -pubin -i ed25519_spki.pem -outform DER out ed25519_spki.der

c. Compute the SHA-256 Hash

Now compute the SHA-256 hashes (in hexadecimals) of the DER-encoded SPKI:


openssl dgst -sha256 *_spki.der
You should see an output like:
SHA256(rsa_spki.der)= A6927F680FD9FE1EF8A6100559EF2C7958677577500048322F7E6927F680FD9A
SHA256(ecdsa_spki.der)= B1EF8A6100559EF2C7958677577500048322F7E6927F680FD9FE1EF8A610055B
SHA256(ed25519_spki.der)= CF2C7958677577500048322F7E6927F680FD9FE1EF8A6100559EF2C79586775C

Make note of the hex strings; remove any spaces in case they exist.

3: Creating TLSA records

Now that you computated the hash strings, you can assemble the TLSA records, to place those in your DNS zone. The TLSA records owner name is built from the port and protocol. SSH resides on TCP port :22, so the conversion labeling is:
_22._tcp.host.domain.tld.

Example DNS records

_22._tcp.host.domain.tld.  IN TLSA  3 1 1 A6927F680FD9FE1EF8A6100559EF2C7958677577500048322F7E6927F680FD9A _22._tcp.host.domain.tld.  IN TLSA  3 1 1 B1EF8A6100559EF2C7958677577500048322F7E6927F680FD9FE1EF8A610055B _22._tcp.host.domain.tld.  IN TLSA  3 1 1 CF2C7958677577500048322F7E6927F680FD9FE1EF8A6100559EF2C79586775C

Breakdown of the 3 1 1 flags:

Place the TLSA record(s) in your domains DNS zone, and re-sign it with DNSSEC.

4: Configuring OpenSSH to use DANE

a: Client Configuration

On the client side, you must enable DANE verification. Edit (or create) your SSH configuration file (e.g. ~/.ssh/ssh_config or the systemwide /etc/ssh/ssh_config) and add:

Host *.domain.tld
  VerifyHostKeyDNS  yes
  DANE              yes
  

b: Server Configuration

No extra server-side configuration is required; the server simply needs to present it's usual hostkey. The security of DANE here relies on the TLSA records in DNS and the DNSSEC chain of trust.

5: Testing & Troubleshooting

1: Test the connection

From the client, connect to the SSH server. Run your SSH command with verbose output (e.g. ssh -vvv user@host.domain.tld).
Look for debug lines related to DANE/TLSA verification. You should see that the client queries the TLSA record (for _22._tcp.host.domain.tld) and compares the hash.

2: Verify DNSSEC

Ensure that all of your DNS resolvers do validate DNSSEC. You may use commandline tools like delv, dig, kdig, drill,
or online DNSSEC validators like DNSviz(ualizer), Zonemaster, DNSSEC name and shame! or digwebinterface.com.

3: Check hash matching

Verify that hashes in the TLSA records exactly matches the SHA-256 hashes computated from the hostkey's SPKI.

4: Logs and errors

If the connection is rejected or if you see errors, then increase the logging verbosity or check your DNS zone's DNSSEC signatures.

6: Final Considerations

Conclusion

By following the steps above, you can set up a DANE-enabled SSH services using TLSA records with the 3 1 1 flags. Such configuration enhances security of SSH hostkey verification by leveraging the DNSSEC trust infrastructure.