NB: The OpenSSH clients I am using are all at version 7.2, so no RemoteCommand available.
Assume the following setting:
- machine
foois a jump host and provides access to hostbarvia itslocalhost:10022 barsits inside a network inside of which we can access hostrdpand access its RDP port (3389). I actually give the IP ofrdpinside my command lines and configuration, but I presume that it is legit to use its name as long as name lookup works. For brevity I am usingrdphere.
The goal is now to gain access to rdp:3389 by connecting to bar via jump host foo and forward that to localhost:33389 on the local machine from which I am invoking ssh bar.
[local:33389] --> {foo} --> {bar} --> [rdp:3389]
Interlude
I have solved this previously with PuTTY as follows:
- create a connection to
fooand configure a local forwarding-L 33389:localhost:33389, thus tyinglocalhost:33389on the local machine tolocalhost:33389onfoo. - use the following remote command to carry the port forwarding into the network inside of which
barsits by passingssh -L 33389:rdp:3389 -A bar. Host baris configured onfooinside of.ssh/configto connect tolocalhost:10022and thereby end up onbarvia the jump host.
The PuTTY configuration works like a charm, but it relies on a remote command to be executed. While a shell alias would be one way of going about this, I was wondering if there’s a way to keep everything inside the ssh_config(5) used by my client, using ProxyCommand?
A rough equivalent of the above PuTTY configuration is this:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 -p 10022 localhost
or, provided that Host bar is configured on foo to go through localhost:10022 of foo:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 bar
And this seems to get the job done.
But of course this is plenty to type and it would be neater to be able to put this all into the configuration file and simply type ssh bar on the local machine.
With RemoteCommand as introduced in OpenSSH 7.6 this seems to be rather trivial:
Host bar
HostName foo
RemoteCommand ssh -L 33389:rdp:3389 -A -p 10022 localhost
LocalForward 33389 localhost:33389
… which should roughly translate to the ssh invocation shown above. But as mentioned before, I am using an older (packaged) version of OpenSSH without support for the RemoteCommand stanza.
Here’s the attempt that seems to come closest to what I want to achieve.
Host bar
HostName localhost
Port 10022
ProxyCommand ssh -L 33389:localhost:33389 -W %h:%p foo
LocalForward 33389 rdp:3389
The idea being that on the local machine I will simply invoke ssh bar. In fact it works in that I end up on the shell prompt of bar, but the port forwarding doesn’t work at all. While sudo lsof -i|grep 3389 on the local machine gives me:
ssh 15271 accden 6u IPv6 7933201 0t0 TCP localhost:33389 (LISTEN) ssh 15271 accden 7u IPv4 7933202 0t0 TCP localhost:33389 (LISTEN)
On the jump host I see nothing listening on any port containing 3389.
Since ProxyCommand establishes the connection to foo and I am giving a LocalForward for the connection to bar, I’d expect this to work.
What am I doing wrong?
Goal is to use ssh bar to connect to bar and at the same time make rdp:3389 available on the local machine as localhost:33389. Tweaking the ssh_config(5) files on the local machine and foo are allowed. Passing remote commands is not a valid answer, though.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
First, with your kind of setting, what would work, requiring anyway two ssh:
Host foo
LocalForward 10022:bar:22
Host bar
Hostname localhost
Port 10022
LocalForward 33389 rdp:3389
term1$ ssh foo # or use ssh -f -N -o ExitOnForwardFailure=yes foo for background task
term2$ ssh bar
What you’d really need wouldn’t be RemoteCommand but ProxyJump, really simplifying your configuration, with goal reached only with:
ssh -L 33389:rdp:3389 -J foo bar
Or the equivalent (only) configuration:
Host bar
ProxyJump foo
LocalForward 33389 rdp:3389
With zero intermediate port needed.
Unfortunately ProxyJump is available only starting from openssh 7.3
But it’s easily replaced with the ProxyCommand/-W combo you were using before.
ssh -L 33389:rdp:3389 -o 'ProxyCommand=ssh foo -W %h:%p' bar
or as configuration file:
Host bar
ProxyCommand ssh -W %h:%p foo
LocalForward 33389 rdp:3389
There are still two ssh running: the hidden one is the one as ProxyCommand parameter still running on the local host doing the link using a pair of pipes with the main ssh, instead of an extra tcp port. Trying to involve the intermediate host in participating with the port forwarding is insecure or can clash (other users of foo can access the tunnel or use the same port), and prone to errors. Tunnel ends should always be kept on the client host if possible, where there’s full control. Intermediate tunnels should either not exist or point to the next ssh entry point (that’s the -W ‘s usage here).
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0