在build立出站TCP连接时,无法绑定到特定的IPv4地址,也不能绑定到parsing为IPv4和IPv6地址的主机名

我花了大概6个小时试图解决这个问题,现在我认为当连接到一个具有IPv6地址的主机名时,CentOS / Linux无法绑定到特定的虚拟IPv4地址。 这是有多个IP地址的服务器上的问题。

我正在使用Centos 6(Linux内核2.6.32-573.12.1.el6.x86_64)

重现这个巨大的:

  1. find至less具有29个IPv4公共地址空间和IPv6公共IP的Linux机器。
  2. 别名至less有一个额外的IPv4到主接口(eth0或其他)。 在这个例子中,我将30.0.0.1作为机器的主eth0 IPv4地址,而30.0.0.2是绑定到30.0.0.0/29networking上的eth0:2的别名。
  3. find具有IPv4和IPv6地址的主机名。 例如,www.microsoft.com。
  4. telnet -b 30.0.0.2 www.microsoft.com 80 (此testing使用特定的ipv4地址进行出站连接)
  5. 尝试主机名的IPv6地址失败后,IPv4请求连接成功,但TCP连接实际上是从主机IP(30.0.0.1)启动的,而不是您想要的IP(30.0.0.2)。 Netstat否则说,但它是错误的。 如果您连接到您拥有的主机名并可以查看其日志,则连接来自主IP(30.0.0.1),而不是您想要的IP(30.0.0.2)。
  6. 尝试另一个没有IPv6地址的域,例如: telnet -b 30.0.0.2 serverfault.com 。 有用。 它使你想要的IP连接。

这是一个问题,因为某些程序(如邮件(exim))在发出出站TCP请求时需要使用某些IP,这不一定是主机的IP。 当进行出站TCP连接时,机器上的某些客户端/程序依靠ACL或反向DNS来正确匹配。

所以,如果其他人注意到他们的程序无法绑定到正确的接口进行传出连接的同一个奇怪的问题,这可能是为什么。

此问题仅影响IPv4连接。 IPv6连接正确地绑定到您在机器上具有的任何传出IP。

这对于telnet来说不是问题。 我也使用我的邮件服务器(exim)testing了这个问题,并得到了类似的结果。 如果目标主机名具有IPv6地址,则它将从错误的IP进行IPv4连接。

也许有人有这个奇怪的问题的解决scheme,但在这个时候,我认为这可能是一个Linuxnetworking的错误。

Ps-如果有人想知道如果主机名parsing为IPv6地址,为什么不build立IPv6连接?有时IPv6地址closures或者连接无法build立,那么它将恢复到它的IPv4地址。

你可以信任netstat给你正确的IP地址信息(至less和-n )。

如果TCP连接的端点不同意使用哪个IP地址,则意味着两者之间存在NAT。

从评论中提供的附加信息中,我们了解到,在这种特殊情况下,一个多余的iptables规则-A POSTROUTING -j MASQUERADE是导致问题的原因。