Schlagwort-Archive: OpenSSH Secure Shell

OpenSSH Secure Shell provides a large suite of secure tunneling capabilities, several authentication methods, and sophisticated configuration options.

SSH Tunnel Reverse Port forwarding

VPN Tunnel mit SSH Port Weiterleitung

SSH ist bei Linux von Beginn an dabei, auch Apple hat Secure Shell in macOS integriert, und Microsoft verpasste ebenfalls OpenSSH unter Windows 10 ab 1803 und Server 2019 als optio­nales Feature. Dazu gibt es SSH-Tunnel und SSH Port forwarding von den seit geraumer Zeit bekannten Tools wie PuTTY und KiTTY. Warum also SSH nicht auch als VPN Tunnel nutzen, dabei stehen nützliche Möglichkeiten für den Einsatz zur Verfügung, beispielsweise wenn ein VPN Tunnel nicht an der Firewall terminiert werden soll, oder wenn in Unternehmensnetzwerke zusätzliche Software nicht installiert werden kann, oder die rechte dazu fehlen. Ein SSH Reverse Tunnel ist immer dann hilfreich, wenn es Zugriff auf ein Remote Computer geben soll, dieser hinter einer Firewall steht.

Anwendung von SSH als VPN Tunnel und Port forwarding mit OpenSSH auf Linux, macOS und Windows

SSH Tunnel zu Remote Host B

Bei diesem Beispiel wird ein Tunnel von Host A zu Host B aufgebaut, Host B ist ein Webserver von diesem die Intranet Seite http://192.168.111.10 auf Host A geöffnet werden soll. Die einzige voraussetzung ist dabei, das es beim Router ein NAT Mapping über Port 22 zu Host B gibt, und das SSH auf jedem Host vorhanden ist.

Abbildung: ssh tunnel host A to host B

Das Command im Linux Terminal auf Host A wie folgt ausführen:

$ ssh -NT -L 80:192.168.111.10:80 cherry@172.17.16.15 -p 45680

Auf Host A kann nun die Webseite http://localhost geöffnet werden. Der SSH Tunnel macht die Weiterleitung über TCP Port 80 auf Host B von 192.168.111.10 zum localhost 127.0.0.1 auf Host A, der externe Port ist 45680. Bei Host B authentifizieren wir mit Benutzer cherry.

Die Bedeutung der Parameter:
-L = Lokaler Port.
-N = kein Remote Command ausführen.
-p = Externer SSH Port (NAT Port bei Firewall).
-T = kein Terminal öffnen.

Auf dem Host B muss der SSH Daemon konfiguriert und aktiviert sein, in der Konfigurationsdatei /etc/ssh/sshd_config sind folgende Einstellungen erforderlich, diese bei vielen Linux distributionen der Standard ist.

# Force SSH Protocol 2
Protocol 2

#Turn on Privileged Separation for security
UsePrivilegeSeparation yes

#Deny root login
PermitRootLogin no

#Do not allow empty passwords
PermitEmptyPasswords no

# installations will only check .ssh/authorized_keys
AuthorizedKeysFile      .ssh/authorized_keys

# Forward my X Sessions
X11Forwarding yes
X11DisplayOffset 10

# I hate Motd displays
PrintMotd no

# It's alliivee
TCPKeepAlive yes

#AllowTcpForwarding yes

  Die mit # auskommentierten Zeilen sind default Werte, zB. #AllowTcpForwarding ist per default yes.

Als SSH Server eignen sich viele Geräte, die auf Linux und FreeBSD OS laufen, so auch Synology NAS, FreeNAS, FreePBX Distro, OpenWrt, Raspberry Pi (Raspbian) und nun auch Windows Server, um nur einige zu nennen.

SSH Tunnel zu Remote Host C

In diesem Beispiel wird ein SSH Tunnel von Host A zu Host C aufgebaut, Host C ist ein RDS-Terminalserver, Host B dient als Port forwarder.

Abbildung: ssh tunnel host A to host C

Das Command im Linux Terminal auf Host A wie folgt ausführen:

$ ssh -NT -L 3389:192.168.111.10:3389 cherry@172.17.16.15 -p 43389

Die Remotedesktop Sitzung zu Host C wird über localhost auf Host A aufgebaut, durch drücken der Taste Win + R wird Ausführen geöffnet, dazu die Eingabe mstsc /v:localhost mit OK bestätigen.

 In diesem Beispiel wird der Standard TCP Port 3389 für RDP als interner sowie auch als externer Port verwendet. Es können alle unprivilegierte Ports (-L) höher als 1024 verwendet werden, kommt ein anderer Port als 3389 zur Anwendung, dann muss der Port zur ausführung an RDP übergeben werden, zB: mstsc /v:localhost:44389

Bei Host B muss der Kernel für IP forwarding aktiviert sein, das Command hierfür in der Shell als root ist:

$ net.ipv4.ip_forward = 1

Alternativ wird mit echo in der Shell Console das selbe bewirkt:

$ echo 1 > /proc/sys/net/ipv4/ip_forward

Den aktuellen IPv4 forward Status wie folgt abfragen:

$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Mit 1 wird die aktivierung bestätigt, 0 gilt für die deaktivierung. Die Änderung ist nicht Boot persistent, damit nach dem nächsten start das IP forwarding wieder aktiv ist, editiert man mit nano oder mit sudo vi /etc/sysctl.conf

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

Es empfiehlt sich zur Authentifizierung ein SSH Schlüssel zu verwenden, ein Schlüsselpaar kann wie folgt erzeugt werden:

$ ssh-keygen -f ~/.ssh/key_rsa -t rsa -b 4096

Den Public Key ~/.ssh/key_rsa.pub speichert man im Home Pfad des Benutzers, hier in diesem Beispiel auf dem Host B unter dem Pfad in der Datei ~/.ssh/authorized_keys, mehr dazu in diesem Artikel hier.

  Die Authentifizierung unter Verwendung von SSH Schlüssel ist nicht nur sicherer, es bieten sich weitere vorteile, Beispielweise wird der Anwender nicht aufgefordert ein Passwort eingeben zu müssen, auch lässt sich so der SSH Tunnel und weitere Commands aus einem Script ausführen.

SSH Tunnel unter macOS

Bei Apple macOS steht SSH erst nach der Aktivierung zur Verfügung, dies im Terminal wie folgt zur Ausführung kommt:

$ sudo systemsetup -setremotelogin on

Danach kann der SSH Tunnel unter macOS aufgebaut werden.

$ ssh -i ~/.ssh/key_rsa -NT -R 3389:192.168.111.11:3389 cherry@172.17.16.15 -p 43389

Mit dem Remote Desktop for Mac wird jetzt bei Gateway localhost eingetragen und die RDP Session aufgebaut, auf diese weise sind Terminalserver geschützt und nur über SSH erreichbar.

macOS bietet auch die möglichkeit zur automatisierung und nutzt dazu launchd und die launch system services, folgendes Script wird angelegt unter:
@/Library/LaunchDaemons/server.hostc.client.cherry.home.plist mit folgendem Inhalt:

<plist version="1.0">
   <dict>
   <key>Label</key>
   <string>server.hostc.client.cherry.home</string>
   <key>ProgramArguments</key>
   <array>
	  <string>ssh</string>
	  <string>-NTC</string>
	  <string>-o ServerAliveInterval=60</string>
	  <string>-o ExitOnForwardFailure=yes</string>
	  <string>-i</string>
	  <string>/Users/cherry/.ssh/key_rsa</string>
	  <string>-R 3389:192.168.111.11:3389</string>
	  <string>cherry@172.17.16.15</string>
          <string>-p 43389</string>
   </array>
   <key>UserName</key>
   <string>cherry</string>
   <key>RunAtLoad</key>
   <true>
   <key>KeepAlive</key>
   <true>
</true></true></dict>
</plist>

OpenSSH-Server Installation aus PowerShell

Bei Windows Server 2019 kann der OpenSSH-Server auch mit erhöhten Rechte aus der PowerShell als Administrator bereitgestellt werden.

PS C:\> Get-WindowsCapability -Online | ? name -like *OpenSSH.Server* | Add-WindowsCapability -Online
  Bei Windows 10 ist der OpenSSH Client in den Einstellungen zu finden, unter Apps & Features – Optionale Features – OpenSSH-Client.

Schlüsselpaar mit SSH-KEYGEN

SSH-KEYGEN Schlüsselpaar Erstellung für SSH Public-Key-Authentifizierung

Die Public-Key-Authentifizierung, oder auch Asymmetrisches Kryptosystem genannt, ist eine Authentifizierungsmethode, die von OpenSSH und OpenSSL verwendet wird, um Benutzer mit Hilfe eines Schlüsselpaars, bestehend aus digitalen Signaturen, privatem und öffentlichem Schlüssel, an einem Server anzumelden. Ein solches mit SSH-KEYGEN generiertes Schlüsselpaar ist wesentlich schwerer zu kompromittieren als ein Kennwort.

OpenSSH RSA-Key mit SSH-KEYGEN generieren

Der einfachste Weg ein Schlüsselpaar im OpenSSH Format zu generieren, ist die Ausführung von ssh-keygen ohne Argumente in der Shell. In diesem Fall wird nach der Datei gefragt, in der die Schlüssel gespeichert werden sollen. Wie hier in diesem Beispiel:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:TZ+isKhohYE6wOcKuqWxElclsdZw4UxJwFtnB9txEC8 user@debian.localdomain
The key's randomart image is:
+---[RSA 3072]----+
|   .+.o...+o.    |
|    oOo.oo.+     |
|o   o=*o..E .    |
|oo oo. . o o .   |
|o =.  . S o o    |
|=..o   . . .     |
|+++   . .        |
|oO   . .         |
|B.... .          |
+----[SHA256]-----+

SSH-Schlüssel für die Benutzerauthentifizierung werden normalerweise in der Benutzerbasis unter dem Verzeichnis .ssh gespeichert.

Ein Schlüsselpaar generieren

Mit SSH-KEYGEN ein Schlüsselpaar mit der übergabe von Parameter generieren.

$ ssh-keygen -f ~/.ssh/key_rsa -t rsa -b 4096

Die SSH-KEYGEN Parameter haben folgende Bedeutung:
-f die Schlüsseldatei
-t der Algorithmus
-b die Schlüssellänge
Der längste Schlüssel ist 4096. Wird kein Algorithmus übergeben, ist der Standard ein RSA Key.

Bei der Frage nach der Passphrase für den privaten Schlüssel, kann eine Passphrase eingegeben werden, im übernächsten Abschnitt wird gezeigt, wie diese generiert werden kann, durch drücken der Eingabetaste, ohne eine Passphrase wird der Schlüssel ohne Passwortschutz erstellt.

Der Zweck der Passphrase besteht normalerweise darin, den Schlüssel zu schützen. Es handelt sich um einen zweiten Authentifizierungsfaktor. Dies macht die Schlüsseldatei ohne öffentlichen Schlüssel für Angreifer unbrauchbar. Es kommt nicht selten vor das Hacker nach Dateien von kompromittierten Systemen filtern, auch aus Backups und stillgelegter Hardware.

Passphrase (Passwort) generieren

Eine sichere Passphrase kann automatisch generiert werden, mit folgender Eingabe wird eine 32 Zeichen lange Passphrase erzeugt.

$ date +%s | sha256sum | base64 | head -c 32 ; echo

Auch kann OpenSSL genutzt werden, um mit dem eingebauten Zufallsgenerator (rand) eine Passphrase zu generieren, diese wie folgt ausgegeben wird.

$ openssl rand -base64 32

Zum privaten Schlüssel und die dazugehörende Passphrase dürfen nicht autorisierte kein Zugang haben, wird der private Schlüssel entwendet, muss ein neuer generiert werden, daraufhin der öffentliche Schlüssel ebenfalls ausgetauscht wird.

Öffentlicher Schlüssel erneut generieren

Geht nur der öffentliche Schlüssel verloren, zeigt folgende Eingabe wie der öffentliche Schlüssel mit der SSH-KEYGEN Option -y aus dem privaten OpenSSH Schlüssel wieder erzeugt werden kann, dazu wird die Passphrase benötigt.

$ ssh-keygen -y -f ~/.ssh/key_rsa > ~/.ssh/key_rsa.pub

Zu beachten ist, das am Ende der Datei key_rsa.pub der Kommentar (key comment) wieder hinzugefügt werden muss, nach einem Leerzeichen, wie in diesem Beispiel user@host.localdomain:

$ ssh-rsa AAAA...HPCQ== user@host.localdomain

  In key_rsa.pub an keiner weiteren stelle etwas verändern.

Soll die Passphrase entfernt werden, kann dies mit folgender Eingabe druchgeführt werden:

$ ssh-keygen -p -P old_passphrase -N "" -f ~/.ssh/key_rsa

Durch die leere Eingabe zwischen den Anführungszeichen wird keine neue Passphrase geschrieben, somit wird diese gelöscht.

Ein ECDSA-Key generieren

Als nächstes wird mit SSH-KEYGEN ein ECDSA Schlüsselpaar mit der Schlüssellänge 521 Bit erzeugt, und unter der Benutzerbasis ~/.ssh gespeichert. Gültige längen sind 256, 384 or 521 bits.

$ ssh-keygen -f ~/.ssh/key-ecdsa -t ecdsa -b 521

ECDSA ist ein neuer Algorithmus für digitale Signaturen, der von der US-Regierung unter Verwendung elliptischer Kurven standardisiert wurde. Es ist wahrscheinlich aktuell der beste Algorithmus. Die meisten SSH-Clients unterstützen heute ECDSA.

Im Verzeichnis Pfad ~/.ssh wurden nun zwei Dateien erstellt. Die Datei mit der Erweiterung .pub ist der öffentliche Schlüssel. Die Datei key-ecdsa in diesem Beispiel, ist der private Schlüssel und ist nur für den Besitzer lesbar.

-rw-------.  1 user user  801 20. Mai 20:33 key-ecdsa
-rw-r--r--.  1 user user  279 20. Mai 20:33 key-ecdsa.pub

Öffentlicher Schlüssel auf Server speichern

Der öffentliche Schlüssel key-ecdsa.pub als SHA2 Hash wird nun in der Datei authorized_keys auf dem Server im Home Verzeichnis des Benutzers unter .ssh gespeichert.

$ cat ~/.ssh/authorized_keys
ecdsa-sha2-nistp521 AAAAE2vjZHNhLXNoYTItbmlzdHA1MjEFASBIbml
zdHA1MjEAfACFBAHnx0uIYUprY7D7myKMf1H+6NjCIV9U2GhZ69/oRE546i
QsvqSnSBs6SyL2ekvSe2JO3WXkrQ4gGpdLr9+XcLxfbAD79Oc8Z/Gcpr8mN
uKabOc4V/Seyr6AQ3l2KC+k8Wp0SBWG2ZofN0QYsPND8yIUL8Y7bS+t2tH9
dhSmeVwnLHUQNoktbVPoVDHw== user@host.localdomain

Public-Key Transfer mit ssh-copy-id

Um die Authentifizierung mit öffentlichem Schlüssel zu verwenden, muss der öffentliche Schlüssel auf den Server kopiert und in der Datei authorized_keys gespeichert werden. Dies kann bequem mit dem Tool ssh-copy-id durchgeführt werden.

$ ssh-copy-id -i ~/.ssh/key-ecdsa user@host.foo.bar

Nun kann man sich am Server Anmelden ohne das ein Passwort eingegeben werden muss, auch für automatisierte Aufgaben und für Anmeldungen aus Scripts ist diese Methode geeignet.

$ ssh user@host.foo.bar
Last login: Mon May 20 21:53:46 2019 from 192.168.7.85

Bei der Fehlersuche kann der Verbose Modus hilfreich sein, dabei werden zahlreiche Debugging-Meldungen über den Fortschritt ausgegeben, wie Verbindungs-, Authentifizierungs- und Konfigurationsprobleme.

$ ssh -v user@host.foo.bar

  Mehrere -v Optionen erhöht die Ausführlichkeit, max. -vvv.

OpenSSH config

Hat man unterschiedliche Hosts und Schlüsselpaare, kann in der Datei config unter ~/.ssh dies definiert werden.

$ vi ~/.ssh/config
Host *.foo.bar
  User user
  Port 22
  HostKeyAlgorithms +ssh-rsa
  PubkeyAcceptedKeyTypes +ssh-rsa
  IdentityFile key-ecdsa

Host host.fooo.bar
  User user
  Port 22
  HostKeyAlgorithms +ssh-dss
  PubkeyAcceptedKeyTypes +ssh-dss
  IdentityFile id_dss