我花了大约 6 个小时试图解决这个问题,现在我相信 CentOS/Linux 在连接到具有 IPv6 地址的主机名时无法绑定到特定的虚拟 IPv4 地址。这是具有多个 IP 地址的服务器上的问题。
我正在使用 Centos 6(Linux 内核 2.6.32-573.12.1.el6.x86_64)
要复制这个大:
- 查找至少具有 /29 IPv4 公共地址空间和 IPv6 公共 IP 的 Linux 机器。
- 将至少一个其他 IPv4 别名设为主接口(eth0 或其他)。在此示例中,我将 30.0.0.1 设为机器的主 eth0 IPv4 地址,30.0.0.2 是绑定到 30.0.0.0/29 网络上的 eth0:2 的别名。
- 查找同时具有 IPv4 和 IPv6 地址的主机名。例如 www.microsoft.com。
telnet -b 30.0.0.2 www.microsoft.com 80
(这将测试使用特定的 ipv4 地址建立出站连接)- 在尝试主机名的 IPv6 地址失败后,IPv4 请求成功连接,但 TCP 连接实际上从机器的主 IP(30.0.0.1)发起,而不是您想要的 IP(30.0.0.2)。Netstat 的说法并非如此,但这是错误的。如果您连接到您拥有的主机名并且可以查看其日志,则连接来自主 IP(30.0.0.1),而不是您想要的 IP(30.0.0.2)。
- 尝试另一个没有 IPv6 地址的域名,例如:
telnet -b 30.0.0.2 serverfault.com
。它可以工作。它会从您想要的 IP 建立连接。
这是一个问题,因为某些程序(如邮件 (exim))在发出出站 TCP 请求时需要使用某些 IP,而这些 IP 不一定是主机的 IP。机器上的某些客户端/程序在建立出站 TCP 连接时依赖 ACL 或反向 DNS 来正确匹配。
因此,如果其他人也注意到了同样奇怪的问题,即他们的程序在建立传出连接时无法绑定到正确的接口,那么这可能就是原因。
此问题仅影响 IPv4 连接。IPv6 连接可正确绑定到您机器上的任何传出 IP。
这不是 telnet 的问题。我也使用我的邮件服务器 (exim) 测试了这个问题,得到了类似的结果。如果目标主机名有 IPv6 地址,它会从错误的 IP 建立 IPv4 连接。
也许有人对这个奇怪的问题有解决方案,但现在,我认为这可能是 Linux 网络错误。
Ps-如果有人想知道如果主机名解析为 IPv6 地址为什么不直接建立 IPv6 连接...有时 IPv6 地址已关闭或无法建立连接,那么它会恢复为其 IPv4 地址。
答案1
您可以信赖netstat
我们为您提供有关 IP 地址的正确信息(至少在-n
使用期间)。
如果 TCP 连接的端点对所使用的 IP 地址存在分歧,则意味着两者之间存在 NAT。
从评论中提供的附加信息中,我们了解到,在这种特殊情况下,多余的 iptables 规则-A POSTROUTING -j MASQUERADE
是导致问题的原因。