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, poursetuid
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 ?