Récupérer des données localement d’une session SSH distante sous Linux

By Flavien ROUX

L’accès à distance aux systèmes est plus courant que jamais. Cependant, en raison des différentes limitations des protocoles et des environnements, le partage de données générales et de presse-papiers n’est pas toujours disponible d’emblée entre les machines clientes et les serveurs.

Dans ce tutoriel, nous verrons comment transférer des données localement à partir d’une session SSH distante sous Linux. Tout d’abord, nous précisons brièvement ce qu’est SSH et comment nous l’utilisons. Ensuite, nous expliquons comment nous pouvons rediriger la sortie des sessions interactives et non interactives. Enfin, nous concluons avec le cas spécifique de la redirection vers le presse-papiers.

Nous avons testé le code de ce tutoriel sur Debian 11 (Bullseye) avec GNU Bash 5.1.4. Il est conforme à POSIX et devrait fonctionner dans tout environnement de ce type.

Le protocole SSH

Secure Shell (SSH) est un protocole réseau cryptographique pour le transfert sécurisé d’informations.

Pour nos besoins, nous supposerons que les clés SSH sont déjà

générées
copiées sur notre serveur distant baeldung.com
configurées sur nos machines locales et distantes

Cela signifie que l’accès aux clés par défaut est facilement disponible, et nous sauterons l’authentification dans nos commandes client ssh (Secure Shell).

L’authentification étant le principal obstacle, avec un accès aux clés configuré, l’utilisation de ssh devient triviale.

Modes d’exécution à distance de SSH

De manière générale, nous pouvons utiliser ssh pour exécuter une ou plusieurs commandes et quitter ou lancer une session interactive et attendre une entrée. Pour nos besoins, ce dernier scénario est plus complexe. Discutons brièvement des deux.

Interactive

En mode de session SSH interactive, nous entrons des commandes à l’invite, mais elles s’exécutent toutes sur la machine distante :

$ hostname
personal.local
$ ssh [email protected]
$ hostname
baeldung.com

Ici, nous utilisons hostname pour afficher le nom d’hôte de la machine actuelle. Ensuite, nous entrons dans une session SSH interactive à distance avec l’utilisateur x sur le serveur baeldung.com, où nous montrons que le nom d’hôte renvoyé par la même commande est celui du système distant.

Le protocole SSH y parvient en exécutant simplement le shell par défaut sur la machine distante, qui prend en charge toute la session SSH. La sortie de cette session interactive met fin à l’interpréteur de commandes ainsi qu’au processus du client SSH et redonne le contrôle au terminal, là où nous l’avons démarré.

A lire également :  Plusieurs glibc sur une seule machine Linux

Script

L’une des nombreuses fonctionnalités du protocole SSH est l’exécution de commandes à distance :

$ hostname
personal.local
$ ssh [email protected] ‘hostname’ (nom d’hôte)
baeldung.com

En fait, nous ignorons les capacités interactives de ssh et nous exécutons simplement la ou les commandes fournies, en retournant la sortie. Notez que la commande est fournie en tant qu’argument.

Nous allons examiner les deux modes d’exécution en détail. Continuons avec le mode script non interactif.

Redirection de sortie SSH non interactive

Puisque ssh se comporte comme toute autre commande Linux en termes d’entrée et de sortie, une fois que nous avons capturé l’un de ses flux, nous pouvons le traiter comme bon nous semble.
freestar

Transférer la sortie SSH

Comme pour les autres flux, nous pouvons acheminer la sortie de ssh :

$ ssh [email protected] ‘ip address’ | grep global
inet 10.0.6.66/24 brd 10.0.6.255 scope global eth0

Ici, nous obtenons les informations réseau de la machine distante via ip. Ensuite, nous les transmettons à grep (Global Regular Expression Print) pour filtrer uniquement l’IP globale.

Bien sûr, nous pouvons obtenir cet effet sans passer par des pipes directs.

SSH dans un sous-shell

En effet, nous pouvons utiliser un sous-shell pour obtenir les données retournées par SSH :

$ REMOTE_HOSTNAME= »$(ssh [email protected] ‘hostname’) »
$ ping « ${REMOTE_HOSTNAME} »
PING baeldung.com (203.0.113.66) 56(84) octets de données.
64 octets provenant de 203.0.113.66 (203.0.113.66) : icmp_seq=1 ttl=666 time=66.6 ms

Nous enregistrons d’abord le nom d’hôte distant dans la variable REMOTE_HOSTNAME. Ensuite, nous utilisons la commande ping avec le nom d’hôte comme argument.

Bien entendu, ces solutions sont rarement utiles sans le filtrage d’éléments de données isolés dans un environnement ssh interactif.

Redirection de la sortie SSH interactive

Puisque la sortie complète d’une session SSH n’est disponible pour le piping qu’après la fin du client ssh, nous devons trouver une solution pour obtenir immédiatement les données actuelles des sessions interactives.

Duplication de flux

Une façon d’obtenir des données de stdout sans redirection complète est la commande tee :

$ echo ‘—–‘ > stdout.txt
$ ssh [email protected] | tee stdout.txt
$ hostname
baeldung.com
$ exit

$ cat stdout.txt

$ hostname
baeldung.com
$ exit

Tout d’abord, nous créons un fichier stdout.txt et le remplissons de cinq tirets. Ensuite, nous démarrons une session SSH, en envoyant un message à tee. Remarquez comment tee redirige toutes les informations de la session SSH simultanément vers stdout et stdout.txt.

Bien sûr, le problème ici est la verbosité et le manque de filtres. Ensuite, nous allons vérifier des approches plus granulaires.

Netcat

Une autre façon d’extraire des informations d’une session SSH en direct est de les envoyer. Nous pouvons utiliser nc (Netcat) pour transférer les informations de la session vers le client. Pour cela, nous devons d’abord démarrer un serveur séparé sur le client lui-même :

A lire également :  Comment configurer VS Code pour qu'il soit portable

$ nc -l -p 36661

L’option -l démarre un serveur d’écoute sur le port suivant -p. Après cela, dans un terminal séparé, nous établissons une session de tunnel SSH inverse :

$ ssh [email protected] -R localhost:36660:localhost:36661

Nous lisons l’argument du drapeau -R (tunnel inverse) comme suit : rediriger toute donnée vers le port 36660 de l’hôte distant vers la machine cliente actuelle au port 36661. Cela nous permet d’envoyer des données via nc sur le serveur SSH vers le serveur nc que nous avons ouvert sur le client :

$ echo « $(date) » | nc localhost 36660

Ici, nous envoyons la date actuelle au port 36660 de localhost, qui est le serveur SSH. Cependant, cette information est en fait transmise au port 36661 du client à cause du tunnel inverse.

En effet, en revenant au terminal du client avec notre serveur nc, nous pouvons voir la date courante juste en dessous de la commande Netcat. En gros, ce processus établit simplement une connexion inverse avec le client, que le serveur utilise pour renvoyer les données.

Il existe des alternatives à nc pour réaliser la même chose. De plus, les autres options dont nous allons parler offrent une fonction bonus précieuse : l’accès au presse-papiers.
freestar

Presse-papiers SSH

La norme du protocole SSH ne spécifie pas de mécanisme de presse-papiers. Cependant, nous pouvons souvent utiliser toutes les options de copier-coller dont nous disposons localement.

Par exemple, nous pouvons simplement sélectionner, copier et coller du texte à partir de la fenêtre du terminal GUI, où la session SSH a été lancée. Alternativement, nous pouvons utiliser l’une des méthodes ci-dessous.

Sélections X

Si nous voulons envoyer vers le presse-papiers via la ligne de commande, nous pouvons utiliser les commandes xsel ou xclip :

$ ssh [email protected] ‘hostname’ | xsel –input
$ xsel –output
baeldung.com

En gros, on envoie la sortie de ssh à la commande xsel. Il est important de noter que nous ne serons pas en mesure d’utiliser des outils tels que xsel et xclip si X Server ne tourne pas localement.

D’autre part, l’utilisation de X11 à distance n’est possible via xclip que si :

installons et exécutons X Server sur la machine locale
ajouter ou décommenter X11Forwarding yes dans /etc/ssh/sshd_config.

Pour utiliser xclip, nous démarrons le client ssh avec l’indicateur -X (X11 forwarding) :

$ ssh -X [email protected]
$ echo « $(date) » | xclip -i

Après avoir utilisé xclip pour obtenir les données en entrée sur la machine distante, nous pouvons utiliser la sortie sur la machine locale :

$ xclip -o
Dim 10 Oct 2021 10:00:00 AM EST

A lire également :  Comment actualiser liste dossiers Windows live mail ?

Il est important de noter que ces données ne sont disponibles que pendant la session SSH, pas après.
freestar

Presse-papiers Netcat

Bien sûr, nous pouvons utiliser la solution Netcat ci-dessus, mais en passant par xsel :

$ nc -l -p 36661 | xsel –input

Toutes les données que nous recevons sur le serveur nc vont directement dans le presse-papiers, que nous pouvons restaurer via xsel sur le client. Cependant, il existe d’autres options, qui combinent toutes ces fonctionnalités dans un package spécialisé.

Lemonade

Une de ces alternatives est la commande lemonade – un outil unique, qui nous permet de :

de démarrer un listener sur le client
d'envoyer des données de la session SSH au client
exécuter des actions prédéfinies sur le serveur

En fait, nous utilisons cet outil à peu près de la même manière que nc. Tout d’abord, nous démarrons le serveur lemonade dans un terminal :

$ lemonade start

Ensuite, dans un autre terminal, nous nous connectons en ssh à notre serveur comme nous l’avons fait précédemment. Le seul changement est le port du tunnel inverse – les deux sont 2489, la valeur par défaut pour lemonade :

$ ssh [email protected] -R localhost:2489:localhost:2489

Enfin, nous utilisons lemonade sur le serveur pour renvoyer les données au client :

$ echo « $(date) » | lemonade copy

Il est important de noter qu’en utilisant la commande copy de lemonade, nous déplaçons les données de la session SSH directement dans notre presse-papiers local. Nous pouvons ensuite coller ces données non seulement via l’interface graphique mais aussi la ligne de commande sur le client :

$ lemonade paste
Dim 10 Oct 2021 10:00:00 AM EST

Notez que cet outil, comme les autres, doit être installé à la fois sur le serveur et le client. De plus, lemonade possède d’autres fonctionnalités utiles, comme l’ouverture d’un navigateur sur le client, la redirection vers une URL donnée.
freestar

Clippy

Nous pouvons réaliser tout ce qui précède avec Clippy. De plus, Clippy implémente plus de sécurité et la possibilité de démarrer une session SSH directement avec l’outil. Cela facilite la configuration du tunnel inverse :

$ clippy ssh [email protected]
$ echo « $(date) » | clippy set

Comme pour les autres méthodes, nous obtenons les données via le même outil sur le client :

$ clippy get
Dim 10 Oct 2021 10:10:00 AM EST

Clippy prend également en charge l’exécution de commandes arbitraires sur le bureau au lieu de la seule ligne de commande, comme le fait SSH.

Résumé

Dans ce tutoriel, nous avons abordé les moyens de récupérer des données sur le client après et pendant une session SSH sur un serveur. Nous avons envisagé des scénarios interactifs et non interactifs. Enfin, nous avons également exploré les options permettant d’envoyer des données directement dans le presse-papiers local.

En conclusion, il existe de multiples façons, certaines plus faciles que d’autres, d’envoyer des données du serveur au client, même lorsqu’il s’agit du presse-papiers du client.