I am currently trying to work out how to SSH to servers behind firewalls that deny all incoming connections. The servers can SSH out, so I am wondering if there is a way to get the server behind the firewall to create an SSH tunnel to my workstation, then allow my workstation to send commands back to the server through it?
I have looked into tunneling / reverse tunneling, but these appear to be port forwarding solutions, which will not work as the firewall denies all connections on all ports.
Ideally, I would like to do this in Ruby (using the Net::SSH gem), such that instead of opening a new connection like:
Net::SSH.start('host', 'user', :password => "password")
I could somehow bind to an existing tunnel.
Thanks!
SSH port forwarding allows traffic to be forwarded from one port on the server to another port on the client. This can be used to bypass firewalls that are blocking traffic on a specific port.
Since open ports present a security risk, firewalls installed to protect servers from hackers sometimes block connections to them. Unfortunately, this means that even harmless users who are trying to SSH into their servers may receive a Connection refused error as a result of firewall settings.
All that is required on the target machine is an SSH client. The key to bypassing firewalls is using a technology called reverse tunneling. Reverse tunneling basically sends data backwards over the Internet. Most people use the Internet as clients, creating tunnels out into the Internet.
This is fairly simple if you have control over the server. I'll give the command-line version, and you can work that into any framework you like:
server$ ssh -R 9091:localhost:22 client.example.egg client$ ssh -p 9091 localhost
The server establishes a connection to the client first which starts listening on the "R"emote end (i.e. the client) on port 9091 (something I just made up), and forwards those connections to localhost:22
, i.e. to the ssh server on itself.
The client then just needs to connect to its own local port 9091, which is transparently forwarded to the server's ssh server.
This will usually wreak havoc to your public key checking (and adherent security!), because the client's ssh client doesn't know that localhost:9091
is the same as server:22
. If your client is Putty, then you have an option to provide the "real" server name somewhere so that the credentials can be looked up properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With