我在 Ubuntu 23.04 上有几个服务,BIND 和 Nginx,它们配置为绑定到特定的 IPv6 地址。但是,它们无法启动,因为 systemd 尝试在 IPv6 地址通过 DHCPv6 出现之前启动它们。从我的日志来看,我相信 DHCPv6 地址在 DHCPv4 出现两秒后出现。
我可以在启动后手动重新启动服务以让它们绑定到 IPv6 地址,但是在 IPv6 启动之前停止它们启动的最佳方法是什么?
答案1
Linux 支持 IP_FREEBIND 套接字选项,程序可以在尝试绑定到特定地址之前启用该选项。nginx 和 BIND 都不支持此功能,但net.ipv6.ip_nonlocal_bind
sysctl 可以在系统范围内启用此功能(这可能有点冒险,因为这意味着 bind() 永远不会失败,即使它应该)。
如果您正在使用 systemd-networkd(即使通过 netplan 间接使用),那么您可以在单元中使用一项服务,该After=
服务的唯一目的是等待所有网络接口配置完毕。(NetworkManager 有一个类似的服务。)通常您可以通过它使用它,network-online.target
但也可以直接使用它:
a) 间接(通常方式):
# systemctl 启用 systemd-networkd-wait-online #systemctl 编辑命名 [单元] 想要=网络在线.目标 之后=网络在线.目标
b) 直接:
#systemctl 编辑命名 [单元] 想要=systemd-networkd-wait-online.service 之后=systemd-networkd-wait-online.service
不过,一般来说,我更喜欢绑定到通配符地址并使用防火墙 (nftables) 来限制对服务的访问。(我已经看到并滥用了一个将其服务绑定到地址接口 A,但其防火墙没有采取任何措施来阻止来自接口 B 的数据包路由到这些地址。)