I have an ssh tunnel listening on a local port, say 8888, opened from a remote machine with ssh -R 8888:localhost:80 myuser@myhost
. I need to write a script for "myuser" on "myhost" that will close this tunnel.
The script will be executed by "myuser" on "myhost". It won't be executed by the root nor it will be able to sudo.
One approach wound be to find PID of the process listening on 8888 using lsof or netstat and then kill the process. However, both lsof and netstat refuse to give me the PID without going sudo. With netstat I just get -
instead of "PID/Program name" without sudo.
Is there a way to find out PID of the process listening on a given port without the root priviledges? The process listening on this port is running under the same user we are. Or is there any other way to close the ssh tunnel from outside of it?
Note that using the ssh escape sequence to reset the connection is not a solution as we are not in the tunnel. Our script needs to run separately of the tunnel on the same host by the same user.
Also note that just running killall sshd
is not a solution as it will kill all other ssh connections not just this one.
This question is not a duplicate of many similar questions, because all of their accepted answers I have found requires root priviledges, or just kills all ssh connections.
The host "myhost" is running Ubuntu 12.04.5.
Edit: Discussion summary as requested by @Jakuje:
@Patrick suggested an approach to use
setuid
or to modify/etc/sudoers
to allow the user to run the script with root priviledges without having full sudo. Although, forsetuid
we'd need to write a binary instead of the script. However, allowing the user to run the script with root priviledges could be a potential security risk. And still this solution does not cover the case the user has no root access at all, so he cannot modify/etc/sudoers
. If @Patrick writes this as an answer I'll definitely upvote it, but I won't mark it accepted, yet.@EricRenouf found out that sshd does chown the socket to the user so the user can't use
/proc/*/fd
to find the process that has the socket. Which is probably why neither lsof nor netstat show it.
More ideas:
As @EricRenouf found there is probably no way to get sshd PID by the opened socket port number nor inode. But I'm curious if there isn't any other trick how to find this sshd PID or how to tell it to close the connection. Maybe somehow directly with sshd.
For instance, if I enabled sshd debug mode sshd -d
then it would log which sshd process opened a tunnel to which port in /var/log/auth.log
which is readable by the user. So the script could parse the log and find the PID there. But running a debug mode sshd is not a good idea. There is actually a simple patch for sshd to log opened tunnels even without debug mode. But I'm not sure running a patched sshd would be a good idea either.
Is there any other trick?
sshd
which is almost certainly running asroot
. I think this is backed up by looking in/proc/net/tcp
and finding the entry for22B8
(hex for 8888) and seeing (for me at least) that theuid
column has0