[image above is a screenshot of 0pointer.de – in place of a systemd logo]
This is short how-to on setting up a systemd service that is run from a user account.
In the /etc/systemd/system directory:
a) create a service file that implements the service. In my case, I wanted to set up a service that would be started at boot and run under my userid. This service is to set up a ssh tunnel to a system that is on another, external network.
$ cat /etc/systemd/system/ssh-tunnel.service [Unit] Description=ssh tunnel After=network.target [Service] User=harish Group=harish Type=simple WorkingDirectory=/home/harish ExecStart=/home/harish/sshpipe.sh Restart=on-failure [Install] WantedBy=multi-user.target $
b) This is a service that is to be started after the network.target is reached – obviously, no network, nothing happens. Then the section [Service] has details as to who’s UID it is to be invoked. Included are the User, Group, and WorkingDirectory details. The file that is to be run when this service is started is called sshpipe.sh and that is also indicated.
# ps -ef|grep ssh root 898 812 0 Jul17 ? 00:00:00 /usr/libexec/sssd/sssd_ssh --uid 0 --gid 0 --logger=files root 1333 1 0 Jul17 ? 00:00:00 /usr/sbin/sshd -D harish 30062 1 0 16:30 ? 00:00:00 /bin/sh /home/harish/sshpipe.sh harish 30063 30062 0 16:30 ? 00:00:00 /usr/bin/ssh -N -R 2048:localhost:22 email@example.com
c) As can be seen above, the sshpipe.sh is invoked under my UID and in this case, because I am have set it up as passwordless ssh connection (which you have set up earlier), the command will work seamlessly.
d) The file sshpipe.sh is as follows:
$ cat sshpipe.sh #!/bin/sh /usr/bin/ssh -N -R 2048:localhost:22 firstname.lastname@example.org $
Essentially, the command says that is run (in my case a Red Hat Enterprise Linux 7.5 system running in an Intel NUC RYBDWi35) is connecting to port 2048 on the remote host 10.10.10.10 under my UID and linking back up port 22 on this NUC. So, when I log into 10.10.10.10, I can run:
$ ssh -p 2048 localhost
and I am back into the NUC.
e) So, once the systemd service file, in this case, ssh-tunnel.service is created, you will have to enable it and start it.
# systemctl enable ssh-tunnel.service Created symlink from /etc/systemd/system/multi-user.target.wants/ssh-tunnel.service to /etc/systemd/system/ssh-tunnel.service. # systemctl start ssh-tunnel.service # systemctl status ssh-tunnel.service -l ● ssh-tunnel.service - ssh tunnel back Loaded: loaded (/etc/systemd/system/ssh-tunnel.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2018-07-19 19:13:50 +08; 9s ago Main PID: 421 (sshpipe.sh) Tasks: 2 CGroup: /system.slice/ssh-tunnel.service ├─421 /bin/sh /home/harish/sshpipe.sh └─436 /usr/bin/ssh -N -R 2048:localhost:22 email@example.com Jul 19 19:13:50 r7 systemd: Started ssh tunnel. Jul 19 19:13:50 r7 systemd: Starting ssh tunnel...
That’s about it.
I really do like systemd for the elegance provided.
[Update based on comments on g+: https://plus.google.com/u/0/+HarishPillay/posts/527ieimh6Tv%5D
In this instance, since the shell script has exactly one line, it can be placed in the unit file where it refers to the script. The updated file is as follows:
# cat ssh-tunnel.service [Unit] Description=ssh tunnel After=network.target [Service] User=harish Group=harish Type=simple WorkingDirectory=/home/harish ExecStart=/usr/bin/ssh -N -R 2048:localhost:22 firstname.lastname@example.org Restart=on-failure [Install] WantedBy=multi-user.target [root@r7 system]#
The reason I had the script was because it was something I have been using for a long time – predates systemd and since I wanted to make sure that I could work this tunnel with systemd, I just kept the script.