# Labo SSH Ces notes sont principalement issues d'un atelier pratique s'étant déroulé le 7/12/2020. Certains sous-titres ont été augmentés par la suite. ## Objectif du labo : L'objectif était d'apprendre à générer et à utiliser une paire de clés SSH pour se connecter à une machine distante. Comme machine distante à laquelle se connecter, nous avons utilisé Raoul, la brique de test (merci Raoul !). ## Utilité des Clés SSH Les clés SSH permettent de se connecter à une machine distante sans utiliser un couplage nom d'utilisateur / mot de passe. Une identification par nom d'utilisateur peut en effet faire l'objet d'une attaque par brute force. L'usage de clés est plus sécurisé. Lorsqu'on utilise des clés SSH, l'authentification se fait sur la base du couplage clé privée / clé publique. Une fois la clé publique copiée dans le fichier des clés autorisées du serveur, il n'est possible de se connecter à la machine qu'en possédant la clé privée. On peut alors désactiver totalement la possibilité de se connecter au serveur via SSH avec un nom d'utilisateur et un mot de passe. ## Une identité Une clé SSH correspond à une identité. Elle est liée à la machine avec laquelle on se connecte. Techniquement, elle peut-être copiée dans une autre machine mais une bonne pratique est d'avoir une clé par machine. En cas de problème, ceci facilite le débuggage : on voit tout de suite d'où provient la connexion qui pose problème. ## Combien de clés utiliser ? Il y a plusieurs positions par rapport à cette question. Certains préféreront avoir une clé unique pour tout, d'autres une clé par serveur. On peut trouver un milieu en utilisant une clé par groupe de serveurs. Utiliser plusieurs clés permet de ne pas devoir changer partout au cas où l'une des clés est compromise (bien qu'en cas de perte de l'ordinateur, il faille tout changer quand même). Utiliser plusieurs clés, par serveur ou par groupe de serveur, permet également d'utiliser des niveaux de sécurité différents : des clés qui permettent une connexion sans mot de passe pour des services peu critiques et des clés avec des mots de passe d'une complexité croissante pour des situations plus critiques. ## Backup En cas de réinstallation, on peut conserver sa clé sur un support externe et la replacer dans le dossier ~/.ssh (mais en gardant à l'idée qu'il s'agit d' 1 identité pour 1 machine) ## Génération d'une paire de Clés SSH On peut générer une paire de clés SSH avec la commande : ```ssh-keygen -t ed25519 -f ~/.ssh/test -N neutrinet``` Où : * ssh-keygen indique qu'on va générer des clés * -t ed25519 indique qu'on va utiliser un algorithme de courbe élliptique. Celui-ci est plus sécurisé que le chiffrement RSA utilisé par défaut par ssh-keygen (mais n'est pas toujours supporté par tous les systèmes) * -f ~/.ssh/test indique le chemin du fichier dans lequel sera généré la clé * -N neutrinet indique la phrase de passe qu'il faudra taper lors de la connexion avec la clé SSH, ici "neutrinet" (c'est pour tester). Pour éviter de laisser sa phrase de passe en claire dans son historique, on peut se passer de ce dernier argument. Le mot de passe est alors demandé interactivement. La commande ci-dessus renvoie : ``` Generating public/private ed25519 key pair. Your identification has been saved in /home/celo/.ssh/test Your public key has been saved in /home/celo/.ssh/test.pub The key fingerprint is: SHA256:jfw71QpaoBmO0Q2cZIR3XrTSGC8Uvgeu+ZP8wFm85qM celo@sushi The key's randomart image is: +--[ED25519 256]--+ | =+.+o. | | ..=o.=.. | | o =*.+ | | . oo+O | | + +S.= . | | . ++ =o.. . | | o.+++o . | | .=+o.. | | E++o | +----[SHA256]-----+ ``` Deux fichiers ont été enregistrés, la clé publique avec une extension .pub et la clé privée (fichier sans extension). Les deux fichiers n'ont pas les mêmes permissions. La clé privée doit être conservée secrètement. La clé publique sera copiée sur le serveur auquel on souhaite accéder par cette clé. On peut ouvrir la clé publique pour copier son contenu avec : ``` cat ~/.ssh/test.pub ``` ## Usage des clés SSH ### Copie de la clé publique sur le serveur Dans le cadre de ce labo, on connaît les identifiants de la brique Raoul. On va donc pouvoir placer nous-mêmes notre clé dans le fichier authorized_keys du serveur : ``` celo@sushi:~$ ssh admin@cube.example.com admin@cube:~$ cd ~/.ssh admin@cube:~/.ssh$ nano authorized_keys ``` Si le fichier est créé pour la première fois, il faut lui donner les bonnes permissions (lecture/écriture uniquement pour l'utilisateur) avec : ```chmod 600 authorized_keys``` ### Connexion avec ssh -i Pour se connecter à Raoul, on peut ensuite se connecter avec la clé SSH sans taper le mot de passe admin de la brique : ```ssh -i ~/.ssh/test admin@cube.example.com``` Où : * ssh -i indique qu'on va se connecter avec une identité spécifique (une clé SSH) * ~/.ssh/test indique l'emplacement de la clé à utiliser * admin@cube.example.com indique l'utilisateur avec lequel on veut se connecter sur la brique et le domaine auquel est destinée la connexion ### Configuration du client SSH La méthode ci-dessus fonctionne mais n'est pas vraiment pratique, notamment si l'on a beaucoup de clés et de serveurs auxquels se connecter. Il faut copier le chemin vers la clé à chaque fois et on ne sait pas facilement quelle clé correspond à quoi. Pour faciliter les choses, on peut éditer notre fichier de configuration SSH pour l'emploi des différentes clés : ```nano ~/.ssh/config``` Pour la brique Raoul, on écrit les lignes qui suivent : ``` Host cube.example.com PreferredAuthentications publickey,password IdentityFile ~/.ssh/test User admin Port 22 ``` Où : * Host indique le nom de domaine ou l'IP du serveur * PreferredAuthentications indique les méthodes préférées d'authentification. Ici, "publickey" signifie qu'on préfère utiliser une clé SSH. "password" indique qu'en second lieu, dans le cas où cette clé ne correspond pas, on souhaite se connecter avec un identifiant et un mot de passe. * IdentityFile indique le chemin de la clé utilisée * User indique l'utilisateur pour la connexion * Port indique le port à utiliser Après ces modifications, on peut se connecter sur la brique Raoul uniquement en tapant : ```ssh cube.example.com``` ## SSH-Agent Lors d'une session par clé SSH, si l'on sait qu'on va devoir se reconnnecter plusieurs fois au serveur et que l'on ne souhaite pas retaper plusieurs fois un mot de passe long, on peut utiliser un processus qui s'appelle le SSH-agent. Le SSH-agent va tourner en arrière plan et peut prendre des commandes. Il va exporter une variable d'environnement contenant le chemin vers le socket sur lequel le SSH-agent écoute. * eval $(ssh-agent) : lance l'agent * pgrep ssh-agent -a : montre les agents en exécution * ssh-add : permet de gérer des clés comme un gestionnaire de mots de passe * ssh-add ~/.ssh/test : ajoute la clé de test pour Raoul * ssh-add -l : liste les clés accessibles à l'agent * ssh -A : utilise l'agent pour se connecter à d'autres serveur une fois connecté sur un premier serveur. C'est un peu comme un Jump mais c'est moins sécurisé. Cela permet néanmoins d'utiliser sa clé pour se connecter à d'autres serveurs. Lorsqu'on utilise plusieurs clés et qu'on communique avec plusieurs machines, on peut configurer SSH agent pour éviter de devoir ajouter manuellement la clé à l'agent. Pour cela, on crée le fichier ''ssh-agent.service'' dans ''~/.config/systemd/user/'' . Comme les dossiers systemd et user n'existent pas forcément, il faut les créer (on utilise -p pour créer les deux dossiers d'un coup) : ``` mkdir -p ~/.config/systemd/user ``` Puis on édite le service : ``` nano ~/.config/systemd/user/ssh-agent.service ``` On colle le contenu : ``` [Unit] Description=SSH key agent [Service] Type=simple Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket ExecStart=/usr/bin/ssh-agent -t 1h -D -a $SSH_AUTH_SOCK [Install] WantedBy=default.target ``` Avec l'option `-t` on peut définir la durée de validité des clés SSH, ce qui est pratique pour ne pas avoir une dizaine de clés actives à la fin de la journée. Lorsque la config a été créée, on fait: ``` systemctl start --user ssh-agent systemctl enable --user ssh-agent ``` Dans la config `~/.bashrc` ou `~/.zshrc`, on rajoute: ``` export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" ``` Enfin, on ouvre un nouveau terminal et on vérifie que le ssh-agent tourne: ``` ssh-add -l ``` On rajoute également la commande magique dans `~/.ssh/config` pour que SSH rajoute les clés qu'il utilise directement dans le SSH agent: ``` AddKeysToAgent yes ``` ## Utilisation de screen Screen tourne en arrière plan et permet de garder ce qu'on est en train de faire si on est déconnecté du serveur (évite ainsi aussi de perdre ou de corrompre des données si la connexion est interrompue). Une fois reconnecté, il suffit de se reconnecter à screen. Screen permet aussi de travailler à plusieurs sur le même shell en permettant de partager la même session depuis plusieurs machines. Lorsqu'on est dans la même session screen, on voit toutes les commandes qui y sont effectuées par les autres participants. Les commandes screen sont : * Ctrl + D : quitte / tue screen s'il ne reste qu'une session * Ctrl + A et commande d : permet de détacher le screen sans le tuer * screen -ls : liste des screen existants * screen -r : rattacher un screen existant * screen -s : permet de partager un screen * screen -x : permet de se rajouter à un screen existant En cas de coupure de courant ou de réseau alors qu'on effectue des manipulations sur le serveur, le screen sera détaché comme avec Ctrl + A et d, mais restera actif. On pourra le rattacher à la reconnexion. ## Ressources : - https://simonlefort.be/informatique:ssh (génération et gestion des clés SSH) - https://www.ssh.com/ssh/agent (SSH-agent) - https://km.azerttyu.net/Screen-ssh-que-du-bonheur (screen) - https://tutox.fr/2020/04/16/generer-des-cles-ssh-qui-tiennent-la-route/ (DSA. RSA ? ECDSA ? ed25519 !) - https://wiki.archlinux.org/title/SSH_keys#Start_ssh-agent_with_systemd_user