在禁用 ipv6 的计算机上,让 IPv4/IPv6 双栈服务器绑定到 0.0.0.0 而不是 ::?

在禁用 ipv6 的计算机上,让 IPv4/IPv6 双栈服务器绑定到 0.0.0.0 而不是 ::?

我有一个使用内核选项启动的 Linux (Ubuntu Groovy) 服务器,ipv6.disable=1因此 IPv6 不可用。

我还有一些双栈软件,宣称它适用于仅 IPv4 的计算机,而且我无法更改。该软件现在想要绑定到::,这当然失败了。我可以以某种方式配置操作系统以使该服务器绑定0.0.0.0并使用 IPv4 吗?

编辑:或者,这可以在绑定之前、名称解析期间完成吗?该软件尝试解析::,如果它将获得 IPv4 地址127.0.0.1作为响应,我认为它将使用 IPv4。

答案1

即使有可能,您所要求的也不会起作用。如果软件绑定到::,那么它可以假设地址将以 IPv6 格式呈现给它。接受的套接字将是 IPv6,并且 IPv4 地址将被封装。

所以 192.168.1.1 变成 ::FFFF:192.168.1.1

换句话说,即使您可以以某种方式绑定到不同的 IP,您也会将其设置为 IPv4 套接字,而软件不会编译为处理该套接字。该软件需要它是一个 IPv6 套接字,但它不能,因为 IPv6 已被禁用。

禁用 IPv6 时没有兼容性代码。最重要的是您禁用了 IPv6,而您使用的软件要求启用它。


这里唯一的选择是启用 IPv6(从你的问题中不清楚为什么需要禁用它)或自己从源代码重新编译 IPv6 软件,可能会修补源代码以“修复”问题。

答案2

您可以做的就是妥协:启用 IPv6,但不允许它在任何地方有效使用。

启动时启用 IPv6,但通过使用sysctl -w ...以下参数或在/etc/sysctl.conf/中添加这些参数,在未来和当前的接口上禁用它/etc/sysctl.d

  net.ipv6.conf.default.disable_ipv6=1
  net.ipv6.conf.all.disable_ipv6=1

这样,IPv6 的使用就被有效禁用,而 IPv6 套接字 API 仍保持启用状态。因此,应用程序仍然可以在双堆栈模式下绑定::并获取也与其关联的 IPv4(这是默认情况下,根据RFC 3493)。

您可以考虑关于 ::1 的异常和问题接口,具体取决于配置和应用程序行为。多项选择中:

  • /etc/hosts从如下所示的条目中删除:

    ::1     localhost ip6-localhost ip6-loopback
    
  • 或者不要禁用 IPv6(在之前的设置之后)得到 ::1 :

    net.ipv6.conf.lo.disable_ipv6=0
    
  • 如果选择保留 中的条目/etc/hosts,请考虑使 127.0.0.1 优先于 ::1,或者通过添加以下内容来简单地使 IPv4 优于 IPv6 /etc/gai.conf

    precedence ::ffff:127.0.0.1/128 100
    

    或者:

    precedence ::ffff:0:0/96  100
    

注意:某些网络配置工具(例如 NetworkManager)会将切换重置disable_ipv6为其自己的设置,因此必须显式配置为在配置的接口上禁用 IPv6。

替代方法:如果这太麻烦而无法接受,这里有一个禁用 IPv6 的替代方法(在带有 的内核上CONFIG_IP_ADVANCED_ROUTER,所有主要发行版内核都这样做)。

通过替换来防止 IPv6 路由规则使用路由表偏好 0规则与黑洞导致任何 IPv6 路由查找失败的规则(可以删除所有规则,包括首选项 32766,以获取Network is unreachable而不是Invalid argument):

ip -6 rule delete preference 0
ip -6 rule add preference 0 blackhole

即使在任何界面上没有任何其他设置:

$ ping ::1
ping: connect: Invalid argument
ping ff05::2
ping: connect: Invalid argument

虽然监听 IPv6 仍然成功(并且根据 RFC 默认为双堆栈):

$ socat tcp6-listen:4242 /dev/null &
[1] 430541
$ ss -tnle sport == 4242
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port                     
LISTEN  0       5                   *:4242             *:*           uid:1000 ino:5971821 sk:1106 v6only:0 <->

由于 IPv4 路由不受阻碍,它仍然可以在双堆栈模式下接收 IPv4 流量。

相关内容