首页 > 解决方案 > 我的 systemd 单元文件和 bash 脚本不适用于接口 ppp0 检查

问题描述

试图理解 systemd 并制作一个有效的服务,使用两个 bash 脚本我必须关闭/打开一个 IPsec/L2tpd 隧道。如果我从命令行使用 bash 脚本命令,一切正常,但由于某种原因,我遇到了争用条件或缺乏同步或其他问题,因为使用我的 systemd 单元文件是随机且间歇性的,通常需要随机次数的重启才能获得它工作。

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

目的是通过服务启动 ppp0 接口(或将其关闭)。我对此有几个症状,如您所见,我尝试了各种配置(将它们评论输入/输出)。我迷路了。我使用此配置获得的各种条件:-

就像我说的,如果我从命令行以. ./vpn-connect.sh. ./vpn-disconnect.sh在我需要时使用,例如登录后的vpn-connect和关机前的vpn-disconnect

请帮忙 :)

我接受我可能没有以“正确”的方式做这件事,但我不是专家,在来这里之前已经尝试过并得到了一些方法。可能有更好的方法来检查 ppp0 接口是否关闭/启动,并且肯定有更好的方法来制作服务文件?

提前感谢大师。

标签: bashnetworkingsystemdpppl2tp

解决方案


两个脚本!这将很难管理。考虑制作一个脚本并使用参数传递模式。但是您可以只使用一个脚本并使用陷阱自动清理。像这样:

#!/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

然后不要RemainAfterExit=yes,只做:

[Service]
ExecStart=/usr/bin/bash /home/vpn-connect.sh
StandardOutput=journal
StandardError=inherit

这种方式systemctl将“看到”进程正在运行。默认KillSignal=值为 SIGTERM。所以systemctl stop将发送SIGTERM到您的 bash 进程,这反过来将使 buash 执行shutdown部分。TimeoutStopSec=配置等待 sript 关闭的时间。


推荐阅读