bashnetwork-programmingsystemdpppl2tp

My systemd unit file and bash scripts not working for interface ppp0 checks


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.

vpn-disconnect.sh

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-connect.sh

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

/etc/systemd/system/vpn.service

[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.


Solution

  • 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.