1

I'm using a Debian 9.11 system. I ran into a problem where systemd service runs my script but does not produce the desired result.

I created a script named my_autossh.sh and put it under /usr/bin. The content of the script is as follows.

autossh -f -n -T -N -o "ServerAliveInterval=60" -D 7070 username@www.abc.com

And then I created a file named my_autossh.service and put it under /etc/systemd/system. The content of the file is as follows.

[Unit]
Description=autossh connection with www.abc.com for VPN service

[Service]
Type=simple
ExecStart=/bin/bash /usr/bin/my_autossh.sh

[Install]
WantedBy=multi-user.target

And then I give execution permissions to both files by executing the following

sudo chmod +x /usr/bin/my_autossh.sh
sudo chmod +x /etc/systemd/system/my_autossh.service

And then tried to start the service by executing

sudo systemctl enable my_autossh.service
sudo systemctl start my_autossh.service

Running sudo systemctl status my_autossh.service returns the following result

● my_autossh.service - autossh connection with www.abc.com for VPN service
service Loaded: loaded (/etc/systemd/system/my_autossh.service;
enabled; vendor preset: enabled)
Active: inactive (dead) since Thu 2020-01-16 11:24:09 CST; 6min ago
Process: 8196 ExecStart=/bin/bash /usr/bin/my_autossh.sh (code=exited, status=0/SUCCESS)
Main PID: 8196 (code=exited, status=0/SUCCESS)

Jan 16 11:24:09 tlt-p003 systemd[1]: Started autossh connection with www.abc.com for VPN service.
Jan 16 11:24:09 tlt-p003
autossh[8214]: starting ssh (count 1)

However when I run ps aux | grep to check if autossh is running, it isn't. Running /usr/bin/my_autossh.sh does start autossh. Why?

2

If you run a systemd with Type=simple, then you want to run that service in foreground, which means it should block while the service is alive, rather than forking a background daemon and exiting.

The autossh -f option puts it in background, so it's doing the opposite of what you want. Drop that option and this should work.

Additionally, you'll want to launch autossh from the shell script using the exec command, which will replace the shell with autossh in the same process. This makes it so that autossh is a direct child process of systemd, so whenever systemd tries to interact with it (for example, send it a signal when trying to stop it), it will be sending the signal directly to the autossh process and not to a shell that's running it.

Putting it all together, you should modify your shell script to read:

exec autossh -n -T -N -o "ServerAliveInterval=60" -D 7070 username@www.abc.com

Note that you don't really need a separate shell script for this command-line, it doesn't use any features of the shell that are not supported or work differently in systemd... So you could simply use that directly in the ExecStart= of your unit file:

[Service]
Type=simple
ExecStart=/usr/bin/autossh -n -T -N -o "ServerAliveInterval=60" -D 7070 username@www.abc.com
|improve this answer|||||
  • Switching to Type=forking might be a better choice, as it lets systemd distinguish between the daemon "still starting" and "fully started" (depending on whether it's been written properly). – user1686 Jan 16 at 8:49
  • 1
    It's the opposite of best practice to use forking. unix.stackexchange.com/a/504374/5132 – JdeBP Jan 16 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.