我有一台笔记本电脑。当我在家工作时,我会建立一个到某些服务器的 ssh 隧道。该隧道被实现为一个 systemd 服务,它会自动启动,并在出现故障时重新启动。
目前,当我将笔记本电脑带到办公室时,隧道也已建立。有没有办法根据我所在的位置来决定隧道服务的启动?该位置可能基于我的 IP 地址,或者是否可以 ping 通某个服务器。
仅当我在家而不是在办公室时才建立隧道的最佳方法是什么?
答案1
man systemd.unit
定义了大量的条件和断言。
我可能会运行两个systemd
单元:
- A
Type=oneshot
运行脚本,然后根据结果生成文件。您的脚本可能会检查 SSID、默认路由、IP 地址或其他有意义的内容。 - 您的主隧道服务基于
Condition...=
该文件和After=
关系。
例如:
[Unit]
Description=Checking for ssid
[Service]
Type=oneshot
ExecStart=-/bin/bash -c "touch %t/$(/usr/sbin/iwgetid -r).ssid"
然后
[Unit]
Description=VPN Tunnel
After=ssid.service
ConditionPathExists=%t/AtHome.ssid
[Service]
...
请注意,Condition...=
检查仅在启动时运行。因此,只有当您的计算机在该位置启动时它才会起作用。我将文件放入其中,%t
因为它总是在重新启动时被清除。
如果您希望它在不重新启动的情况下工作,您需要某种计时器来轮询第一个条件,并在文件不存在时启动冲突的服务。这会停止你的隧道服务。
更简单的解决方案也可以像使用ExecStartPre=
和Restart=on-failure
[Unit]
Description=VPN Tunnel
[Service]
ExecStartPre=/bin/bash -c "test $(/usr/sbin/iwgetid -r) = MyHome"
Restart=on-failure
RestartSec=2m
...
这将检查 SSID 是否与“MyHome”匹配。如果成功,它将运行其余的服务。如果失败,它会在之后重试RestartSec=
(默认100ms,但这太快了,所以我在这里将其设置为5m)。
您提到您当前的解决方案已经在失败时重新启动,因此这可能会污染该解决方案,这意味着您的第一个解决方案可能会更好。另外,systemctl status
如果您没有使用家庭 WiFi,则会显示您的系统已降级。