服务器在启动时无法绑定到地址

服务器在启动时无法绑定到地址

我正在处理已知 问题在 RHEL 7 中,指定要绑定的地址的服务将无法正确启动。我发现了许多类似的报告,许多人说他们已经通过更新 systemd 解决了这个问题,但我仍然面临这个问题。这会影响我机器上所有不只是绑定到 0.0.0.0 的服务(sshd、sshd、vsftpd、nginx)。

我找到了各种所谓的解决方法,但没有一种对我有效。以 sshd 为例,配置如下:

Port 22
ListenAddress 192.168.242.225
...

以下是我单独和组合尝试过的方法:

https://bugzilla.redhat.com/show_bug.cgi?id=1352214#c4(我也尝试过sys-subsystem-net-devices-eth1.device代替network-online.target但我怀疑这不会等待寻址发生。)

mkdir /etc/systemd/system/sshd.service.d
tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
After=network-online.target
EOF

https://bugzilla.redhat.com/show_bug.cgi?id=1352214#c11

mkdir /etc/systemd/system/sshd.service.d
tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
Wants=network-online.target
After=network-online.target
EOF

https://bugzilla.redhat.com/show_bug.cgi?id=1438749#c0

systemctl add-wants multi-user.target network.target

从某处

mkdir /etc/systemd/system/sshd.service.requires
ln -s /usr/lib/systemd/system/network-online.target /etc/systemd/system/sshd.service.requires/

无论我怎么尝试,通常都会得到“错误:绑定到 192.168.242.125 上的端口 22 失败:无法分配请求的地址”。有时,一切都启动得很顺利,我猜这是由于时间问题。

运行 Scientific Linux (RHEL) 7.5 并启用网络管理器,所有 IP 寻址都是静态的。如果有任何其他详细信息可能有帮助,请告诉我。这里journalctl是启动失败后sshd 单元文件中的输出After=network-online.target。相关内容从第 1700 行开始。希望有人遇到过这个问题并成功解决了!

答案1

如果你正在使用 NetworkManager,那么为了按network-online.target预期工作,你需要启用服务NetworkManager-wait-online.service,这是实际上等待网络上线以满足该目标。

需要network-online.target“挂接”到您的网络管理器(因为 NetworkManager 不是唯一的选择,所以还有 systemd-networkd 可用于管理网络。)

为了network-online.target使用 NetworkManager,您需要有一个/etc/systemd/system/network-online.target.wants/指向 的符号链接/usr/lib/systemd/system/NetworkManager-wait-online.service

您可以通过启用该服务来实际创建:

$ sudo systemctl enable NetworkManager-wait-online.service
Created symlink from /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service to /usr/lib/systemd/system/NetworkManager-wait-online.service.

一旦完成,依赖关系network-online.target就应该开始工作,等待 NetworkManager 完成启动时应该启动的所有接口。

为了帮助诊断该设置中的任何问题,您可能还需要查看systemctl status network-online.target和的输出,因为它们可能对正在发生的事情有更多线索。(特别是,如果依赖于的守护进程正在启动systemctl status NetworkManager-wait-online.service,时间戳可能会有所帮助network-online.target NetworkManager-wait-online.service已完成,那么您的配置可能存在问题。


在您列出的解决方案中,我推荐这个:

# mkdir /etc/systemd/system/sshd.service.d
# tee /etc/systemd/system/sshd.service.d/wait.conf << 'EOF'
[Unit]
Wants=network-online.target
After=network-online.target
EOF

因为network-online.target是您真正想要的(以确保所有 IP 都已启动等)并且包括Wants=确保将请求其启动。

从其他方法来看,这种方法行不通:systemctl add-wants multi-user.target network.target,因为它不会在服务本身(SSH 守护程序等)和完全启动的网络之间创建任何依赖关系。它只是说您希望网络处于启动状态...

并且涉及目录的那个/etc/systemd/system/sshd.service.requires/缺少After=依赖项(我认为这是必不可少的,而不仅仅是暗示.requires/它)。如果你认为Requires=比更好Wants=(它更强大,如果依赖项失败则导致单元失败),那么我建议只是使用它/etc/systemd/system/sshd.service.d/wait.conf,覆盖文件绝对是管理此配置的更灵活的方式来。

添加依赖项sys-subsystem-net-devices-eth1.device也无济于事,因为这仅表明设备存在(从 udev 的角度来看),并未说明设备已启动并已配置。所以这也不是一个选择。

答案2

也许更好的办法是不是配置系统服务以监听特定的 IP 地址,并在必要时通过主机防火墙控制对它们的访问。

如果您确实需要在网络接口上配置特定 IP 地址之前将其绑定到这些地址,您可以通过net.ipv4.ip_nonlocal_bind为 IPv4 设置 sysctl 并为 IPv6 设置 sysctl来解决时间问题net.ipv6.ip_nonlocal_bind。然后,服务可以绑定到任何网络接口上未配置的 IP 地址,但直到在接口上配置这些 IP 地址后,服务才可访问。

相关内容