In diesem Beitrag erläutere ich meine SSH Konfiguration für Server und Clients. Ich erkläre außerdem wie man sie einrichtet. Sie schränkt die erlaubten kryptographischen Algorithmen auf als sicher geltende ein. Meine Auswahl der Algorithmen basiert auf dem Artikel Secure Secure Shell.
Ich beschreibe zuerst die verschiedenen verwendeten Optionen und wie man sie Konfiguriert. Am Ende habe ich nochmal die kompletten Konfigurationsdateien zum einfachen kopieren eingefügt.
Bei der Konfiguration muss extrem vorsichtig vorgegangen werden, da man sich u.U. auch komplett vom Server aussperren kann. Ich übernehme dafür keine Haftung.
Server
Starten wir mit der Serverkonfiguration, welche in der Datei /etc/ssh/sshd_config hinterlegt ist. Ich erläutere zuerst die einzelnen Optionen und beschreibe welche Konfiguration außerhalb der Konfigurationsdatei notwendig ist. Am Ende des Beitrages habe ich nochmals die komplette Server-Konfiguration eingefügt und beschreibe auch wie diese geladen werden kann.
Der SSH Server hört standardmäßig auf Port 22, was ich auch so belassen habe. Falls ein Server mehrere IP-Adressen hat, kann mit ListenAddress eingeschränkt werden auf welchen IP-Adresse der SSH Server eine Verbindung akzeptieren soll.
# Port to listen on Port 22 # IP to listen on #ListenAddress :: #ListenAddress 0.0.0.0
KexAlgorithms schränkt die erlaubten Algorithmen für einen Schlüsseltausch ein. Ich erlaube hier nur ed25519 als Algorithmus, die Begründung hierfür findet sich im oben verlinkten Artikel.
# Allow only secure key exchange algorithms KexAlgorithms curve25519-sha256@libssh.org
Protocol 2 bedeutet, dass nur die neuere SSH Version verwendet werden soll und nicht die unsichere Version 1. HostKey definiert welche Schlüssel bzw. Algorithmen der Server für die Authentifizierung verwenden soll – hier ed25519 und RSA. Die Begründung für meine Auswahl befindet sich wieder im verlinkten Artikel.
# Allow only SSH version 2 Protocol 2 # Allow only secure server authentication algorithms HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key
Um diese Algorithmen zu verwenden löschen wir zuerst alle vorhandenen Host Schlüssel vom Server. Anschließend generieren wir neue – mit ausreichender Länge für RSA.
$ cd /etc/ssh/ $ sudo rm ssh_host_*key* $ sudo ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" < /dev/null Generating public/private ed25519 key pair. Your identification has been saved in ssh_host_ed25519_key Your public key has been saved in ssh_host_ed25519_key.pub The key fingerprint is: SHA256:NyxgQMDgtQcMCrMMWlAgCbbexBefl562QVo2xL62pNg root@server The key's randomart image is: +--[ED25519 256]--+ |@X*=o. .. | |@+=.o.o o.. | |++ + ooo.B | |. o o. .Boo | | . . .S== | | .*o. | | o +.. | | . E . | | | +----[SHA256]-----+ $ sudo ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N "" < /dev/null Generating public/private rsa key pair. Your identification has been saved in ssh_host_rsa_key Your public key has been saved in ssh_host_rsa_key.pub The key fingerprint is: SHA256:js+jmapYIhg4QA5PeMQa96PIrBPEWYPNVs2HzrjYNMI root@server The key's randomart image is: +---[RSA 4096]----+ |.=* ..o . | |*++* + . | |o**.. + . | |++ Eo+ o | |B. .=.o S | |+=.. o o | |=.. . . | |++ =. | |......+.o. | +----[SHA256]-----+
Bitte beachtet, dass sich durch den letzten Schritt die HostKeys des Servers ändern. Ihr bekommt somit eine Warnung, wenn ihr euch das nächste Mal mit dem Server verbindet, dass sich der Host Key des Servers geändert hat. Um diesen überprüfen zu können berechnen wir nun den Hash der ed25519 und RSA Keys und notieren diese.
$ ssh-keygen -lf ssh_host_ed25519_key.pub 256 SHA256:NyxgQMDgtQcMCrMMWlAgCbbexBefl562QVo2xL62pNg user@host (ED25519) $ ssh-keygen -lf ssh_host_rsa_key.pub 4096 SHA256:js+jmapYIhg4QA5PeMQa96PIrBPEWYPNVs2HzrjYNMI user@host (RSA)
Auf älteren Systemen wie Debian Jessie wird der Hash als md5 ausgegeben. Um beim erneuten Verbinden den HostKey vergleichen können wird aber der SHA256 Hash benötigt. Der Hash kann in diesem Falle auch mit nachfolgendem Befehl berechnet werden – Das „=“ am Ende der Ausgabe kann ignoriert werden.
$ awk '{print $2}' ssh_host_ed25519_key.pub | base64 -d | sha256sum -b | awk '{print $1}' | xxd -r -p | base64 zD+K1cChDUaxA/d1bv6ok8b2rACe2DiiwJO6wspWBik= $ awk '{print $2}' ssh_host_rsa_key.pub | base64 -d | sha256sum -b | awk '{print $1}' | xxd -r -p | base64 Fp+MTtblJoPBAStfnpJ8JBeGWJhW1foHoOKpkSmeMws=
Beim nächsten Verbinden wird folgende Warnung angezeigt, dass sich der Host Key des Servers geändert hat.
$ ssh user@host
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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 a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:NyxgQMDgtQcMCrMMWlAgCbbexBefl562QVo2xL62pNg.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/user/.ssh/known_hosts:1
remove with:
ssh-keygen -f "/home/user/.ssh/known_hosts" -R host
ED25519 host key for host has changed and you have requested strict checking.
Host key verification failed.
Der alte Host Key kann mit dem in der Warnung angezeigten Befehl einfach gelöscht werden.
$ ssh-keygen -f "/home/user/.ssh/known_hosts" -R host
# Host host found: line 1
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old
Beim erneuten Verbinden wird nun nachgefragt ob der neue Key akzeptiert werden soll. Bevor dies bestätigt wird sollte geprüft werden, ob der angezeigte Hashwert mit dem notierten des neuen Keys übereinstimmt.
$ ssh user@host
The authenticity of host 'host (xxx.xxx.xxx.xxx)' can't be established.
ED25519 key fingerprint is SHA256:NyxgQMDgtQcMCrMMWlAgCbbexBefl562QVo2xL62pNg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'host' (ED25519) to the list of known hosts.
Aus Sicherheitsgründen sollte es für Clients nur erlaubt sein sich mittels Public-Key Authentication anzumelden und nicht mittels Passwörter.
# Allow only public key authentication PasswordAuthentication no ChallengeResponseAuthentication no PubkeyAuthentication yes
Es ist sinnvoll nur den Benutzern eine SSH Verbindung zu erlauben die dies auch benötigen. AllowGroups erlaubt nur Benutzern dieser Gruppe eine Verbindung über SSH.
# Only allow SSH for users member of group ssh-user AllowGroups ssh-user
Dazu muss die Gruppe erstellt und anschließend alle Benutzer welche Zugriff erhalten sollen hinzugefügt werden.
$ sudo groupadd ssh-user
$ sudo usermod -a -G ssh-user <username>
Wenn ein Benutzer keinen Zugriff mehr haben soll muss er natürlich aus der Gruppe gelöscht werden. Dies kann mit nachfolgendem Befehl erledigt werden.
$ sudo deluser <username> ssh-user
Als nächstes werden die erlaubten symmetrischen kryptographischen (Ciphers) sowie MAC (MACs) Algorithmen aufgelistet. Meine Auswahl basiert auch hier wieder auf der im verlinkten Artikel weiter oben.
# Allow only secure symmetric ciphers Ciphers chacha20-poly1305@openssh.com # Allow only secure message authentication codes MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
Die nachfolgenden Parameter sind meist in der Standardkonfiguration vorhanden. Ich habe allerdings X11Forwarding deaktiviert, da ich es nicht nutze. PermitRootLogin prohibit-password sagt, dass sich root nicht über ein Passwort anmelden darf. Die Option prohibit-password wurde mit OpenSSH 7.0 eingeführt. Für Distributionen welche eine ältere Version nutzen (wie z.B. Debian Jessie oder Raspbian, welches auf Debian Jessie basiert) muss die alternative Option without-password verwendet werden. Sie hat die gleiche Funktionalität.
# Use Privilege Separation for security reasons UsePrivilegeSeparation yes # Logging SyslogFacility AUTH LogLevel INFO # Time to wait for complete login LoginGraceTime 120 # Allow root logins only with public-keys PermitRootLogin prohibit-password # Enhance security StrictModes yes # Don't read the user's ~/.rhosts and ~/.shosts files IgnoreRhosts yes # Disable host based authentication HostbasedAuthentication no # Disable empty passwords PermitEmptyPasswords no # Disable X11 Forwarding X11Forwarding no # Print last login PrintLastLog yes # Do not print the message of the day PrintMotd no # Keep session alive TCPKeepAlive yes # Allow client to pass locale environment variables AcceptEnv LANG LC_* # Allow sftp Subsystem sftp /usr/lib/openssh/sftp-server # Use PAM to allow mail notification at login UsePAM yes
Client
Die Konfigurationsdatei auf Clientseite spiegelt die gesetzten Parameter auf Serverseite wieder ist aber kürzer. Sie befindet sich in der Datei /etc/ssh/ssh_config. Ich beschreibe hier wie beim Server die einzelnen Parameter und welche Konfiguration außerhalb der Konfigurationsdatei notwendig ist. Am Ende des Beitrages befindet sich nach der Server-Konfiguration auch eine Kopie der kompletten Client-Konfiguration.
Es erlaubt mittels KexAlgorithms den gleichen Schlüsseltauschalgorithmus wie der Server.
# For all hosts Host * # Allow only secure Key Exchange Algorithms KexAlgorithms curve25519-sha256@libssh.org
Es wird auch nur die Authentifizierung über Public-Keys mit im oben verlinkten Artikel empfohlenen Algorithmen erlaubt.
# Do not allow password authentication PasswordAuthentication no ChallengeResponseAuthentication no # Allow authentication with public keys PubkeyAuthentication yes HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa
Damit sich der Client mittels Public-Keys beim Server anmelden kann muss er sich vorher einen geeigneten Schlüssel generieren und den öffentlichen Teil dem Server hinterlegen. Wie dies funktioniert habe ich im Artikel SSH Authentifizierung mittels Public-Keys beschrieben.
Die angegebenen Ciphers und MACs spiegeln die auf der Serverseite wieder.
# Allow only secure symmetric ciphers Ciphers chacha20-poly1305@openssh.com # Allow only secure MACs MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
Der Zweck der restlichen Optionen ist ungenutzte Features zu deaktivieren, das locale des Clients an den Server zu senden und die bekannten Server zu verschleiern.
# Disable unused features UseRoaming no # Pass locale to server SendEnv LANG LC_* # Obfuscate known hosts HashKnownHosts yes
Zur einfacheren Verwaltung von SSH-Verbindungen kann auf Clientseite eine extra Konfigurationsdatei angelegt werden. Wie dies funktioniert beschreibe ich im Artikel Konfigurationsdatei zum Verwalten von SSH Verbindungen.
Konfigurationsdateien
Wenn oben genannte Schritte durchgeführt wurden können die nachfolgenden Konfigurationsdateien auf Client- und Serverseite übernommen werden. Sie sind eine Zusammenfassung der einzelnen Konfigurationsschnipsel. Ich weise hier nochmals darauf hin das man damit sehr vorsichtig sein sollte, da man sich unter Umständen vom Server ausschließen kann.
Server
Die Konfiguration des Servers ist in der Datei /etc/ssh/sshd_config hinterlegt. Nachfolgend meine komplette Konfigurationsdatei.
# Carstens SSH configuration file # Port to listen on Port 22 # IP to listen on #ListenAddress :: #ListenAddress 0.0.0.0 # Allow only secure key exchange algorithms KexAlgorithms curve25519-sha256@libssh.org # Allow only SSH version 2 Protocol 2 # Allow only secure server authentication algorithms HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key # Allow only public key authentication PasswordAuthentication no ChallengeResponseAuthentication no PubkeyAuthentication yes # Only allow SSH for users member of group ssh-user AllowGroups ssh-user # Allow only secure symmetric ciphers Ciphers chacha20-poly1305@openssh.com # Allow only secure message authentication codes MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com # Use Privilege Separation for security reasons UsePrivilegeSeparation yes # Logging SyslogFacility AUTH LogLevel INFO # Time to wait for complete login LoginGraceTime 120 # Allow root logins only with public-keys PermitRootLogin prohibit-password # Enhance security StrictModes yes # Don't read the user's ~/.rhosts and ~/.shosts files IgnoreRhosts yes # Disable host based authentication HostbasedAuthentication no # Disable empty passwords PermitEmptyPasswords no # Disable X11 Forwarding X11Forwarding no # Print last login PrintLastLog yes # Do not print the message of the day PrintMotd no # Keep session alive TCPKeepAlive yes # Allow client to pass locale environment variables AcceptEnv LANG LC_* # Allow sftp Subsystem sftp /usr/lib/openssh/sftp-server # Use PAM to allow mail notification at login UsePAM yes
Damit die Änderungen beim Server wirksam werden muss im Anschluss noch die Konfiguration des ssh Servers neu geladen werden.
$ sudo service ssh reload
Client
Die Konfiguration des Clients ist in der Datei /etc/ssh/ssh_config hinterlegt. Nachfolgend meine komplette Konfigurationsdatei.
# Carstens SSH configuration file # For all hosts Host * # Allow only secure Key Exchange Algorithms KexAlgorithms curve25519-sha256@libssh.org # Do not allow password authentication PasswordAuthentication no ChallengeResponseAuthentication no # Allow authentication with public keys PubkeyAuthentication yes HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa # Allow only secure symmetric ciphers Ciphers chacha20-poly1305@openssh.com # Allow only secure MACs MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com # Disable unused features UseRoaming no # Pass locale to server SendEnv LANG LC_* # Obfuscate known hosts HashKnownHosts yes
Sie wird automatisch verwendet, wenn die nächste SSH Verbindung aufgebaut wird.
Hallo Carsten,
im Abschnitt „Client“ steht folgender Satz:
Die Konfiguration des Clients ist in der Datei /etc/ssh/sshd_config hinterlegt.
Das müsste aber
Die Konfiguration des Clients ist in der Datei /etc/ssh/ssh_config hinterlegt.
heißen.
Danke für die gut Vorlage !
Stefan Scherer
Hallo Stefan,
vielen Dank für den Hinweis, ich habe es direkt angepasst. Es freut mich das dir die Vorlage gefällt.
Carsten
Hallo Carsten,
Die MACs hmac-ripemd160-etm@openssh.com und hmac-ripemd160 werden unter Ubuntu LTS 18.04 nicht mehr unterstützt und der SSH Server lässt sich damit nicht restarten. Nachdem ich diese aus der Konfigurations entfernt hat, funktioniert es wunderbar.
Vielen Dank für diese gute Anleitung.
Oliver
Hallo Oliver,
vielen Dank für deinen Kommentar!
Ich habe die Anleitung auf den aktuellen Stand gebracht
Veile Grüße
Carsten