I found this systemd service file to start autossh to keep up a ssh tunnel: https://gist.github.com/thomasfr/9707568
[Unit]
Description=Keeps a tunnel to 'remote.example.com' open
After=network.target
[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa
[Install]
WantedBy=multi-user.target
Is there a way to configure systemd to start several tunnels in one service.
I don't want to create N system service files, since I want to avoid copy+paste.
All service files would be identical except "remote.example.com" would be replace with other host names.
1.5 year later ...
I asked this question roughly 1.5 year ago.
My mind has changed. Yes, it's nice, that you can do this with systemd, but I will use configuration-management in the future.
Why should systemd implement a template language and substitute %h? .. I think it makes no sense.
Several months later I think this looping and templating should be solved on a different level. I would use Ansible or TerraForm for this now.
Well, assuming that the only thing changing per unit file is the
remote.example.com
part, you can use an Instantiated Service.From the
systemd.unit
man page:Basically, you create a single unit file, which contains a variable (usually
%i
) where the differences occur and then they get linked when you "enable" that service.For example, I have a unit file called
/etc/systemd/system/[email protected]
that looks like this:Which I've then enabled
And can intereact with
As you can see, all instances of
%i
in the unit file get replaced withsomehost.example.com
.There's a bunch more specifiers that you can use in a unit file though, but I find
%i
to work best in cases like this.Here is a python example, which was what I was looking for. The
@
in the service filename lets you start N processes:Various methods to call it
Enabling various counts for example:
Enable 30 workers:
Enable 2 workers:
Then be sure to reload:
Now you can start/stop then in various ways:
Start 1:
Start Multiple:
Stop Multiple:
Check status:
UPDATE: To manage instances as one service, you can do something like this:
/etc/systemd/system/[email protected]:
/usr/bin/some-worker-start.sh:
/etc/systemd/system/some-worker.service:
And now you can manage all instances with
sudo systemctl some-worker (start|restart|stop)
Here is some boilerplate for your
script.py
:GregL's answer helped me a great deal. Here is an example of a unit template I used in my code using the example above for a gearman job server. I made a shell script that lets me create X amount of "workers" using this one template.
I have searched for solution to a similar task and actually have found one, that i believe is easier to accomplish, but is supposed to be hacky. (and is not mentioned here)
Service /etc/systemd/system/ssh_tunnel.service:
/etc/openvpn/ssh_tunnels.sh:
Result:
However, i haven't checked yet, how it survives vpn restart, but it's another topic.