The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,969 other subscribers

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: -p 33322

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 | 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
  • $ ssh -R 9000:localhost:3000

It also explains you can make SSH go do the background (i.e. not open a shell) with $ ssh -nNT -L 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 emacs & will start an emacs on, 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 ( for IPv4 or [::1] for IPv6), for instance when forwarding Microsoft RDP port 3389also 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> (ESTABLISHED)
sshd       5029  jeroenp    3u  IPv4  350758      0t0  TCP> (ESTABLISHED)
sshd       6788     root    3u  IPv4 6705764      0t0  TCP> (ESTABLISHED)
sshd       6791  jeroenp    3u  IPv4 6705764      0t0  TCP> (ESTABLISHED)
sshd       6791  jeroenp    9u  IPv6 6706480      0t0  TCP [::1]:ms-wbt-server (LISTEN)
sshd       6791  jeroenp   10u  IPv4 6706481      0t0  TCP (LISTEN)
sshd      13320     root    3u  IPv4 6319692      0t0  TCP> (ESTABLISHED)
sshd      13323  jeroenp    3u  IPv4 6319692      0t0  TCP> (ESTABLISHED)
sshd      16505     root    3u  IPv4 6374150      0t0  TCP> (ESTABLISHED)
sshd      16508  jeroenp    3u  IPv4 6374150      0t0  TCP> (ESTABLISHED)

See :

Anyway, here is the diff in firewall and and sshd config:

commit c8a2c7ca64a6d1cfa0027e19450efb1a0621c58d
Author: Jeroen Wiert Pluimers <>
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_*
 ## Type:   string

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: