SSH-Server¶
Siehe auch
- Verwandte Artikel
- Offizielle Dokumentation
man sshd,man sshd_config,man ssh,man ssh_config
- Linuxfabrik
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 # prevent malware (and everything else) from tunneling
ClientAliveCountMax 0 # do not send keep-alive messages
ClientAliveInterval 300 # 5 minute idle timeout, then logout
DisableForwarding yes # CIS: umbrella switch that disables all forwarding types
GSSAPIAuthentication no # disable GSSAPI unless Kerberos SSO is actually used
HostbasedAuthentication no # disable .rhosts and /etc/hosts.equiv (SSHv2)
IgnoreRhosts yes # disable .rhosts and .shosts files
LoginGraceTime 60 # disconnect timeout after failed login
LogLevel VERBOSE # raise logging (required for fail2ban)
MaxAuthTries 3 # drop connection after N failed auth attempts (default 6)
MaxSessions 4 # max multiplexed sessions per connection
MaxStartups 10:30:60 # concurrent unauthenticated connections (start:rate%:full)
PasswordAuthentication no # disable password login
PermitEmptyPasswords no # no empty passwords
PermitRootLogin no # disable direct root login (keep a sudo-capable user)
PermitUserEnvironment no # prevent users from setting env vars (PATH etc.)
Port 56669 # non-standard port - no real security, just less brute force noise
PubkeyAuthentication yes # allow key-based authentication
UsePAM yes # delegate authentication to PAM
X11Forwarding no # disable X11 tunneling through sshd forwarding
Wer den SSH-Port ändert, muss dies auch per SELinux erlauben:
dnf --assumeyes 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 direkt in der sshd_config. Stattdessen die systemweite
Crypto-Policies konfigurieren, die auch vom SSH-Daemon verwendet wird. Wer
aus Compliance-Gründen eine harte Baseline in der sshd_config haben muss (CIS-
Benchmark-Profil), kann die in der Mozilla-OpenSSH-Guide hinterlegten Listen übernehmen.
Siehe auch
Weitere CIS-Empfehlungen¶
Über die obige Baseline hinaus verlangt der CIS-Benchmark für RHEL 10 noch ein paar Hardening-Punkte rund um den SSH-Server, die hier der Vollständigkeit halber erwähnt werden:
- Dateiberechtigungen auf
sshd_config /etc/ssh/sshd_configmussroot:rootgehören und0600(bzw. restrictiver) sein. Analog gilt0644für Public-Host-Keys (/etc/ssh/ssh_host_*_key.pub) und0600oder restriktiver für Private-Host-Keys (/etc/ssh/ssh_host_*_key).AllowUsers/AllowGroupsExpliziter SSH-Zugriff für bestimmte Benutzer oder Gruppen, statt über die TCP-Wrapper- oder firewalld-Schicht. Mindestens eine der Direktiven
AllowUsers,AllowGroups,DenyUsersoderDenyGroupssollte gesetzt sein.- Login-Banner
Banner /etc/issue.netsetzen; die Datei selbst mit einem nüchternen, juristisch tragfähigen Warnhinweis befüllen (in Rechtsverfahren hat sich ein expliziter Hinweis auf Autorisierungspflicht bewährt).MaxStartups,MaxSessions,MaxAuthTriesOben in der Baseline bereits gesetzt. CIS schreibt
MaxAuthTries <= 4,MaxStartups <= 10:30:60vor.
Benutzerzugriff auf SSH steuern¶
- per TCP-Wrapper
Der Zugriff auf den SSH-Daemon lässt sich mittels
/etc/hosts.allowund/etc/hosts.denysteuern, den sogenannten TCP Wrappers-Dateien. Der Servicename zur Steuerung lautet hiersshd. Soll der SSH-Service nur aus der Domänelinuxfabrik.cherreichbar sein, trägt man in der/etc/hosts.denyein:sshd:ALL EXCEPT .linuxfabrik.ch
Die Datei
/etc/hosts.allowwird zuerst gelesen. Wird kein passender Match gefunden, kommt die/etc/hosts.denyzur 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 - /etc/ssh/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-idverwendet 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_hostsund verbindet sich neu.