当 ListenAddress 设置为 Wireguard VPN IP 时,SSH 无法启动

Kei*_*ith 3 systemd sshd wireguard

wg0假设我有一个名为的wireguard 网络10.0.0.1/24。我使用 systemd 在启动时启动它:

# systemctl enable wg-quick@wg0
Run Code Online (Sandbox Code Playgroud)

我希望 sshd 仅侦听wireguard 地址 ,10.0.0.1而不是0.0.0.0。所以我设置ListenAddress了/etc/ssh/sshd_config:

ListenAddress  10.0.0.1
#ListenAddress  ::
AddressFamily  inet
Run Code Online (Sandbox Code Playgroud)

注意:我设置了地址族,因为我在这里仅使用 IPv4 而不是 IPv6。我认为如果不设置,ssh将继续监听::IPv6。

如果我保存配置并重新启动 sshd,效果很好。但是服务器重新启动后,尽管在 systemd 中启用了 ssh,但仍无法启动。系统日志输出告诉我们原因:

sshd[xxx]: error: Bind to port 22 on 10.0.0.1 failed: Cannot assign requested address.
Run Code Online (Sandbox Code Playgroud)

显然,我们有一个竞争条件,即 sshd 在 Wireguard 接口准备好之前尝试(但失败)启动。

显而易见的解决方案是编辑/etc/systemd/system/sshd.service并添加wg-quick@wg0为依赖项。After=然而, 、Wants=、 或的组合并Requires=不能解决问题。似乎wg-quick@wg0报告它已经完成,尽管网络接口实际上还没有准备好。

Kei*_*ith 6

sys-devices-virtual-net-XXX.device如果被列为依赖项,Systemd 将等待接口准备好。因此,要让 sshd 等待 wg0 接口,请将这些行添加到以下[Unit]部分/etc/systemd/system/sshd.service:

After=network.target wg-quick@wg0.service
Requires=sys-devices-virtual-net-wg0.device
Run Code Online (Sandbox Code Playgroud)

这应该适用于侦听wireguard 地址的任何服务。SSH 还需要After=auditd.service. 中的项目After=可以用空格分隔或多行After=。

最后,重新加载守护进程并重新启动服务:

# systemctl daemon-reload
# systemctl restart sshd
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以使用“systemctl edit sshd”,然后添加“[Unit]”块和上面的行;那么你不需要修改内置服务文件,也不需要执行“daemon-reload”。 (5认同)