20

When creating a persistent reverse SSH tunnel, is autossh useful on a system running systemd? Typically, autossh is run by a service with the option -M set to zero which disables monitoring of the link. This means that ssh has to exit before autossh will restart it. From the man page:

Setting the monitor port to 0 turns the monitoring function off, and autossh will only restart ssh upon ssh's exit. For example, if you are using a recent version of OpenSSH, you may wish to explore using the ServerAliveInterval and ServerAliveCountMax options to have the SSH client exit if it finds itself no longer connected to the server. In many ways this may be a better solution than the monitoring port.

It seems that the systemd service itself is capable of doing this with a service file that contains these options:

Type=simple
Restart=always
RestartSec=10

So is autossh redundant when run by a systemd service? Or is it doing other things that help to keep the SSH connection up?

Thanks.

2

2 Answers 2

12

Thanks for a great question. I had a systemd service running with autossh -M 0. And just realized that using autossh along with systemd is redundant.

Here is my new service without autossh. It is running fine and restarting even if I kill the ssh process myself.

[Unit]
Description=autossh
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
ExecStart=
ExecStart=/usr/bin/ssh -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o ExitOnForwardFailure=yes -R8023:localhost:22 sshtunnel@[address of my server] -N -p 22 -i /root/.ssh/id_rsa_insecure
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

HOW TO START THE SERVICE:

  1. Create sshtunnel user on the server (don't give root permissions)
  2. Put the unencrypted RSA key "id_rsa_insecure" here /root/.ssh/. The public part you should put on the server in /home/sshtunnel/.ssh/authorized_keys
  3. Make a file "autossh.service" with the code above and put it here /etc/systemd/system
  4. Run following commands
sudo systemctl daemon-reload
sudo systemctl start autossh
sudo systemctl enable autossh

A few explanatory notes:

ExitOnForwardFailure

this is what I missed first time. Without this option if port forwarding fails for some reason (and it happens, believe me) the SSH tunnel will exists but it would be useless. So it needs to be killed and restarted.

/root/.ssh/id_rsa_insecure

As you can see from the name the key is not encrypted so it has to be a special key, and you have to restrict the user with this key from doing anything on the server side but creating a reverse channel. The straightforward way to do it is to restrict the behavior in the authorized_keys file on the server side.

# /home/sshtunnel/.ssh/authorized_keys
command="/bin/true" ssh-rsa [the public key]

This prevents the "sshtunnel" user from launching the shell and performing any commands.

Additional security:

What I tried and it did not work: 1) on server side: change the shell in /etc/passwd to /bin/false for "sshtunnel" user 2) on server side: add permitopen=host:port in the authorized_keys file for sshtunnel id_rsa_insecure key

What I did not try but I think it should work: you can restrict the "sshtunnel" user further (allowing only specific port forwarding) by configuring SELinux user profiles - but I don't have a code handy for that. Please let me know if anyone would have a code.

I would love to hear any security faults in my current solution. Thanks

2
  • add -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" to disable known_hosts check
    – marstone
    Oct 3, 2022 at 3:15
  • Why changing the shell did not work for you? I created the user with adduser --system ..., which defaults to shell /usr/sbin/nologin, and it seems to works fine
    – MestreLion
    Jun 2, 2023 at 7:22
3

Since trying both is relatively easy, test the reliability of both approaches and confirm for yourself.

I think you'll find that autossh is better suited for the job. autossh designed to run in the foreground, while systemd is designed primarily for background services that aren't attached to a particular TTY.

Also, autossh has at least one feature specific to the task:

Periodically (by default every 10 minutes), autossh attempts to pass traffic on the monitor forwarded port. If this fails, autossh will kill the child ssh process (if it is still running) and start a new one;

So autossh is doing more than keeping a process running, it's confirming that the ssh connection is actually working.

1
  • Thanks for your answer, Mike. As per my question, the autossh periodic monitoring is turned off by setting -M to zero. To the best of my knowledge, the SSH process must exit before autossh will attempt to restart the connection. I do currently have a test running to see which is more reliable but the test is not very effective as I cannot simulate all possible network conditions, system loads etc., hence why I was looking for the experience of others.
    – Guy
    Feb 15, 2018 at 10:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .