Reverse ssh tunnel between two linux boxes to allow RDP traffic over port 3389
Posted by jpluimers on 2017/06/12
You know the drill: site that limits incoming traffic and has painful VPN. Luckily this time outgoing ssh traffic on port 22 was allowed (because they do SFTP which is SSH File Transfer).
Since I’ve outside Linux boxes and could run a Linux VM there (all Tumbleweed based), this allowed me to do a reverse SSH tunnel. Those are always a bit confusing, but this set of drawings really helps: What’s ssh port forwarding and what’s the difference between ssh local and remote port forwarding – Unix & Linux Stack Exchange [WayBack].
Which brings me to a statement like this:
ssh -o "ExitOnForwardFailure yes" -R :3389:192.168.199.114:3389 -p 33322 93.184.216.34
That didn’t work: a remote machine could not RDP to port 3389, but a local telnet localhost 3389
would. The reason is that by default sshd
binds a remote port to the local address only and not the wildcard addres.
So you have to open up the remote config a bit: at least /etc/sshd_config
and most likely also your firewall.
lekensteyn explains the sshd side at tunnel – Reverse port tunnelling – Ask Ubuntu [WayBack]; the below settings allows the ssh client to specify the server binding (local or wildcard).
If you are more paranoid, you can even tighten this up further as explained in security – How to create a restricted SSH user for port forwarding? – Ask Ubuntu [WayBack].
The client-side you can even go beyond ExitOnForwardFailure (which terminates the ssh connection if the port cannot be forwarded, i.e. you logged in twice with the same port forwarding, see Can I make SSH fail when a port forwarding fails? – Super User [WayBack]) which you might to complement by following the tips on ClientAliveInterval
and ServerAliveInterval
in linux – How to release ports on the SSH server when a reverse ssh tunnel disconnects abruptly/uncleanly – Super User [WayBack] and SSH remote port forwarding failed – Server Fault [WayBack].
The reason? If you don’t then you can get the below error after ssh authentication and need to manually kill the blocking ssh session:
Error: remote port forwarding failed for listen port 3389
I usually use this pstree
like construct to check which ssh sessions were active:
ps axf -ejH | less
Finally you can even shell – List open SSH tunnels – Super User [WayBack] and use the -n
-N
-T
and -f
options to avoid a remote shell and other things (see networking – How does reverse SSH tunneling work? – Unix & Linux Stack Exchange [WayBack]).
More tricks and tips
If you get an error like bind: Cannot assign requested address
, then usually it is IPv6 getting in the way of IPv4, so you need the -4
switch for to force IPv4 as per[WayBack] SSH port forwarding: bind: Cannot assign requested address | Electricmonk.nl weblog:
-4 Forces ssh to use IPv4 addresses only.
A few more tricks are at [WayBack] SSH Tunnel – Local and Remote Port Forwarding Explained With Examples – Trackets Blog, for instance about the meaning of localhost
in these two occasions:
-
$ ssh -L 9000:localhost:5432 user@example.com
-
$ ssh -R 9000:localhost:3000 user@example.com
It also explains you can make SSH go do the background (i.e. not open a shell) with $ ssh -nNT -L 9000:imgur.com:80 user@example.com
demonstrating these switches:
-N Do not execute a remote command. This is useful for just forwarding ports.
-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A common trick is to use this to run X11 programs on a remote machine. For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel. The ssh program will be put in the background. (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)
-T Disable pseudo-terminal allocation.
Note that when entering passwords on the console, you want to replace -n
with -f
:
-f Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. This implies -n. The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm.
If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with -f will wait for all remote port forwards to be successfully established before placing itself in the background.
Oh and there is Be Genius – Talk: SSH Can Do That? [WayBack]
If you forget the GateWayPorts
setting in /etc/ssh/sshd_config
, then it defaults to no
causing remote tunnels to only listen to local interfaces (127.0.0.1
for IPv4 or [::1]
for IPv6), for instance when forwarding Microsoft RDP port 3389
also known as ms-wbt-server
:
# lsof -i -n | grep -w '^\<sshd\>' sshd 1664 root 3u IPv4 21299 0t0 TCP *:ssh (LISTEN) sshd 1664 root 4u IPv6 21301 0t0 TCP *:ssh (LISTEN) sshd 5026 root 3u IPv4 350758 0t0 TCP 192.168.124.32:ssh->192.168.171.24:52417 (ESTABLISHED) sshd 5029 jeroenp 3u IPv4 350758 0t0 TCP 192.168.124.32:ssh->192.168.171.24:52417 (ESTABLISHED) sshd 6788 root 3u IPv4 6705764 0t0 TCP 192.168.124.32:ssh->145.131.245.153:noit-transport (ESTABLISHED) sshd 6791 jeroenp 3u IPv4 6705764 0t0 TCP 192.168.124.32:ssh->145.131.245.153:noit-transport (ESTABLISHED) sshd 6791 jeroenp 9u IPv6 6706480 0t0 TCP [::1]:ms-wbt-server (LISTEN) sshd 6791 jeroenp 10u IPv4 6706481 0t0 TCP 127.0.0.1:ms-wbt-server (LISTEN) sshd 13320 root 3u IPv4 6319692 0t0 TCP 192.168.124.32:ssh->192.168.171.24:56801 (ESTABLISHED) sshd 13323 jeroenp 3u IPv4 6319692 0t0 TCP 192.168.124.32:ssh->192.168.171.24:56801 (ESTABLISHED) sshd 16505 root 3u IPv4 6374150 0t0 TCP 192.168.124.32:ssh->192.168.171.24:21505 (ESTABLISHED) sshd 16508 jeroenp 3u IPv4 6374150 0t0 TCP 192.168.124.32:ssh->192.168.171.24:21505 (ESTABLISHED)
See :
- [WayBack] Selecting Interface for SSH Port Forwarding – Server Fault
- [WayBack] reverse ssh tunnel listens on wrong interface – Server Fault
Anyway, here is the diff in firewall and and sshd config:
commit c8a2c7ca64a6d1cfa0027e19450efb1a0621c58d Author: Jeroen Wiert Pluimers <jeroen.bitbucket.org@pluimers.com> Date: Tue Oct 4 17:02:31 2016 +0200 open 3389 in firewall and allow sshd GatewayPorts clientspecified so a remote ssh RDP tunnel can be established diff --git a/ssh/sshd_config b/ssh/sshd_config index b76bbe2..f6e8e49 100644 --- a/ssh/sshd_config +++ b/ssh/sshd_config @@ -113,7 +113,8 @@ UsePAM yes #AllowAgentForwarding yes #AllowTcpForwarding yes -GatewayPorts no +#GatewayPorts no +GatewayPorts clientspecified X11Forwarding no #X11DisplayOffset 10 #X11UseLocalhost yes diff --git a/sysconfig/SuSEfirewall2 b/sysconfig/SuSEfirewall2 index 0596477..930883e 100644 --- a/sysconfig/SuSEfirewall2 +++ b/sysconfig/SuSEfirewall2 @@ -250,7 +250,7 @@ FW_PROTECT_FROM_INT="no" # # Note: this setting has precedence over FW_SERVICES_ACCEPT_* # -FW_SERVICES_EXT_TCP="" +FW_SERVICES_EXT_TCP="3389" ## Type: string #
Leave a Reply