SSH-Server
Siehe auch
Wichtige Eigenschaften von SSH:
Authentifizierung der Gegenstelle.
Die symmetrische Verschlüsselung der Datenübertragung mit sitzungsabhängigen Schlüsseln erschwert eine Entschlüsselung der Kommunikation durch Dritte massiv.
Manipulation der übertragenen Daten wird verhindert und ermöglicht Datenintegrität.
Änderungen an der Konfiguration des SSH-Servers sollten immer in einer zweiten SSH-Session getestet werden, um ein versehentliches Aussperren zu verhindern. In der ersten SSH-Session also Änderungen vornehmen und den SSH-Daemon neu starten, aber Test der Settings, Login, Logout usw. im zweiten Terminal vornehmen.
SSH-Server härten
Die folgenden Einstellungen lassen sich in der /etc/ssh/sshd_config
vornehmen, um die Sicherheit je nach Anforderung weiter zu erhöhen oder den SSH-Server anzupassen. Nach Änderung der Einstellungen muss der SSH-Server neu gestartet werden, was auch bei laufender SSH-Session funktioniert.
AllowTcpForwarding no # hindert Malware (aber auch alles andere) an Tunneling
ClientAliveCountMax 0 # keine KeepAlive-Messages senden
ClientAliveInterval 300 # 5 Minuten Idle-Timeout, danach Logout
HostbasedAuthentication no # .rhosts und /etc/hosts.equiv-Dateien abschalten (SSHv2)
IgnoreRhosts yes # .rhosts und .shosts-Dateien abschalten
LoginGraceTime 60 # Disconnect-Timeout nach erfolglosem Login
LogLevel VERBOSE # Logging erhöhen (Pflicht für Fail2ban)
MaxAuthTries 3 # Anzahl der erfolglosen Login-Versuche, bis der Server die Verbindung trennt, von 6 auf 2 reduzieren
MaxSessions 4 # wie der Name schon sagt...
MaxStartups 10:30:60 # Maximale Anzahl von Concurrent Unauthorized Connections (start:rate%:full)
PasswordAuthentication no # Anmeldung per Passwort abschalten
PermitEmptyPasswords no # keine leeren Passwörter zulassen
PermitRootLogin no # Login mit root-Rechten abschalten - Achtung, Ersatz-Benutzer sollte bereitstehen
PermitUserEnvironment no # das Setzen von Environment-Optionen (Pfaden etc.) durch Benutzer verhindern
Port 56669 # SSH-Port auf 56669 ändern (keine Sicherheit, aber reduziert die Anzahl der Brute-Force SSH-Loginversuche deutlich)
PubkeyAuthentication yes # Anmeldung per Zertifikat zulassen
UsePAM yes # PAM nutzen
X11Forwarding no # Tunneling von X11-Traffic per sshd-Forwarding verbieten
Wer den SSH-Port ändert, muss dies auch per SELinux erlauben:
yum -y install policycoreutils-python
dnf -y install policycoreutils-python-utils
semanage port --add --type ssh_port_t --proto tcp 56669
Änderungen an Verschlüsselungsoptionen wie Ciphers
, MACs
oder KexAlgorithms
empfehlen wir nicht. Stattdessen sollten hier die systemweite Crypto-Policies konfiguriert werden, die auch vom SSH-Daemon verwendet werden.
Siehe auch
Benutzerzugriff auf SSH steuern
- per TCP-Wrapper
Der Zugriff auf den SSH-Daemon lässt sich mittels
/etc/hosts.allow
und/etc/hosts.deny
steuern, den sogenannten TCP Wrappers-Dateien. Der Servicename zur Steuerung lautet hiersshd
. Soll der SSH-Service nur aus der Domänelinuxfabrik.ch
erreichbar sein, trägt man in der/etc/hosts.deny
ein:sshd:ALL EXCEPT .linuxfabrik.ch
Die Datei
/etc/hosts.allow
wird zuerst gelesen. Wird kein passender Match gefunden, kommt die/etc/hosts.deny
zur Anwendung. Wird wieder kein passender Match gefunden, wird der Zugriff gewährt. Die Dateien lassen sich auch einzeln entfernen.Weil es einfacher und sehr effektiv ist, empfehlen wir, nur die Allow-Liste zu pflegen und allen anderen in der Deny-Liste den Zugriff zu entziehen.
- per
/etc/sshd/sshd_config
AllowUsers root linus@host AllowGroups ... DenyUsers ... DenyGroups ...
- per
/etc/passwd
Um den Benutzer linus auszuschliessen, kann man diesem auf dem SSH-Host auch den Shell-Zugriff entziehen:
usermod --shell=/bin/false linus
Tipp
Es ist allgemein empfohlen, den SSH-Zugang für root abzuschalten (PermitRootLogin no
). In so einem Fall erstellt man sich einen Standard-Benutzer, packt diesen in die wheel-Gruppe, loggt sich mit diesem über SSH ein, arbeitet mit sudo
oder wechselt mit su -
in die root-Shell.
SFTP
Es gibt des öfteren die Anforderung, einen möglichst sicheren SFTP-Server aufzusetzen. Die SFTP-Benutzer sollen dabei ausschliesslich SSH-Keys verwenden, keine interaktive Shell per SSH öffnen und ihr SFTP-Verzeichnis auch nicht verlassen dürfen. Alle anderen SSH-Logins sollen von diesen Einschränkungen nicht betroffen sein. Aus Admin-Sicht soll das ganze möglichst auch ohne Zusatzsoftware wie VSFTP oder andere auskommen, sondern mit dem SSH-Daemon umgesetzt werden.
Geht. Zunächst sicherstellen, dass eine Authentifizierung mit Public-Keys möglich ist:
PubkeyAuthentication yes
Eine Benutzergruppe namens sftpusers anlegen:
groupadd sftpusers
Die einzelnen SFTP-Benutzer der Benutzergruppe sftpusers hinzufügen:
usermod --groups sftpusers linus
Die SSH Public-Keys der einzelnen SFTP-Benutzer in ihren jeweiligen Home-Verzeichnissen ablegen. Anschliessend:
chown linus:linus /home/linus/.ssh/authorized_keys
chmod 0600 /home/linus/.ssh/authorized_keys
Fehlt nur noch die Konfiguration des SSH-Daemon. Folgende Einstellungen ans Ende der /etc/ssh/sshd_config
packen und danach den SSH-Server neu starten:
Subsystem sftp internal-sftp
Match Group sftpusers
AllowTcpForwarding no
ChrootDirectory /home
ForceCommand internal-sftp
PasswordAuthentication no
X11Forwarding no
systemctl restart sshd
Das war es schon. Der Client kann sich jetzt verbinden:
sftp linus@host
sftp> pwd
sftp> ls
sftp> cd linus
Die wichtigsten SFTP-Kommandos…
- … direkt auf dem SFTP-Server:
pwd
: Aktuelles Verzeichnis ausgeben.mkdir
: Verzeichnis anlegen.cd
: Verzeichnis wechseln.get /path/to/local/file
: Lokale Datei auf den entfernten Client kopieren.put /path/to/remote/file
: Entfernte Datei auf den SFTP-Server kopieren.exit
: Verbindung beenden.
- … gegen den Client:
lpwd
: „local pwd“, aktuell genutztes Client-Verzeichnis ausgeben.lmkdir
: Client-Verzeichnis anlegen.lcd
: Client-Verzeichnis wechseln.
Die „local“-Varianten bedeuten also „Ausführung auf dem Client“. Alle anderen Kommandos werden auf dem SFTP-Server ausgefuehrt, wie bei SSH auch.
Siehe auch man sftp
.
Port-Foward-only User
Manchmal benötigt man einen User-Account, der nur Port-Forwarding verwenden darf, also keinen Shell-Zugriff haben soll. Dazu muss zuerst ein UNIX User erstellt werden. Der User
useradd portfwdonly
Und danach folgende SSH-Einstellungen gesetzt werden.
Match User portfwdonly
# deny all
AllowAgentForwarding no
AllowStreamLocalForwarding no
ForceCommand echo 'Port forwarding only account. Shell access is not allowed. Please use the "-N" option for ssh.'
PermitTTY no
PermitTunnel no
PermitUserRC no
X11Forwarding no
# allow explicitly
PermitOpen 127.0.0.1:3306 localhost:3306
Zu beachten ist, dass der User sowohl Port-Forwarding als auch Reverse Port-Forwarding mit den freigegebenen Ports verwenden darf.
Performance
Mit folgendem Skript lässt sich die Geschwindigkeit einiger SSH-Chiffren im Vergleich testen (benötigt einen passwort-losen SSH-Zugang auf den eigenen Host). Die Performance ist stark abhängig von der darunterliegenden / verwendeten Hardware:
#!/usr/bin/env bash
for i in $(ssh -Q cipher); \
do dd if=/dev/zero bs=1M count=1000 status=progress 2> /dev/null \
| ssh -c "aes256-gcm@openssh.com" localhost "bash -c 'time -p cat' > /dev/null" 2>&1 \
| grep real \
| gawk '{print "'"$i"': "1000 / $2" MByte/s, " $2 " s" }' \
&& sleep 1;
done
Resultat auf einer OpenStack Cloud-VM:
aes256-gcm@openssh.com: 248.139 MByte/s, 4.03 s
aes128-gcm@openssh.com: 248.139 MByte/s, 4.03 s
aes256-ctr: 247.525 MByte/s, 4.04 s
chacha20-poly1305@openssh.com: 242.131 MByte/s, 4.13 s
aes256-cbc: 241.546 MByte/s, 4.14 s
3des-cbc: 240.385 MByte/s, 4.16 s
aes192-ctr: 234.742 MByte/s, 4.26 s
aes128-cbc: 233.645 MByte/s, 4.28 s
aes128-ctr: 230.947 MByte/s, 4.33 s
aes192-cbc: 227.273 MByte/s, 4.40 s
rijndael-cbc@lysator.liu.se: 194.553 MByte/s, 5.14 s
Resultat auf einer VM in KVM auf einem Notebook mit Intel-Prozessor und NVMe:
aes256-cbc: 1369.86 MByte/s, 0.73 s
chacha20-poly1305@openssh.com: 1265.82 MByte/s, 0.79 s
aes192-ctr: 1234.57 MByte/s, 0.81 s
3des-cbc: 1204.82 MByte/s, 0.83 s
aes192-cbc: 1176.47 MByte/s, 0.85 s
aes128-gcm@openssh.com: 1162.79 MByte/s, 0.86 s
aes128-cbc: 1149.43 MByte/s, 0.87 s
aes256-ctr: 961.538 MByte/s, 1.04 s
aes256-gcm@openssh.com: 925.926 MByte/s, 1.08 s
aes128-ctr: 925.926 MByte/s, 1.08 s
Troubleshooting
- Postponed publickey for root from 10.26.6.74 port 54321 ssh2
Die RSA-Keys stimmen,
ssh-copy-id
verwendet bzw. Dateiberechtigungen auf alle Keys stimmen, und SELinux motzt auch nicht? Dann liegt es daran, dass man das Schlüsselpaar auf der Client-Maschine unter einem anderen Benutzer (z.B. linus) erzeugt hat als für den Benutzer, mit dem man sich auf der Zielmaschine anmelden möchte (z.B. root). Hier hilft die explizite Angabe des zu kopierenden SSH-Keys perssh-copy-id -i ~/.ssh/id_rsa.pub root@10.26.6.74
.- Wie erhält man den SSH-Fingerprint zu einem SSH-Server?
Am einfachsten, man löscht den Eintrag in seiner
~/.ssh/known_hosts
und verbindet sich neu.
Built on 2024-11-18