Several months ago, I wrote a post to describe how to setup an autossh daemon with upstart. Since Ubuntu 15.04 has switched to systemd, I would like to do the same with systemd. I will give a brief introduction to systemd in this post.
Systemd Unit File
Systemd services are configured by unit files. By convention, these files
use .service
as their file name extension.
On Ubuntu, there are two directories for unit files:
/lib/systemd
-- This is the directory for unit files provided by the installed packages./etc/systemd
-- This is the directory for the administrators to create, override, modify or mask the unit files in/lib/systemd
.
Although the autossh package does not come with any unit file, we can create
one in /lib/systemd
:
$ sudo vim /lib/systemd/system/autossh.service
Here's the content of the unit file:
[Unit]
Description=autossh
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=autossh
EnvironmentFile=/etc/default/autossh
ExecStart=
ExecStart=/usr/bin/autossh $SSH_OPTIONS
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
Some explanations to the options:
Description= contains some words that can describe the service. This will show up in the logs.
Wants= specifies the dependencies of the services. If this service is activated, systemd will also activate the listed services.
In our case, we would like to make sure that the network interface is ready, thus we specified
network-online.target
[1].After= specifies the order to launch the service. With the
After
option, systemd will only launch the service after the activation of listed services. Notice that this option is orthogonal toWants
(orRequires
.) IfAfter
is not specified, systemd may launch the dependencies simultaneously.Type= specifies the type of the service. There are several options: simple, fork, oneshot, and etc.
- A simple service will contain one long running process. The process will not stop unless we kill the service.
- A fork service means that the
ExecStart
command will fork a subprocess and return immediately. In the other words, the command will manage the process by themselves. - An oneshot service will launch a new process whenever an event triggers this service.
User= specifies the user as whom the service process is run. By default, the process is run as
root
.EnvironmentFile= specifies the path to an environment file, which contains the environment variables for the service process.
ExecStart= specifies the command to launch the service. We have to specify the full path to the executable to be executed.
Notice that there are two
ExecStart
in our unit file. They are not typos. In order to allow this unit file to be included by another unit file, we have to clearExecStart
before specifying a new command.WantedBy= specifies the init stage to launch the service (if the service is enabled.)
Now, we can create a soft link in /etc/systemd/system
:
$ sudo ln -s /lib/systemd/system/autossh.service \
/etc/systemd/system/autossh.service
Environment File
Did you notice that there is a variable $SSH_OPTIONS
in the
ExecStart
option above? It will be substituted by the environment
variable from the file specified by EnvironmentFile
. Environment
files are the files which contain the configurations which should be passed to
the service.
Let's create an environment file:
$ sudo vim /etc/default/autossh
The environment file resembles to a Bash script. Here's the example for our autossh service:
AUTOSSH_POLL=60
AUTOSSH_FIRST_POLL=30
AUTOSSH_GATETIME=0
AUTOSSH_PORT=22000
SSH_OPTIONS="-N -R 2222:localhost:22 example.com -i /home/autossh/.ssh/id_rsa"
We can find more options by reading autossh man pages.
Start the Service
Before we can start our service, we have to ask systemd to reload all unit files:
$ sudo systemctl daemon-reload
Now, we can start autossh service with:
$ sudo systemctl start autossh
And then, we can check the status with:
$ sudo systemctl status autossh
With this command, you should be able to see the following output (if the unit file is correct):
* autossh.service - autossh
Loaded: loaded (/lib/systemd/system/autossh.service; enabled;
vendor preset: enabled)
Active: active (running) since Sun 2015-11-15 22:51:25 CST; 1min 1s ago
Main PID: 14382 (autossh)
CGroup: /system.slice/autossh.service
|-14382 /usr/lib/autossh/autossh -N -R 8022:localhost:22 ....
`-14385 /usr/bin/ssh -L ...
If there are some problems, check /var/log/syslog
for more details.
BTW, to stop the service, we can use the following command:
$ sudo systemctl stop autossh
Launch Service at Boot Time
OK. If everything goes well, then we may ask systemd to launch our service during the boot time. To do so, we have to enable the service with:
$ sudo systemctl enable autossh
Conclusion
In this post, I have covered some basic concept of systemd unit files and basic commands to control systemd:
- Reload unit files with
sudo systemctl daemon-reload
- Start/stop service with:
sudo systemctl [start/stop] [name]
- Check service status with:
sudo systemctl status [name]
- Register/unregister the service for the boot time with:
sudo systemctl [enable/disable] [name]
Hope you enjoy this article.
Reference
- Wikipedia: systemd
- Arch Linux wiki: systemd
- Ubuntu wiki: systemd for upstart users
- RedHat RHEL7: System Administrator's Guide: Chapter 8
- Systemd Manuals: systemd.unit and systemd.service.
- Running Services After the Network is up
[1] | It is non-trivial to write an unit file for the service that requires network connections, read Running Services After the Network is up for more details. |