  toggle dark mode toggle dark mode

SSH via a relay server

posted on 2020-03-31T16:47:48Z · last modified on 2020-05-31T23:12:02Z · view page on GitHub
tags: linux (2) vps (1)

I often connect via SSH to my desktop computer at my desk at University. However, this computer is behind a firewall and I cannot connect to it from my laptop directly. Luckily I have my Virtual Private Server (VPS) where I - among other things - serve this blog. I use this VPS as a relay server to access my desktop from anywhere with my laptop (and vice versa).

Relay server?

When I talk about a relay server, I mean a situation like the following:


Both my laptop and desktop computer can ssh into the VPS, but the desktop is behind a firewall and the laptop often changes ip adresses. To easily enable an ssh connection between the laptop and the desktop a connection through the VPS can offer a solution. So... How?

1. Desktop VPS

First, the desktop needs to allow incoming ssh connections (you might need to install OpenSSH). Usually this is done by enabling and starting a systemd service:

desktop-user@desktop$    sudo systemctl enable sshd
desktop-user@desktop$    sudo systemctl start sshd

Then, the desktop needs to make a permanent connection with the VPS:

desktop-user@desktop$    ssh -R 2222:localhost:22 vps-user@vps-ip

Apart from connecting to the vps, we also forward port 22 - the standard ssh port - to port 2222 on the VPS. We'll come back to that later.

You could background this process and be done with it. However, I prefer something more robust. First create a new ssh id (just keep id_rsa as filename and don't create a password for the key) and then copy it to the vps.

desktop-user@desktop$    ssh-keygen
desktop-user@desktop$    ssh-copy-id vps-user@vps-ip

After generating and copying your SSH ID to the VPS, you should be able to ssh into the VPS without a password (you might have set this up already when configuring the VPS). Double check this:

desktop-user@desktop$    ssh vps-user@vps-ip

Then, use a tool like autossh (you might need to install it), which will attempt to restart the connection whenever the connection breaks for some reason.

desktop-user@desktop$    autossh -M 0 -N -R 2222:localhost:22  -i /home/flaport/.ssh/id_rsa -o "ServerAliveInterval 30" -o "ServerAliveCountMax 10" vps-user@vps-ip

And while we're at it, to make it even more robust, we can create a systemd service for this:

file: /etc/systemd/system/sshtunnel.service

    Description=Permanent ssh-tunnel to a VPS

    ExecStart=/usr/bin/autossh -M 0 -N -R 2223:localhost:22  -i /home/flaport/.ssh/id_rsa -o "ServerAliveInterval 30" -o "ServerAliveCountMax 10" vps-user@vps-ip


Enable and start it:

desktop-user@desktop$    sudo systemctl enable sshtunnel
desktop-user@desktop$    sudo systemctl start sshtunnel

Now, the desktop will create a permanent ssh-tunnel to the vps. The ssh-tunnel will be started at boot (if you enabled the service) and it will be restarted whenever it fails. Perfect!

2. Laptop VPS

Connecting the laptop to the VPS works the same as connecting the desktop to the VPS. The discussion from above can largely be repeated (change port 2222 to another port number though). However, when you're not interested in enabling connections from the desktop to the laptop, large parts of the above section can be skipped for the laptop. This is what remains:

laptop-user@laptop$    ssh-keygen            # again, don't set a password and just use id_rsa as id
laptop-user@laptop$    ssh-copy-id vps-id    # copy the id_rsa ssh-id to the vps
laptop-user@laptop$    ssh vps-id            # check if you can login into the vps without a password.

Great this works! Now the magic begins:

3. Laptop Desktop

To better understand the magic, of the relay, first ssh into the vps:

laptop-user@laptop$    ssh vps-user@vps-ip

Remember we forwarded port 22 of the desktop to port 2222 on the vps? Well, now - when inside the VPS - we can ssh via port 2222 into the desktop. Magic!

vps-user@vps$    ssh -p 2222 desktop-user@localhost

We made connection to the desktop!

Of course, having this two-step process is a bit cumbersome. It would be great if there is a one-step connection. Guess what - there is. Connecting through the vps from the laptop to the desktop can be done via a single command:

laptop-user@laptop$    ssh -t vps-user@vps-ip ssh -p 2222 desktop-user@localhost

The -t flag basically executes the second ssh command automatically whenever the first ssh connection is made.

Unfortunately, using the above command has some downsides. For one, copying files from the laptop to the desktop and vice versa (either via scp or via rsync) remains impossible.

To solve this problem, a different approach can be followed by editing the SSH config on the laptop:

file: ~/.ssh/config

    Host desktop
    User desktop-user
    ProxyCommand /usr/bin/ssh vps-user@vps -W localhost:2222

And here it is: connecting to the desktop from the laptop is now as simple as

laptop-user@laptop$    ssh desktop

Moreover, copying files and folders can be done with scp or rsync. For example:

laptop-user@laptop$    scp file.txt desktop:~/Documents/
laptop-user@laptop$    rsync -av ~/Downloads/ desktop:~/Downloads/

That's it!

PS: If a connection from the desktop to the laptop is needed, just do the following find and replace

    laptop, desktop => desktop, laptop
    2222 => 3333

on this post and read it again from the start 😉

If you like this post, consider leaving a comment or star it on GitHub.