Petit rappel sur le forward d'agent SSH et solutions.
Si comme moi vous êtes admin sys, vous utilisez forcément SSH au quotidien pour gérer votre parc [...] Et si vous êtes un vrai admin sys, vous utilisez aussi forcément une clef SSH pour vous connecter plutôt qu’un mot de passe. Sauf qu’il est plus que pénible d’avoir à saisir sa phrase de passe avant chaque connexion à une machine, et donc il est plus que probable que vous utilisiez aussi un agent SSH pour charger vos clefs une bonne fois pour toutes à la première connexion.
[...] En effet, on a bien souvent certaines machines qui ne sont pas directement accessibles sur Internet (les machines virtuelles généralement), mais nécessitent une machine de rebond (bounce) pour y parvenir. Dans les grands parcs, il n’est même pas rare d’avoir une unique machine exposée dans la zone démilitarisée (DMZ), toutes les autres étant bien à l’abri derrière les pare-feux. Avec l’agent forward, notre agent SSH va se propager au travers du réseau via les machines auxquelles on se connecte, permettant ainsi de se connecter aux machines finales sans mot de passe et sans avoir à copier notre clef SSH sur chaque machine intermédiaire. La plupart du temps, l’admin sys étant un fainéant notoire, il a tendance à activer l’agent-forwarding par défaut pour ne pas avoir à se préoccuper du chemin à suivre pour joindre une machine et ainsi pouvoir accéder à n’importe quelle machine du parc depuis n’importe quelle autre.
Les deux fonctionnalités (ssh-agent + agent-forward) cumulées peuvent avoir un impact très important sur la sécurité de vos clefs SSH. Votre agent SSH local charge toutes vos clefs SSH au démarrage, et se chargera de les proposer à votre client SSH quand il en aura besoin. [ NDLR : je suis très sceptique sur ce point. Il faut faire un ssh-add pour chaque clé et filer la passphrase kiVaBien. Or, cette passphrase est forcément différente pour chaque clé, si vous faites les choses bien. ] Pour la communication avec le client SSH, l’agent met à disposition un socket UNIX de la forme /tmp/ssh-/agent.<pid de l’agent> et le publie dans la variable d’environnement SSH_AUTH_SOCK. Lorsqu’on fait du transfert d’agent, ce socket va se propager sur chaque machine intermédiaire pour assurer la communication avec le client SSH, toujours via la variable SSH_AUTH_SOCK.
Et c’est là que quelque chose de terrible peut se produire… Le transfert d’agent crée aussi un socket UNIX sur la machine intermédiaire, socket qui est un simple fichier quelque part sur le disque. Et donc tout utilisateur capable de lire ce fichier peut communiquer avec votre agent SSH transféré ! Toute personne connectée sous le même utilisateur SSH que vous peut le faire. L’utilisateur root peut le faire. L’administrateur de l’hôte physique hébergeant votre machine virtuelle peut le faire (cas des VPS, mutualisés, etc). Pour exploiter ce socket, il suffit à un attaquant de trouver le socket (un simple ls /tmp/ssh-* lui les listera tous) et de définir manuellement la variable d’environnement SSH_AUTH_SOCK pour utiliser votre agent SSH…
Là où ça pique vraiment, c’est que votre agent SSH de départ connaît toutes vos clefs. Pas seulement celle que vous avez réellement utilisée pour votre chaîne de connexion. Toutes. Si vous avez par exemple une clef A pour vos machines persos et une clef B pour vos machines pros, que les deux sont chargées dans l’agent que vous avez exporté, votre collègue connecté en même temps peut alors se connecter à toutes vos machines perso !
Heu ? Quelle idée d'avoir sa clé perso sur les machines du taff ? :O Bon, dans ton cas, t'as partoche chiffrée et y'a pas d'autres root que toi sur ton desk@taff mais ce n'est pas le cas de la majorité des gens.
Maintenant qu’on a vu comment on pouvait exploiter l’agent SSH des autres, voyons comment on peut se prémunir de ce genre de problème.
Ne pas utiliser de transfert d’agent SSH
On peut conserver les possibilités de rebond via l’option ProxyCommand et -W de SSH.
En pratique, sur des infrastructures un peu complexe, cette possibilité est très vite limitante puisque ça devient très vite l’enfer si on doit passer par plus d’une machine intermédiaire et qu’en plus on ne peut plus joindre les machines finales à partir de n’importe quelle autre machine (il faut obligatoirement revenir à la machine locale).
Limiter le transfert d’agent à la seule clef utilisée
L’option
IdentitiesOnlyexiste dans SSH pour limiter les clefs possibles pour un agent SSH. Si vous voulez donc l’activer par défaut, il faut ajouter à votre ~/.ssh/config [...]Vos chaînes de connexion doivent du coup utiliser la même clef SSH à chaque rebond, ce qui peut parfois être problématique (par exemple vos frontaux sécurisés n’acceptent que les clefs ED22519 quand vos vieilles machines finales en sont restées à RSA-4096).
Cloisonner les clefs SSH via des agents multiples
L’un des gros problèmes de la « faille » de l’agent SSH est surtout que l’agent expose l’ensemble de vos clefs SSH, et non pas uniquement celles concernées par la connexion établie. À la limite, si GitHub ne pouvait avoir accès qu’à ses propres machines, vous aux vôtres et vos collègues à celles de votre parc professionnel, il n’y aurait plus vraiment de problème.
L’idéal serait donc d’avoir un agent SSH par groupe de connexion (pro, perso, dev, git…), chacun chargé uniquement des clefs qui vont bien. Ça aurait en plus l’énorme avantage d’alléger le nombre de clefs par agent, et donc d’accélérer les connexions, l’agent testant les clefs disponibles les unes après les autres jusqu’à parvenir à se connecter (ce qui peut en plus causer des problèmes si vous avez trop de clefs qui échouent ou un fail2ban en face).
SSH ne gère nativement pas cette séparation, il va donc falloir ruser un peu.
SSH-Ident a été développé initialement par Carlo Contavalli et j’ai corrigé 2 ou 3 trucs dessus (support de SSH_ASKPASS, suppression des invocations bash…). Il remplace SSH et se base sur les options passées à SSH pour déterminer à quelle identité raccrocher la connexion. Chaque identité se trouve isoler dans un sous-répertoire de ~/.ssh/identities/, avec son fichier de configuration, ses clefs SSH propres, son agent SSH…
rsync et autres outils liés à SSH ne posent pas de soucis particuliers avec SSH-Ident. Je rencontre uniquement des problèmes avec scp, qui cherche à invoquer ssh via un chemin en dur et non via le mécanisme du PATH, ainsi que sur la machine distante ce qui pose des problèmes si SSH-Ident est aussi déployé là-bas. [...]