Utilisation du serveur OpenSSH en pratique

Linux Pratique n° 108 | juillet 2018 | Nicolas Greneche
Creative Commons
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Dans un article précédent, nous avons détaillé l'utilisation du client OpenSSH. Nous allons maintenant voir comment mettre en place votre propre serveur OpenSSH en continuant à suivre les aventures de Johannes et Alice.

Dans cet article nous allons voir comment mettre en place un serveur OpenSSH. Dans les distributions Linux courantes c'est une chose assez aisée. L'étape suivante sera de le rendre disponible à l’extérieur en configurant la règle de redirection sur le pare-feu du site. Enfin nous durcirons la sécurité de notre serveur par quelques mesures très simples.

1. Poursuite du cas pratique

Johannes a quand même du travail pour permettre à Alice d'accéder à sa machine en SSH. L'installation du serveur OpenSSH n'est pas si compliquée. Comme nous allons le voir c'est très bien intégré aux différents systèmes de gestion de paquets. Il lui faudra ensuite configurer une redirection de port sur son pare-feu pour que Alice puisse se connecter depuis l’extérieur sur sa machine. Le pare-feu de Johannes dispose de deux interfaces réseaux. La première est connectée au routeur de son site. En gros, cette patte du pare-feu est connectée à Internet. La seconde est connectée à la distribution de son site. La distribution est l'ensemble des commutateurs du site sur lesquels sont branchés les clients finaux. En conséquence, lorsqu'une machine de l’extérieur veut communiquer avec une machine de la société Avatar elle doit obligatoirement passer par le pare-feu. De façon analogue, lorsqu'une machine de la société Avatar doit communiquer avec une machine de l’extérieur elle doit également passer par le pare-feu. On dit que le pare-feu est un composant mandataire de sécurité. Le mot mandataire est un synonyme d'obligatoire très usité en sécurité informatique. Le trafic réseau est donc transféré d'une interface à l'autre.

Johannes doit donc configurer une règle de redirection de trafic pour que le trafic arrivant sur le port TCP 6822 de son pare-feu répondant au doux nom fw.avatar.com soit redirigé vers la machine pc-boulot d'Alice sur le port TCP 22 (le port standard du serveur SSH). C'est pour cette raison que dans le premier article Alice devait se connecter sur le pare-feu et pas en direct sur sa machine. Pour mémoire, les machines internes au réseau ne sont pas accessibles de l’extérieur car elles sont situées sur des plages réseau privées.

2. Installation du serveur OpenSSH

Commençons par installer le serveur OpenSSH sur la machine pc-boulot d'Alice (il va sans dire que Johannes a l'accès root sur cette machine). Comme je l'ai mentionné, c'est intégré au service de gestion de paquet :

johannes@pc-boulot:/home/johannes# sudo apt-get install openssh-server

Lors de l'installation du paquet, je voudrais attirer l'attention du lecteur sur ces lignes :

Creating SSH2 RSA key; this may take some time ...

2048 SHA256:BLUkgjGdbcFX9wCsfOoIG4gtkdSeex4K/xcnsRo0qEA root@pc-boulot (RSA)

Creating SSH2 DSA key; this may take some time ...

1024 SHA256:Ug9fJa14YMR9Fud/7bXTokffK/hM/sBVse10nSR/6Y8 root@pc-boulot (DSA)

Creating SSH2 ECDSA key; this may take some time ...

256 SHA256:Rh6izWEXkCV6HZLIpzlGQje178vhDgb77ItaZgpDsIQ root@pc-boulot (ECDSA)

Creating SSH2 ED25519 key; this may take some time ...

256 SHA256:UD4b7njwxWp1Q3wYf2R//udgPRzfGaeZ/6kE3VgZM+s root@pc-boulot (ED25519)

A l'installation du serveur OpenSSH, le gestionnaire de paquet lui génère ses clés. Lorsqu'un utilisateur se connecte pour la première fois à un serveur OpenSSH, celui ci lui présente une empreinte. Cette empreinte est dérivée de ces clefs. Ainsi, lorsque le client valide l'empreinte, il l'associe de façon durable au serveur auquel il est connecté. Si l'empreinte présentée change, le client va refuser de se connecter et lever une alerte. Cette association serveur / empreinte est enregistrée dans le fichier known_hosts du client.

A la fin de l'installation, nous disposons de l’exécutable /usr/sbin/sshd qui est le serveur OpenSSH. Voyons si il est en exécution sur la machine :

johannes@pc-boulot:/home/johannes# sudo netstat -laputn -A inet | grep sshd

tcp        0      0 0.0.0.0:22            0.0.0.0:*               LISTEN      1296/sshd

L'outil netstat permet (entre autres) de lister les sockets ouverts sur une machine. Ici on voit bien qu'un processus sshd (avec le PID 1296) écoute sur le port TCP 22 de l'adresse 0.0.0.0. Pour faire simple, on peut dire que cette adresse désigneles adresses IP de toutes les interfaces réseau de la machine.

3. Configuration du pare-feu

Johannes doit maintenant passer à la configuration de son pare-feu. Pour cela il doit faire en sorte que ce qui arrive sur le port 6822 de son pare-feu soit redirigé vers le port 22 de la machine pc-boulot d'Alice. La toute première étape est d’autoriser le transfert de trafic réseau entre les deux interfaces du pare-feu. Cette autorisation se positionne au niveau du noyau. Sous Linux les développeurs du noyau ont prévu de laisser des attributs accessible par l'utilisateur root pour en modifier le comportement. Ces attributs sont configurables via la commande sysctl. Dans le cas présent, ce qui nous intéresse c'est d'autoriser le transfert de paquets IP d'une interface à l'autre. Il s'agit de l'attribut net.ipv4.ip_forward. L'interface interne est eno2 et celle connectée à Internet est eno1. Pour que ça perdure dans le temps il faut faire ça dans le fichier /etc/sysctl.conf :

root@fw:/root# cat /etc/sysctl.conf

net.ipv4.ip_forward = 1

Et ensuite rafraîchir les variables avec la commande suivante :

root@fw:/root# sysctl -p

Configurons maintenant la redirection à proprement parler. Ce sont juste deux commandes IPTables à entrer. La commande iptables permet à l'utilisateur root d'ajouter ou de supprimer des règles de filtrage réseau. Ici nous allons ajouter deux règles.

La première est sur l'interface réseau eno1 connectée à Internet. Elle permettra aux machine internes de sortir sur Internet avec l'adresse IP publique associée à l'interface eno1. En fait c'est une règle analogue à celle qui est positionnée sur la box personnelle d'Alice pour lui permettre d'aller sur Internet en utilisant son IP publique. Voici la règle en question :

root@fw:/root# iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE

Cette règle indique qu'une fois routé par l'interface de sortie eno1 le trafic doit être « masqué » (masquerade) c'est à dire qu'une translation d'adresse est appliquée pour substituer l'adresse source du trafic par celle de l'interface eno1 routable sur Internet (afin que la machine contactée puisse répondre). On notera qu'il peut paraître dangereux au lecteur de permettre à toutes les machines internes de sortir sur Internet en direct. En réalité, on peut limiter la portée de cette règle grâce au paramètres -s (source, c'est à dire quelle machine interne peut sortir) ou -d (destination, c'est à dire vers qui les machines peuvent sortir).

La seconde effectue la redirection à proprement parler. Elle se positionne évidemment sur eno1. La voici :

root@fw:/root# iptables -t nat -A PREROUTING -i eno1 -p tcp --dport 6822 \

-j DNAT --to pc-boulot:22

Cette règle nous indique que les paquets arrivant sur le port destination 6822 (--dport) de l'interface eno1 (-i) doivent être redirigés vers pc-boulot sur le port 22 (--to). On notera que le couple d'options –dport et -i est totalement raccord avec les paramètres de connexion utilisés par Alice dans le premier article. On pourrait penser que cette règle est suffisante, sauf que la première la complète pour que les machines internes contactées puissent répondre.

Je finirais cette partie par une note. Il est fort probable qu'avant d'installer un accès pour Alice la société Avatar disposait d'un pare-feu fonctionnel pour filtrer les entrées / sorties réseau. La conséquence est que la politique par défaut est sans doutes de ne laisser entrer que ce qui est autorisé. Dans ce cas Johannes doit ajouter une troisième règle :

root@fw:/root# iptables -A FORWARD -i eno1 -p tcp --dport 6822 -d pc-boulot -j ACCEPT

Cette règle autorise le trafic à traverser l'interface pour être redirigé vers la machine d'Alice.

4. Configuration du serveur OpenSSH

On y est, toute la tuyauterie est en place. Dans l'absolu, avec les paramètres de configuration par défauts Alice doit pouvoir se connecter de chez elle sur sa machine de travail. Dans un premier temps, nous allons vérifier si la configuration couvre bien les besoins fonctionnels d'Alice. Pour cela, je vais d'abord discuter quelques paramètres de configuration du serveur sshd. Pour mémoire Alice a besoin de deux choses : 1) utiliser des clés SSH 2) permettre à son IDE lancé sur pc-boulot de produire ses affichages sur son portable. Tout se passe dans le sshd_config :

johannes@pc-boulot:/home/johannes# sudo cat /etc/ssh/sshd_config

[...]

AuthorizedKeysFile     .ssh/authorized_keys .ssh/authorized_keys2

[...]

X11Forwarding yes

le premier paramètre AuthorizedKeysFile indique que Alice doit mettre la partie publique de sa clé (contenu du fichier avatar.pub dans l'article précédent) dans le fichier /home/alice/.ssh/authorized_keys (l'autre fichier étant en voie d'obsolescence). La valeur de l'attribut est relatif à l'emplacement de la home de l'utilisateur. En effet, lorsque l'utilisateur se connecte, le serveur sshd fork un processus bash qui s’exécute avec l'identité et l’environnement de l'utilisateur. Le second paramètre (X11Forwarding) permet aux applications lancées sur la machine cible d'une connexion SSH d'utiliser le serveur X de la machine qui se connecte pour produire ses affichages. Voilà pour la configuration basique. Alice peut maintenant travailler de chez elle. Mais bon quand on parle de SSH, on parle de sécurité ! Nous allons donc durcir un peu la configuration.

5. Durcissement de la configuration de sshd

Avant toute mesure de durcissement il faut se poser la question de savoir quel utilisateur doit pouvoir passer administrateur sur cette machine. Dans ce cas la, il y a fort à parier que ça va concerner Johannes pour l'administration et Alice pour pouvoir ajouter / retirer des programmes. Sous Ubuntu le compte root est désactivé et on doit passer par sudo. Johannes est déjà dans le groupe sudo, on peut ajouter Alice :

johannes@pc-boulot:/home/johannes# sudo usermod -aG sudo alice

Maintenant Alice peut lancer des commandes avec les privilèges d'administrateur sur sa machine. Puisque plus personne n'a besoin d'être directement root, on peut désactiver l'accès root dans le sshd_config :

PermitRootLogin no

En effet le compte root a beau être désactivé, il ne l'est que si on passe par la PAM pour s'authentifier. L'authentification par clés n'est pas liée à la PAM. En conséquence, si on ne configure pas cette directive, un accès root est potentiellement possible. D'ailleurs, comme on en est à restreindre les utilisateurs, on peut limiter explicitement l'accès SSH à Alice et Johannes. C'est ce que permet la directive AllowUsers :

AllowUsers alice johannes

Il existe trois autres directives assez explicites : AllowGroups, DenyUsers et DenyGroups. Mon conseil est de pas trop les combiner car le plus restrictif l'emporte. Par exemple les Allow ne s'additionnent pas. Si vous déclarez un AllowGroups avec la valeur toto et que vous mettez dans AllowUsers un utilisateur titi qui n'est pas dans le groupe toto alors titi ne pourra pas se connecter.

Une troisième mesure très efficace est de changer le port par défaut de SSH. La plaie des accès à distance de manière générale ce sont les tentatives d'attaque par force brute. Les attaquants utilisent des programmes qui essayent plein de couples identifiant / mot de passe sur la machine pour tenter d'obtenir un accès. Cependant avant de tenter une force brute, il faut d'abord trouver le point d'entrée (c'est à dire un port réseau ouvert sur la machine). Le changement de port rend cette découverte bien plus compliquée (voire impossible, sauf si on est victime d'une attaque ciblée). Pour Alice, pas besoin ! Elle est cachée derrière le pare-feu de Johannes. Maintenant si sa machine était directement exposée sur Internet, il faudrait utiliser la directive suivante :

Port 6822

On notera qu'il existe plein d'autres possibilités de dissimulations de services : Port Knocking, Single Packet Authentication etc. Le changement de port à l'avantage de la simplicité et de ne pas nécessiter d'ajouter des logiciels côté client pour que ça fonctionne.

6. Protection du service sshd

La dernière étape de protection de notre service sshd est de lui adjoindre un logiciel tierce nommé fail2ban pour mettre les attaquants par force brute en liste noire. Il faut savoir que chaque tentative d’authentification au service sshd produit un entrée dans le fichier de log /var/log/auth.log

johannes@pc-boulot:/home/johannes# sudo grep alice /var/log/auth.log

Apr 20 15:37:53 pc-boulot sshd[4589]: Accepted password for alice from pc-portable port 41790 ssh2

Apr 20 15:37:53 pc-boulot sshd[4589]: pam_unix(sshd:session): session opened for user alice by (uid=0)

Apr 20 15:37:53 pc-boulot systemd-logind[4589]: New session 5189 of user alice.

Or si on se trompe :

Apr 21 09:37:06 pc-boulot sshd[4589]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=pc-pirate  user=nico

C'est typiquement le genre de ligne répétée un grand nombre de fois qu'on retrouve dans les logs. La signature d'une attaque par force brute et qu'on trouve plein de tentative pour des utilisateurs différent (user=) mais provenant toutes de la même machine (rhost=). L'idée derrière fail2ban est de surveiller le fichier /var/log/auth.log pour bloquer les attaquants en bloquant la machine identifiée par rhost qui fait trop de tentatives ratées.

Pour faire cela, fail2ban s'appuie sur deux composants : iptables et inotify. Plus besoin de présenter le premier ! Le second est un mécanisme implémenté dans le noyau qui remonte les événements sur les fichiers. Un programme peut donc s'accrocher à cette source d'information via une API (il en existe dans quasiment tous les langages) pour déclencher des actions sur certaines de ces informations. Ainsi, fail2ban traque les ajouts de ligne dans le fichier auth.log et il cherche, via un expression régulière, si il s'agit d'une tentative ratée et d’où elle vient puis il la garde en mémoire. A partir de la, si cette source tente trop de connexion ratées alors fail2ban crée une règle iptables pour bloquer cette source d'attaque (ou cet utilisateur maladroit). Pour installer fail2ban et le mettre en œuvre sur la machine d'Alice c'est très simple :

johannes@pc-boulot:/home/johannes# sudo apt-get install fail2ban

Et voila ! Tout est prêt. Il n'y a rien d'autres à faire pour une configuration standard. En pratique, cette configuration est un peu trop laxiste. Mon conseil est de la durcir avec les paramètres suivants positionnés dans le fichier /etc/fail2ban/jail.d/custom.conf :

johannes@pc-boulot:/home/johannes# sudo /etc/fail2ban/jail.d/custom.conf

[DEFAULT]

findtime = 3600

bantime = 86400

maxretry = 3

Ce qui signifie que 3 tentatives de connexions ratées (maxretry) provenant de la même adresse dans un intervalle de 3600 secondes (findtime) soit 1h entraînent un blocage de cette adresse pendant 86400 secondes (bantime) soit une journée. Enfin si votre serveur est configuré sur un port non standard, il faudra ajouter la section suivante au custom.conf :

[sshd]

enabled = true

port = 6822

Voilà pour fail2ban.

Conclusion

Ces deux articles complémentaires vous ont donné les clés nécessaires à l'exploitation d'un serveur OpenSSH dans un environnement de production en suivant les aventures de Johannes et Alice. Il y aurait encore beaucoup de choses à discuter mais en conclusion je vais vous inviter à parcourir un excellent ouvrage certes un peu daté mais néanmoins assez complet sur le sujet : SSH, The Secure Shell : The Definitive Guide, 2nd Edition aux éditions O'Reilly. En combinant ce livre avec la lecture de la page de man du fichier sshd_config vous serez à l'état de l'art de l'utilisation d'OpenSSH !

Tags : OpenSSH