Passei cerca de 6 horas tentando descobrir isso e agora acredito que o CentOS/Linux não consegue se vincular a um endereço IPv4 virtual específico ao conectar-se a um nome de host que possui um endereço IPv6. Este é um problema em servidores que possuem vários endereços IP.
Estou usando Centos 6 (kernel Linux 2.6.32-573.12.1.el6.x86_64)
Para reproduzir este grande:
- Encontre uma máquina Linux com pelo menos um espaço de endereço público IPv4 /29 e um IP público IPv6.
- Alias pelo menos um IPv4 adicional para a interface principal (eth0 ou outro). Para este exemplo, direi 30.0.0.1 como o endereço IPv4 eth0 primário da máquina e 30.0.0.2 é um alias vinculado a eth0:2 em uma rede de 30.0.0.0/29.
- Encontre um nome de host que tenha endereços IPv4 e IPv6. Por exemplo, www.microsoft.com.
telnet -b 30.0.0.2 www.microsoft.com 80
(Isso testa a conexão de saída usando um endereço ipv4 específico)- A solicitação IPv4 se conecta com sucesso depois de tentar sem sucesso os endereços IPv6 do nome do host, mas a conexão TCP realmente inicia a partir do IP principal da máquina (30.0.0.1), não do IP que você deseja (30.0.0.2). Netstat diz o contrário, mas está ERRADO. Se você se conectar a um nome de host que você possui e puder visualizar seus logs, a conexão vem do IP principal (30.0.0.1) e não do IP que você deseja (30.0.0.2).
- Tente outro domínio que não tenha um endereço IPv6, como:
telnet -b 30.0.0.2 serverfault.com
. Funciona. Ele faz a conexão a partir do IP que você quiser.
Isso é um problema, porque certos programas, como o mail (exim), precisam usar certos IPs ao fazer solicitações TCP de saída, que não são necessariamente o IP da máquina principal. Certos clientes/programas na máquina dependem de ACLs ou DNS reverso para corresponder corretamente ao fazer conexões TCP de saída.
Portanto, se mais alguém estiver percebendo o mesmo problema estranho em que seu programa não pode se conectar à interface correta ao fazer conexões de saída, provavelmente é por isso.
Esse problema afeta apenas as conexões IPv4. As conexões IPv6 se ligam corretamente a qualquer IP de saída que você tenha na máquina.
Este não é um problema com o telnet. Também testei esse problema usando meu servidor de correio (exim) e obtive resultados semelhantes. Ele faz conexões IPv4 do IP errado se o nome do host de destino tiver um endereço IPv6.
Talvez alguém tenha uma solução para esse problema estranho, mas, no momento, acho que pode ser um bug de rede do Linux.
Ps- Se alguém se perguntar por que não apenas fazer uma conexão IPv6 se o nome do host resolver para um endereço IPv6 ... às vezes o endereço IPv6 está inativo ou a conexão não pode ser estabelecida, então ele reverte para seu endereço IPv4.
Você pode confiar
netstat
em fornecer informações corretas sobre os endereços IP (pelo menos enquanto-n
for usado).Se os pontos de extremidade de uma conexão TCP discordarem sobre quais endereços IP estão em uso, isso significa que há um NAT em algum lugar entre os dois.
A partir das informações adicionais fornecidas nos comentários, descobrimos que, neste caso específico, uma regra supérflua do iptables
-A POSTROUTING -j MASQUERADE
era a causa do problema.