[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