arthur.bebou

Le site arthur.bebou.netlib.re - retour accueil

git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |

commit d5f8eaceeb3dcc442142bdd4f6ae7d143db2e6f7
parent f6409580b0e21f5fb8d097a6b0bddbc68d115bf1
Auteurice: Arthur Pons <arthur.pons@unistra.fr>
Date:   Thu, 14 Nov 2024 11:16:05 +0100

Nouvel article à propos de mosh et ssh

Diffstat:
Acontents/mosh-multi/index.sh | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+), 0 deletions(-)

diff --git a/contents/mosh-multi/index.sh b/contents/mosh-multi/index.sh @@ -0,0 +1,134 @@ +#! page +title: Mosh, IRC, les multi-connections ssh et NAT +author: Arthur Pons +description: Comment faire de la multiconnection ssh à travers mosh sur un serveur derrière un NAT +publication: 2024-11-14 + +sectionmd: main + +Sur bebou nous avons un serveur IRC. J'aime bien avoir une fenêtre ouverte en +continu sur le serveur afin de répondre rapidement aux copaines. L'objectif est +: + + * de ne rater aucun message sur le serveur IRC + * de ne pas avoir à se reconnecter et relancer la session quand on coupe la + connexion + * de profiter de cette session constamment ouverte pour accélerer toutes les + commandes ssh qu'on lance ensuite + +## Ne rien rater de ce qui se raconte sur IRC + +À la création d'un compte, le serveur lance automatiquement une session +[tmux](https://github.com/tmux/tmux/wiki) avec un client IRC dedans. De cette +manière quand une personne quitte sa session, tmux continue à tourner, le client +reste ouvert et ainsi elle ne passera à côté d'aucun message. + +A l'usage c'est génial *sauf que* si vous utilisez ssh vous n'êtes pas sans +savoir que c'est fragile. ssh fonctionne de telle manière à ce que la connexion +saute au moindre souci. Vous avez perdu la wifi pendant une seconde ? Plus de +connexion. Vous avez mis votre ordi en veille ? Plus de connexion. La session +tmux permet de ne pas perdre l'état de la session sur laquelle vous étiez[^1] +mais il faudra tout de même vous y reconnecter. + +## Ne jamais perdre sa connexion + +C'est là qu'intervient [mosh](https://mosh.org). Je ne vous fais pas la réclame +complète, vous pouvez aller sur le site du projet directement. Ce qui nous +intéresse ici est principalement la capacité de `mosh` à récupérer la connexion +là où elle s'est arrêtée partout où avec ssh elle aurait ét morte pour de bon. +On ouvre la session une fois au démarrage de son pc puis on l'oublie, elle sera +toujours vivante. *Second besoin satisfait*. + +Si vous en êtes là vous constaterez une chose : lancer une nouvelle commande +ssh prend tout de même du temps. En effet, par défaut, le client ssh initie une +nouvelle connexion pour chaque ouverture de session. Il faudra repasser par +tout le système d'authentification à chaque fois, ce qui prend du temps. +On pourrait penser qu'il est possible de réutiliser la connexion existante et +ainsi s'économiser de précieuses secondes. + +## Réutiliser la connexion + +Effectivement, c'est possible avec la configuration ssh suivante, à mettre dans +son `~/.ssh/config` : + + Host * + ControlMaster auto + ControlPath ~/.ssh/sh-%r@%h:%p + ControlPersist yes + + * `Host *` : Pour toute connexion + * `ControlMaster auto` : utiliser une connexion existante si elle existe, + sinon la créer + * `ControlPath ~/.ssh/sh-%r@%h:%p` : Le chemin du socket par lequel passer + sera `~/.ssh/sh-%r@%h:%p`. `%r` est le nom du compte, `%h` le nom de la + machine et `%p` le port + * `ControlPersist yes` : Si une connexion se termine, laisser le socket + ouvert (jusqu'à redémarrage de la machin) pour toute autre connexion + +La dernière ligne est essentielle si l'on utilise mosh. À la connexion mosh +ouvre une connexion ssh pour échanger des clefs de chiffrement, la ferme +instantanément puis ouvre une session mosh. `ControlPersist yes` permet de +conserver le socket créé à cette occasion même après la fermeture de la +connexion ssh. + +**Sécurité** : avant d'adopter cette configuration demandez vous si cela vous +expose à un risque que vous ne pouvez pas accepter. En effet si on la combine +avec un agent ssh relaxe, du type à ne presque jamais demander le mot de passe +des clefs ssh, c'est la porte ouverte à toute connexion du moment que l'on +mette la main sur votre ordinateur. Pas forcément grave pour bebou mais +certainement plus dans un cadre professionnel par exemple. Si vous +voulez plus de sécurité vous pouvez jouer sur la valeur de `ControlPersist` +afin d'avoir un timeout par exemple. Voir `man ssh_config`. Il est également +possible d'avoir un script tiers qui désactive la clef dans votre agent ssh +et/ou supprime le socket à la mise en veille de votre pc. Posez vous les +bonnes questions et adoptez le bon niveau de sécurité. + +## Faire fonctionner `ControlMaster` et mosh ensemble vers un serveur NATé + +On pourrait en avoir fini sauf que non ! Pour ouvrir une connection, mosh a +besoin de connaître l'ip de la machine distante. Pour cela il existe plusieurs +techniques. Celle par défaut de mosh, nommée "proxy", utilise la `ProxyCommand` +d'ssh pour récupérer le nom canonique de l'hôte distant et ainsi son ip. Malin. +Sauf que, comme nous l'enseigne [cette +issue](https://github.com/mobile-shell/mosh/issues/24), la configuration +`ControlMaster` désactive `ProxyCommand`. La personne qui développe mosh a +retenu comme solution de forcer la désactivation de `ControlMaster` lors de la +connexion ssh qui précède la connexion mosh avec un `-S`[^2]. Certaines +personnes voulant tout de même utiliser `ControlMaster`, deux autres techniques +ne nécessitant pas `ProxyCommand` on été implémentées. L'une, `local`, +consiste à vérifier des valeurs de variables d'environnement locales (à vous de +les setup). L'autre, `remote`, profite de la première connexion ssh pour +exécuter une commande donnant l'ip sur la machine distante, lit ce résultat et +le passe au processus exécutant la commande `mosh-client`. Dans le code +d'origine de `mosh` cette technique repose sur le contenu de la variable +d'environnement `$SSH_CONNECTION`. Malheureusement sur un serveur NATé, tel que +bebou, `$SSH_CONNECTION` contiendra l'ip **locale** du serveur et non pas l'ip +du routeur derrière lequel il est. Pour récupérer la bonne ip il convient donc +de modifier la commande shell lancée à distance pour une commande donnant la +bonne ip, par exemple un `curl` vers https://ipinfo.io/ip. En l'occurrence dans +la version que j'ai, on modifie la ligne 368 : + + shell_quote ( '[ -n "$SSH_CONNECTION" ] && printf "\nMOSH SSH_CONNECTION %s\n" "$SSH_CONNECTION"' ) . + +par : + + shell_quote ( 'printf "\nMOSH SSH_CONNECTION c d %s e\n" "$(curl -sS http://ipinfo.io/ip)"' ) . + +Si vous préférez une autre technique pour récupérer l'ip mettez ce que vous +voulez à la place du `curl`. Après cette modification on pourra utiliser +l'option `--experimental-remote-ip=remote` de mosh pour forcer l'utilisation +de cette technique en lieu de celle qui désactive `ControlMaster`. + +Le résultat de toute cette affaire : dès que l'on lance une session mosh, y +compris vers un serveur NATé, un socket persistant est créé ! + +[^1]: et ce serait la première raison d'être des multiplexeurs type tmux et + screen. Ayant découvert cette informatique à un moment où les connexions + étaient déjà très fiables dans les grandes villes française je n'avais + jamais perçu cet avantage là. Je pensais que c'était pour avoir plusieurs + fenêtre sur un même terminal. +[^2]: vous pouvez aller lire tout ça dans le script mosh en faisant un `vim + $(whereis mosh)`. C'est du perl et c'est lisible. Le `-S` est ligne 408 + par exemple. On y voit la construction de la commande ssh qui sera lancée, + avec la commande proxy contenant un `%h` permettant de récupérer le nom + canonique de l'hôte.