Reverse SSH Tunneling via tmate?

4 minute read

Published:

Have you been in situations where you require access to a remote PC but PC is located within some private network that has firewall and multiple layers of security protecting it?

               ┌─────────┐      ┌───────┐      ┌────────┐
               │Remote PC│<--x--│  ???  │<-----│Local PC│
               └─────────┘      └───────┘      └────────┘
                             "ACCESS DENIED"

Well, i have. I tried using the standard reverse SSH tunneling method, but still failed after several tries. To make it worse, I’m still unable to get that working. Maybe I should revisit that again some time soon.

As I’ve been using tmux for my usual terminal multiplexing on a daily basis. Some of you might be aware that I’ve been running i3wm and spectrwm as my tiling windows manager on linux distros, maybe more on this next time. Some of you might think “it doesn’t make sense to use tmux when you are using tiling windows managers”, well, true. But i prefer running one terminal and have tmux handle the multiplexing.

Anyways, back to the topic, tmate is a fork of tmux which was developed with a different purpose. Mainly, it was originally designed for users to share their terminal with a remote users. This is especially useful during “pair-programming” exercise when both users gets to see the same screen. If authorized, the remote user are also given write access to assist the other user. Furthermore, it allows both users to troubleshoot a particular issue simultaneously.

In one of the latest update of tmate version 4.2.0(as of 17 Nov 2019), the author introduced the ability to run the said program in foreground mode. While this mode removes the ability for both device from sharing the same screen, the program now only outputs on the local PC. This mode also ensure the program never dies by respawning a shell when it exits. 1

Why is that useful? Where’s the reverse SSH Tunneling?

Here’s where the magic happens!

Typically, tmate generates a random connection string which is not stable across restarts. Meaning, without the session name, every time tmate is launch, the ssh location varies. Hence, problematic for remote access users - since the connection strings changes every time.

With the new add on, you can now specify a unique session name when running tmate in foreground mode. This allows you to connect you via ssh <session-name>. To name sessions, you would have you specify your API key with the -k parameter. You can get your API key here. Upon registering, the following command allows you to connect to your named session:

$ tmate -k "API KEY" -n hello-world

ssh session: ssh <registered user name>/hello-world@<region>.tmate.io
                                  proxy
               ┌─────────┐      ┌───────┐      ┌────────┐
               │Remote PC│<-----│ tmate │<-----│Local PC│
               └─────────┘      └───────┘      └────────┘
                             "ACCESS GRANTED"

It’s that simple!

However, there’s one big flaw here. It can be pretty easy to guess your session name, hackers can just run some brute force test to attempt connecting to any available tmate sessions over the internet!

PANIC!

Secure it!

Thankfully, the authors also provided ways to secure your connection from unwanted intruders. To do so, first you would have to copy your public key from your local PC to your remote PC using ssh-copy-id [-i [identity file]] [-p port] [user@]hostname. This effectively creates a file in ~/.ssh/authorized_keys. With this file, you can tell tmate to run in foreground mode, with a specific session name, AND only allow the keys founds in the authorized_keys file!

$ tmate -k "API KEY" -n <session name> -a ~/.ssh/authorized_keys 

Simplify it!

To simplify the process you can do the following:

  1. Create a file ~/.tmate.conf using touch ~/.tmate.conf
  2. Use your preferred text editor (nvim for me) and put in the following details:
    set tmate-api-key "YOUR API KEYS OBTAINED FROM REGISTERING"
    set tmate-session-name "YOUR SESSION NAME"
    set tmate-authorized-keys "~/.ssh/authorized_keys"
    
  3. Run tmate -F from your terminal and you’re done! You can now ssh into your PC from anywhere using: ssh <registered user name>/<YOUR SESSION NAME>@<region>.tmate.io. The region is decided by tmate, as of not, I’m not sure if you can assign it differently. Maybe via VPN or so.