我的 systemd 单元文件和 bash 脚本不适用于接口 ppp0 检查
My systemd unit file and bash scripts not working for interface ppp0 checks
试图理解 systemd 并制作一个可用的服务,使用两个 bash 脚本我必须 down/up 一个 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 "[=11=]: 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 "[=12=]: 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]
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 接口。我对此有一些症状,如您所见,我尝试了各种配置(评论它们 in/out)。我迷路了。我使用此配置遇到的各种情况:-
- vpn-connect 在 vpn-disconnect 完成之前开始的竞争条件。
- bash 脚本的僵尸进程阻止新启动的脚本完成(相互冲突试图 down/up ppp0)
- vpn-connect 永远不会结束,因为 ppp0 没有启动。
- vpn-disconnect 失败,因为 ppp0 没有关闭。
还有更多 - 困惑!
就像我说的,如果我从命令行 运行 它们 就完美了。 ./vpn-connect.sh 或 。 ./vpn-disconnect.sh 当我需要它们时,例如 vpn-connect 在我登录后和 vpn-disconnect 在我关机之前。
请帮助:)
我承认我可能没有按照 'correct' 的方式来做这件事,但我不是专家,在来这里之前已经尝试过一些方法。可能有更好的方法来检查 ppp0 接口是否是 down/up 并且肯定有更好的方法来制作服务文件?
在此先感谢大师。
将 VPN 作为服务启动似乎不是一个好主意。这确实是可能的,但该服务应该在系统启动时启动,所以你必须处理对网络等的依赖。
由于您的脚本在独立模式下工作正常,我建议将它们用作主网络接口的 up/down 挂钩(参见 Run script when eth0 UP)。
P.S。在这一行
while grep ppp0 /proc/net/dev < /dev/null; do
你可能想说
while grep ppp0 /proc/net/dev > /dev/null; do
或
while grep -q ppp0 /proc/net/dev; do
两个剧本!那将很难管理。考虑制作一个脚本并使用参数传递模式。但是您可以只使用一个脚本并使用陷阱自动清理。像这样:
#!/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 "[=10=]: 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=
配置等待脚本关闭的时间。
试图理解 systemd 并制作一个可用的服务,使用两个 bash 脚本我必须 down/up 一个 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 "[=11=]: 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 "[=12=]: 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]
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 接口。我对此有一些症状,如您所见,我尝试了各种配置(评论它们 in/out)。我迷路了。我使用此配置遇到的各种情况:-
- vpn-connect 在 vpn-disconnect 完成之前开始的竞争条件。
- bash 脚本的僵尸进程阻止新启动的脚本完成(相互冲突试图 down/up ppp0)
- vpn-connect 永远不会结束,因为 ppp0 没有启动。
- vpn-disconnect 失败,因为 ppp0 没有关闭。 还有更多 - 困惑!
就像我说的,如果我从命令行 运行 它们 就完美了。 ./vpn-connect.sh 或 。 ./vpn-disconnect.sh 当我需要它们时,例如 vpn-connect 在我登录后和 vpn-disconnect 在我关机之前。
请帮助:)
我承认我可能没有按照 'correct' 的方式来做这件事,但我不是专家,在来这里之前已经尝试过一些方法。可能有更好的方法来检查 ppp0 接口是否是 down/up 并且肯定有更好的方法来制作服务文件?
在此先感谢大师。
将 VPN 作为服务启动似乎不是一个好主意。这确实是可能的,但该服务应该在系统启动时启动,所以你必须处理对网络等的依赖。
由于您的脚本在独立模式下工作正常,我建议将它们用作主网络接口的 up/down 挂钩(参见 Run script when eth0 UP)。
P.S。在这一行
while grep ppp0 /proc/net/dev < /dev/null; do
你可能想说
while grep ppp0 /proc/net/dev > /dev/null; do
或
while grep -q ppp0 /proc/net/dev; do
两个剧本!那将很难管理。考虑制作一个脚本并使用参数传递模式。但是您可以只使用一个脚本并使用陷阱自动清理。像这样:
#!/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 "[=10=]: 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=
配置等待脚本关闭的时间。