Linux – Establishing an SSH connection between machines behind firewalls

firewalllinuxport-forwardingssh

I have two machines, A and C, each of which is behind a firewall so they can’t accept incoming SSH requests on port 22. I have a third machine, B, outside both firewalls and I wanted to SSH from A to C using B. I am able to do what I think is called an SSH tunnel from C -> B like so

ssh -fNR 10000:localhost:22 -i key_file_for_B_on_C user_on_B@B

Following what looks like the almost what I want on this question I now try the command:

ssh -ti key_file_for_C_on_A -l user_on_C -o "ProxyCommand ssh -ti key_file_for_B_on_A -W %h:%p user_on_B@B" -p 10000 B

That doesn’t seem to work, I get the error:

channel 0: open failed: connect failed: Connection timed out

Is this the right approach? What might I be doing wrong?

Best Answer

I think the problem with your example is the final arguments; you are sshing to B, when you should be listing the "final destination", albeit the port-forwarded host/port, which is port 10000, but should be localhost, not B, as B is resolved from the perspective of A, and port 10000 on B is probably not open externally. E.g., corrected:

ssh -ti key_file_for_C_on_A -l user_on_C -o "ProxyCommand ssh -ti key_file_for_B_on_A -W %h:%p user_on_B@B" -p 10000 localhost

To prove it to myself, I setup the same experiment, albeit slightly simpler since my username is the same on all hosts, and I'm using agent forwarding; note that my hophost (your B) accepts ssh on a non-standard port, 2222.

On C:

ssh -fNAR 12345:localhost:22 hophost -p 2222

Then on A:

ssh -A localhost -p 12345 -o "ProxyCommand ssh -A hophost -p 2222 nc %h %p"

Alternatively, you can encode a bunch of this into your .ssh/config on A:

Host C
  HostName localhost
  Port 12345
  ForwardAgent yes
  #ProxyCommand ssh -A hophost -p 2222 nc %h %p
  ProxyCommand ssh -A hophost -p 2222 -W %h:%p
  #ProxyCommand $HOME/.ssh/proxy -w 2 -h hophost:2222 %h %p

Then your command on A is simply

ssh C

Note I also included two alternative ProxyCommand versions. The first uses nc in case your ssh version is older than 5.3, when the -W option was added. The other uses a proxy script I've used for a long time to both hop-through some hosts (as in this example) and use corkscrew to get out from firewalls which block outbound ssh. You can see the ssh-proxy script on my github. It simplifies ~/.ssh/config entries when you want to use a proxy for Host * entries, but I don't promise that it always works in all situations, as I've modified it over time as I've needed to for different situations, so any of the options might be fragile or even busted, but it might help.

Related Question