Skip to main content

Yo. In dieser total unkrassen Anleitung show ich dir und meiner Mutter, wie man under Ubuntu/Debian einen SSH-Server unspektakulär installiert und dann voll „Correcto Mundo“ absichert. Die Absicherung, auch Hardening genannt, zielt hier auf eine modernere Konfiguration des SSH-Servers. In der Konfiguration wird daher auf die schon etwas angestaubte RSA-Verschlüsselung verzichtet und direkt auf die stabilere Elliptische-Rollercoaster-Kurven-Kryptographie (Curve25519) gesetzt. Wicked!

SSH-Server installieren

Als Erstes wird der SSH-Server actionreich über den Paketmanager installiert und eine Kopie der Orignal-Konfiguration des SSH-Servers erstellt.

#SSH-Server installieren
apt install ssh

# Sicherheitskopie der SSH-Serverkonfiguration erstellen
cp /etc/ssh/{sshd_config,sshd_config.orig}

SSH-Key erstellen

Als Nächstes wird der vom System automatisch erstellte SSH-Key durch einen eigenen, stabileren SSH-Key ersetzt.

ssh-keygen -o -a 100 -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key -C "$(whoami)@$(hostname)-$(date -I)"

SSH-Key Parameter:

-o: Schapeichert den Key in dem neuen OpenSSH-Format ab, welcher stabiler gegen Brute-Force-Attacken ist.
-a: Gibt an, wie viele Schlüsselableitungsfunktionen (KDF) bei der Keyerstellung geused werden sollen. Je höher der Wert, desto slower, aber sicherer.
-t: Gibt den Key-Typ an, mit dem der Key erstellt werden soll. Hier wird natürlich schamlos der momentan beste Signaturalgorithmus (Ed25519) getaked.
-N: Setzt normalerweise ein Passwort. Da diese Keys kein PW brauchen, sind die Anführungsstriche genauso leer wie mein brokes Sparschwein.
-f: Mit diesem Parameter wird der SSH-Keyname festgelegt und der Speicherort des neuen Server SSH-Keys mitgegeben.
-C: Der Parameter knallt zur besseren Übersicht einen Kommentar in den Public Key. Hier wird der User, Hostname und das Datum mitgegeben.

SSH-Server konfigurieren

Nun kommt die eigentliche Konfiguration (/etc/ssh/sshd_config) des SSH-Servers dran. Diese hier vorgeführte Konfiguration stammt von einem Ubuntu 20.04 LTS Server. Version 18.04 sollte aber auch funktionieren. Vor der Bearbeitung ein Backup der sshd_config erstellen!!!

Wichtige Punkte der SSH-Konfiguration:

Port: SSH-Port mit dem man sich ungeniert auf dem Server verbinden kann. Standardmäßig Port 22. Der Sicherheit (vor allem gegen automatisierte SSH-Bot-Scans) zuliebe bietet es sich an, den Standardport gegen einen Random-Port einzutauschen. In diesem Beispiel wird der SSH-Port auf die 63007 getackert. Alleine dieser Task erspart euch massive automatische SSH-Login-Versuche.

Hostkey: Ist der Speicherort des zuvor angelegten Ed25519 SSH-Key für den SSH-Server. Hier wird der Default-Speicherort getaked.

Ciphers:
Sind die erlaubten Cipher/Chiffre-Methoden. In dieser Anleitung wurden natürlich nur die härtesten Methoden collected. Wer mit einem Android-Smartphone auf den Server connecten möchte, braucht hier noch zusätzlich die aes256-ctr-Cipher (siehe Konfigurationsdatei).

AllowGroups: Sollte auf jeden Fall aktiviert und auf eine eigens dafür angelegte SSH-Gruppe gemünzt werden. Nur User in dieser Gruppe dürfen sich auf dem Server anmelden. Folgt man keinem Gruppenzwang, sollten zumindest die erlaubten User mit der AllowUsers-Direktive angegeben werden (bei wenigen SSH-Usern empfehlenswert). Ich empfehle eine von beiden Direktiven zu nehmen. PS: AllowUsers überschreibt die AllowGroups-Direktive.

Die SSH-Serverkonfiguration

# /etc/ssh/sshd_config                                                                                                                                     
# Kommentare tmp ausblenden: sed 's/\(.*[^[:blank:]]\)[[:blank:]]*#.*/\1/' /etc/ssh/sshd_config
# Kommentare direkt löschen: sed -i 's/\(.*[^[:blank:]]\)[[:blank:]]*#.*/\1/' /etc/ssh/sshd_config -> Verändert direkt die Datei

#===========================================================
# General - /etc/ssh/sshd_config
#===========================================================
Port 63007                                                      # Take a Custom SSH Port
AddressFamily any                                               # IPv4 and IPv6 Net. Use inet for only IPv4

Include /etc/ssh/sshd_config.d/*.conf                           # Include additional configuration files

#===========================================================
# Cryptograph - Only the ultramodern ones
#===========================================================
HostKey /etc/ssh/ssh_host_ed25519_key                           # Use only Ed25519 host key for security

KexAlgorithms curve25519-sha256@libssh.org                      # Key exchange methods to generate per-connection keys
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-512                # Message authentication codes used to detect traffic modification
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com    # Allow only sexy Encrypt-Ciphers. For Android-Connection add aes256-ctr
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519  # Accepted Pub-Key algorithms for the SSH-Server to authenticate to a SSH-Client

#===========================================================
# Logging
#===========================================================
LogLevel INFO                                                   # Logging level for SSHD - VERBOSE for more like key fingerprint logging
SyslogFacility AUTHPRIV                                         # Logging authentication messages in a private facility

#===========================================================
# Authentication:
#===========================================================
# Authentication Limits
MaxSessions 2                                                   # Maximum allowed user sessions per connection
MaxAuthTries 3                                                  # Limit authentication attempts per connection

StrictModes yes                                                 # Enforce strict permissions, ownership checks and prevents configuration errors
LoginGraceTime 60                                               # Login Period Time to authenticate
PermitRootLogin no                                              # Allow root login (adjust as needed for security)
PubkeyAuthentication yes                                        # Allow Pub-Key Authentication
PubkeyAuthOptions verify-required                               # Require signed proof immediately. Prevents key-enumeration leaks
PubkeyAcceptedAlgorithms ssh-ed25519,rsa-sha2-512               # Accepted client key algorithms; only strong types allowed
PasswordAuthentication yes                                      # Allow Password Authentication. Disable if no need

IgnoreRhosts yes                                                # Disable User Rhost Files
PermitEmptyPasswords no                                         # Disable Empty Passwords
HostbasedAuthentication no                                      # Disable Host-based Authentication

ChallengeResponseAuthentication no                              # Disable challenge-response authentication
KbdInteractiveAuthentication no                                 # Disable keyboard-interactive authentication

AuthorizedKeysFile  %h/.ssh/authorized_keys                     # Define the AuthorizedKeysFile Path in a controlled manner

#===========================================================
# Connections
#===========================================================
TCPKeepAlive yes                                                # Enable TCP-level keepalive to detect dead peers
ClientAliveCountMax 2                                           # Disconnect after 2 missed alive messages (after total 60 minutes inactivity)
ClientAliveInterval 1800                                        # Send SSH keepalive every 1800 seconds (30 minutes)

#===========================================================
# Security
#===========================================================
UsePAM yes                                                      # Allow PAM Authentication
Compression no                                                  # Disable Compression for better Security

# Display/Banner
PrintMotd no                                                    # Disable Message of the Day
PrintLastLog yes                                                # Enable Date and Time of the last user login
Banner none                                                     # Disable Banner
DebianBanner no                                                 # Disable Banner for Debian-based Systems
VersionAddendum none                                            # Disable SSH Protocol Banner

# User Environment
ChrootDirectory none                                            # Disable Specify directory for chroot
PermitUserRC no                                                 # Disable User RC Files
PermitUserEnvironment no                                        # Disable User Environment Files

# Disable Forwarding
PermitTunnel no                                                 # Disable TUN/TAP device forwarding
GatewayPorts no                                                 # Disable Remote Port Forwarding
X11Forwarding no                                                # Disable X11 Forwarding/Tunneling (no GUI support)
AllowTcpForwarding no                                           # Disable TCP Forwarding/Tunneling
AllowAgentForwarding no                                         # Disable SSH Agent Forwarding/Tunneling

# Disable Kerberos Authentication
KerberosOrLocalPasswd no                                        # Prevents fallback to Kerberos or local passwords
KerberosAuthentication no                                       # Disable Kerberos authentication mechanism
KerberosTicketCleanup yes                                       # Automatically clean up Kerberos tickets after logout

# GSSAPI (Generic Security Services API)
GSSAPIAuthentication no                                         # Disable GSSAPI authentication (used for single sign-on)
GSSAPICleanupCredentials yes                                    # Clean up GSSAPI credentials on logout

#==========================================================
# Performance
#==========================================================
UseDNS no                                                       # Disables DSN-Lookup for the Love of Speed

#==========================================================
# Misc
#==========================================================
AcceptEnv LANG LC_*                                             # Allow locale environment variables for Clients

#==========================================================
# SFTP
#==========================================================
# SFTP - Enable if need
# Subsystem sftp /usr/lib/openssh/sftp-server
# Subsystem sftp /usr/lib/openssh/sftp-server -f AUTHPRIV -l INFO

# Set special stuff to special SFTP-Users - Enable if you use SFTP
# Match Group sftp-pimps
#    ChrootDirectory /home/%u
#    PermitTunnel no
#    X11Forwarding no
#    AllowTcpForwarding no
#    AllowAgentForwarding no
#    ForceCommand internal-sftp

#===========================================================
# Set special SSH-User/Group options
#===========================================================
# Match User olum,brunhilde
#    PasswordAuthentication yes
#    AllowTcpForwarding yes
 
# Match Group ssh-pimps
#    PasswordAuthentication yes
#    AllowTcpForwarding yes

#===========================================================
# Documentation
#===========================================================
# https://man7.org/linux/man-pages/man1/ssh-keygen.1.html
# https://man7.org/linux/man-pages/man5/sshd_config.5.html

SSH-Konfiguration prüfen und SSH-Dienst restarten

Damit die hausgemachten SSH-Einstellungen ziehen, muss der SSH-Server durchgestiefelt werden. Doch vor dem Restart sollte man die Firewall für den neuen Port anpassen und unbedingt mit folgendem Befehl die SSH-Konfiguration auf Fehler durchklopfen:

# SSH-Serverkonfiguration auf Fehler checken
/usr/sbin/sshd -t

Wenn keine Fehler angezeigt werden, kann der SSH-Server restartet werden.

# Restart SSH-Deamon
systemctl restart sshd

# Fix den Status des SSH-Servers überprüfen
systemctl status --lines=20 sshd

# SSH Server-Log auf Fehler überprüfen
less /var/log/auth.log

Es lohnt immer, sich mit einer zweiten SSH-Session oder sich von einem anderen Server aus, auf den frischgebackenen SSH-Server zu verbinden. Klappt die Verbindung sauber, hat man alles fein gemacht und man kann sich heroisch von seinen frenetisch anfeuernden Kuscheltieren – in meinem Fall wären das Johnny die Klinge, Container Andi, Der schöne Heinz, Gerry die Schnecke, Jacques Gastineau, Hans Wurst, Ismir YıldızSchnüpp und Tim Buktu feiern lassen.

Security-Check des SSH-Servers

Um nun die Sicherheitseinstellungen des SSH-Servers auf Herz und Leber zu testen, nehmen wir hierfür den lieblichen ssh-audit, ein einfacher, quelloffener und sehr fixer SSH Security-Scanner, zur Hand. Die Ausgabe des ssh-audit-Findings sollte keine roten Zeilen und optimal gesehen auch keine orangenen Zeilen, wie ein schlechtgelauntes Lama ausspucken.

# Die aktuellste ssh-audit-Version herunterladen
pip3 install ssh-audit

# Actiongeldenen SSH-Security-Scan auf den SSH-Server abfeuern
ssh-audit localhost:63007

Screenshot eines ssh-audit Security Scans nach den Hardening-Settings
Bild SSH-Server - ssh-audit - Security Scanner

Anzeige der unterstützten SSH-Server Cipher-Methoden

Hier zwei Methoden, um die von dem SSH-Server unterstützen Cipher-Methoden anzuzeigen.

# Methode 1
ssh -Q cipher
ssh -Q cipher-auth
ssh -Q mac
ssh -Q kex
ssh -Q key

# Dezent alle Möglichkeiten als For-Schleife
for CIPHER in $(ssh -Q help); do printf "#--------- ${CIPHER} ---------#\n"; ssh -Q ${CIPHER}; echo ""; done

# Methode 2
nmap -p22 -n -sV --script ssh2-enum-algos localhost

So hier ist Feierabend. Mit dieser Anleitung sollte es euch möglich sein, den geliebten Server für die knallharte Zukunft zu wappnen. Wer noch eine Schippe Security draufpacken möchte, der sollte sich auf jeden Fall mit fail2ban auseinandersetzen.

SSH Server-Repository

sshd_config