I'm forwarding a local port via ssh to a remote server. Since I don't want to track which ports are available, I specify 0 for the remote local port:

ssh -R0: example.com

Now I want to determine the port sshd has allocated from the remote system. It's possible to do so when having root privileges like this:

$ ssh -R0: root@example.com
# ss -4lntp|grep pid=$(ps -o ppid= -p $$),|awk '{print $4}'

Unfortunately this doesn't work as unprivileged user because the port forwarding is done by sshd which runs as root.

Is there another way to determine the allocated port? Even if not possible with bash, is it possible given the ssh protocol at all?

  • You can go ahead and pick a port above 1024 (you have to be privileged to bind to ports below 1024, traditionally), the odds are on your side. It has nothing to do with the port at the other end of your ssh circuit. – quadruplebucky Jun 16 '17 at 17:16
  • But I don't want to pick a port, because then I would need to keep track of which port is used on which system etc. Using port 0 is exactly what I want (and what this feature is intended for), I just need to figure out the port somehow. – Johannes 'fish' Ziemke Jun 18 '17 at 9:35

Unfortunately, I don't believe this is possible as an unprivileged user. I've searched for this quite a bit myself.

For my purposes, I allowed my "tunnel" user sudo access to the lsof command. I'm tunneling a service on one network, through my client, to the server, to be accessed by anyone on the servers network. I don't allow this user to do anything else (hence the "sleep infinity" and I have other rules in place to disable TTY and such)


tunnel ALL=NOPASSWD:/usr/bin/lsof *

Using this script reports the connected port in the client window


#ip and port used by client to connect to server
ip=`echo $SSH_CLIENT | awk '{ print $1 }'`
sport=`echo $SSH_CLIENT | awk '{ print $2 }'`
echo "Connected through $search"

#returns the PID of the SSH Session
spid=`sudo lsof -i 4 -n -P | grep "$search" | grep "tunnel" | awk '{ print $2 }'`

#uses the pid of SSH session to find the tunneled port
port=`sudo lsof -i 4 -n -P | grep "$spid" | grep "*:" | awk '{ print $9}' | sed 's/[^0-9]*//g'`
if [ -z "$port" ]
    #port returned empty
    echo "Unable to open tunnel. Please try again."
    echo "   session closing in $i seconds"
    sleep 10
    echo "You've been assigned port $port"
    sleep infinity

I then force this commend to run on login from the /etc/sshd_config file

Match User tunnel
    ForceCommand /home/tunnel/tunnel.sh

Currently I'm only expecting to search for one port. Modification would be needed to check for more than one. I've removed some potentially redundant error checking I had in my original script. Further modification may be needed if you want your user to have access to TTY.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.