Einführung
Verbindet man sich zum ersten Mal per SSH mit einem Server, sieht man den
Fingerabdruck des Servers. Diesen sollte man im Idealfall vergleichen und erst
mit yes
bestätigen, wenn man sich sicher ist, dass es sich um den richtigen
Fingerprint handelt. Stimmt der Fingerabdruck nicht, könnte man Opfer einer Man
in the Middle Attacke sein. Das Vergleichen der Fingerprints ist etwas mühsam
und mittels fuzzying (beispielsweise mit dem Tool ffp
) können sehr ähnliche
Fingerprints erstellt werden, welche dem Menschen auf den ersten Blick gleich
erscheinen. Man kann sich einfach vor gefälschten SSH Fingerprints schützen,
indem man diese in einem DNSSEC signierten speziellen DNS Record hinterlegt.
Hierfür gibt es den speziellen SSHFP
Record.
Wofür brauche ich den SSHFP Record?
Verbindet man sich zum ersten Mal per SSH mit einem Server, sieht man den
Fingerabdruck des Servers. Diesen kann man mit yes
bestätigen und damit in die
Datei ~/.ssh/known_hosts
eintragen. Hat sich der Fingerabdruck bei einem
erneuten Verbinden verändert, bekommt man eine Warnung. Ist es der selbe, ist
alles OK und der Verbindungsaufbau geht weiter.
Damit der Finerprint nicht von Hand verglichen werden muss, kann man diesen in
einem speziellen DNS Record hinterlegen. Dieser DNS Record heisst SSHFP
und
wurde im RFC 4155 spezifiziert und im RFC 6594 erweitert.
Automatisches erstellen des SSHFP Records
Den SSHFP
Record kann man sich direkt mit ssh-keygen
generieren lassen. Hier
ein Beispiel für den Host motd.ch
:
$ ssh-keygen -r motd.ch.
motd.ch. IN SSHFP 1 1 598e08adbfdee83121bb4e646fa4873574243a81
motd.ch. IN SSHFP 2 1 69174e7205988757021b546b70342200f8465606
Wichtig:
- Dies muss auf dem Host ausgeführt werden, wessen
SSHFP
Record man erstellen will. - Man beachte den Punkt am Schluss des Hostsnamens. Dieser ist nötig, damit der
Eintrag in der Zone stimmt. Ohne “Root Punkt” würde ein Eintrag für
motd.ch.motd.ch.
erstellt werden, da der Nameserver gegebenenfalls den Zonennamen bzw.$ORIGIN
an den Hostnamen anhängt.
Aufbau des SSHFP Records
Die erste Zahl steht für den verwendeten Algorithmus:
0
: Reserviert1
: RSA2
: DSS3
: ECDSA4
: ED25519
Die zweite Zahl steht für den Fingerprint Typ:
0
: Reserviert1
: SHA-12
: SHA-256
Diese Aufstellung ist auch bei der IANA abrufbar: DNS SSHFP Resource Record Parameters: https://www.iana.org/assignments/dns-sshfp-rr-parameters/dns-sshfp-rr-parameters.xhtml.
Händisches Erstellen des SSHFP Records
Ältere Versionen von ssh-keygen
generieren keine Einträge für den ECDSA und
den ED25519 Algorithmus. Diese muss man gegebenenfalls von Hand erstellen. Ich
habe mir folgendes Script geschrieben, welches für alle verfügbaren Algorithmen
und Fingerprint Typen alle SSHFP
Records erstellt:
#!/usr/bin/env bash
HOST="$1"
if (($# < 1)) then echo "Usage: sshfpgen "
exit 1
fi
for i in /etc/ssh/ssh_host_*_key.pub
do
case "`cut -d_ -f3 <<< $i`"
in
rsa)
echo $HOST IN SSHFP 1 1 `cut -f2 -d ' ' $i | base64 -d | sha1sum | cut -f 1 -d ' '`
echo $HOST IN SSHFP 1 2 `cut -f2 -d ' ' $i | base64 -d | sha256sum | cut -f 1 -d ' '`
;;
dsa)
echo $HOST IN SSHFP 2 1 `cut -f2 -d ' ' $i | base64 -d | sha1sum | cut -f 1 -d ' '`
echo $HOST IN SSHFP 2 2 `cut -f2 -d ' ' $i | base64 -d | sha256sum | cut -f 1 -d ' '`
;;
ecdsa)
echo $HOST IN SSHFP 3 1 `cut -f2 -d ' ' $i | base64 -d | sha1sum | cut -f 1 -d ' '`
echo $HOST IN SSHFP 3 2 `cut -f2 -d ' ' $i | base64 -d | sha256sum | cut -f 1 -d ' '`
;;
ed25519)
echo $HOST IN SSHFP 4 1 `cut -f2 -d ' ' $i | base64 -d | sha1sum | cut -f 1 -d ' '`
echo $HOST IN SSHFP 4 2 `cut -f2 -d ' ' $i | base64 -d | sha256sum | cut -f 1 -d ' '`
;;
esac
done
Die aktuellste Version davon gibt es auf GitHub in meinem Scripts Repository: sshfpgen.
So generiert man alle SSHFP Records:
$ ./sshfpgen motd.ch.
motd.ch. IN SSHFP 2 1 69174e7205988757021b546b70342200f8465606
motd.ch. IN SSHFP 2 2 d6b6aba95e89b9b117480dfb495d961cfbadac3ef8dc6fd4d8d82a3b7ee0f5e2
motd.ch. IN SSHFP 3 1 63ebb25f257e0e91fb689132b4f69afa529ddd85
motd.ch. IN SSHFP 3 2 c2cdc18577ac20773f8c8015452ff18bb54bd7da17ab66c5f5e1a266336de232
motd.ch. IN SSHFP 1 1 598e08adbfdee83121bb4e646fa4873574243a81
motd.ch. IN SSHFP 1 2 cbf16ba44d531224d8af0ca49440e05826a2d7e2aa68e179136cb42c33e5d160
Wie man sieht sind jetzt einige Einträge (Neu ECDSA und zusätzlich alle mit SHA256) mehr erstellt worden. Diese kann man jetzt ins Zonenfile eintragen.
Eintragen ins Zonenfile
Dieser SSHFP
Record trägt man jetzt in der DNS Zone ein, welche für diesen
Hostnamen zuständig ist. Damit man der Antwort vom DNS Server auch trauen kann,
sollte diese Zone auch mit DNSSEC signiert sein und der verwendete Resolver
sollte die Antwort überprüfen (man beachte das ad
Flag in der Ausgabe).
$ dig motd.ch sshfp +nostats +noadditional +noauthority +noquestion @8.8.8.8 ` `
; <<>> DiG 9.9.2-P2 <<>> motd.ch sshfp +nostats +noadditional +noauthority +noquestion @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7916
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; ANSWER SECTION:
motd.ch. 86400 IN SSHFP 3 2 C2CDC18577AC20773F8C8015452FF18BB54BD7DA17AB66C5F5E1A266 336DE232
motd.ch. 86400 IN SSHFP 1 1 598E08ADBFDEE83121BB4E646FA4873574243A81
motd.ch. 86400 IN SSHFP 1 2 CBF16BA44D531224D8AF0CA49440E05826A2D7E2AA68E179136CB42C 33E5D160
motd.ch. 86400 IN SSHFP 2 1 69174E7205988757021B546B70342200F8465606
motd.ch. 86400 IN SSHFP 2 2 D6B6ABA95E89B9B117480DFB495D961CFBADAC3EF8DC6FD4D8D82A3B 7EE0F5E2
motd.ch. 86400 IN SSHFP 3 1 63EBB25F257E0E91FB689132B4F69AFA529DDD85
SSH Client konfigurieren
Jetzt muss man dem SSH Client noch sagen, dass er die SSHFP Records zur Verifizierung verwenden soll. Dazu fügt man in der Datei /etc/ssh/ssh_config
folgenden Eintrag ein:
VerifyHostKeyDNS ask
Durch die Option ask
muss man weiterhin mit yes
bestätigen, man bekommt
jedoch den Hinweis, dass der Key mit dem SSHFP
Record übereinstimmt..
Verwendet man yes
statt ask
wird der Key automatisch akzeptiert.
SSH Verbindung aufbauen
Folgendermassen sieht der Verbindungsaufbau aus, wenn man sich zum ersten Mal mit dem Server verbindet:
$ ssh motd.ch
The authenticity of host 'motd.ch (5.45.105.71)' can't be established.
ECDSA key fingerprint is 8e:ff:01:35:98:88:56:f7:1f:7a:11:28:86:e4:34:11.
Matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'motd.ch,5.45.105.71' (ECDSA) to the list of known hosts.
Yay! Man sieht die Zeile: “Matching host key fingerprint found in DNS.”. Der Public SSH Fingerprint stimmt also mit dem SSHFP Record überein.
Stimmt der SSHFP
Record und der Fingerprint nicht überein, erscheint folgende Meldung:
$ ssh motd.ch
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
8e:ff:01:35:98:88:56:f7:1f:7a:11:28:86:e4:34:11.
Please contact your system administrator.
Update the SSHFP RR in DNS with the new host key to get rid of this message.
The authenticity of host 'motd.ch (5.45.105.71)' can't be established.
ECDSA key fingerprint is 8e:ff:01:35:98:88:56:f7:1f:7a:11:28:86:e4:34:11.
No matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)?
Links und weitere Informationen
- Fuzzy Fingerprints Attacking Vulnerabilities in the Human Brain: https://www.thc.org/papers/ffp.html
- RFC 4255: Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints: https://tools.ietf.org/html/rfc4255
- RFC 6594: Use of the SHA-256 Algorithm with RSA, Digital Signature Algorithm (DSA), and Elliptic Curve DSA (ECDSA) in SSHFP Resource Records: http://tools.ietf.org/html/rfc6594
- IANA: DNS SSHFP Resource Record Parameters: https://www.iana.org/assignments/dns-sshfp-rr-parameters/dns-sshfp-rr-parameters.xhtml