SSH via a relay server
posted on 2020-03-31T16:47:48Z · last modified on 2020-05-31T23:12:02Z · view page on GitHubI 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
[Unit]
Description=Permanent ssh-tunnel to a VPS
After=network-online.target
[Service]
User=flaport
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
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
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.