SSH (Secure Shell)
SSH bietet einen sicheren (da verschlüsselten) Zugang zu einem entfernten Rechner/Server. Es ist deshalb sicher weil die Verbindung mit starker Verschlüsselung gesichert wird und sich beide Partner ausweisen (Authentifizieren) müssen. Die Authentifizierung erfolgt typischerweise entweder durch Passwort oder mit public/private-Key (z.B. bei automatisierten Anmeldungen in Skripten wichtig) oder durch andere Authentifizierungsarten.
Somit kann weder mitgelesen werden, noch kann sich jemand (unbemerkt) in die Mitte setzen („Man-in-the-middle (MITM)-Attacke“)
und beiden Partner die Gegenseite vorspielen.
Mit SSH lassen sich Dateien austauschen (mit sftp, scp) und Tunnel für unverschlüsselte Protokolle einrichten. Die Daten können auf Wunsch komprimiert übertragen werden und man kann Bildschirminhalte grafischer Programme (vom X-Server des Servers) übertragen.
Syntax: Ein minimaler Aufruf folgt dem Schema
ssh SERVER
dabei ist die Angabe des Benutzers (-l Benutzer) optional, wenn keiner angegeben wurde, wird der aktuelle Benutzername genommen.
ssh -l Benutzer SERVER
Bei langen Befehlszeilen lässt sich Zeit durch vorher festgelegte Optionen in Konfigurationsdateien oder über Aliase sparen.
Dateiaustausch über SSH
Dateien austauschen:
sftp
eignet sich gut für einzelne und mehrere Dateien (Eingabe mget
)
- Für das übertragen kompletter verzeichnis-struktionen taugt der Befehl
sftp
leider nichts, dafür nimmt man scp:
download:
scp benutzer@entfernterRechner:/Verzeichnis/Datei /lokalesVerzeichnis/Datei
upload:
scp /lokalesVerzeichnis/Datei benutzer@entfernterRechner:/Verzeichnis/Datei
Mit der Option -r lassen sich rekursiv ganze Verzeichnisse übertragen.
SSH Portweiterleitung (forwarding)
Eine sehr nützliche Eigenschaft von SSH ist die Möglichkeit (unverschlüsselte) Protokolle durch den verschlüsselten SSH-Tunnel zu schicken („tunneln“).
ssh user@remote.host -L 8080:127.0.0.1:80 -N -g
Dafür gibt man den lokalen Port an (hier 8080) und nach dem Doppelpunkt die Adresse an die es geleitet werden soll (hier wird „127.0.0.1:80“ als Ziel angegeben, d.h. der localhost (127.0.0.1) auf dem Port 80, also der entfernte Rechner selbst). Der Parameter „-g“ besagt das der Port auf allen Netzwerkschnittstellen geöffnet werden soll, „-N“ verbietet die Ausführung von Befehlen auf dem Zielrechner, was nur beim reinen tunneln sinnvoll ist.
Manche Programm (wie Vinagre siehe Screenshot) bieten dies als Funktion an.
SSH VPN
X-Server über SSH
Programmfenster grafischer (X-)Programme können auch über SSH übertragen werden. Dazu ruft man ssh zusätzlich mit der Option -X
auf.
Also normalerweise
ssh -X SERVER
oder mit slogin:
slogin -X SERVER
Die Variable wird dann auf dem Host gleich korrekt gesetzt. In der SSH-Konfiguration muss X11Forwarding aktiviert sein (standard).
X11Forwarding yes X11DisplayOffset 10
X11DisplayOffset
sorgt für ausreichenden Abstand zu bereits existierenden Displays.
Auf dem Server dessen grafisches Programm übertragen werden soll müssen einige Bibliotheken des Xserver installiert sein. Bei Debian6 war nach der Installation von xinit
war alles nötige vorhanden, wahrscheinlich reichen aber weniger Paket (xserver-xorg-core
oder evtl. noch xserver-xorg
dazu).
Links
- autossh: vermeidet „hängende“ Tunnel durch Testschleife und neuverbinden bei Abbruch.
SSH Client- und Serversoftware
*nix-kompatible
Clients
- OpenSSH-Client
- Kssh: KDE-Frontend
- lsh-client
- putty für X
- secpanel
Server
- OpenSSH-Server: Der Standard-Server
- lsh-server
- dropbear: Ressourcenschonend, z. B. für embedded-Systeme
SSH unter Windows
- Powershell einstellen das er sich passphrase merkt:
Clients
- Windows 10
- Version 0.0.1.0
/dism /online /Add-Capability /CapabilityName:OpenSSH.Client~~~~0.0.1.0
- aktuelle Version finden
/dism /online /Get-Capabilities | findstr /i openssh
- bitvise SSH client - kostenlos für privaten Gebrauch oder max. 4 Installationen pro Umgebung - kann SSH + Dateiübertragung + pageant benutzen
- swish - SFTP Integration in den Windows Explorer (alpha)
- SmartFTP Pro (kommerziell)
- privateshell (kommerziell)
Server
- Cygwin bzw. der Cygwin live-CD
- bitvise SSH Server (kostet nach 30 Tagen)
- OpenSSH for Windows - wird aktuell nicht gepflegt, letzte verfügbare Version ist 3.81p1-1 vom 9 Juli 2004!
Befehle von Windows aus unter Linux ausführen
- putty key generator → „generate“ oder „load existing private key file“
- „load existing private key file“:
- Dateipfad angeben
- als ppk-Datei speichern
- Key im Zielsystem hinterlegen:
- interaktiv mit winscp einloggen
- Verzeichnis /root/.ssh anlegen
- den öffentlichen Schlüssel simpel umbenannt als „authorized_keys“ in diesem Verzeichnis ablegen
- in der Batchdatei alle Systeme mit jeweils einem Befehl eintragen:
- Kommando 1):
plink.exe -ssh -2 -P 22 -i ssh_key.ppk root@1.2.3.4 halt
Authentifizierungsarten
Zum besseren Verständnis vorher die Authentifizierung des Servers:
Oft bekommt man beim (ersten) verbinden auf einen Server folgende Meldung:
user@hostname:~$ ssh -l root host.de The authenticity of host 'host.de (123.123.123.123)' can't be established. RSA key fingerprint is 06:1f:f0:9e:76:b1:4e:9e:8f:5f:29:11:56:71:5e:9e. Are you sure you want to continue connecting (yes/no)?
Das bedeutet, dass er den Host bisher (unter dieser IP) nicht kennt und nicht gewähleistet werden kann, das dies auch wirklich der Server ist, zu dem man wollte. Daher sollte man nur in (gut) geschützten Netzwerken „yes“ eingeben, es sei denn man kann den Fingerabdruck („RSA key fingerprint“) eindeutig als den richtigen erkennen (durch Vergleich mit dem vorher notierten).
Wenn man „yes“ eingibt kommt folgende Meldung:
Warning: Permanently added 'host.de,123.123.123.123' (RSA) to the list of known hosts.
D.h. er fragt in Zukunft nicht mehr, da er in einer Liste von bekannten Server (in der Datei ~/.ssh/known_hosts
) gespeichert hat. In Zukunft wird nur noch nach dem Passwort gefragt.
Bei Änderungen des Schlüssels auf dem Server (oder schlimmer: wenn ein Angreifer so tut als ob er der Server ist) wird der Verbindungsaufbau verweigert:
$ ssh SERVER @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: POSSIBLE DNS SPOOFING DETECTED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The RSA host key for SERVER has changed, and the key for the according IP address SERVER-IP is unknown. This could either mean that DNS SPOOFING is happening or the IP address for the host and its host key have changed at the same time. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ 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 the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is 01:12:34:56:78:90:12:12:34:56:78:90:12:34:56:78. Please contact your system administrator. Add correct host key in /home/USER/.ssh/known_hosts to get rid of this message. Offending key in /home/USER/.ssh/known_hosts:4 RSA host key for SERVER has changed and you have requested strict checking. Host key verification failed.
Wenn man sicher ist, dass die Änderung rechtens ist (z.B. weil man sie selber veranlasst hat ), löscht man aus seiner .ssh/known_hosts die angegebene Zeile (hier im Beispiel die 4. Zeile) heraus. Am einfachsten geht dies mit Editor der Wahl, die meisten unterstützen eine Option +ZEILENNR. Mit vim würde der Aufruf also
vim +4 ~/.ssh/known_hosts
lauten.
Die verantwortliche Option StrictHostKeyChecking
steht im Standardfall auf ask (Benutzer bei unbekannten Schlüsseln fragen, bei geänderten Schlüsseln abbrechen) kann jedoch auch auf yes
(keine neuen Schlüssel werden in die known_hosts
hinzugefügt) oder no
(alle neuen Schlüssel hinzufügen) gesetzt werden.
Passwortauthentifizierung
Es ist das Standardverhalten.
Der Server authentifiziert sich über seinen „Fingerabdruck“ der Client mit seinem (gültigen) Passwort.
Public-Key-Authentifizierung
Was aber wenn ich nicht ständig mein Passwort (wenn auch verschlüsselt) durch das Netz schicken will?
Das Konzept in Kurzform: Der Benutzer erzeugt ein Schlüsselpaar (einen öffentlichen, einen privaten Schlüssel). Diese Schlüssel werden auf dem lokalen Rechner gespeichert.
Auf dem entfernten Rechner, bei dem man sich einloggen will, speichert man den öffentlichen Schlüssel. Möchte man sich nun auf dem entfernten Rechner anmelden, sendet der entfernte Rechner eine, mit dem öffentlichen Schlüssel verschlüsselte Zufallszahl, welche der lokale Rechner mit dem privaten Schlüssel (und evtl Passwortabfrage für diesen) entschlüsselt. Die entschlüsselte Zahl wird zurück an den entfernten Rechner gesendet, welcher nun (wenn die Zahlen übereinstimmen) den Benutzer „Authentifiziert“ hat. Dabei wurde weder der öffentliche noch der private Schlüssel über das Netz geschickt, lediglich eine Zufallszahl.
Der entfernte Rechner authentifiziert sich auch selbst: gleiches Prinzip - öffentlicher Schlüssel bei uns, privater Schlüssel auf entferntem Rechner.
Die Einstellung PubkeyAuthentication
regelt ob Public-Key-Authentifizierung erlaubt ist (Standardwert ist yes
).
Der Client kann übrigens mit der Einstellung „IdentityFile“ auch einen abweichenden Schlüssel für einen bestimmten Server angeben:
Host server.tld IdentityFile ~/.ssh/other-key.id_rsa
Achtung: da kein Passwort abgefragt wird, muss man sicher gehen, dass keiner der privaten Schlüssel in fremde Hände fällt. Außerdem sollte eine Passphrase für den privaten Schlüssel vergeben werden.
Vorgehensweise
ssh-copy-id
Das Werkzeug ssh-copy-id nimmt alle Schritte (vom Client aus) automatisch vor.
- man legt ggf. einen eigenen Benutzer an
- Ed25519
ssh-keygen -t ecdsa
oder RSA-Schlüssel erzeugen (für alten OpenSSH-Versionen vor 6.5; dsa-keys sind unsicher; Standard sind 2048 Bit, hier auf 4096 Bit erhöht)
ssh-keygen -t rsa -b 4096
. Ausgabe:
ssh-keygen -t rsa -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (/home/USER/.ssh/id_rsa): id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa. Your public key has been saved in id_rsa.pub. The key fingerprint is: SHA256:hspFtyqTQd0VdPwMpgIa/FVHResMIZBJG/VgNHYi3hk freier-Kommentar-z.B.-e-Mail-oder-USER@HOST The key's randomart image is: +---[RSA 4096]----+ | .+.o. ++| | . .o+o. = +| | . ..oo+ + = | | . .. oo+o o .| | o .S oo.. *.| | =oo o = o| | +.* + E| | ..o * | | .+++ | +----[SHA256]-----+
id_rsa
ist der private Schlüssel undid_rsa.pub
ist der öffentliche Schlüssel. - nun kopieren wir den/die Schlüssel auf den Server: man ruft
ssh-copy-id -i ~/.ssh/id_rsa.pub user@clientHOST
Ohne Angabe von -i nimmt
ssh-copy-id
die Existenz von~/.ssh/identity.pub
an und versucht diesen öffentlichen Schlüssel zu übertragen.
manuell
- Auf dem Host
- man legt ggf. einen eigenen Benutzer an
- man ruft
ssh-keygen -d
auf, bei neueren Versionen anders (Debian Wheezy):ssh-keygen -t dsa
bzw.
ssh-keygen -t rsa -b 2048
. Ausgabe:
$ ssh-keygen -d Generating public/private dsa key pair. Enter file in which to save the key (/home/USER/.ssh/id_dsa): Created directory '/home/USER/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/USER/.ssh/id_dsa. Your public key has been saved in /home/USER/.ssh/id_dsa.pub. The key fingerprint is: 01:23:45:67:89:01:23:45:67:89:01:23:45:67:89:01 USER@HOST
id_dsa
ist der private Schlüssel undid_dsa.pub
ist der öffentliche Schlüssel. - man kopiert
/home/USER/.ssh/id_dsa
und/home/USER/.ssh/id_dsa.pub
auf die Clients
- auf den Clients:
- den öffentlichen Schlüssel an die authorized_keys anhängen:
cat id_dsa.pub >> ~/.ssh/authorized_keys
Das Verzeichnis ~/.ssh und die Datei ~/.ssh/authorized_keys darf nicht von der Gruppe des Benutzers beschrieben werden können. Sonst scheitert die Authentifizierung wenn der SSH-Dienst des Servers StrictModes
konfiguriert hat.
Heise Netze beschreibt das in dem Artikel SSH absichern gut.
Konvertierung von SSH2 zu OpenSSH Format
---- BEGIN SSH2 PUBLIC KEY ---- Comment: "Kommentar" AAAAB3NzaC1yc2EAAAABJQAAAIBmhLUTJiP[und so weiter]== ---- END SSH2 PUBLIC KEY ----
zu
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAqof[und so weiter
Das erledigt dieser folgende Befehl: ssh-keygen -i -f $Dateiname
Pubkey aus private Key erzeugen
Falls der pubkey nicht vorliegt:
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
ForwardAgent / ProxyCommand
Im Normlfall meldet man sich direkt an einem Server mit seinem SSH-Schlüssel an. Manchmal sind jedoch interne Server nicht direkt erreichbar sondern müssen über einen Gateway/Jumphost-Server erreicht werden.
Für diesen Fall ist der ForwardAgent gedacht, er kann global bzw. besser für bestimmte Hosts aktiviert werden:
Host jumphost.domain.tld
ForwardAgent yes
Diese Methode hat jedoch einen gravierenden Sicherheitsnachteil: Während die Sitzung läuft kann vom Jumphost auf den Zielserver zugegriffen werden (in dem Sicherheitskontext wie auch der Schlüssel gilt). Somit sollte diese Funktion maximal auf/über vertrauenswürdigen Server(n) benutzt werden.
Das Risiko ist jedoch gar nicht nötig, mit ProxyCommand lässt sich eine vergleichbare Funktionalität ohne Abstriche bei der Sicherheit bewerkstelligen.
Host jumphost Hostname jumphost.domain.tld Host intern Hostname intern.domain.tld Port 2222 ProxyCommand ssh -W %h:%p jumphost.domain.tld
Somit ist nun intern.domain.tld mittels pubkey über den jumphost erreichbar
ssh intern
Hostbased
Die Authentifizierung erfolgt anhand des Hostnamens und dem Benutzer, i. d. R. ohne weitere Passwortabfrage.
Keyboard-Interactive
incl. PAM
Kerberos/GSSAPI
Die Authentifizierung wird durch ein Kerberos-Ticket wahlweise stattdessen oder zusätzlich durch andere Methoden wie Systempasswort. Ab Version 3.7 wird Kerberos v4 nicht mehr unterstützt.
Smartcards
Man kann die privaten Schlüssel auf Smartcards speichern. OpenSSH unterstützt Cyberflex-Smartcards sowie PKCS#15 unter OpenSC.
Konfiguration
Bei OpenSSH werden Einstellungen
- für den (openssh-) Server: In der Datei
/etc/ssh/sshd_config
- für (openssh-) Client: Systemweit in den Dateien
/etc/ssh/ssh_config
oder Benutzerspezifisch in~/.ssh/config
vorgenommen.
Dokumentation findet sich auch mit dem Befehl
man 5 ssh_config
wichtige Dateien von SSH
Die folgenden Dateien werden von SSH (und darauf basierenden Programmen wie scp) benutzt.
Systemweite Einstellungen | |
---|---|
Pfad | Funktion |
/etc/ssh/ssh_known_hosts | enthält eine Liste von Schlüsseln bekannter Rechner. Wird nicht automatisch erweitert. |
/etc/ssh/ssh_config | Systemweite Einstellungen des SSH-Clients |
/etc/ssh/sshd_config | Systemweite Einstellungen des SSH-Servers |
/etc/ssh/sshrc | Der Inhalt der Datei wird nach der Authentifizierung aber vor der Shell (oder dem Befehl) ausgeführt. |
/etc/ssh/ssh_host_dsa_key / ssh_host_dsa_key.pub | DSA-keys für den SSH-Server |
/etc/ssh/ssh_host_rsa_key | RSA-keys für den SSH-Server |
/etc/ssh/ssh_host_ecdsa_key ssh_host_rsa_key.pub | ECDSA-keys für den SSH-Server |
Benutzerspezifische Einstellungen | ||
---|---|---|
Pfad | Funktion | |
~/.ssh/authorized_keys | Liste aller öffentlichen Schlüssel die für eine public-key-Authentizierung benutzt werden können | |
~/.ssh/config | optional: Legt Einstellungen für entfernte Hosts fest | |
~/.ssh/known_hosts | enthält eine Liste von Schlüsseln bekannter Rechner. Wird automatisch durch den Benutzer erweitert. | |
~/.hushlogin | Bei Existenz wird die Ausgabe der letzten Login-Zeit und der Message-of-the-day (motd) unterdrückt. | |
~/.ssh/rc | wie /etc/ssh/sshrc aber nur für diesen Benutzer | |
~/.ssh/environment | Zusätzliche Umgebungsvariablen die beim Einloggen definiert werden. |
Schlüssel der Benutzer | |
---|---|
private Schlüssel | SSH-Version |
~/.ssh/identity | Version 1 RSA |
~/.ssh/id-dsa | Version 2 DSA |
~/.ssh/id_rsa | Version 2 RSA |
Die privaten Schlüssel dürfen nur vom Benutzer lesbar sein, sonst werden diese ignoriert.
öffentliche Schlüssel | |
---|---|
~/.ssh/identity.pub | Version 1 RSA |
~/.ssh/id_dsa.pub | Version 2 DSA |
~/.ssh/id_rsa.pub | Version 2 RSA |
rhost-Authentifizierung (veraltet, unsicher) | |
---|---|
/etc/hosts.equiv | enthält Rechnernamen |
/etc/ssh/shosts.equiv | enthält Rechnernamen, nicht für rlogin/rsh-Zugang |
~/.rhosts | enthält Rechnernamen / Benutzer, darf nicht für andere lesbar sein |
~/.shosts | wie /etc/ssh/shosts.equiv nur benutzerspezifisch |
Anmerkung: ~ steht für das Homeverzeichnis.
SSH-Keys für den SSH-Dienst neu erzeugen
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key /etc/init.d/ssh restart
SSH-Passphrase hinzufügen / ändern
Der private Schlüssel sollte mit einem Passwort bzw. einer Passphrase geschützt werden.
Überprüfen ob Passphrase gesetzt (wenn ja, dann Fehlermeldung „incorrect passphrase supplied to decrypt private key“): ssh-keygen -y -P „“ -f ~/.ssh/id_rsa
Änderungen der Passphrase geht einfach mit ssh-keygen
:
ssh-keygen -f ~/.ssh/id_dsa -p
bzw. bei einem RSA-Schlüssel:
ssh-keygen -f ~/.ssh/id_rsa -p
pkcs#8-Schutz aktivieren:
openssl pkcs8 -topk8 -v2 des3 -in ~/.ssh/id_rsa.old -out ~/.ssh/id_rsa
SSH-Passphrase entfernen
RSA:
openssl rsa -in ~/.ssh/id_rsa -out private_key_without_pass_phrase
ECDSA: ? ED25519:?
Verbindungsabbrüche verhindern
Bei häufigen Verbindungsabbrüchen kann man ClientAliveInterval (seit OpenSSH 3.8 auch ServerAliveInterval) statt TCPKeepAlive setzen. Das standardmäßige „TCPKeepAlive yes
“ verursacht Abbrüche auch bei kurzen Unterbrechungen (und kann sowieso von einem Angreifer gefälscht werden) während ClientAliveInterval
innerhalb von (hier) 180 Sekunden eine kryptografisch kodierte Antwort von Client erwartet bevor die Verbindung abgebrochen wird.
Server-config (systemweit: /etc/ssh/sshd_config
):
TCPKeepAlive no ClientAliveInterval 180
Client-config (systemweit: /etc/ssh/ssh_config
)
TCPKeepAlive no ServerAliveInterval 180
Anmerkung: ServerAliveInterval ist seit OpenSSH 3.8 dabei.
Einstellungen lokal abspeichern
Lange Parameterlisten kann man vermeiden indem man in Konfigurationsdateien Einstellungen hinterlegt. Diese werden Systemweit in den Dateien /etc/ssh/ssh_config
oder Benutzerspezifisch in ~/.ssh/config
vorgenommen.
Host *.domain.de Port 12345 User ich Compression yes ForwardX11 yes
Somit reicht der Aufruf von ssh subdomain.domain.de ohne die o.g. Einstellungen noch extra zu übergeben.
Auch Hostname+Domain kann man schon vorgeben, somit verkürzt sich die Kommandozeile auf ssh RECHNER
:
host RECHNER Hostname die.richtige.URL.de
Rechner mit externen Tools verwalten
Alternativ zur Konfiguration der einzelnen Hosts kann man spezialisierte Tools benutzen. Dann wird der Aufruf über „TOOLNAME Hostalias“ erfolgen, also etwa
sshmgr Rechner1
SSH absichern
Als Minimum würde ich die folgenden Einstellungen in der Datei /etc/ssh/sshd_config
vornehmen:
- nur Protokollversion 2 benutzen
Protocol 2
- keine root-logins zulassen (Administration wird ausschließlich über normale Benutzer vorgenommen und dann fallweise per sudo oder bei Bedarf permanent (su) auf root-Rechte wechseln. Dazu muss ein Eintrag in der Datei
/etc/sudoers
angelegt werden (mit dem Befehlvisudo
):Benutzer1 ALL=(ALL) ALL
Es kann auch die Berechtigung für einzelne Aufgaben vergeben werden (zur Not auch ohne Passworteingabe)):
PermitRootLogin no
in der
/etc/ssh/sshd_config
anschließendsystemctl reload sshd
- oder nur pubkey:
PermitRootLogin without-password
- Warnmeldung + logout via /root/.ssh/authorized_keys:
command="echo 'Please login as the user \"debian\" rather than the user \"root\".';echo;sleep 10;exit 142" ssh-rsa some-key text
- Distributionsbanner abschalten (Beispiel: SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.10 Version wird immer noch angezeigt, dafür gibt es keine Option):
- Ubuntu:
DebianBanner no
- RHEL:
Banner none
- nur bestimmten Benutzern den Login erlauben:
AllowUsers Benutzer1 Benutzer2
- nur bestimmten Gruppen den Login erlauben:
AllowGroups Gruppe1 Gruppe2
- bestimmten Benutzern den Login verbieten:
DenyUsers Benutzer1 Benutzer2
- maximale Anzahl der Loginversuche begrenzen: Nur 3 Versuche (pro Verbindung) zulassen
MaxAuthTries 3
verwendeten Pubkey loggen
Vorbereitung: in der Datei authorized_keys pro Schlüssel einen Variable definieren, Beispielformat
environment="SSH_USER=Admin1" ssh-rsa $Pubkey_Admin1 $Kommentar
In der Datei /etc/ssh/sshrc
können Befehle definiert werden (hier Logging des Benutzers nach syslog) die bei jedem SSH-Login ausgeführt werden:
#!/bin/bash if [ "$SSH_USER" = "" ]; then logger -pauth.info "Login by unknown user as \"$USER\". \$SSH_CLIENT=$SSH_CLIENT." else logger -pauth.info "Login by \"$SSH_USER\" as \"$USER\". \$SSH_CLIENT=$SSH_CLIENT." fi
chroot SSH
Wer ganz sicher gehen will, sperrt SSH in einen Käfig (chroot von change root). Damit kann der eingesperrte Benutzer nur innerhalb seiner Ordner navigieren. Allerdings bietet bisher keine Distribution diese Funktionen von Haus aus an, also muss man selber eine gepatchte Version kompilieren und installieren.
Port-Knocking
Durch port knocking (Senden eines speziellen Pakets, erst dann wird der Port freigeschaltet) ist man vor unbekannten Sicherheitslücken (0-Day Exploits) in SSH und vor Portscans geschützt.
Brute-force-Attacken auf SSH
Wenn man SSH auf den Standard-Port betreibt, sieht man in den Log-Dateien eine Vielzahl von (fehlgeschlagenen) Login-Versuchen. Meist werden Standardbenutzer wie root und Standardpasswörter probiert.
Zur Abwehr kann man Log-Based Intrusion Detection systems (LIDS) (wie denyhosts oder fail2ban) benutzen, die z.B. ab einer einstellbaren Anzahl von Fehlversuchen den angreifenden Rechner (temporär) sperren.
Sauberer ist meist eine spezielle Firewallregel. Damit spart man sich die möglichen Sicherheitslücken durch das parsen der Log-Dateien die die Tools zwangsläufig durchführen müssen. Der Programmcode der im Bereich des Kernels angesiedelten Firewalls ist besser auf Sicherheitslücken überprüft.
Evtl. ist es sinnvoll auf einen hohen Port wechseln (wenn das für die Benutzer ok ist, hier im Beispiel auf 54321):
Port 54321
Authentifizierung nur per Public-key
Authentifizierung per Passwort abschalten? Dann aber vorher den pub-key generieren + auf den SSH-Server kopieren (ssh-copy)!
echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config echo "PasswordAuthentication no" >> /etc/ssh/sshd_config /etc/init.t/sshd reload
SSH-Sitzungen auf Befehle und Hosts einschränken
Die Datei .ssh/authorized_keys
lässt sich dazu benutzen:
- Den Login auf eine IP oder einen DNS-Namen zu begrenzen (hier backup.server.tld mit „from=“)
- Benutzer auf bestimmte Befehle festzulegen (hier den Befehl date mit command=date). Durch die Variable $SSH_ORIGINAL_COMMAND könnte ein Skript den ursprünglich übergebenen Befehl auswerten.
from="backup.server.tld",command="date" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIs8XjTqbVGSYQ84aEeBtsg+8p80ndQOP7aSJikLKH3cYMPV/pklGB8s7K9ZrlpVkYJR+ZHnG7xbNqwjiGR4JzW2ugOeisYyDXjDDvFKkgaqHVc8yln4LA9rYbPg/g7VaDGilCMAsXISJ6K6CwrrJbqA1BYHnth56Onait7e5bK4qdUuCcUsgwkNg/gwTcL6C6UZa1cojk/al4+EBbOnqWM8boXyGxxitUb+94LiXs8XXOLz11Q+abFtc9OE/AJMJ1I51TAfz03i4sNMUxRbLacb5LmgJtf0e8mk2gAFPqQ8XkU6rAzGR/3h3bhVwQrpsicje0kbUyQZBog8JgIGkIwEwJOlspHbMTLnhxsxvIymhuEQOi4MkT1c5C0cYimDxDS9fOePdnebgUH+bnWEQcTr6NMY5RTQX0CG8WCK2VlMRXCYKnt2ne5FXmTkqY4X/06lWKSh++bdvzEO96W7Tp2n84s/Py7m5NwQYt6NMy9kMNwjMxXVJUZQv43k6hg3frx7qlyPPhxWUzMYvRcc1sRQhu//uO/Zq305n5pJxUXAUuU3X6OSGX4mc/R9qjcw6yKHfxLbLM4n2wgdTAdthrWz1zkFvw1kceW5yrkIckHdv1Q7WL9zPYOO44g8FR7zqpbJsgKhFVZJ7EEw7AnfSotzgjPUMr3iSOrM1YfHBt8w== Kommentar
upload-Benutzer auf SFTP beschränken
addgroup sftponly → Benutzer zur Gruppe hinzufügen
SSHD-Config:
Subsystem sftp internal-sftp Match Group sftponly ChrootDirectory ~ ForceCommand internal-sftp -l INFO AllowTcpForwarding no
Ergebnis:
ssh webuser@HOST
this service allows sftp connections only.
#!/bin/sh # # erstellt einen sftponly-Benutzer, # $home darf nicht vom Benutzer beschreibbar sein (wg. chroot), Unterordner schon! # if [ -z $1 ]; then echo "Fehler: Parameter leer, Benutzung: $0 [neuer-Benutzername]" exit 1 fi if [ "`id -u`" -ne 0 ]; then echo "Fehler: Skript bitte mit root-Rechten aufrufen (sudo $0)" fi user="$1" home="/srv/sftp/$user" if [ -d "$home" ]; then echo "Ordner $home existiert bereits, breche ab." exit 1 fi useradd -d "$home" -G sftponly -s /bin/false "$user" # adduser --home "$home" --ingroup sftponly --shell /bin/false "$user" if [ $? -ne 0 ] ; then echo "Fehler: Konnte Benutzer $user nicht anlegen." exit 1 fi if [ ! -d "$home" ]; then mkdir "$home" if [ $? -ne 0 ]; then echo "Fehler: konnte $home nicht anlegen, breche ab." exit 1 fi fi chown root "$home" chgrp "$user" "$home" chmod 750 "$home" # ssh: ssh_config_dir="$home"/.ssh ssh_authorized_keys="$ssh_config_dir"/authorized_keys ssh_austausch_dir="$home"/austausch mkdir "$ssh_config_dir" chown root "$ssh_config_dir" chgrp "$user" "$ssh_config_dir" chmod 750 "$ssh_config_dir" # Sonderanforderung: der Benutzer soll die Liste der pub-keys nicht verändern dürfen (ggf. streichen) touch "$ssh_authorized_keys" chmod 640 "$ssh_authorized_keys" chown root "$ssh_authorized_keys" chgrp "$user" "$ssh_authorized_keys" echo "SSH-Pubkeys Bitte in die Datei $home/.ssh/authorized_keys ablegen." # austausch-Ordner mkdir "$ssh_austausch_dir" chmod 750 "$ssh_austausch_dir" chown "$user" "$ssh_austausch_dir" chgrp "$user" "$ssh_austausch_dir" chmod g+w "$ssh_austausch_dir"
SFTP-Benutzung
einzelne Datei:
- download: sftp {user}@{host}:{remoteFileName} {localFileName}
- upload: sftp {user}@{host}:{remote_dir} «< $'put {local_file_path}'
https://stackoverflow.com/questions/16721891/single-line-sftp-from-terminal https://www.tecmint.com/sftp-upload-download-directory-in-linux/
schnellerer Verbindungsaufbau (ControlMaster)
OpenSSH ab Version 4.0 enthält ein neues Feature: ControlMaster. Damit geht der Verbindungsaufbau bei mehrfachen Verbindungen deutlich schneller weil die aktuell existierende Verbindung erneut benutzt wird.
DSA-keys erlauben
OpenSSH 7.0 deaktivert dsa-Schlüssel standardmäßig (weil diese unsicher sind 2):
PubkeyAcceptedKeyTypes=+ssh-dss
spezielle Anwendungen
sshfs
Mit SSHFS steht unter Linux (und Windows) ein Userspace-Dateisystem basierend auf FUSE zur Verfügung. Damit kann man ganze Verzeichnisbäume in das lokale Dateisystem am sog. Mountpoint einhängen. Ab Kernelversion 2.6.14 gehört FUSE standardmäßig zum Kernel.
Links
mounten
sshfs ssh-konto@ssh-server:[PFAD] mount-point
Für den Befehl muss unter Ubuntu das Paket sshfs mit
apt-get install sshfs
installiert und evtl. mit
sudo modprobe fuse
das Kernelmodul für FUSE geladen werden.
Nützlich können sich die Optionen (Parameter -o) und dann die folgenden Schlüsselwörter:
reconnect
für das erneute Verbinden,- transform_symlinks und follow_symlinks verbessern das Verhalten bei Symlinks
uid=Zahl
undguid=Zahl
sowie diverse caching Einstellungen auswirken (siehe Befehlman sshfs
).
Beispielaufruf:
sshfs DATEISERVER:/srv /media/MOUNTPOINT -o reconnect,Ciphers="blowfish-cbc"
Ein permanenter Eintrag in der /etc/fstab erleichtert das mounten enorm:
sshfs#root@DATEISERVER:/srv MOUNTPOINT fuse user,noauto 0 0
Die oben genannten Optionen können hier ebenfalls angegeben werden 3):
sshfs#root@fDATEISERVER:/srv /media/MOUNTPOINT fuse user,noauto,reconnect,Ciphers="blowfish-cbc" 0 0
Anschließend reicht ein einfaches mount /media/MOUNTPOINT
für den Zugriff auf die Daten. Auch das unmounten ist jetzt einfacher: umount /media/MOUNTPOINT
.
unmount
fusermount -u mount-point
Beim Eintrag in der /etc/fstab reicht umount mount-point
.
Dateiübertragung über eine existierende SSH-Verbindung
Wenn man nicht eine zweite SSH-Verbindung aufbauen will (gerade bei Sprüngen über mehrere Systeme kann das nervig sein), braucht man zssh
. Das ist ein Programm, das sich um ssh „herumlegt“ (ein sog. „wrapper“) und Datenaustausch mittels zmodem-Protokoll bietet.
Man muss es nur auf der lokalen Computer installieren (apt-get install zssh
bei Debian/Ubuntu) und auf dem entfernten Rechner „lrzsz“.
Eventuell erzeugt man sich einen Alias in der ~/.bashrc
, neue Zeile mit:
alias ssh=zssh
damit wird bei der Eingabe von ssh
automatisch mit zssh
ersetzt. Dies ist für die Bash-Shell angegeben, aber nicht unbedingt nötig.
Auf dem verbundenen Rechner/Server muss man dann nur noch mit STRG-Leertaste in den interaktiven Modus gehen.
Um eine Datei zu senden gibt man
sz -e <Datei>
ein. Der Parameter „-e“ vermeidet Fehler bei fehlerhaften 8-Bit-Terminals.
SSH-Shells
SSH ist als sichere Variante zu ftp(s) beim Upload von Dateien nützlich. Dennoch muss man dafür dem Benutzer auch einen Login geben der es dem Benutzer emöglicht Programme und andere Tätigkeiten auszuführen die evtl. sicherheitskritisch sind. Spezielle Shells (technisch meist genauer „wrapper“) beschränken die Funktionalität von SSH.
Fingerprint nicht überprüfen
Bei der ersten Verbindung zu einem neuen SSH-Server fragt SSH nach ob der Fingerprint stimmt and speichert ihn in ~/.ssh/known_hosts
ab. Bei späteren Verbindungen kommt nur noch eine Nachfrage falls sich der Serverschlüssel geändert hat.
Wenn dies der Fall ist wird die Verbindung abgebrochen und der (fehlerhafte?) Eintrag muss aus der known_hosts gelöscht werden.
Ein geänderter Schlüssel hat diese Ursachen:
- Der SSH-dienst oder der Rechner wurde neu installiert ohne den alten Schlüssel zu übertragen
- der Schlüssel wurde ausgetauscht
- der DNS-Name zeigt nun auf einen anderen Rechner
- ein Angreifer (man-in-the-middle) versucht sich zwischen Server und Client zu schmuggeln
In manchen Fällen kann dies störend sein (häufig wechselnde Testsysteme) und der Sicherheitsverlust (kein Überprüfung des Servers!) mag nicht relevant sein.
Eine Umgehung des Sicherheitschecks ist einerseits durch StrictHostKeyChecking no und der Umstellung von UserKnownHostsFile auf /dev/null (was immer eine leere Antwort gibt) möglich:
Host 192.168.0.* StrictHostKeyChecking no UserKnownHostsFile=/dev/null
Für Produktivsysteme oder im Internet sind diese Einstellungen absolut nicht empfohlen, da damit ein grundlegender Sicherheitsmechanismus ausgehebelt wird. Ggf. sollte eher über eine Verteilung geänderter Fingerprints nachgedacht werden.
Fingerprint aktualisieren
Wer viele SSH-Server zu verwalten hat möchte man mit Automatisierungsprogrammen wie dsh nicht drüber gehen wenn bei jedem Aufruf erstmal gefragt wird ob der unbekannte SSH-Fingerprint vertrauenswürdig ist. Statt StrictHostKeyChecking abzuschalten könnte man sich auch vorher die aktuelle Liste der Fingerprint aktualisieren und damit spätere Nachfragen vermeiden. Das Programm ssh-keyscan erledigt diese Aufgabe komfortabel.
#!/bin/sh keytype="rsa,ecdsa,ed25519" # # keytype: specifies the type of the key to fetch from the scanned hosts. The possible values are “rsa1” for protocol version 1 and “dsa”, “ecdsa”, “ed25519”, or “rsa” for # protocol version 2. Multiple values may be specified by separating them with commas. The default is to fetch “rsa” and “ecdsa” key hostfile="alle-Server.txt" # kann natürlich auch per Variable gefüllt werden: # for h in $SERVER_LIST; do for h in $(cat "$hostfile"); do ip=$(dig +short $h) ssh-keyscan -t $keytype $ip >> ~/.ssh/known_hosts ssh-keyscan -t $keytype $h >> ~/.ssh/known_hosts done
noauto
sorgt dafür das nicht beim booten eingehängt wird, was bei einem unbeaufsichtigtem Server und Passwortabfrage schlecht wäre