[Linux] ssh, faire suivre tty *et* stdin

Marc Chantreux mc@::1
Sam 9 Nov 18:37:41 CET 2024


salut,

On Sat, Nov 09, 2024 at 05:32:36PM +0100, Arthur Pons wrote:
> Est-ce qu'il est possible de faire en sorte qu'ssh connecte la stdin côté
> serveur sur un pipe local *et* la tty distante sur la tty locale
> pour que le script distant puisse récupérer ce qui est lu depuis le pipe
> *et* offrir de l'interactivité à la personne l'ayant lancé à distance depuis
> son terminal ?

pour la 2eme partie je pense que c'est déjà le comportement par défaut
puisque tu as

* stdout qui est fait pour les programmes
* stderr qui est fait pour les hommes
* le sabat qui est fait pour l'homme et non l'homme pour le sabat

par contre tu as 1 seul flux en entrée, ainsi fonctionne unix :)
à ma connaissance donc, la seule façon de faire est d'écrire un serveur
qui multiplexe. le plus simple est de faire un wrapper qui lit le
payload avant de redonner la main à l'interactivité.

petit exemple pour illustrer le concept (qui marchera aussi via ssh
puisque c'est "juste" un pipe, l'invention la plus incroyable de tous
les temps).

rm /tmp/data
seq 9 | {
	while read line; do
		case "${line}"
		in (5) DATA=/tmp/data exec awk '
			BEGIN { print "now I have the payload in "ENVIRON["DATA"] }
			{ print " read from stdin: line "$0 }
			END {
				print "by the way, the payload was"
				system("grep -nH . "ENVIRON["DATA"])
			}
		'
		;; (*) echo $line >> /tmp/data
		esac
	done
}

now I have the payload in /tmp/data
 read from stdin: line 6
 read from stdin: line 7
 read from stdin: line 8
 read from stdin: line 9
by the way, the payload was
/tmp/data:1:1
/tmp/data:2:2
/tmp/data:3:3
/tmp/data:4:4

si je met le contenu de la boucle dans /tmp/sh et que je lance

	seq 9 | ssh localhost 'exec sh /tmp/sh'

j'ai la même sortie.

fais attention à ce que tout ce qui se passe coté serveur soit
unbuffered pour que ça réagisse à la moindre touche.

> Si ce n'est pas clair, l'explication

je sais pas si c'était clair mais il me semble avoir deviné ce sur quoi
tu bosses :)

> 	read continue < /dev/tty

> Mais si ssh lit depuis un pipe tout est déroulé d'un coup :

> 	$ echo "abcd" | ssh -t user@::1 'cat > tmpf;read _;echo test'
> 	*tmpf est bien créé*
> 	test

tu y es presque: ce qu'il te manque c'est que cat lit tout le stream.
il est de ta responsabilité de stopper de lire quand tu sais que tu as
tout le payload.

> 	$ : | ssh -t meso@::1 'echo "avant"; read _ < /dev/tty ; echo "après"'

heuu ... /dev/tty n'est pas un vrai fichier: c'est un port qui de permet
d'ajouter du contenu dans le strem de stdin donc pas exporté sur le
serveur. *à ma connaissance*, il n'y a pas autre chose que les stdio qui
sont forwardés.

par contre tu as fais un ssh -t donc les stdio seront traités comme un
terminal.

> même tenté l'option -tt :

je connais pas -tt :)

courage!

(en vrai tu sais que si tu me poses la question pendant un atelier ou un
hacksxb, je te répondrais … même si j'ai très envie d'avancer sur ma
"conf réseau dégueulasse de développeur de merde qui a fait du perl dans
sa jeunesse et qui donc a déjà prouvé qu'il n'est pas rattrapable" dixit
Adlp ;)

-- 
Marc Chantreux
Pôle CESAR (Calcul et services avancés à la recherche)
Université de Strasbourg
14 rue René Descartes,
BP 80010, 67084 STRASBOURG CEDEX
03.68.85.60.79



Plus d'informations sur la liste de diffusion linux