SSHFP mit DNSSEC

DNSSEC ist nicht nur eine lang ersehnte Erweiterung, um DNS-Abfragen sicherer zu machen, sondern das eigentlich interessante liegt in den Anwendungen, die mit der durch DNSSEC garantierten Authentizität und Integrität möglich werden. DANE haben wir bereits hier auf dem LRZ-Wiki erwähnt, und die Einrichtung am Beispiel von Postfix beschrieben.

Eine weitere Anwendung liegt in der Hinterlegung von SSH Fingerprints, die mittels eines DNSSEC-validierenden Resolvers dann authentifiziert werden können.

SSH Keys und Fingerprints

Der Dialog zur Bestätigung des Fingerprints eines ssh Host keys ist wohl bekannt:



BADWLRZ-CM48587:.ssh di49cub$ ssh dnssec-ws01

The authenticity of host 'dnssec-ws01.dnssec.bayern (<no hostip for proxy command>)' can't be established.

ECDSA key fingerprint is SHA256:X0zVrd7dqEO4z4dmgxkpoKrFbZLgO7MPG+v+vOPkeMY.

Are you sure you want to continue connecting (yes/no)?



Wenn man diese Frage gemäß guter Sicherheitsrichtlinien beantworten will, müsste man den Fingerprint des ssh-keys auf anderem Wege überprüfen, idealerweise persönlich beim Systemadminstrator oder per klassischer gedruckter Post.

Niemand macht das, weil es schlichtweg zu umständlich ist, und es wird darauf vertraut, dass der Fingerprint dem Schlüssel des Hosts entspricht, mit dem man sich verbinden will.

Man antwortet mit "yes", landet wie gewünscht auf der Konsole von "dnssec-ws01" (oder ist zumindest im guten Glauben, dass es die richtige Maschine ist), und wird zukünftig nicht mehr genervt.


SSHFP-Einträge im DNS

SSHFP Fingerprints können aber als Resource Record auf dem DNS-Server hinterlegt werden. Da DNS selbst keine authentischen Antworten garantieren kann, macht das natürlich nur in Verbindung mit DNSSEC Sinn. Es funktioniert zwar auch ohne DNSSEC, aber dann wird auch bei einem "Matching Fingerprint" noch nachgefragt.

D.h. der Betreiber der Zone, in der sich der ssh-Server befindet, muss seinen autoritativen Nameserver mit DNSSEC-Signierung betreiben, und der Benutzer, der sich mit dem SSH-Server verbinden will, braucht einen validierenden Resolver, dem er vertraut (d.h. dieser muss entweder lokal laufen oder über eine sichere Verbindung erreicht werden).

Auf dem autoritativen Nameserver muss dann einen SSHFP Resource Record gemäß RFC 4255 ("Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints") eingetragen werden, wobei das zu empfehlende SHA-256-Hashing in RFC 6594 ("Use of the SHA-256 Algorithm with RSA, Digital Signature Algorithm (DSA), and Elliptic Curve DSA (ECDSA) in SSHFP Resource Record") beschrieben ist.

Im Interesse kürzer Schlüssellängen, haben sich weitest gehend Ellicptic-Curve-Schlüssel durchgesetzt, deren Verwendung für SSHFP in RFC 7470 ("Using Ed25519 in SSHFP Resource Records") besondere Beachtung finden.

SSHFP Resource Records

dnssec-ws01.dnssec.bayern IN SSHFP 1 2 16323945829b3cbd3735409f1e79d1d981ce2de4261db7456687290159766a08
dnssec-ws01.dnssec.bayern IN SSHFP 2 2 b17ccccd54b29312743ae3b86168a5381c596f0d4ce4f2b8aed0dc0043de9f88


Die Felder im Detail:

dnssec-ws01.dnssec.bayern (Hostname) IN SSHFP (Typ: Internet SSH fingerprint) 1 (Schlüssel-Typ: RSA) 2 (Hash-Typ: SHA-256) 57D79129FA85BCC0D9E15CE25C96E639E2DB3316 (SHA-1 Hash des Schlüssels)

dnssec-ws01.dnssec.bayern (Hostname) IN SSHFP (Typ: Internet SSH fingerprint) 1 (Schlüssel-Typ: DSA) 2 (Hash-Typ: SHA-256) 

b17ccccd54b29312743ae3b86168a5381c596f0d4ce4f2b8aed0dc0043de9f88 (SHA-256 Hash des Schlüssels)


Die SSHFP-Einträge können mit sshfp -s <hostname> ausgelesen werden:


sshfp -s dnssec-ws01.dnssec.bayern


WARNING: Ignoring -k option, -s was passwd

# dnssec-ws01.dnssec.bayern SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u3

# dnssec-ws01.dnssec.bayern SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u3


dnssec-ws01.dnssec.bayern IN SSHFP 1 1 57D79129FA85BCC0D9E15CE25C96E639E2DB3316

dnssec-ws01.dnssec.bayern IN SSHFP 2 1 CF239AE438FF149185378D9735BE42B519416D0F



Alle Schlüsselalgorithmen und Hashtypen des SSHFP Resource Records sind bei IANA aufgelistet. Ein Server kann natürlich mehrere SSH-Keys anbieten und deren Hashes im DNS hinterlegt werden:

WertAlgorithmusRFC Referenz
0reserviertRFC 4255
1RSARFC 4255
2DSARFC 4255
3ECDSARFC 6594
4Ed25519RFC 7479
WertHashRFC Referenz
0reserviertRFC 4255
1SHA-1RFC 4255
2SHA-256RFC 6594


Erstellen des SSHFP RR

Die Lage der Host keys ist in /etc/ssh/sshd_config angegeben, z.B.

# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key


Für alle HostKeys kann der Schlüsselhash bequem mit ssh-keygen erstellt werden, wenn man die Option "-r" und den Hostnamen als Parameter angibt:


ssh-keygen -r dnssec-ws01


dnssec-ws01 IN SSHFP 1 1 57d79129fa85bcc0d9e15ce25c96e639e2db3316

dnssec-ws01 IN SSHFP 1 2 16323945829b3cbd3735409f1e79d1d981ce2de4261db7456687290159766a08

dnssec-ws01 IN SSHFP 2 1 cf239ae438ff149185378d9735be42b519416d0f

dnssec-ws01 IN SSHFP 2 2 b17ccccd54b29312743ae3b86168a5381c596f0d4ce4f2b8aed0dc0043de9f88

dnssec-ws01 IN SSHFP 3 1 9d7b545d326bbcf54c1d9ef2d83ee625fed6775b

dnssec-ws01 IN SSHFP 3 2 5f4cd5addedda843b8cf8766831929a0aac56d92e03bb30f1bebfebce3e478c6

dnssec-ws01 IN SSHFP 4 1 ddaa4d1608a01da20bdda216d1ba3c8e55332145

dnssec-ws01 IN SSHFP 4 2 29aeea1299bbb0e9eaf699aac433eefc44b30aa6e866b5d7ecf7e6f5f5471b11



Dann können die entsprechenden SSHFP RR im autoritativen Nameserver eingetragen werden, und die Zone neu signiert werden.

Überprüfung mit dig

Mit dig kann man die SSHFP Resource Records inklusive DNSSEC-Signatur auslesen, für alle vier Schlüsselalgorithmen existiert nur eine RRSIG, weil sie alle vom selben Typ IN SSHFP zugehörig zum Eigentümer dnssec-ws01.dnssec.bayern. sind:


dig dnssec-ws01.dnssec.bayern. sshfp +dnssec +multi


dnssec-ws01.dnssec.bayern. 3600    IN SSHFP 4 2 (
                29AEEA1299BBB0E9EAF699AAC433EEFC44B30AA6E866
                B5D7ECF7E6F5F5471B11 )
dnssec-ws01.dnssec.bayern. 3600    IN SSHFP 1 2 (
                16323945829B3CBD3735409F1E79D1D981CE2DE4261D
                B7456687290159766A08 )
dnssec-ws01.dnssec.bayern. 3600    IN SSHFP 3 2 (
                5F4CD5ADDEDDA843B8CF8766831929A0AAC56D92E03B
                B30F1BEBFEBCE3E478C6 )
dnssec-ws01.dnssec.bayern. 3600    IN SSHFP 2 2 (
                B17CCCCD54B29312743AE3B86168A5381C596F0D4CE4
                F2B8AED0DC0043DE9F88 )
dnssec-ws01.dnssec.bayern. 3600    IN RRSIG SSHFP 8 3 3600 (
                20170330193947 20170105190838 36675 dnssec.bayern.
                QjResvVufRf3IcvtQmFdsb0kUEgkoqTeUIF7llsgYIGb
                AEJB16wL0LFE/DswIP/nYwmixNeSh1GzzZSMtLUGZRJB
                wcXKb4AW7zzeRgoIfZnWIT/w4cFA0NFmy7HiIgUN/Ert
                7R7iJl1eLpF9F7moL1dap95qIXSzy3DRREMRNcyWAcVw
                SCdsu/nA+ETxXdkR5E0+6zDSsjeCKlMqTzQIPNXJGNgH
                RQ8FXKfsOlrY8zPQ5V929z/MzeUXHy3XVB0qKnRlkn+o
                iDolXhgKuESgB7pXMmjWPHM6kBhmQhW8sM7wJVCa8A15
                DxCHkVOc+1WYDpXvMjekPJdrip4I/lTTVA== )

SSH-Verbindung mit DNS HostKey-Überprüfung


Damit das Nachschlagen des richtigen SSHFP funktioniert, müssen die Searchdomains in /etc/resolv.conf mit den Einträgen in der CanonicalDomains in /etc/sshd_config  oder in ~/.ssh/config übereinstimmen:


/etc/resolv.conf

search lrz.de srv.lrz.de dnssec.bayern


~/.ssh/config

VerifyHostKeyDNS yes
GSSAPITrustDns yes
CanonicalDomains lrz.de dnssec.bayern
CanonicalizeHostname yes

   

oder


/etc/sshd_config

VerifyHostKeyDNS yes
GSSAPITrustDns yes
CanonicalDomains lrz.de dnssec.bayern
CanonicalizeHostname yes


Verbindet man sich dann mit der Option "-o VerifyHostKeyDNS=yes" mit dem ssh-Server, dann wird der Hostkey im DNS gefunden. Damit wird dann implizit ohne Nachfrage dem Fingerprint des Servers vertraut.

$ ssh dnssec-ws01 -o VerifyHostKeyDNS=yes


The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Mar 21 18:34:00 2017 from wsc20.srv.lrz.de
18:35 [root@dnssec-ws01 ~]#




Unter macOS unterstützt OpenSSH_7.3p1, LibreSSL 2.4.1 GSSAPITrustDns nicht

$ ssh dnssec-ws01 -o VerifyHostKeyDNS=yes


The authenticity of host 'dnssec-ws01.dnssec.bayern (<no hostip for proxy command>)' can't be established.

ECDSA key fingerprint is SHA256:X0zVrd7dqEO4z4dmgxkpoKrFbZLgO7MPG+v+vOPkeMY.

Matching host key fingerprint found in DNS.

Are you sure you want to continue connecting (yes/no)?



Dies ist vor allem für Gateways oder Supercomputing-Cluster, git usw. ein deutlicher Zusatznutzen, der durch DNSSEC ermöglicht wird.


Altlasten

Wenn die HostKeys auf dem Server gewechselt werden, müssen auch die DNS-Einträge geändert werden. Dabei sollte man dann auch die alten, ungültigen SSHFP-Einträge löschen, um Altlasten zu vermeiden.


SSHFP aus Client-Sicht

Um mit einem SSH-Client, den SSHFP-Eintrag aus dem DNS zur Verification des Hostkeys verwenden zu können, muss dies in den ssh-Optionen angegeben werden.


Unter Linux, entweder global in der /etc/ssh/sshd_config oder in der .ssh/config des Benutzers mit


VerifyHostKeyDNS yes


oder fallweise bei jeder Verbindung mit der Option


-o "VerifyHostKeyDNS=yes"


Will man die Verification mittels des SSHFP-Eintrags zwingend voraussetzen, kann in der /etc/ssh_config pro Host (oder mit Wildcard)


Host *

    StrictHostKeyChecking yes


gesetzt werden.


Die Unterstützung von VerifyHostKeyDNS ist aber noch nicht bei allen ssh-Clients verbreitet:


AnwendungUnterstützung
OpenSSHseit 6.6
macOSseit 10.12 "Sierra"
PuttyNein, seit Jahren auf der Wunschliste...