Basicaly requirements are:
- ServerB needs to be only reachable from ServerA. You don't connect to it directly.
- ServerA needs to have TCP Tunneling enabled.
- ServerA needs to be reachable from you.
You set up connection to ServerB through a jumphost (in .ssh/config
):
Host ServerB
ProxyJump ServerA
This assumes that if you enter ssh ServerA
, you'll end up on ServerA, and if you, while being at ServerA, enter ssh ServerB
, you'll end up on ServerB. E.g. the name "ServerB" should be resolvable on ServerA, but it won't care if it is resolvable on your side. Those could be host names or "slugs" (nicknames). In latter case you associate their hostnames or IP addresses again in .ssh/config
:
Host ServerA
HostName ip.add.re.ss
Host ServerB
ProxyJump ServerA
HostName host.na.me
You can also specify which user name to use for proxy host:
Host ServerA
User proxyuser
HostName ip.add.re.ss
Host ServerB
ProxyJump ServerA
HostName host.na.me
After that, you enter ssh ServerB
. The OpenSSH connects to ServerA and uses some random port to forward through this connection to ServerB's address, port 22. This connection is forked into background; OpenSSH immediately connects to this random forwarded port (to localhost, but it really checks its key in .ssh/known_hosts
against the name "ServerB" and IP address specified in HostName, if any), so you'll end up directly on ServerB. If you issue "who", it'll say you are connected from ServerA address. Anyone sitting between you and ServerA has no possible way to know you are really talking with ServerB.
You may use any SSH command line options, those will be used for ServerB connection (made through forwarded port). E.g. if you use ssh -D 12345 user@ServerB
, it will connect to ServerA as proxyuser with port forwarded to ServerB:22, then connect to that port and authenticate to ServerB as user, and it will install SOCKS5 proxy on the port 12345. Exit address for that SOCKS5 would be ServerB, e.g. if you use that proxy (e.g. in a browser), remote parties will see you are connecting from ServerB's address.
You may stack more jumphosts, it will work too:
Host ServerB
ProxyJump ServerA
Host ServerC
ProxyJump ServerC
and ssh ServerC
will first connect to ServerA with port forwarding to ServerB:22, then it'll connect through that forwarding to ServerB with another port forwarding to ServerC, and then connect to that another port and you'll end up with ServerC shell.
Notice you will be asked for a password for each connection. This is quite cumbersome. Better have key-based authentication set up and use ssh-agent
.