Semântica de :: e 0.0.0.0 em sistemas operacionais de pilha dupla

10

Nos dias apenas IPv4, uma conexão LISTEN aparecendo netstatcomo ouvindo 0.0.0.0responderia às conexões em qualquer interface IPv4 no sistema.

Pelo que entendi, o novo idioma do IPv6 ::escuta em todas as interfaces IPv6 e IPv4 disponíveis . Isso está correto para todos os sistemas operacionais (Unix, Windows, Mac)? Existe um idioma para escutar apenas nas interfaces IPv6?

Alex J
fonte

Respostas:

17

Infelizmente, isso varia dependendo do sistema operacional que você está usando.

No Microsoft Windows, a ligação de um soquete ::só se vincula às portas IPv6. Portanto, para ouvir todos os endereços no IPv4 e no IPv6, é necessário vincular-se a ele 0.0.0.0também ::. O seguinte extrato é de uma caixa do Vista:

C:\>netstat -an | find "445"
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
  TCP    [::]:445               [::]:0                 LISTENING

O exemplo que dou é a porta 445, usada para tráfego SMB quando o NetBIOS não é usado. Como você pode ver, ele é obrigatório para os dois 0.0.0.0e ::para fazer, respectivamente, os clientes IPv4 e IPv6 funcionarem.

No Linux, ::inclui os endereços compatíveis com IPv4, como você adivinhou corretamente, portanto, a ligação 0.0.0.0também é desnecessária. Eu escrevi um programa Python simples que só se liga a um AF_INET6soquete ::. Embora eu também não tenha se vinculado a um AF_INETsoquete (IPv4), ele ainda aceita conexões de clientes IPv4. Se, digamos, se 10.1.1.3conectar a ele, ele aparecerá como se conectando ::ffff:10.1.1.3.

Exceto que fica peludo. O item acima não se aplica ao Linux se /proc/sys/net/ipv6/bindv6onlyestiver definido como 1; nesse caso, o comportamento é exatamente o mesmo que o do Windows - a ligação ::só atenderá solicitações IPv6. Se você quiser escutar solicitações IPv4 também, precisará criar um AF_INETsoquete e escutar 0.0.0.0também. Felizmente, o padrão para bindv6onlyé 0, então há uma chance muito pequena de você lidar com isso (exceto se você usar o Debian, que na verdade é o padrão bindv6only = 1).

Tudo isso é útil para verificar se um serviço está habilitado para IPv6 e se também está habilitado para IPv4. Aqui está o meu servidor SSH:

$ netstat -64ln | grep 22
tcp6    0    0 :::22    :::*    LISTEN

Como você pode ver, o SSH está apenas ouvindo na ::porta 22. No entanto, não está apenas ouvindo clientes IPv6 - funciona bem nos clientes IPv4, devido à ligação compatível com IPv4. Para provar isso, se você olhar para isso:

$ cat /proc/sys/net/ipv6/bindv6only 
0

bindv6onlyestá desativado (o padrão). Se isso fosse definido 1, eu teria que incentivar o SSH a ouvir 0.0.0.0também (ou melhor).

Desculpas por não ter informações sobre o lado do Mac OS X. Eu o usei no passado, mas prefiro a estética do GNOME, por isso não o uso há muito tempo. No entanto, eu acho que o comportamento é o mesmo do Linux.

Espero que isto ajude.

Jeremy Visser
fonte
4

Isso não é possível, pois um segmento do espaço de endereço IPv6 é o mesmo que o espaço IPv4, portanto, mesmo que você possa desabilitar os soquetes IPv4, ainda poderá enviar pacotes IPv4 para o soquete IPv6. Confira a seção de transição do IPv4 na página da Wikipedia sobre IPv4 .

Edit: Ah, um pouco mais abaixo, diz:

Algumas pilhas IPv6 comuns não suportam o recurso de endereço mapeado IPv4, porque as pilhas IPv6 e IPv4 são implementações separadas (Microsoft Windows antes do Vista / Longhorn: por exemplo, XP / 2003) ou devido a questões de segurança (OpenBSD). Nesses sistemas operacionais, é necessário abrir um soquete separado para cada protocolo IP a ser suportado. Em alguns sistemas (por exemplo, Linux, NetBSD, FreeBSD) esse recurso é controlado pela opção de soquete IPV6_V6ONLY conforme especificado na RFC 3493
David Pashley
fonte
-1

Você provavelmente poderia fazê-lo com o seu ID de rede, AAAA: BBBB: CC0: DDDD :: ou o que for para você. Isso garantiria que apenas as interfaces IPv6 fossem atendidas. Eu acho que. Eu não sou mestre em IPv6.

Matt Simmons
fonte