Partager un TTY sur le web

le lundi 28 décembre 2020

Bearstech | Dernière mise à jour : lundi 28 décembre 2020

Notre prochain webinar

WebRTC a bien décoincé le monde de la visioconférence en permettant de partager des flux d'images directement dans un navigateur web sans devoir installer d'applications (avec des soucis de compatibilité, d'OS, de droits).

Une URL, et hop, c'est partagé.

Rapidement, en plus de la webcam, il a été possible de partager des fenêtres et même des écrans. Petit détail : il n'est pas rare d'avoir dans le groupe une personne avec un écran énorme, en haute définition. Pour l'instant, les browsers ne proposent pas de redimensionner la fenêtre, et ils envoient tous les pixels dans le tuyau, un flot avec des milliers de lignes de résolution. Si vous n'avez pas une jolie fibre, votre flot montant se fait engorger, et ça perturbe le flot descendant, le son devient saccadé, bref, vous avez tout cassé.

Si votre bande passante est suffisante, vous allez envoyer une image énorme, avec un texte tout petit, et donc des galères de scroll pour ceux qui ont des écrans de taille raisonnable.

Il est possible de faire plus simple et plus efficient.

DEC VT100 Envoyer du texte sur un fil électrique (le téléscripteur) est antérieur à l'ordinateur (1897), avec un combo clavier imprimante, pour enfin arriver au combo clavier-écran. La marque Télétype a été abrégée TTY et le terme est passé tel quel en informatique. Ça a donné des machines mythiques, comme le VT100 (tout le monde n'a pas la chance d'être né dans le pays du Minitel), qui servent maintenant de références pour les émulateurs de terminaux, que les hackers des films américains utilisent pour montrer qu’eux, ils savent causer aux machines.

Travailler en mode texte (et pas en mode image) reste le pilier de l'administration système. Même Windows s'y met, c'est dire si c'est une bonne idée.

Il est tellement trop simple d'envoyer du texte dans le tuyau et de l'afficher proprement de l'autre côté.

TTYd

ttyd est une passerelle temporelle entre les terminaux des années 70 et les websockets des années 10 (2010 hein), un pont d'à peu près 40 ans de large.

Techniquement, ttyd expose un TTY, via une websocket, vers xterm.js avec ce qu'il faut d'HTML autour. xterm.js est utilisé par à peu près tous les terminaux en javascript, il est bien fini et gère tout ce dont on attend d'un terminal.

La sécurité de la connexion est celle des browsers webs : TLS et DNS.

Pour rendre service, ttyd met à disposition du basic-auth, mais rien n'empêche de gérer en amont une authentification en OAuth2. Il est tout à fait imaginable de brancher Gitlab pour avoir de l'OAuth2 avec 2 facteurs, et un lien avec le projet pour y brancher un terminal.

Pour les vrais paranos, ttyd propose l'option lecture seule, où l'on retire le clavier aux spectateurs.

Comme c'est un affichage en HTML, il sera possible de copier des bouts de texte et même de changer la taille de l'affichage, avec un bête [ctrl][+].

Ah oui, qui dit page web, dit URL, et donc un moyen simple de fournir l'adresse via un mail ou du tchat.

Tmux

ttyd expose un terminal, mais ne le partage pas. Pour partager un terminal, on pourrait imaginer un bête miroir pour chacun (comme ce que l'on en a en visioconférence), mais cette question est résolue depuis longtemps avec tmux (pour Terminal MUltipleXeur). Tmux marche très bien en local, en ssh, et donc en ttyd. Un bon partage de terminal commence par se caler sur le plus petit, histoire que personne n'ait à scroller, même avec un partage en lecture seule.

Tmux permet aussi de se détacher d'un terminal et de revenir plus tard, et pour les audacieux, de découper l'écran, pour afficher plusieurs trucs en même temps.

Docker

C'est juste une session que l'on souhaite exposer, pas une machine complète. Pour ça, il ne faut exposer que le nécessaire et donc utiliser les namespaces de Linux.

Docker fait ça très bien, et il va pouvoir gérer la grappe de service nécessaire à la présentation :

  • ttyd
  • un agent SSH avec LA clef utile pour la démo
  • un bash dans un tmux, avec un accès à la socket de ssh-agent

Là, l'objectif est de faire une présentation dans un terminal, à un groupe de personnes distantes. La présentation va utiliser SSH, pour expliquer comment gérer automatiquement un serveur distant.

Le plus simpliste est d'avoir un partage ttyd en lecture seule, qui va s'attacher à une session tmux. Une session SSH qui va lancer la grappe de services et s'attacher au tty du conteneur tmux. Rien ne tourne en root et il est possible d'ajouter une clef SSH spécifique au projet, pour 1h, avec un conteneur temporaire.

Tout ça est bien rangé avec ce qu'il faut de Makefile et de scripts bash : https://github.com/factorysh/docker-ttyd

Sécurité

Donner un accès distant à une machine via une page web existe depuis longtemps, ça s'appelle un webshell, que nos amis de PHP craignent tant.

Il faut donc suivre scrupuleusement les consignes de sécurité et mettre en place une défense en profondeur. La Première règle est de fournir des droits minimums.

Dans notre cas, ça détermine les choix suivants :

  • ttyd est lancé avec l'option lecture seule ;
  • le tmux est dans un conteneur non privilégié, avec peu de paquets installés ;
  • le ssh utilisé depuis la session a son ssh-agent dédié, et une clef dédiée qui n'est reconnue que par le serveur cible. La clef n'est dans la session que pour 1h ;
  • chaque service a son conteneur et ne partage que le nécessaire avec les autres ;
  • la VM est isolée des autres VMs, avec son propre sous réseau.

La deuxième règle est d'avoir des outils à jour, et dont on a confiance.

  • Le web est confié à golang, avec Traefik qui va utiliser Let's Encrypt pour n'utiliser que du TLS ;
  • Les conteneurs sont reconstruits avant chaque session ;
  • la VM utilise la version stable de l'OS, avec un kernel à jour, ce qui est toujours mieux quand on utilise des conteneurs.

Normalement, on donne des limites à ses conteneurs, pour que ne pas qu'un conteneur qui devient amok entraîne les autres dans sa chute. Mais bon, là, la VM est tellement petite que ça ne changera pas grand chose. Cgroup, sans contraintes, reste pertinent pour remonter des données et afficher des informations dans ctop.

La partie audit n'est pas ultime. Il faudrait sortir les logs sur une autre VM, en utilisant le driver fluent de docker pour causer à un fluentbit qui écrit dans un fichier plat pour commencer. Il est très tentant de récupérer les bouts de code de teleport qui utilise ebpf pour avoir des logs précis de ce qui est fait dans le shell interactif. Le code est là, avec une license Apache2 permissive.

Pour bien faire, il faudrait lever la VM à la volée et tout bazarder une fois la session terminée (en conservant les logs distants, et un instantané de la home dans un stockage à la S3).

Aller plus loin

TTY c'est chouette, mais SSH n'est pas la réponse universelle pour un accès TTY distant. Il y a plein de choses à explorer avec OpenSSH (comme les clefs publiques que l'on va chercher dans Gitlab, ou les clefs signées, ou les clefs jetables, enfin, recyclables, avec une durée de validité), mais aussi les alternatives webs.

Mettre à disposition une session TTY, en interactif ou non, de manière temporaire, avec des droits fins, sur un service qui est quelque part, fait partie des tendances actuelles et va continuer de se répandre.

Comme vrais exemples, aller jeter un oeil sur Gitlab qui sait exposer une console pour déboguer une CI qui s'est coincée, mais surtout, teleport qui donne un accès distant et paranoïaque, avec une capacité d'audit très poussée.

Crédit Image DEC VT100 terminal

Service Audit de Performance web docker

Bearstech vous propose ses services Audit de Performance web docker

Découvrir ce service

Partager cet article

Flux RSS

flux rss

Partager cet article :