I'm using OpenSSH 8.0p1 on Oracle Linux 8.10. When I SSH into a remote host and want to set up a reverse port forward (tunneling from the remote machine back to my local machine), I specify a port of zero (0) to let SSH find an unused port automatically. This allocated port is displayed during the connection setup, like this: `Allocated port 45515 for remote forward to localhost:3289`. This is fine for manual sessions, but I want to capture that port number programmatically so I can set up environment variables on the remote system without needing to manually check the output of the command. Here's what I've tried with no success:
1. I looked around `/proc/$PPID`, the parent process of my shell, but as expected, those entries are owned by root, and I can't access them.
2. I examined the environment variables in my shell, but there's nothing about the allocated port.
3. I can type `~#` in the SSH session to list current port forwards, but that only works if I'm actively using it, which defeats my purpose.
4. Using `~C` allows adding/removing port forwards, but there's no command to list all established forwards.
5. I did find the port using `lsof` run as root, but I don't want to go that route.
Am I overlooking something? Is there really no way to programmatically obtain the allocated port? I appreciate any help!
4 Answers
Consider checking the `man netstat` documentation for additional flags that might help identify your specific needs, though it might require a manual process.
Are you wanting to capture the port from the client or the server side? Just clarifying your goal might help others assist you better.
Sorry for any confusion! I'm trying to find the port allocated to me on the server side where I'm connecting so I can set up environment variables accordingly.
If you're after the port for a specific session, you could use this command:
```
ss -4 -H -t -l -p -n state listening | grep -Eo ".*,pid=${PPID}," | awk '{print $3}' | awk -F ':' '{print $2}'
```
One way to grab the allocated port is to use `netstat`. You can run this command to see ports your user is listening on:
```
netstat -ltne | awk -v uid=$(id -u) '$7 == uid {print $4}' | awk -F: '{print $NF}' | sort -u
```
Alternatively, for a more direct approach, here's how you can access `/proc/net/tcp`:
```
awk -v uid=$(id -u) '$8 == uid && $4 == "0A" {print $2}' /proc/net/tcp{,6} | awk -F: '{print "0x"$NF}' | while read hex; do printf "%dn" "$hex"; done | sort -u
```
This is brilliant, thank you! I especially like the second method; it's precise for my use case where I shouldn't have other listening ports. I think I might suggest this as a feature for OpenSSH or even propose a patch for it!
I just noticed I could simplify the awk command for better efficiency:
```
awk -v uid=$(id -u) '$8 == uid && $4 == "0A" {printf "%dn", strtonum("0x"$NF)}' /proc/net/tcp{,6} | sort -u
```

How would `netstat` identify specifically which port `sshd` allocated for me among all the listening ports?