Aus Linux-Magazin 10/2021

SSH-Verbindungen richtig absichern

© Andriy Popov / 123RF.com

Viele seiner täglichen Arbeiten erledigt der Admin mithilfe des Schweizer Taschenmessers der Systemverwaltung, der Secure Shell. Das mächtige Werkzeug bietet aber meist nur unzureichenden Schutz.

Ein System ist nur so sicher wie sein schwächstes Glied. Das gilt auch für die IT.

Ein mittlerweile noch älteres Protokoll, HTTP, erhielt inzwischen ein hierarchisches Vertrauensmodell, das ein sicheres Miteinander im Netz ermöglicht. Im Unterschied dazu hat sich SSH keinen Zentimeter von der Stelle bewegt. Dennoch bleibt es ein essenzieller Bestandteil eines jeden Linux-Systems und findet sich trotz seines Alters von gut 25 Jahren noch auf praktisch jeder Linux-Maschine.

Sicherheit im Wandel

Die Art und Weise, wie SSH die Authentizität seines Gegenübers feststellt, basiert auf dem Prinzip Trust-on-First-Use (TOFU). Das sieht laut RFC 4251 [1] eine dezentrale Datenbank auf jedem SSH-Client vor (zum Beispiel die Textdatei »known_hosts«), die Informationen über die Fingerabdrücke und einen SHA256-Hash des öffentlichen Schlüssels von vertrauten Kommunikationspartnern abspeichert. Diese Informationen prüft SSH nun bei jedem weiteren Verbindungsaufbau zur selben Netzwerkidentität auf Übereinstimmung. Schlägt der Test fehl, erhält der Benutzer eine eindeutige Fehlermeldung (Abbildung 1).

Abbildung 1: Fehlermeldung bei falschem Fingerabdruck.

Abbildung 1: Fehlermeldung bei falschem Fingerabdruck.

Zu seiner Zeit war das ein vielversprechender Weg, die Integrität von Servern zu ermitteln. Er verlangt den Beteiligten allerdings ab, über einen sicheren dritten Kanal gegenseitig den angegebenen SHA256-Hash zu verifizieren. Nur so lässt sich garantieren, dass der Kommunikationspartner wirklich der ist, für den er sich ausgibt. Diese dezentrale Lösung validiert – mit etwas manueller Arbeit – zuverlässig die Integrität einer Verbindung.

Fehlermeldungen sind ein Indiz für eine Spoofing-Attacke, wie sie bis heute im Web vorkommen. Aktuell gibt es allerdings bessere Möglichkeiten, die Authentizität der Beteiligten zu validieren. Als optimalen Kompromiss zwischen Sicherheit und Bequemlichkeit nutzt man heute eine Public-Key-Infrastructure (PKI) in Kombination mit Zertifikaten. SSH hingegen hat sich als zuverlässiges Protokoll im Internet nicht bewährt und wird heute meist nur noch in privaten Netzwerken genutzt.

Dennoch finden sich im Netz zahlreiche Server mit öffentlich zugänglichen SSH-Ports, darunter IoT-Geräte sowie Anbieter von virtuellen Servern und Infrastruktur. Sie geben besonders anfällige Ziele für Man-in-the-Middle-Angriffe (MITM) ab. Oft wird das Verifizieren der Server-Identität vergessen oder ignoriert, und es kommt eine Verbindung mit einem Betrüger zustande. Noch gefährlicher sind gespiegelte SSH-Schlüsselpaare auf gemieteten Servern, die Angreifer zur Täuschung extrahieren und ausnutzen können. Deswegen sollte man auf solchen Systemen grundsätzlich zu Beginn die Schlüsselpaare neu generieren.

Der Mann in der Mitte

Wie jedes andere Programm auch ist SSH gelegentlich von Sicherheitsschwachstellen betroffen. So ermöglicht es beispielsweise CVE-2020-14145 [2] einem MITM-Angreifer, gezielt Verbindungen zu übernehmen, wenn diese den TOFU-Prozess durchlaufen. Der Exploit beschreibt ein Informationsleck beim Verhandeln von Parametern während des Verbindungsaufbaus. Es ermöglicht dem Angreifer herauszufinden, ob ein OpenSSH-Client schon einen abgespeicherten Fingerabdruck des öffentlichen Schlüssels seines Gegenübers besitzt. In den meisten Fällen lassen sich solche Verbindungen einfach übernehmen, da der Benutzer den Fingerabdruck meist ohne Verifikation blind akzeptiert.

Die Ursache dieses Informationslecks ist die Reihenfolge der Algorithmen in der Liste »server_host_key_algorithms«, die während des Austauschs von Parametern mitgesendet wird. Viele SSH-Clients, darunter auch OpenSSH, stellen gemäß der Anforderungen des offiziellen SSH-Transport-Standards (RFC 4253 [3]) den präferierten Schlüsselerstellungsalgorithmus zum Identifizieren des Authentifizierungsschlüssels an erste Stelle. Hier unterscheiden sich die Listen, je nachdem, ob man den Fingerprint zum öffentlichen Schlüssel des Gegenübers kennt oder nicht.

Listing 1 vergleicht zwei »server_host_key_algorithms«-Listen bevor und nachdem sich ein OpenSSH-8.3-Client mit demselben Server verbunden hat. Man kann erkennen, dass der Server einen SSH-RSA-Schlüssel bevorzugt. Öffentliche Ressourcen wie zum Beispiel das Programm Ssh-mitm (siehe Kasten “Ssh-mitm”) können das Aufbereiten solcher Informationen vereinfachen.

Listing 1

Algorithmenliste mit und ohne known_hosts-Eintrag

# Unbekannter Fingerabdruck
server key:
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
ssh-ed25519
rsa-sha2-512
rsa-sha2-256
ssh-rsa
# Bekannter Fingerabdruck
server key:
rsa-sha2-512
rsa-sha2-256
ssh-rsa
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
ssh-ed25519

Ssh-mitm

Das Programm Ssh-mitm [4] erlaubt, eine Sicherheitsüberwachung vorzunehmen, und ermöglicht das Überwachen des eigenen SSH-Verkehrs. Die Entwickler wollen die Risiken und Probleme des SSH-Protokolls hervorheben und auf sie aufmerksam machen. Der Autor beteiligt sich als Programmierer an diesem Projekt und implementierte viele der Funktionen, die der Sicherheitsüberwachung gelten. Darunter fällt auch das Erkennen des SSH-Informationslecks CVE-2020-14145.

OpenSSH 8.4 implementierte einen kleinen Patch, der das Informationsleck behebt, indem er den standardmäßig ausgewählten Host-Schlüsselalgorithmus (ECDSA-SHA2) benutzt und in der Datei »known_hosts« hinterlegt. Die Schwachstelle lässt sich auch beheben, indem man entweder bestimmte Algorithmen mit der Option »HostKeyAlgorithms« angibt oder eines der auf Zertifikaten basierenden Verfahren für das Authentifizieren verhandelt.

Warum SSH absichern?

SSH ist ein besonderer Fall, da Systemadministratoren es hauptsächlich in ihren eigenen Netzwerken nutzen. Meistens verwenden sie es sogar in einem abgekoppelten Bereich, der speziell zum Verwalten von Geräten reserviert ist und sich nur über ein VPN erreichen lässt. Solch ein Netzwerk lässt wirklich nur dediziertes Personal auf die Verwaltungsschnittstelle eines Servers zugreifen.

Warum muss man SSH dann überhaupt absichern? Es geht darum, im schlimmsten Fall einen Angreifer abzufangen, noch bevor er Shell-Zugriff auf kritische Systeme ergattern kann. Der SSH-Zugriff eröffnet meist weitreichende Möglichkeiten und ist deswegen für Angreifer von besonderem Interesse. Dementsprechend sollte man ihn auch absichern.

In Umgebungen, in denen des Öfteren neue Hosts hinzukommen oder in denen aufgrund von Sicherheitsanforderungen ein regelmäßiger Schlüsselaustausch stattfindet, sollte man besonders auf die Absicherung des SSH-Zugriffs achten: Hier kann es leicht zu einer Übernahme mittels MITM-Attacken kommen. Darüber dienen oft auf SSH aufbauende Software-Tools wie zum Beispiel Ansible als einfacher Angriffspunkt. Diese sind meist aus Bequemlichkeit so konfiguriert, dass sie Host-Schlüssel nicht streng kontrollieren.

Unternehmen, die sich an die Informationssicherheitsrichtlinien des deutschen Bundesamts für Sicherheit in der Informationstechnik (siehe Kasten “BSI”) halten, nehmen regelmäßig einen Austausch der öffentlichen und privaten Schlüsselpaare vor. Das würde aber, wenn SSH in diesen Prozess integriert ist, jedes auf dem TOFU-Prinzip basierende Vertrauenskonzept obsolet machen. Die Integrität des jeweiligen Gegenübers ließe sich bei ständigem Schlüsselwechsel nicht mehr feststellen.

BSI

Das deutsche Bundesamt für Sicherheit in der Informationstechnik veröffentlicht jährlich mehrere Dokumente, die die allgemeine Informationssicherheit in einem Unternehmen adressieren. Die BSI-Standards und eine zusammengefasste Version, das IT-Grundschutz-Kompendium [5], dienen vielen Firmen als öffentliche Informationssicherheitsrichtlinien, da sie den Anforderungen der IT Management ISO-27001-Zertifizierung sehr nahe kommen.

SSH richtig absichern

Um Anforderungen wie dem regelmäßigen Schlüsselaustausch entgegenzukommen, streben viele Systemadministratoren eine Lösung an, die Integrität und Skalierbarkeit unter einen Hut bringt. Um die Integrität eines Servers zu garantieren, ohne händisch ein Verifikationsverfahren über einen sicheren dritten Kanal anzustoßen, bietet OpenSSH an, das Gegenüber mithilfe von SSHFP-DNS-Einträgen zu validieren. Die hinterlegen einen Fingerabdruck des öffentlichen Schlüssels einer Netzwerkidentität in der Zonendatei eines DNS-Servers, der als vertrauenswürdige dritte Quelle dient. Deswegen ist es wichtig, die Integrität des DNS-Servers durch DNSSEC abzusichern.

SSHFP-DNS-Einträge folgen einem speziellen Format und lassen sich für einen bestimmten Host-Namen mit dem Befehl »ssh-keygen« erzeugen (Listing 2). Dessen Ausgabe trägt der Admin dann in einer DNSSEC-signierten Zonendatei ein, sodass SSH-Clients die Daten sicher abfragen können.

Listing 2

SSHFP-DNS-Einträge

# ssh-keygen -r server.example.com -f /etc/ssh/ssh_host_ecdsa_key.pub
server.example.com
 IN SSHFP 3 1 2e99e82cb06d646039fb813242850f69a4fc2c67
server.example.com IN SSHFP 3 2 fbfb8965a367f71e4ed8f6737a2e2db1c04be671db7c9c4e17ac346b9ae7a825

Bei gesetzter SSH-Option »VerifyHostKeyDNS=yes« vergleichen SSH-Clients die mitgelieferten Fingerabdrücke mit denen im DNS. Die Antwort des DNS-Servers muss DNSSEC-signiert werden, sonst verlangt SSH eine manuelle Verifikation des Fingerabdrucks, da es die Integrität des Eintrags nicht mehr garantieren kann. Die SSHFP-DNS-Einträge verhindern das SSH-Informationsleck zwar nicht direkt, unterbinden aber zuverlässig MITM-Angriffe.

Dieser Ansatz ermöglicht zudem eine automatische Verifizierung von Server-Fingerabdrücken. Ein einfacher Schlüsselaustausch gehört nicht direkt dazu, ließe sich aber mit zusätzlichem Konfigurationsaufwand automatisiert einbinden. Diese Lösung bietet sich besonders für Provider an, die ihren Kunden SSH-Zugriff auf gemietete Hosts anbieten wollen. Sie benötigt nur eine öffentliche und signierte Domäne sowie ein paar Einträge in der Zonendatei, um Kunden eine sichere Kommunikation mit ihren Servern zu garantieren.

Proprietäre Zertifikate

Für alle, die ein zentrales Schlüsselverwaltungssystem benötigen, das Integrität für Server und Clients bereitstellen kann, empfiehlt sich eine Public-Key-Infrastruktur (PKI) in Kombination mit Zertifikaten. Weil OpenSSH die weitverbreiteten X.509-Zertifikate nicht unterstützt, greift man zu einer PKI-Struktur in Verbindung mit digital signierten Schlüsseln, einem Ablaufdatum und einer Identitätszuweisung.

Eine solche Umgebung setzt eine schon vorhandene Namensauflösung mit Identitäten für alle Server innerhalb der zu verwaltenden Domäne voraus. Zuerst richtet der Admin eine Root-CA auf Basis der proprietären Zertifikate von OpenSSH ein, die als Vertrauensgrundlage gilt und Zertifikate der einzelnen Server signiert. Das entsprechende Schlüsselpaar lässt sich mit dem Kommando »ssh-keygen -t rsa -f ca_root_key« generieren.

Zertifikate werden auf der CA mit dem privaten Schlüssel signiert und dann auf die einzelnen Hosts verteilt. Server-Zertifikate speichert man am besten unter »/etc/ssh/Host-cert.pub«, Client-Zertifikate unter »~/.ssh/«. Letztere nutzt das SSH-Programm automatisch, wenn sie das Suffix »-cert.pub« tragen.

Das Ausfertigen eines Host-Zertifikats unterscheidet sich, wie im Listing 3 zu sehen, durch die Angabe des Parameters »-h«. Die Laufzeit lässt sich über »-V« setzen; im Beispiel aus dem Listing wäre das Zertifikat vor Ablauf eines halben Jahrs zu erneuern. Das Argument »-n« nimmt eine Liste an Principals entgegen, die die Identitäten des Zertifikats bestimmen. Bei Host-Zertifikaten sollten diese den Domänennamen und der IP-Adresse entsprechen. Bei Client-Zertifikaten dienen sie dazu, diesen Identitäten zuzuordnen, sodass man auf Server-Seite Zugriffsrechte bestimmen kann. Listing 4 zeigt, wie solch ein Zertifikat aussehen kann.

Listing 3

Client- und Host-Zertifikate erstellen

$ ssh-keygen -s ca_root_key -h -n server.example.com,172.16.155.130 -I server.example.com -V +180d server.example.com
$ ssh-keygen -s ca_root_key -n client.example.com -I client.example.com -V +180d client.example.com

Listing 4

Anzeige eines OpenSSH-Zertifikats

[root@server ssh]# ssh-keygen -L -f /etc/ssh/server.example.com-cert.pub
/etc/ssh/server.example.com-cert.pub:
  Type: ssh-rsa-cert-v01@openssh.com host certificate
  Public key: RSA-CERT SHA256:uJbAVibJhbFXr0z5l0i/O08/fOwMq+JGbCDqz+/PJ7s
  Signing CA: RSA SHA256:vIQWA43cZ4b6DEexmOSvtUG0wNFGF/opWQ75lzbwRRs
  Key ID: "server.example.com"
  Serial: 0
  Valid: from 2021-02-18T03:25:00 to 2021-08-17T04:26:39
  Principals:
          server.example.com
          172.16.155.130
  Critical Options: (none)
  Extensions: (none)

Listing 5 zeigt die Konfiguration des Servers. Zeile 1 gibt das installierte Host-Zertifikat an. Die zwei anderen Zeilen ermöglichen es, Zugriffe zu limitieren. »TrustedUserCAKeys« bestimmt, dass durch den öffentlichen Schlüssel CA-validierte Zertifikate auf das lokale System zugreifen können. Um feinkörnigere Zugriffsrechte festzulegen, lässt sich zusätzlich ein »AuthorizedPrincipalsFile« angeben, das den Zugriff auf bestimmte Principals einschränkt.

Listing 5

Zertifikatseinträge in der sshd_conf

HostCertificate /etc/ssh/server.example.com-cert.pub
TrustedUserCAKeys /etc/ssh/ca_root_key.pub
AuthorizedPrincipalsFile /etc/ssh/auth_principals

Auf Clients, die ein Vertrauensverhältnis mit der CA aufbauen sollen, müssen die Einträge aus Listing 6 in der Datei »known_hosts« liegen.

Listing 6

CA-Einträge in known_hosts

@cert-authority *.example.com ssh-rsa PublicKey root@ca.example.com
@cert-authority 172.16.155.* ssh-rsa PublicKey root@ca.example.com

Eine vollständige PKI benötigt zudem einen Weg, die Gültigkeit von Zertifikaten wieder zurückzuziehen. Dazu erstellt der Administrator mit dem Kommando aus Listing 7 eine Key-Revocation-List-Datei für die CA und veröffentlicht sie. Clients müssen nun mit der Option »RevokedHostKeys« und Server mit der »RevokedKeys«-Konfiguration auf eine lokale Version der Liste verweisen. So lassen sich zurückgezogene Zertifikate erkennen.

Listing 7

Key Revocation List erstellen

$ ssh-keygen -k -f revoked_keys -s ca_root_key.pub client.example.com

Nun kann jeder Computer, der dieser CA vertraut, die Identität seines Gegenübers verifizieren. Das führt dazu, dass Warnungen bezüglich falscher Zertifikate oder Signaturen wieder an Bedeutung gewinnen und man sie – so wie im Internet – ernst nehmen sollte. Das Schlüsselpaar der Root-CA muss der Admin so sicher wie möglich aufbewahren, denn wird es kompromittiert, sind alle von diesem Schlüssel signierten Zertifikate nicht mehr vertrauenswürdig.

Der hier vorgestellte Ansatz schützt nicht nur vor MITM-Angriffen, sondern macht auch alle Anwendungen des CVE-2020-14145 invalide.

Pro und Contra

Eine selbst aufgesetzte PKI spielt zwar bei der zentralen Schlüssel- und Integritätsverwaltung ihre Stärken aus, hat aber auch Nachteile. Vor allem verursacht eine eigene Lösung für OpenSSH im Vergleich zu anderen PKI-Strukturen einen hohen zusätzlichen Konfigurationsaufwand, will man sie automatisiert betreiben.

Generell ist der Betrieb einer PKI hohen Aufwand verbunden, muss man dabei doch Prozesse wie das automatische Erneuern von Zertifikaten selbst implementieren. Dem steht jedoch der Vorteil gegenüber, dass der Admin durch die Zertifikate SSH direkt kontrollieren kann. So ist es zum Beispiel möglich, das Durchreichen von Ports zu unterbinden.

Fazit

SSH ist kein perfektes Protokoll, bietet in seiner einfachsten Anwendung aber zumindest grundlegende Maßnahmen gegen Integritätsverlust. Mit zunehmenden Anforderungen an die IT-Sicherheit, wie sie Unternehmen verlangen, kann man sich jedoch nicht mehr auf den vorkonfigurierten Schutz von SSH verlassen. Ohne Schlüsselverwaltung und eindeutige Feststellung von Integrität bietet SSH Cyberattacken eine Angriffsfläche und kann daher systemkritische Infrastruktur gefährden. Abhilfe schaffen hier eine zentrale Schlüsselverwaltung und eine selbstständige Integritätsfeststellung durch eine dritte Entität.

Die wahrscheinlich passendste Lösung für viele Unternehmen, die dieser Artikel aufgrund ihrer Komplexität nicht behandelt, wäre das Einbinden der SSH-Authentifizierung in die eines Active Directory. Mit der von AD vorgesehenen auf X.509-Zertifikaten basierenden Authentifizierung bietet sie sich perfekt an. Auch brächte dieses System eine zentrale Identitätsverwaltung mit. (jcb/jlu)

Der Autor

Simon Böhm leistet derzeit seinen Grundwehrdienst im IKT & Cybersicherheitszentrum des Österreichischen Bundesheeres ab. Privat beschäftigt er sich ebenfalls mit allgemeinen Sicherheitskonzepten in der Netzwerktechnik sowie in der Entwicklung.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben