Reverse SSH tunnel: how can I send my port number to the server?

I have two machines, Client and Server.

Client (who is behind a corporate firewall) opens a reverse SSH tunnel to Server, which has a publicly-accessible IP address, using this command:

ssh -nNT -R0:localhost:2222 [email protected]

In OpenSSH 5.3+, the 0 occurring just after the -R means "pick an available port" rather than explicitly calling for one. The reason I'm doing this is because I don't want to pick a port that's already in use. In truth, there are actually many Clients out there that need to set up similar tunnels.

The problem at this point is that the server does not know which Client is which. If we want to connect back to one of these Clients (via localhost) then how do we know which port refers to which client?

I'm aware that ssh reports the port number to the command line when used in the above manner. However, I'd also like to use autossh to keep the sessions alive. autossh runs its child process via fork/exec, presumably, so that the output of the actual ssh command is lost in the ether.

Furthermore, I can't think of any other way to get the remote port from Client. Thus, I'm wondering if there is a way to determine this port on Server.

One idea I have is to somehow use /etc/sshrc, which is supposedly a script that runs for every connection. However, I don't know how one would get the pertinent information here (perhaps the PID of the particular sshd process handling that connection?) I'd love some pointers.

Thanks!


Solution 1:

Wouldn't a VPN be more appropriate? OpenVPN is super simple to configure. Here is a sample config and some links to guide your through the certificate creation process:

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-dh
./build-key-server server
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

Then create a new file /etc/openvpn/client_server.conf and put the following in it, changing the SERVER_IP_ADDRESS as appropriate

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0

Then build a key per user who is going to connect, and create the config file in the ccd dir

./build-key-pkcs12 [email protected]
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/[email protected]

The IP address MUST be suitable for a /30 subnet (see http://www.subnet-calculator.com/cidr.php), as there is only 2 addresses available (server and client) per connection. So your next available client IP would be 192.168.100.6 and so on.

Then you now have static IPs per connecting user.

Then supply the [email protected] file to the end-user and use the following config file

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 [email protected]
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0

Solution 2:

If the clients each have different usernames, you can use netstat to find out what port that user's sshd process is listening on. For example:

% sudo netstat -tlpn | grep 'sshd: mgorven@'
tcp        0      0 127.0.0.1:22220         0.0.0.0:*               LISTEN      5293/sshd: mgorven@
tcp        0      0 127.0.0.1:5120          0.0.0.0:*               LISTEN      5293/sshd: mgorven@

Solution 3:

You could alter the ephemeral port range (/proc/sys/net/ipv4/ip_local_port_range for Linux) and then use statically allocated ports outside that range.

Solution 4:

I want the same setup like you, I increased the log level of the SSH server to DEBUG, and it showed in the logs what was the local port of the client

for example:

client command: ssh -N -R0:127.0.0.1:5522 [email protected]

server log:

Jun 30 11:28:59 debsid sshd[27577]: debug1: Local forwarding listening on 127.0.0.1 port 35391

there you see the port number