Le site arthur.bebou.netlib.re - retour accueil
git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |
index.sh (7284B)
1 #! page 2 title: Mosh, IRC, les multi-connections ssh et NAT 3 author: Arthur Pons 4 description: Comment faire de la multiconnection ssh à travers mosh sur un serveur derrière un NAT 5 publication: 2024-11-14 6 7 sectionmd: main 8 9 Sur bebou nous avons un serveur IRC. J'aime bien avoir une fenêtre ouverte en 10 continu sur le serveur afin de répondre rapidement aux copaines. L'objectif est 11 : 12 13 * de ne rater aucun message sur le serveur IRC 14 * de ne pas avoir à se reconnecter et relancer la session quand on coupe la 15 connexion 16 * de profiter de cette session constamment ouverte pour accélerer toutes les 17 commandes ssh qu'on lance ensuite 18 19 ## Ne rien rater de ce qui se raconte sur IRC 20 21 À la création d'un compte, le serveur lance automatiquement une session 22 [tmux](https://github.com/tmux/tmux/wiki) avec un client IRC dedans. De cette 23 manière quand une personne quitte sa session, tmux continue à tourner, le client 24 reste ouvert et ainsi elle ne passera à côté d'aucun message. 25 26 A l'usage c'est génial *sauf que* si vous utilisez ssh vous n'êtes pas sans 27 savoir que c'est fragile. ssh fonctionne de telle manière à ce que la connexion 28 saute au moindre souci. Vous avez perdu la wifi pendant une seconde ? Plus de 29 connexion. Vous avez mis votre ordi en veille ? Plus de connexion. La session 30 tmux permet de ne pas perdre l'état de la session sur laquelle vous étiez[^1] 31 mais il faudra tout de même vous y reconnecter. 32 33 ## Ne jamais perdre sa connexion 34 35 C'est là qu'intervient [mosh](https://mosh.org). Je ne vous fais pas la réclame 36 complète, vous pouvez aller sur le site du projet directement. Ce qui nous 37 intéresse ici est principalement la capacité de `mosh` à récupérer la connexion 38 là où elle s'est arrêtée partout où avec ssh elle aurait ét morte pour de bon. 39 On ouvre la session une fois au démarrage de son pc puis on l'oublie, elle sera 40 toujours vivante. *Second besoin satisfait*. 41 42 Si vous en êtes là vous constaterez une chose : lancer une nouvelle commande 43 ssh prend tout de même du temps. En effet, par défaut, le client ssh initie une 44 nouvelle connexion pour chaque ouverture de session. Il faudra repasser par 45 tout le système d'authentification à chaque fois, ce qui prend du temps. 46 On pourrait penser qu'il est possible de réutiliser la connexion existante et 47 ainsi s'économiser de précieuses secondes. 48 49 ## Réutiliser la connexion 50 51 Effectivement, c'est possible avec la configuration ssh suivante, à mettre dans 52 son `~/.ssh/config` : 53 54 Host * 55 ControlMaster auto 56 ControlPath ~/.ssh/sh-%r@%h:%p 57 ControlPersist yes 58 59 * `Host *` : Pour toute connexion 60 * `ControlMaster auto` : utiliser une connexion existante si elle existe, 61 sinon la créer 62 * `ControlPath ~/.ssh/sh-%r@%h:%p` : Le chemin du socket par lequel passer 63 sera `~/.ssh/sh-%r@%h:%p`. `%r` est le nom du compte, `%h` le nom de la 64 machine et `%p` le port 65 * `ControlPersist yes` : Si une connexion se termine, laisser le socket 66 ouvert (jusqu'à redémarrage de la machin) pour toute autre connexion 67 68 La dernière ligne est essentielle si l'on utilise mosh. À la connexion mosh 69 ouvre une connexion ssh pour échanger des clefs de chiffrement, la ferme 70 instantanément puis ouvre une session mosh. `ControlPersist yes` permet de 71 conserver le socket créé à cette occasion même après la fermeture de la 72 connexion ssh. 73 74 **Sécurité** : avant d'adopter cette configuration demandez vous si cela vous 75 expose à un risque que vous ne pouvez pas accepter. En effet si on la combine 76 avec un agent ssh relaxe, du type à ne presque jamais demander le mot de passe 77 des clefs ssh, c'est la porte ouverte à toute connexion du moment que l'on 78 mette la main sur votre ordinateur. Pas forcément grave pour bebou mais 79 certainement plus dans un cadre professionnel par exemple. Si vous 80 voulez plus de sécurité vous pouvez jouer sur la valeur de `ControlPersist` 81 afin d'avoir un timeout par exemple. Voir `man ssh_config`. Il est également 82 possible d'avoir un script tiers qui désactive la clef dans votre agent ssh 83 et/ou supprime le socket à la mise en veille de votre pc. Posez vous les 84 bonnes questions et adoptez le bon niveau de sécurité. 85 86 ## Faire fonctionner `ControlMaster` et mosh ensemble vers un serveur NATé 87 88 On pourrait en avoir fini sauf que non ! Pour ouvrir une connection, mosh a 89 besoin de connaître l'ip de la machine distante. Pour cela il existe plusieurs 90 techniques. Celle par défaut de mosh, nommée "proxy", utilise la `ProxyCommand` 91 d'ssh pour récupérer le nom canonique de l'hôte distant et ainsi son ip. Malin. 92 Sauf que, comme nous l'enseigne [cette 93 issue](https://github.com/mobile-shell/mosh/issues/24), la configuration 94 `ControlMaster` désactive `ProxyCommand`. La personne qui développe mosh a 95 retenu comme solution de forcer la désactivation de `ControlMaster` lors de la 96 connexion ssh qui précède la connexion mosh avec un `-S`[^2]. Certaines 97 personnes voulant tout de même utiliser `ControlMaster`, deux autres techniques 98 ne nécessitant pas `ProxyCommand` on été implémentées. L'une, `local`, 99 consiste à vérifier des valeurs de variables d'environnement locales (à vous de 100 les setup). L'autre, `remote`, profite de la première connexion ssh pour 101 exécuter une commande donnant l'ip sur la machine distante, lit ce résultat et 102 le passe au processus exécutant la commande `mosh-client`. Dans le code 103 d'origine de `mosh` cette technique repose sur le contenu de la variable 104 d'environnement `$SSH_CONNECTION`. Malheureusement sur un serveur NATé, tel que 105 bebou, `$SSH_CONNECTION` contiendra l'ip **locale** du serveur et non pas l'ip 106 du routeur derrière lequel il est. Pour récupérer la bonne ip il convient donc 107 de modifier la commande shell lancée à distance pour une commande donnant la 108 bonne ip, par exemple un `curl` vers https://ipinfo.io/ip. En l'occurrence dans 109 la version que j'ai, on modifie la ligne 368 : 110 111 shell_quote ( '[ -n "$SSH_CONNECTION" ] && printf "\nMOSH SSH_CONNECTION %s\n" "$SSH_CONNECTION"' ) . 112 113 par : 114 115 shell_quote ( 'printf "\nMOSH SSH_CONNECTION c d %s e\n" "$(curl -sS http://ipinfo.io/ip)"' ) . 116 117 Si vous préférez une autre technique pour récupérer l'ip mettez ce que vous 118 voulez à la place du `curl`. Après cette modification on pourra utiliser 119 l'option `--experimental-remote-ip=remote` de mosh pour forcer l'utilisation 120 de cette technique en lieu de celle qui désactive `ControlMaster`. 121 122 Le résultat de toute cette affaire : dès que l'on lance une session mosh, y 123 compris vers un serveur NATé, un socket persistant est créé ! 124 125 [^1]: et ce serait la première raison d'être des multiplexeurs type tmux et 126 screen. Ayant découvert cette informatique à un moment où les connexions 127 étaient déjà très fiables dans les grandes villes française je n'avais 128 jamais perçu cet avantage là. Je pensais que c'était pour avoir plusieurs 129 fenêtre sur un même terminal. 130 [^2]: vous pouvez aller lire tout ça dans le script mosh en faisant un `vim 131 $(whereis mosh)`. C'est du perl et c'est lisible. Le `-S` est ligne 408 132 par exemple. On y voit la construction de la commande ssh qui sera lancée, 133 avec la commande proxy contenant un `%h` permettant de récupérer le nom 134 canonique de l'hôte.