-
ssh (Secure Shell) Verbindung
Der User möchte von der lokalen Maschine (local host) eine Datenverbindung auf eine fernen Maschine (einen Server, einen fernen Host, a remote host)
über ein Netzwerk erstellen. Will er eine sichere Verbindung anhand des ssh-Protokolls aufstellen, wird er das Kommando
ssh verwenden.
Um grundlegende Informationen zu ssh anzuzeigen, wird der User folgendes Kommando eintippen:
ssh -V.
Zum Zeitpunkt des Eintippens (Oktober 2023) wird folgende Zeile ausgegeben:
OpenSSH_8.9p1 Ubuntu-3ubuntu0.4, OpenSSL 3.0.2 15 Mar 2022
Beachte: Es ist auch möglich, die ssh-Version vom Fernserver beim Eröffnen der Verbindung anzuzeigen,
indem die Option -v (verbose, wortreich) aktiviert wird:
ssh -v <Host> oder <TCP-IP-Adresse>
Im Fall einer User-PW Authentifizierung:
Tippt der User Kommando
ssh {<user>@}<host> z.B. ssh akh@192.168.1.17
ein, wird er aufgefordert, sein Passwort einzutippen.
Ist die Authentifizierung erfolgreich, bekommt der User die Kommandozeile auf dem fernen Host (<ServerPrompt>).
Anm.: Der User kann seinen Namen weg lassen, wenn er gleich auf beiden Systemen (dem lokalen und dem fernen) ist.
Das ssh Programm auf der lokalen Maschine (der Klient) verwendet zur Verschlüsselung der Kommunikation
einen öffentlichen RSA-Schlüssel, der vom Server erzeugt und mitgeteilt wurde.
Wenn sich der User zu erstem Mal auf dem Server anmeldet, ist der RSA-Schlüssel logischerweise unbekannt.
Der User muss bestätigen, dass er ihn als Identifikation des Servers akzeptiert.
ssh wird ihn dann der Liste der bekannten Schlüssel hinzufügen.
Vor der Zustimmung sollte idealerweise
auf irgendwelche Weise geprüft werden, dass der angezeigte Fußabdruck des Schlüssels echt ist.
Das gleiche Prozedere wiederholt sich, wenn der Server den alten Schlüssel ersetzt
- es sei denn, der neue Schlüssel kommt nicht vom Server, sondern von einem Hacker, der
einen MITM-Eingriff (Man-in-the-Middle) durchführt. (Auch
in dieser Situation kann es hilfreich sein, die Echtheit des neuen Schlüssels zu prüfen.)
Ist der alte Server-Schlüssel tatsächlich obsolet, sollte er auf der Klient-Seite entsorgt werden.
(Die ssh-Warnmeldung beschreibt, wo der alte Schlüssel liegt bzw. auf welcher Zeile in Datei
/home/user/.ssh/known_hosts).
-
scp (secure copy)
Der Befehl wird verwendet, um Dateien sicher zu kopieren (secure copy) -
entweder vom Lokalrechner (d.h. vom local host bzw. client) zum Fernrechner (d.h. zum Server)
oder umgekehrt.
Anm.: Verbindung mit einem dritten Rechner bzw. einem zweiten Server (client ⇒ server 1 ⇒ server 2 ), die früher
offenbar zugelassen waren, sind mittlerweile aus Sicherheitsgründen stark eingeschränkt oder
sogar nicht mehr zulässig.
Die Syntax von scp orientiert sich an der Syntax vom Kopieren-Befehl auf unixoiden Systemen
cp:
scp {<Optionen>} <Quellpfad> <Zielpfad>
Pfadangaben auf einem Server gehorchen folgender Syntax:
<Nutzer>@<Server>:<Verzeichnis/Datei.Endung>
Beispiele
-
scp datei.txt Nutzer@example.com:/pfad/zum/Verzeichnis
kopiert Datei datei.txt (gespeichert im laufenden Verzeichnis des Lokalrechners)
auf das Fernverzeichnis /pfad/zum/Verzeichnis vom Server example.com.
Der User authentifiziert sich mit seinem Namen Nutzer
(und muss u.U. ein Passwort eintragen).
-
scp datei1.txt datei2.txt Nutzer@example.com:/pfad/zum/Verzeichnis
Das Kopieren von mehreren Dateien.
Anm.:
Vorsicht ist bei der Anwendung von "Wildcards" wie ? oder * geboten,
da unerwartete Effekte können auftreten, wenn man nicht aufpasst.
-
scp -r Verzeichnis1 Nutzer@example.com:/pfad/zum/Verzeichnis2
Lokales Verzeichnis Verzeichnis1 wird auf dem Server unter Verzeichnis2
kopiert. (Option -r steht für rekursiv: der vollständige Inhalt inkl. aller Unterverzeichnissen
wird erfasst.)
Die Verwendung vom Befehl scp, um Dateien über Netzwerke zu kopieren,
ist wahrscheinlich nicht die beste Alternative heutzutage. Das sftp
Protokoll scheint besser geeignet. Es gibt auch sftp-Tools, deren Bedienung sehr intuitiv ist z.B.
FileZilla.
-
ssh Konfiguration
Zumindest auf meinem
Linux Ubuntu
System gelten folgende Regel:
-
Profilbezogene (userspezifische) Konfigurationsparameter sind in Datei ~/.ssh/config gespeichert.
Sie wird von Ubuntu (22.04, meinem BetriebssSystem) nicht standardmäßig angelegt. Der User muss sie bei Bedarf erzeugen
(z.B. via dem Befehl touch ~/.ssh/config).
-
Parameter, die systemweit - für alle User - gelten , sind in /etc/ssh/ssh_config gespeichert.
Es ist möglich, mehrere Konfigdateien anzulegen, und im ssh Befehl zu bestimmen, welche gilt:
via Option F : ssh -F <KonfigDateiName> <userName>@<ServerName>
Hauptsächlich dienen die Informationen in der Konfigdatei dazu, ein ssh Befehl zu verkürzen.
Anstatt des vollständigen Namens (bzw. der IP-Adresse) des Servers kann ein Kürzel bestimmt werden, sowie der zugeordnete Username
oder die zugeordnete Port-Nummer. Andere Parameter der Kommunikation können ad hoc definiert werden. Beispiel von Inhalt einer Konfigdatei:
### ssh login für DerLangeExakteNameDesFernenHosts
Host HostKürzel
Hostname DerLangeNameDesFernenHosts
User UserNameAufDemFernenHost
Port sshPortNummerAufDemFernenHost
PreferredAuthentications publickey
IdentityFile DateiNameDesZugeordnetenSchlüssels
### ssh login für alle anderen fernen Hosts
Host *
User root
Beispiel Provider github:
Host github
Hostname github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/rsa-github
Beispiel Provider manitu:
Host manitu
Hostname ngcobalt340.manitu.net
Port 22
User sshxyz
IdentityFile ~/.ssh/rsa-manitu
Falls die Konfigurationsdatei oben gelesen wird, steht ssh HostKürzel für
ssh -i <IdentityFile> -p <Port> <User>@<Hostname>
- vgl. auch
stackoverflow: use multiple keys on one client.
ssh ermittelt die Kommunikationswerte nach einer festgelegten Reihenfolge, bis alle Werte bekannt sind,
oder bricht ab:
-
Kommandozeile:
Sie hat höchste Priorität, kann jeden Wert überschreiben
u.a. via Option -o.
Z.B.
ssh -o "User=EinAndererUserName" Host
überschreibt den Usernamen für einen Host.
-
Lokal:
Profilbezogene Konfiguration in Datei ~/.ssh/config
-
Global:
Systemweite Konfiguration in Datei /etc/ssh/ssh_config
Siehe auch Referenzen ssh configuration.
-
Handhabung von ssh Schlüsseln
Authentifizierung des Servers (gegenüber dem lokalen Rechner)
Es wurde im Kapitel ssh Verbindung (secure shell)
erwähnt, dass der Server (remote host) (zum Zeitpunkt der allerersten Verbindung) einen öffentlichen
RSA-Schlüssel
an den Klient (den lokalen Rechner, local host)
schickt, der zu seiner Identifikation (bei aller zukünftigen Verbindungen) dient.
Der Klient speichert den öffentlichen Schlüssel des Servers bei sich
(wenn der User den Vorgang zulässt) und er verwendet ihn immer wieder,
um sich bei der Anmeldung der Identität des Servers zu vergewissern.
Dies betrifft nur den Vorgang der Authentisierung des fernen Host,
nicht aber die Verschlüsselung der Kommunikation oder die Authentisierung des Users auf dem Server
(Hat der User das Recht sich anzumelden?).
Datenverschlüsselung (zwischen lokalem und fernem Rechner):
Die Verschlüsselung der Daten wird von einem
symmetrischen
schlüssel (kein RSA-schlüssel) übernommen,
der ad hoc für die Kommunikation erzeugt wird (session based key).
.
Um dieses gemeinsame Geheimnis
(shared secret) von Klient und Server, geschützt von dritten, auszutauschen,
wird eine aufwändige Prozedur (key exchange algorithm) herangezogen, unter Verwendung von RSA-Schlüsseln.
ssh unterstützt verschiedene Technologien der symmetrischen Verschlüsselung:
AES,
Blowfish,
3DES,
CAST128,
ArcFour.
Datenintegrität :
Um die Integrität der Meldungen zu prüfen, muss nach der Verschlüsselung der Daten,
ein 2-stufiger Vorgang angestoßen werden: die Generierung eines sogenannten MAC (Message Authentication Code).
- Hash-Berechnung:
Die Meldung wird
in einen Hash zusammengepresst, d.h. eine Zeichenkette, die aus dem originalen Text
von einer Hash-Funktion berechnet wurde. Solche Hash-Funktionen haben folgende
Eigenschaften:
() Das Ergebnis der Berechnung - obwohl viel kürzer - ist praktisch
eins zu eins dem originalen Text zuzuordnen.
() Aus dem Ergebnis kann der originale Text
nicht rekonstruiert werden.
Während der Eröffnung des Kommunikationskanals wird
u.a. darüber verhandelt, welche Hash-Funktion verwendet wird.
(Unter der Liste der vom Klient unterstützten Funktionen wählt der Server die erste passende aus.)
-
Verschlüsselung des Hash:
Die Verschlüsselung des Hash wird vom symmetrischen Schlüssel vorgenommen, die auch die Daten schon verschlüsselt.
Authentisierung des Users (gegenüber dem Server):
Dieser Schritt erfolgt, erst nachdem die Datenverschlüsselung ausgehandelt wurde.
- Die oft verwendete Vorgehensweise (password authentication):
Der Server fordert das Passwort des Users an, der über den verschlüsselten Kanal übertragen wird.
- Die empfohlene Vorgehensweise (public key authentication):
Der User auf dem lokalen Rechner hat im Vorfeld ein Paar von RSA-Schlüsseln, einen öffentlichen und einen geheimen,
erzeugt. Der öffentliche Anteil wurde (auch im Vorfeld) an den fernen Host (Server) zugeschickt, und wird dort auf einer Datei namens
authorized_keys im Verzeichnis
~/.ssh des Users gespeichert. (Der User hat ein Profil,
sowohl auf dem lokalen, als auch auf dem fernen Rechner).
Der Server nutzt diesen (öffentlichen) (RSA-)Schlüssel, um die Identität des Users zu prüfen (Ist er im Besitz des geheimen Schlüssels,
der ihm ermöglicht, Meldungen, die mit dem öffentlichen Schlüssel kodiert wurden, zu entziffern?)
-
Generierung von ssh Schlüsseln
Schritt: Generation
Ein User wird zwei Schlüssel (öffentlich / geheim) für ssh erzeugen, wenn er sich über diesen
Weg beim Server authentifizieren will - anstatt mit einem Passwort. Dazu verwendet er
den Befehl ssh-keygen.
ssh unterstützt mehrere Algorithmen. Beispiele?
-
ssh-keygen -t rsa -b 4096 -f ~/Downloads/ssh-rsa-akh
() Es werden RSA-Schlüssel der Länge 4096 bits erzeugt.
() Die Option -f nennt einen Dateinamen für die
Schlüssel:
⇒ ssh-rsa-akh (Geheimer Schlüssel),
⇒ ssh-rsa-akh.pub (Öffentlicher Schlüssel).
-
ssh-keygen -t ed25519 -f ~/Downloads/ssh-ed25519-akh
() ed25519 ist ein neuer Typ von Schlüssel, der vom Projekt openssh entwickelt wurde.
Anmerkungen:
-
Die (2) erzeugten Schlüsseldateien sollen standardmäßig im (unsichtbaren) ssh-Verzeichnis des Userprofils gespeichert
werden: ~/.ssh/.
-
Eine "Paraphrase" (Passwort) wird bei der Generierung abgefragt. Sie wird nie
angezeigt. Die Paraphrase - wenn sie nicht leer ist - wird
jedes Mal abgefragt, wenn der Schlüssel herangezogen wird. Beispiel?
Wenn ssh-add zur bequemen Authentifizierung des Users auf dem fernen Host aufgerufen wird.
(Um Sicherheitslücken möglichst zu schließen, wird empfohlen, stets eine starke Paraphrase zu wählen.)
-
Der User kann entscheiden mehrere Schlüssel zu erzeugen, wenn er mehrere Konten auf verschiedenen Rechnern unterhält.
Dies ist die empfohlene Praxis, erfordert aber zusätzlichen Verwaltungsaufwand.
-
Es ist möglich, das Schlüsselpasswort (die Paraphrase) jede Zeit zu ändern - vorausgesetzt man kennt noch das alte Passwort.
ssh-keygen -p
Schritt: Prüfung
Es kann von Interesse sein, den Fingerabdruck des öffentlichen Schlüssels zu prüfen.
Er wird meistens via zwei Algorithmen (ALGO) berechnet: SHA256 (Standardwert) und MD5:
ssh-keygen -l -E <ALGO> -f <Schlüsseldatei>
Addendum
-
Die -C Option (C für comment):
ssh-keygen -t rsa -b 4096 -f <ssh-Schlüssel-Datei> -C <MeineE-Mail-Anschrift>
kann z.B. dazu verwendet, um die Identität des Schlüsseleigentümers zu bestimmen. Des öfteren wird ein (online) User
über die E-Mail-Anschrift erkannt. Es ist insbesondere der Fall für Anmeldung an
GitHub.
Wurde die -C Option weggelassen, wird standardmäßig als Kommentar-Wert <LoginUser@RechnerName> gesetzt.
-
Übertragung von ssh Schlüsseln
Der interessante Anwendungsfall ist, wenn ein User einen öffentlichen Schlüssel (oder mehrere)
- Dateien *.pub - auf den fernen Host senden will,
um sich künftig damit authentifizieren zu können - anstatt ein Passwort einzutragen. Auf dem
fernen Host werden Schlüssel im Users Profil gespeichert - in Datei
~/.ssh/authorized_keys.
Beachte: Ein geheimer Schlüssel darf nie - unter keinem Umstand - übertragen werden.
-
Befehl ssh-copy-id <Optionen> user@Server
Es ist für den User der einfachste Weg.
Liste von Optionen:
-
-p: gibt die Portnummer an. Wichtig,
wenn der Server nicht auf Portnummer 22 (Standardwert) horcht.
-
-n: die Übertragung wird nur simuliert.
Der Schlüssel wird letztendlich nicht übertragen. Ein sogenannter "Trockenversuch" (dry run).
-
-i: gibt an, welche Schlüsseldatei (welche pub-Datei) übertragen werden
soll. Ist die Option nicht gesetzt, werden alle *.pub Dateien im
~/.ssh Verzeichnis übertragen.
-
Befehl scp <Schlüsseldatei> user@Server
Nach dem Kopierem auf das Hauptverzeichnis des Users auf dem Server muss die Schlüsseldatei ins richtige Verzeichnis
verschoben werden. Dafür können folgende Befehle verwendet werden:
-
ssh user@Server (sich anmelden, um ins Hauptverzeichnis des Profils zu gelangen)
-
cat <Schlüsseldatei> >> ~/.ssh/authorized_keys
(Schlüsseldatei in die richtige Datei verschieben)
-
rm <Schlüsseldatei>
(Bereinigung)
-
exit
(Abmeldung)
-
Prüfung, ob der neue Schlüssel aktiviert wurde.
-
Befehl scp <Schlüsseldatei> user@Server
-
Wenn ja, wird das PW des Schlüssels angefordert
Enter passphrase for key '/home/user/.ssh/<Schlüsseldatei>
-
ssh-agent (Befehl)
Ein ssh Dienst (agent) hält
einen oder mehrere Schlüssel bereit. Dies verhindert, dass der User das Schlüssel-PW jedesmal einträgt,
wenn er sich verbinden will (Befehl ssh-agent <EineBestimmteAktion>).
Wenn man eine Konsole eröffnet (auf meinem Rechner eine
Bash Shell eröffnet),
startet der ssh Dienst (ssh-agent) automatisch. Um dies zu prüfen, tippt man folgenden Befehl ein:
eval `ssh-agent -s`. Die Prozesskennung (PID) des Dienstes wird ausgegeben.
Wenn der ssh Dienst abgeschaltet wird, werden alle ggf. damit hochgeladenen Schlüssel aus dem Memory gelöscht.
Dies ist z.B. der Fall, wenn die Konsole wieder geschlossen wird.
Es ist aber auch möglich den Dienst abzuschalten,
ohne die Konsole zu schließen:
ssh-agent -k <Prozess_Kennung>
-
ssh-add (Befehl)
verwaltet vom ssh-agent hochgeladene (geheime) Schlüssel.
Solche Schlüssel stehen dann für ssh, sftp, scp und anderen ssh Befehle zur Verfügung.
Wie im Kapitel ssh-agent
erwähnt, gelten die Operationen unten nur innerhalb einer Shell.
ssh-add -c <DieDateiDesHochzuladendenGeheimenSchlüssels>
Ist keine Schlüsseldatei genannt, wird versucht, der "Standard-Schlüssel" ins Memory hochzuladen.
(Die Hochladung erfordert vom User die einmalige Preisgabe der zugeordneten Paraphrase).
-
Option -c sorgt dafür, dass der ssh Dienst dem User jedes Mal mitteilt,
wenn er zur Nutzung eines Schlüssels aufgefordert wird.
-
Option -t <DieDateiDesHochzuladendenGeheimenSchlüssels> setzt eine maximale Gültigkeitsdauer
der Hochladung, gemessen
in Sekunden (z.B. -t 1800),
in Minuten (z.B. -t 45m),
in Stunden und Minuten (z.B. 3h42)
-
Option -l
listet die Parameter der hochgeladenen (geheimen) Schlüssel auf: u.a. bit-Länge, Fingerabdruck, Kryptoalgorithmus auf.
Wenn vorhanden.
-
Option -L
listet all Parameter der zugeordneten öffentlichen Schlüssel auf, wenn vorhanden.
-
-d <DateiEinesDerHochgeladenenSchlüssel>
löscht einen bestimmten Schlüssel aus dem Memory.
-
-D
löscht alle ins Memory hochgeladenen Schlüssel.
Will der User hochgeladene Schlüssel von einer Shell auf die andere übertragen,
muss er dafür sorgen, dass der gleiche Dienst (ssh-agent) greift. Er muss
den Wert der Variable SSH_AUTH_SOCK aus der
einen Shell in die andere exportieren.
-
In Shell Nr. 1: echo $SSH_AUTH_SOCK
Sich den Wert merken z.B. /tmp/ssh-XXXXXXBtmk9L/agent.1726
In Shell Nr. 2: export SSH_AUTH_SOCK=/tmp/ssh-XXXXXXBtmk9L/agent.1726