1

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:127.0.0.1:9100 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:127.0.0.1:9100 [email protected] # ss -4lntp|grep pid=$(ps -o ppid= -p $$),|awk '{print $4}' 127.0.0.1:39152 

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?

3
  • 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. Commented Jun 16, 2017 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. Commented Jun 18, 2017 at 9:35
  • check this answer unix.stackexchange.com/a/584505 Commented Jul 8, 2023 at 9:19

1 Answer 1

0

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)

/etc/sudoers

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

Using this script reports the connected port in the client window

#!/bin/bash #ip and port used by client to connect to server ip=`echo $SSH_CLIENT | awk '{ print $1 }'` sport=`echo $SSH_CLIENT | awk '{ print $2 }'` search="$ip:$sport" 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" ] then #port returned empty echo "Unable to open tunnel. Please try again." echo " session closing in $i seconds" sleep 10 else echo "You've been assigned port $port" sleep infinity fi 

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.