Trying to understand systemd and craft a service that works , using two bash scripts I have to down/up an IPsec/L2tpd tunnel. All works fine if I use the bash scripts commands from the command line, but for some reason I'm getting race conditions or lack of sync or something because using my systemd unit file is random and intermittent often requiring a random number of restarts to get it working.
echo "d myvpn" > /var/run/xl2tpd/l2tp-control
ipsec down myvpn
while grep ppp0 /proc/net/dev < /dev/null; do
echo "Waiting for ppp0 to go down ..."
sleep 5
done
echo "$0: ppp0/myvpn now down"
VPN_SERVER_IP='161.35.36.182'
VPN_IPSEC_PSK='Vsumz0402#tillykeats'
VPN_USER='pi'
VPN_PASSWORD='Psumz0402'
if [[ $EUID -ne 0 ]] ; then
echo "$0: Must be run as ROOT"
exit 1
fi
/home/daz/VPN/vpn-disconnect.sh
echo "
### Creating ipsec connections file ..."
cat > /etc/ipsec.conf <<EOF
config setup
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
ike=aes128-sha1-modp2048!
esp=aes128-sha1-modp2048!
conn myvpn
keyexchange=ikev1
left=%defaultroute
auto=add
authby=secret
type=transport
leftprotoport=17/1701
rightprotoport=17/1701
right=$VPN_SERVER_IP
EOF
echo "
### Creating PSK file ..."
cat > /etc/ipsec.secrets <<EOF
: PSK "$VPN_IPSEC_PSK"
EOF
chmod 600 /etc/ipsec.secrets
echo "
### Creating xl2tpd config file ..."
cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[lac myvpn]
lns = $VPN_SERVER_IP
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes
EOF
echo "
### Creating PPP client file ..."
cat > /etc/ppp/options.l2tpd.client <<EOF
ipcp-accept-local
ipcp-accept-remote
refuse-eap
require-chap
noccp
noauth
mtu 1280
mru 1280
noipdefault
defaultroute
usepeerdns
connect-delay 5000
name $VPN_USER
password $VPN_PASSWORD
EOF
chmod 600 /etc/ppp/options.l2tpd.client
echo "
### Creating control file ..."
mkdir -p /var/run/xl2tpd
touch /var/run/xl2tpd/l2tp-control
echo "
### Restarting services ..."
service strongswan restart
service xl2tpd restart
echo "
### Bringing up connection ..."
ipsec up myvpn
echo "c myvpn" > /var/run/xl2tpd/l2tp-control
while ! grep ppp0 /proc/net/dev ; do
echo "waiting for ppp0 ..."
sleep 5
done
echo "
### DONE !!"
ifconfig
[Service]
Type=oneshot
#Type=forking
#Type=notify
#Type=simple
#User=root
#Restart=no
#RuntimeMaxSec=10
#RestartSec=1
#User=root
WorkingDirectory=/tmp
RemainAfterExit=yes
ExecStart=/bin/sh -c '/home/vpn-connect.sh'
#ExecStartPre=/bin/sleep 10
#ExecStop=/bin/sh -c '/home/vpn-disconnect.sh'
#KillMode=process
StandardOutput=journal
StandardError=inherit
#SuccessExitStatus=0 143
#RestartSec=5
#Restart=on-failure
#TimeoutStopSec=120
#LimitNOFILE=102642
[Unit]
Description=IPsec L2TP tunner
After=network-online.target
StartLimitIntervalSec=0
[Install]
WantedBy=multi-user.target
The intention is to bring up ppp0 interface (or take it down) through the service. I've had several symptoms with this and as you can see I've tried various configurations (commenting them in/out). I'm lost. Various conditions I'm getting with this config:-
Like I say, it is all perfect if I run them from the command line as . ./vpn-connect.sh or . ./vpn-disconnect.sh as and when I need them, such as vpn-connect after I log in and vpn-disconnect before I power down.
help please :)
I accept I'm probably not doing this the 'correct' way but I'm no expert and have tried and got some way, before coming here. There is probably a better way of checking if the ppp0 interface is down/up and there's certainly got to be a better way of crafting the service file?
Thanks in advance Gurus.
Two script! That will be hard to manage. Consider making one script and pass mode with arguments. But you can just use one script and auto-clean with a trap. Like so:
#!/bin/bash
# vpn-connect.sh
shutdown_func() {
# the stuff from vpn-disconnect.sh here
echo "d myvpn" > /var/run/xl2tpd/l2tp-control
ipsec down myvpn
while grep ppp0 /proc/net/dev < /dev/null; do
echo "Waiting for ppp0 to go down ..."
sleep 5
done
echo "$0: ppp0/myvpn now down"
}
# execute shutdown function when requested to... shutdown
trap 'shutdown_func' SIGTERM
# the rest of vpn-connect.sh script
: blablabl
echo "
### DONE !!"
ifconfig # ??
sleep infinity
then don't RemainAfterExit=yes
and just only do:
[Service]
ExecStart=/usr/bin/bash /home/vpn-connect.sh
StandardOutput=journal
StandardError=inherit
That way systemctl
will "see" that the process is running. The default KillSignal=
is SIGTERM. So systemctl stop
will send SIGTERM
to your bash process, which in turn will make buash execute shutdown
part. The TimeoutStopSec=
configures how long to wait for the sript to shutdown.