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 beste Signaturalgorithmus (Ed25519) getaked.
-N: Setzt normalerweise ein Passwort. Da die Keys kein PW brauchen, sind die Anführungsstriche genauso wie mein brokes Sparschwein, einfach leer.
-f: Mit diesem Parameter wird der SSH-Keyname festgelegt und der Speicherort des neuen 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.

Wichtige Punkte der SSH-Konfiguration:

Port: SSH-Port mit dem man sich ungeniert auf dem Server verbinden kann. Standardmäßig Port 22. Der Sicherheit zuliebe bietet es sich an, den Standardport gegen einen Random-Port einzutauschen. In diesem Beispiel wird der SSH-Port auf die 63007 getackert.

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

#-----------------------------------------------------------
# General - /etc/ssh/sshd_config
#-----------------------------------------------------------
Port 63007                                                      # Custom SSH Port
Protocol 2                                                      # The one and only Protocol

AddressFamily any                                               # IPv4 and IPv6 Net. Use inet for only IPv4
# ListenAddress $IP_INTERN                                      # Set Listening Intern Address
# ListenAddress $IP_EXTERN                                      # Set Listening Extern Address

#-----------------------------------------------------------
# HostKey - Only the curvy one
#-----------------------------------------------------------
HostKey /etc/ssh/ssh_host_ed25519_key                           # Allow only the vely vely secure ECDSA Pub-Key Authentication

#-----------------------------------------------------------
# Ciphers - Only the ultramodern ones
#-----------------------------------------------------------
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                                                   # VERBOSE for more like key fingerprint logging
SyslogFacility AUTHPRIV                                         # Logging Authentication Commands

#-----------------------------------------------------------
# Authentication:
#-----------------------------------------------------------
MaxSessions 2                                                   # Maximum allowed User Sessions
MaxAuthTries 3                                                  # Maximum allowed Auth Attempts

StrictModes yes                                                 # Prevents Configuration Errors
LoginGraceTime 60                                               # Login Period Time to authenticate
PermitRootLogin no                                              # Disable direct root Login

PubkeyAuthentication yes                                        # Allow Pub-Key Authentication
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

TCPKeepAlive yes                                                # Prevent from dropping the Connection
ClientAliveCountMax 2                                           # Sends 2 times ClientAlive Message till drop
ClientAliveInterval 1800                                        # Kills Connection after 30 Min inactivity

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

# AllowUsers olum brunhilde                                     # Allow special Users. Here olum and brunhilde
# AllowGroups ssh-pimps                                         # Allow special Group. Group here is ssh-pimps

# RekeyLimit 1G 1H                                              # Limiting amount of data transmitted with a single session key

Banner none                                                     # Disable Banner
DebianBanner no                                                 # Disable Banner for Debian-based Systems
VersionAddendum none                                            # Disable SSH Protocol Banner

PrintMotd no                                                    # Disable Message of the Day
PrintLastLog yes                                                # Enable Date and Time of the last user login

PermitTunnel no                                                 # Disable tun Device forwarding. Only SSH Connections!
PermitUserRC no                                                 # Disable User RC Files
PermitUserEnvironment no                                        # Disable User Environment Files

# Disable Forwarding
GatewayPorts no                                                 # Disable Remote Port Forwarding
X11Forwarding no                                                # Disable X11 Forwarding/Tunneling (GUI)
AllowTcpForwarding no                                           # Disable TCP Forwarding/Tunneling
AllowAgentForwarding no                                         # Disable Agent Forwarding/Tunneling

# Disable Kerberos Authentication                               # Disable Kerberos Authentication
KerberosOrLocalPasswd no
KerberosAuthentication no
KerberosTicketCleanup yes
GSSAPIAuthentication no
GSSAPICleanupCredentials yes

AuthorizedKeysFile  %h/.ssh/authorized_keys                     # Set AuthorizedKeysFile in a controlled manner

#-----------------------------------------------------------
# Misc
#-----------------------------------------------------------
UseDNS no                                                       # Disables DSN-Lookup for the Love of Speed
AcceptEnv LANG LC_*                                             # Allow locale environment variables for Clients

#-----------------------------------------------------------
# SFTP
#-----------------------------------------------------------
# SFTP - Enable if need
# 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.

SSH Server-Repo

sshd_config