Systemd

“位置”上的系統條件

  • February 8, 2022

我有一台筆記型電腦。當我在家工作時,我會建立一個到某些伺服器的 ssh 隧道。隧道實現為 systemd 服務,它會自動啟動並在失敗時重新啟動。

此刻,當我將筆記型電腦帶到辦公室時,隧道也已建立。有沒有辦法根據我的位置來調整我的隧道服務的啟動?該位置可能基於我的 IP 地址,或者是否可以 ping 某個伺服器。

僅當我在家而不是在辦公室時才建立隧道的最佳方法是什麼?

man systemd.unit定義了大量的條件和斷言。

我可能會執行兩個systemd單元:

  1. AType=oneshot執行腳本,然後根據結果生成文件。您的腳本可能會檢查 SSID、預設路由、IP 地址或其他有意義的內容。
  2. 您的主要隧道服務具有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 上,將顯示您的系統已降級。

引用自:https://unix.stackexchange.com/questions/689767