问题
PT下载机今天重启之后突然连不上SSH了,我以为是之前的防火墙或者Fail2Ban设置有问题把我自己拦住了。
更换IP后还是连不上,不得不连上显示器键盘鼠标查看问题。
发现是SSH服务没有启动,错误信息:
1 | error: Bind to port 53156 on 192.168.50.219 faild: Cannot assign requested address. |
不过开机之后手动启动SSH是没有任何报错的:
经过排查启动失败的原因应该是sshd服务启动时间在wg0接口(WireGuard)启动之前,而我之前修改了sshd设置,从默认绑定的任意IP(0.0.0.0)到具体的IP(192.168.50.219,192.168.70.219),而此时还没有192.168.70.219
这个IP,导致了sshd启动失败。并且这种情况sshd退出的状态码是255
,而sshd.service
中使用参数RestartPreventExitStatus=255
禁止在遇到这种状态码时自动重启。最终就导致了sshd绑定IP时遇到了未知的IP而异常退出,并且不再尝试重启。
其实报错信息中可以看到,绑定的物理网卡IP(192.168.50.219)也出错了,原因应该相同。在sshd.service
中使用参数After=network.target auditd.service
确保sshd服务在network.target
之后启动。但是network.target
并不代表网络接口已经被配置。
在systemd-NetworkTarget及Network Configuration Synchronization Points中提到:
network.target indicates that the network management stack has been started. Ordering after it has little meaning during start-up: whether any network interfaces are already configured when it is reached is not defined.
正确的等待“网络就绪”后再启动某个服务的方法参考Network Configuration Synchronization Points中的Discussion和FAQ部分。
我并没有单独处理这个问题,下面使用的两个方法都能够“顺便”解决物理网卡接口没来得及配置的问题。
解决方法1
第一个方法就是修改sshd.service
,移除参数RestartPreventExitStatus=255
,让sshd不论什么原因启动失败后都尝试重启;并且增加参数RestartSec=10s
推迟sshd重启时间,即第一次失败10秒后再启动,这期间wg0接口已经启动完成。10s的时间是一个估计值,可以加长确保wg0接口启动完成,但不建议设置更短。
不要直接编辑/lib/systemd/system/ssh.service
或者/etc/systemd/system/ssh.service
,systemctrl
提供了edit
方式覆盖已有的设置。使用命令sudo systemctl edit sshd
,编辑需要覆盖sshd.service
中的设置。
在两条注释中添加要覆盖的配置项,RestartPreventExitStatus=
表示将该参数清空:
1 | [Service] |
设置后重启系统查看日志,结果符合预期,第一次启动失败10秒之后重启正常:
解决方法2
另一个方法也需要修改sshd.service
,使用参数Requires
和After
指定sshd服务依赖wg0,并且让sshd在wg0启动之后再启动,修改的内容为:
1 | [Unit] |
图中红框是新增的设置,After=network.target auditd.service
这部分是原配置文件存在的:
重启后检查日志,符合预期,直接启动成功,没有重启:
解决方法3
还找到了这样一种方法,修改内核参数net.ipv4.ip_nonlocal_bind=1
,允许绑定非本地IP地址,这样可以在网卡IP还没有确定的时候让sshd能够绑定配置文件中预设的IP。原理上可行,但我没有验证,这里仅作记录。