![如何在 OpenVPN 客户端连接时重新启动 systemd 单元](https://linux22.com/image/750670/%E5%A6%82%E4%BD%95%E5%9C%A8%20OpenVPN%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9E%E6%8E%A5%E6%97%B6%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8%20systemd%20%E5%8D%95%E5%85%83.png)
对于一般用途来说,知道如何检测网络变化并重新启动服务会很好 - 但我的具体用例是希望在我的 OpenVPN 客户端连接后重新启动 sshd。如果不对默认服务进行大量重新配置(我想避免),sshd 似乎会在基本网络服务上立即启动(这是有道理的,因为单元文件包含After=network.target
)。
sshd 也是特定的 - 我不希望它监听外部接口上的端口 22。起初我以为我可以通过防火墙简单地保护它,但由于我发现我的防火墙脚本运行不正确......最好双向保护。是的,我已经发现了这个愚蠢的错误并修复了防火墙(记录在案 - 需要START_FIREHOL=yes
在 /etc/default/firehol 中配置)。
看起来,如果将 sshd 配置为侦听某个显式 IP,但该 IP 未处于活动状态,则侦听器将不会启动,也不会在该 IP 处于活动状态时自动绑定。由于最好让 sshd 在可以时启动任何其他有效侦听器,而不是可能根本不启动,因此我不想“要求”OpenVPN 客户端在 sshd 启动之前完成。因此我提出了挑战。
我在 OpenVPN 中找到了“ipchange”设置 - 但我无法通过短暂的努力使其发挥作用,而且无论如何,我宁愿有一个更通用的解决方案以供将来使用。
我尝试过的任何针对 OpenVPN 客户端实例的依赖关系都触发得太早了 - 尽管客户端单元尚未完成 DHCP 初始化,但它显示为“已启动”。这意味着 IP 尚未激活。
我没有找到与网络接口状态相关的 systemd 单元依赖关系的任何文档 - 因此我想征求一下意见。
答案1
我不知道这是否是最好的解决方案 - 但它是一个有效的解决方案。
当创建/激活接口时,Systemd 会自动创建网络设备单元。在我的例子中,作为第一个 OpenVPN 连接,所涉及的单元是“sys-devices-virtual-net-tun0.device”。看来,当配置 IP 时,这个单元算作“已启动”。
我没有找到 systemd 单元的明确“重启”配置设置 - 因此我创建了以下服务:
openvpn-online.service
[Unit]
Description=Restart Network Services on VPN Connection
Conflicts=shutdown.target
[email protected] sys-devices-virtual-net-tun0.device
[email protected] sys-devices-virtual-net-tun0.device
[email protected] sys-devices-virtual-net-tun0.device
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart sshd
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
这感觉...不太优雅...但运行起来却很完美。现在 sshd 可以提前启动,然后在 OpenVPN 客户端完成 DHCP 后重新启动。
Systemd 还允许每个单位有多ExecStart=
行oneshot
- 因此我可以根据需要为其他服务进行调整。