1

I have written a systemd file to start my VPN Service using a particular configuration file. What I would like to be able to do is have this file replaced with a randomly selected configuration file each time the service starts.

So far i have tried using

ExecStartPre=cp -f `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1` /etc/openvpn/%i.conf

to copy the randomly picked file to the specified configuration file. Some alternativly I have tried are

  • used rsync -c instead of cp
  • double quotes around the whole ExecStartPre command
  • escaping the `

Finally I have also tried the following ExecStart to

ExecStart=/usr/sbin/openvpn --config `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1`

All with no effect.

Currently the systemd file is as follows

[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
Type=notify
PrivateTmp=true
ExecStartPre=cp -f `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1` /etc/openvpn/%i.conf
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf

[Install]
WantedBy=multi-user.target

I am expecting the configuration file to be changed before each start of the service but so far I don't see any errors or the configuration file being replaced.

Any help will be greatly appreciated.
Thanks

2

The ExecStart= command is not run by a shell and does not provide the usual shell language features. About the only things it has are quoting and $variable substitution – but it does not have pipes or `backticks` or $(command substitution).

In order to use these features, a) explicitly run a shell like /bin/sh:

ExecStart=/bin/sh -c "cp `foo | bar` baz"

or b) move your commands into a shell script and run that from ExecStart=.

Note that OpenVPN itself already supports declaring multiple servers within the same configuration, using <connection> blocks and --remote-random, as shown in its manual page:

client
remote-random
<connection>
remote foo.example.com 1194 udp
</connection>
<connection>
remote bar.example.com 1194 udp
</connection>
| improve this answer | |
  • See COMMAND LINES in systemd.service(5): "Specifically, redirection using "<", "<<", ">", and ">>", pipes using "|", running programs in the background using "&", and other elements of shell syntax are not supported." – U. Windl Apr 29 '19 at 8:16
0

Thanks @grawity that clears things up a lot. Utilising your answer I have now successfully modified my systemd service file to the below that does exactly what i need.

[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
Type=notify
PrivateTmp=true
ExecStartPre=/bin/bash -c "ls /etc/openvpn/ovpn_udp/au* | shuf -n 1 | xargs -r -n1 -I'{}' cp -f '{}' /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf

[Install]
WantedBy=multi-user.target
| improve this answer | |

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.