5 votes

Fermer le tunnel ssh sans root et sans tuer toutes les autres connexions ssh

J'ai un tunnel ssh qui écoute sur un port local, disons 8888, ouvert à partir d'une machine distante avec l'adresse suivante ssh -R 8888:localhost:80 myuser@myhost . Je dois écrire un script pour "myuser" sur "myhost" qui fermera ce tunnel.

Le script sera exécuté par "myuser" sur "myhost". Il ne sera pas exécuté par le root et il ne pourra pas non plus faire de sudo.

Une approche consiste à trouver le PID du processus qui écoute sur 8888 en utilisant lsof ou netstat, puis de tuer le processus. Cependant, lsof et netstat refusent tous deux de me donner le PID sans passer par sudo. Avec netstat, j'obtiens simplement - au lieu de "PID/nom du programme" sans sudo.

Existe-t-il un moyen de connaître le PID du processus qui écoute sur un port donné sans avoir les privilèges de root ? Le processus qui écoute sur ce port est exécuté sous le même utilisateur que nous. Ou existe-t-il un autre moyen de fermer le tunnel ssh depuis l'extérieur ?

Notez que l'utilisation de la séquence d'échappement ssh pour réinitialiser la connexion n'est pas une solution car nous sommes no dans le tunnel. Notre script doit être exécuté séparément du tunnel sur le même hôte par le même utilisateur.

Notez également que le simple fait d'exécuter killall sshd n'est pas une solution car cela va tuer toutes les autres connexions ssh et pas seulement celle-ci.

Cette question n'est pas un doublon de nombreuses questions similaires, parce que toutes les réponses acceptées que j'ai trouvées nécessitent des privilèges root, ou tuent simplement toutes les connexions ssh.

L'hôte "myhost" fonctionne sous Ubuntu 12.04.5.


Edit : Résumé de la discussion comme demandé par @Jakuje :

  • @Patrick a suggéré une approche à utiliser setuid ou de modifier /etc/sudoers pour permettre à l'utilisateur d'exécuter le script avec les privilèges de root sans avoir le sudo complet. Bien que, pour setuid nous aurions besoin d'écrire un binaire au lieu du script. Cependant, permettre à l'utilisateur d'exécuter le script avec les privilèges de root pourrait être un risque potentiel de sécurité. Et encore cette solution ne couvre pas le cas où l'utilisateur n'a pas du tout d'accès root, donc il ne peut modifier /etc/sudoers . Si @Patrick écrit ceci comme une réponse, je vais certainement l'upvoter, mais je ne vais pas la marquer comme acceptée, pour le moment.

  • @EricRenouf a découvert que sshd fait un chown du socket à l'utilisateur pour que l'utilisateur ne puisse pas utiliser /proc/*/fd pour trouver le processus qui a le socket. C'est probablement pourquoi ni lsof ni netstat ne le montrent.

Plus d'idées :

Comme @EricRenouf l'a trouvé, il n'y a probablement aucun moyen d'obtenir le PID de sshd par le numéro de port de la socket ouverte ou l'inode. Mais je suis curieux de savoir s'il n'y a pas une autre astuce pour trouver ce PID sshd ou pour lui demander de fermer la connexion. Peut-être d'une manière ou d'une autre directement avec sshd.

Par exemple, si j'ai activé le mode débogage de sshd sshd -d alors il enregistrera quel processus sshd a ouvert un tunnel vers quel port en /var/log/auth.log qui est lisible par l'utilisateur. Ainsi, le script pourrait analyser le journal et y trouver le PID. Mais exécuter un sshd en mode débogage n'est pas une bonne idée. Il existe en fait un patch simple pour sshd pour enregistrer les tunnels ouverts, même sans le mode débogage. Mais je ne suis pas sûr qu'exécuter un sshd patché soit une bonne idée non plus.

Y a-t-il une autre astuce ?

2voto

Google Fail Points 174

Commencez par configurer une clé SSH personnalisée pour vous connecter à "myhost". Ensuite, éditez votre fichier .ssh/authorized_keys sur "myhost" pour que le PID parent du Shell soit écrit dans un fichier :

command="echo $PPID > tunnel.pid; bash" ssh-rsa AAA...

Vous pourriez vouloir modifier d'autres paramètres pour la sécurité et/ou vous pourriez écrire un script personnalisé pour simplement écrire le PID et suspendre. Le principe est le même dans les deux cas.

Une fois que vous avez le PID du processus qui maintient la session SSH ouverte, c'est juste une question de script...

kill `cat tunnel.pid`

...pour terminer le processus, fermant ainsi la session SSH.

Notez que vous pouvez utiliser l'option -i à la ssh pour spécifier une clé privée à utiliser pour la connexion.

Edit : Tuer le processus Shell ne fermera pas le tunnel s'il y a des connexions actives, donc nous tuons le processus SSH parent.

Edit : Bien que ma première inclination avec toute connexion SSH automatisée soit d'utiliser des clés SSH, le même processus pourrait être émulé avec :

ssh -R 8888:localhost:80 myuser@myhost 'echo $PPID > tunnel.pid; for ((;;)); do sleep 1; done'

Vous pouvez également substituer un script qui vérifie d'autres critères pour décider quand se terminer. C'est probablement une façon plus propre de gérer cela.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X