How can a reverse-SSH connection be launched and maintained on Ubuntu boot with systemd?

My mum has a wee laptop that needs, when it boots up, to reverse-SSH connect itself to a server (so I can help out when needed).

I'm struggling to get the connection to persist when it is started by systemd.

In /reverse_SSH.sh I've got something like this:

#!/bin/bash
while true; do
    ssh -R 19123:localhost:22 [email protected]
    sleep 1000
done

In /etc/systemd/system/reverse_SSH.service I've got something like this:

[Unit]
Description=reverse-SSH

[Service]
Type=fork
ExecStart=/reverse_SSH.sh

[Install]
WantedBy=multi-user.target

When I run sudo systemctl start reverse_SSH, the SSH connection does appear to happen, and the MOTD of the server can be seen in the output of sudo systemctl status reverse_SSH, but the SSH connection doesn't seem to persist and I can't access the machine on the server with a command like ssh sonnyboy@localhost -p 19123.

What nonsense am I doing wrong? Thanks!


Solution 1:

I would prefer to use the autossh package for such service. So first install it:

sudo apt update && sudo apt install autossh

Then create configuration entry for your connection, by creating a new file within the directory /etc/ssh/ssh_config.d/. Let's call it reverse.ssh.www.example.org.conf. Here is an example:

sudo nano /etc/ssh/ssh_config.d/reverse.ssh.www.example.org.conf
# This file is loaded by /etc/ssh/ssh_config
Host reverse.ssh.www.example.org
    HostName www.example.org
    IdentityFile /root/.ssh/your_passles_id_rsa
    User mum
    Port 22
    RemoteForward 19123 127.0.0.1:22
    GatewayPorts yes
    Compression yes
  • Note the SSH key is possession of the root user who will manage the connection by our service.
  • The last two options are not mandatory.

Finally create the service:

sudo nano /etc/systemd/system/reverse-autossh-www-example-org.service
[Unit]
Description=Keeps a resident tunnel to www.example.org open
#After=network.target
After=network-online.target

[Service]
User=root
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" reverse.ssh.www.example.org
ExecStop=/usr/bin/killall -s KILL autossh
#ExecStop=/bin/kill $MAINPID
Restart=always
RestartSec=3
#Environment=AUTOSSH_GATETIME=0

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable reverse-autossh-www-example-org.service
sudo systemctl start reverse-autossh-www-example-org.service

I've used this configuration for last two years in order to solve similar task - it works like a charm. However, here are few references:

  • https://www.freedesktop.org/software/systemd/man/systemd.service.html
  • https://linuxize.com/post/using-the-ssh-config-file/
  • https://gist.github.com/thomasfr/9707568