hmichael@tronyxworld.be:~$

Sécuriser OpenSSH

Sshd est le processus du serveur OpenSSH.

Il écoute les connexions entrantes à l’aide du protocole SSH et agit comme serveur pour le protocole.

Il gère l’authentification des utilisateurs, le chiffrement, les connexions de terminaux, les transferts de fichiers et le tunneling.

La problématique

Lorsqu’on déploie notre distribution la configuration par défaut n’est pas sécurisée ni très restrictive.

A titre d’exemple voici le résultat d’un ssh-audit.

Sous CentOS 8 :

centos7_sshaudit

Sous Debian Buster :

debianbuster_sshaudit

Pas fameux pour un protocole sensé nous permettre une connexion sécurisée à nos serveurs…

Création et mise en place d’une clé ed25519

Avant d’attaquer la configuration du serveur openSSH il est nécessaire de créer une paire de clé privée/publique.

Pour ceux qui n’auraient pas déjà une clé, on va en créer une à l’aide de l’outil ssh-keygen.

Les options utilisées :

  • -C : Nous permet d’ajouter un commentaire à la clé. Pour ma part je met mon adresse mail.
  • -t : Pour spécifier le type de clé qu’on créé.
  • -o : Sauvegarde votre clé dans le nouveau format openssh au lieu de l’ancien format PEM.
  • -a : C’est le nombre de tour de Key Derivation Function. Plus le nombre est élevé plus la vérification de la passphrase sera lente et donc résistante aux attaques brute force.
  • -f : Permet de précisier le répertoire de sortie de la clé.
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "VOTRE@EMAIL.com"

Lors de la création de votre clé une passphrase va vous être demandée, prenez garde à bien la retenir ou la noter dans votre utilitaire de gestion de mot de passe c’est très important de ne jamais la perdre.

La commande va générer un dossier .ssh/ dans votre répertoire utilisateur.

Ce dossier contiendra 3 fichiers :

  • id_ed25519 : Votre clé privée à ne jamais donner.
  • id_ed25519.pub : Votre clé publique qui sera partagée.
  • authorized_keys : Le fichier contenant les clé publiques des utilisateurs pouvant se connecter à votre machine/serveur.

Modification des permissions pour éviter les erreurs :

chmod 0700 ~/.ssh
chmod 0600 ~/.ssh/id_ed25519
chmod 0644 ~/.ssh/authorized_keys

Copie de la clé publique sur le serveur cible :

ssh-copy-id -i ~/.ssh/id_ed25519.pub login@IP_SERVER

La commande va se charger de générer un dossier .ssh/ sur le serveur contenant le fichier .ssh/authorized_keys et c’est dans ce fichier que notre clé id_ed25519.pub sera copiée, cela permettra d’effectuer la correspondance lors des futurs connexions.

Connexion pour valider notre configuration :

ssh login@IP_SERVER

Si vous avez bien effectué vos manipulations aucun mot de passe ne devrait vous être demandé.

Pensez à sauvegarder le contenu du dossier .ssh/ de votre machine sur votre NAS/Disque externe pour éviter de perdre l’accès à vos serveurs.

Configuration de openSSH Server

Avant toute modification du fichier /etc/ssh/sshd_config on en fait une copie :

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

Au cas où vous feriez une erreur lors de vos configurations vous aurez la possibilité de revenir à un fichier fonctionnel.

A l’installation du package openssh-server votre distribution le préconfigure, nous allons le modifier afin de :

  • Refuser les login depuis le root.
  • Refuser l’identification par mot de passe.
  • N’accepter QUE l’authentification par clé.
  • Changer le port par défaut du SSH.
  • Augmentation du niveau de log.
  • On force l’usage du protocol niveau 2.
  • On retire le support ECDSA & RSA.
  • Déclaration des utilisateurs systèmes pouvant se connecter via AllowUsers.
  • Prise en compte de l’IPv4 & IPv6.

Voici la configuration que cela donne :

# Interface & Port
Port 61022
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::

HostKey /etc/ssh/ssh_host_ed25519_key

Protocol 2

SyslogFacility AUTHPRIV
LogLevel VERBOSE

# Authentication restriction
LoginGraceTime 30s
PermitRootLogin no
StrictModes yes
MaxAuthTries 3
MaxSessions 5

PubkeyAuthentication yes
AllowUsers hmichael
AuthorizedKeysFile  .ssh/authorized_keys .ssh/authorized_keys2

HostbasedAuthentication no
IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
PermitEmptyPasswords no
PasswordAuthentication no

# Change to no to disable s/key passwords
ChallengeResponseAuthentication no

UsePAM yes

AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
PermitTTY yes
PermitUserEnvironment no
PrintMotd no
PrintLastLog no

#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
UseDNS yes
PidFile /var/run/sshd.pid
MaxStartups 10:30:100
PermitTunnel no
#ChrootDirectory none
VersionAddendum none

# no default banner path
Banner none

# Accept locale-related environment variables
AcceptEnv LANG LC_*

# override default of no subsystems
Subsystem   sftp   /usr/libexec/openssh/sftp-server

Si vous êtes sous CentOS avec SELINUX d’activé il faut ajouter une règle pour permettre l’accès via le nouveau port SSH déclaré dans la configuration :

sudo semanage port -a -t ssh_port_t -p tcp SSH_PORT

Au cas où il vous retournerait “semanage command not found” il vous suffit d’installer le pkg nécessaire via dnf install policycoreutils-python-utils -y et de relancer la commande précédente.

Pour prendre en charge la nouvelle configuration on relance le service openssh :

sudo systemctl restart sshd.service

Dorénavant pour se connecter en SSH il faudra préciser le nouveau port à l’aide de l’option -p :

# IPv4
ssh login@IP_SERVER -p SSH_PORT

# IPv6
ssh -6 login@IP_SERVER -p SSH_PORT

N’hésitez pas à en faire un alias dans votre .bashrc/.zshrc afin de gagner du temps :

alias NOM_ALIAS="ssh login@IP_SERVER -p SSH_PORT"

Si vous avez un firewall actif n’oubliez pas d’ajouter la règle pour accepter la connexion sur ce nouveau port.

Cette base de configuration est plus sécurisée mais elle n’augmente pas pour autant le niveau de chiffrement des communications effectuées au travers de SSH.

Augmentons la sécurité des échanges

On va sécuriser les échanges en jouant sur 3 options supplémentaires :

  • Ciphers : Le chiffrement utilisé.
  • KexAlgorithms : Les algorithmes utilisés pour l’échange de clé.
  • MACs : Message Authentication code, c’est le code qui accompagnent les données échangées dans le but d’assurer leur intégrité pour être certain qu’elles n’ont subies aucune altération pendant/après la transmission.

Pour forcer notre serveur à utiliser ces options il est nécessaire d’effectuer quelques modifications qui diffèrent selon votre distribution.

CentOS 8

  • Régénération de la clé ED25519 du serveur :
sudo rm -f /etc/ssh/ssh_host_*
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
sudo chgrp ssh_keys /etc/ssh/ssh_host_ed25519_key
sudo chmod g+r /etc/ssh/ssh_host_ed25519_key
  • Retrait des moduli Diffie-Hellman faible :
sudo awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe
sudo mv -f /etc/ssh/moduli.safe /etc/ssh/moduli
  • Désactivation des clés DSA/ECDSA & RSA si ce n’est pas déjà fait :
sudo sed -i 's/^HostKey \/etc\/ssh\/ssh_host_\(dsa\|ecdsa\|rsa\)_key$/\#HostKey \/etc\/ssh\/ssh_host_\1_key/g' /etc/ssh/sshd_config
  • Restriction des ciphers, clés d’échange et des codes d’authentification :
# Sauvegarde du fichier originel
sudo cp /etc/crypto-policies/back-ends/opensshserver.config /etc/crypto-policies/back-ends/opensshserver.config.orig

# On injecte nos ciphers, clé et codes d'authentification
sudo echo -e "CRYPTO_POLICY='-oCiphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com -oGSSAPIKexAlgorithms=gss-curve25519-sha256- -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512 -oHostKeyAlgorithms=ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oPubkeyAcceptedKeyTypes=ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-rsa-cert-v01@openssh.com'" > /etc/crypto-policies/back-ends/opensshserver.config
  • Redémarrage du service sshd :
sudo systemctl restart sshd.service

Debian 10 & Ubuntu Server 18.04/20.04

  • Régénération de la clé ED25519 du serveur :
sudo rm -f /etc/ssh/ssh_host_*
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
  • Retrait des moduli Diffie-Hellman faible :
sudo awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe
sudo mv -f /etc/ssh/moduli.safe /etc/ssh/moduli
  • Désactivation des clés DSA/ECDSA & RSA si ce n’est pas déjà fait :
sudo sed -i 's/^HostKey \/etc\/ssh\/ssh_host_\(dsa\|ecdsa\|rsa\)_key$/\#HostKey \/etc\/ssh\/ssh_host_\1_key/g' /etc/ssh/sshd_config
  • Restriction des ciphers, clés d’échange et des codes d’authentification :
# On injecte nos ciphers, clé et codes d'authentification
# Pour Ubuntu
sudo echo -e "\nKexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\nMACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com\nHostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com" >> /etc/ssh/sshd_config

# Pour Debian
sudo echo -e "\nKexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\nMACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com" >> /etc/ssh/sshd_config
  • Redémarrage du service sshd :
sudo systemctl restart sshd.service

Commandes utiles

Des commandes qui peuvent être utiles :

  • sshd -T : Vous permet de tester votre configuration et de débug.
  • ssh -Q cipher : Liste les ciphers disponible sur votre serveur.
  • ssh -Q cipher-auth : Liste les ciphers d’authentification.
  • ssh -Q mac : Liste les MAC.
  • ssh -Q kex : Liste les algorithmes.
  • ssh -Q key : Liste les clé.

Tester son serveur

Voici 2 outils vous permettant de tester le niveau de sécurité de votre serveur openssh.

  • Le site ssh-audit.
  • L’outil python ssh-audit utilisable depuis votre terminal disponible ici.

Et comme vous pouvez le constater le site me donne une belle note de 100% (Serveur CentOS8) :

SSH-Audit100