Sémantique de :: et 0.0.0.0 dans les systèmes d'exploitation à double pile

10

À l'époque IPv4 uniquement, une connexion LISTEN apparaissant netstatcomme écoutant 0.0.0.0répondait aux connexions sur n'importe quelle interface IPv4 du système.

Si je comprends bien, le nouvel idiome IPv6 ::écoute sur toutes les interfaces IPv6 et IPv4 disponibles . Est-ce correct, pour tous les systèmes d'exploitation (Unix, Windows, Mac)? Existe-t-il un idiome à écouter uniquement sur les interfaces IPv6?

Alex J
la source

Réponses:

17

Malheureusement, cela diffère selon le système d'exploitation que vous utilisez.

Sous Microsoft Windows, la liaison d'un socket ::ne se lie qu'aux ports IPv6. Ainsi, pour écouter toutes les adresses sur IPv4 et IPv6, vous devez vous lier à 0.0.0.0ainsi ::. L'extrait suivant provient d'une boîte Vista:

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

L'exemple que je donne est le port 445, utilisé pour le trafic SMB lorsque NetBIOS n'est pas utilisé. Comme vous pouvez le voir, il lie les deux 0.0.0.0et ::fait fonctionner respectivement les clients IPv4 et IPv6.

Sous Linux, ::comprend les adresses compatibles IPv4, comme vous l'avez bien deviné, il 0.0.0.0n'est donc pas nécessaire de s'y connecter également. J'ai écrit un programme Python simple qui ne se lie qu'à une AF_INET6socket ::. Même si je ne me suis pas également lié à un AF_INETsocket (IPv4), il accepte toujours les connexions des clients IPv4. Si, par exemple, il s'y 10.1.1.3connecte, il apparaîtra comme se connectant depuis ::ffff:10.1.1.3.

Sauf que ça devient poilu. Ce qui précède ne s'applique pas à Linux si /proc/sys/net/ipv6/bindv6onlyest défini sur 1, auquel cas le comportement est exactement le même que Windows - la liaison à ::n'écoutera que les requêtes IPv6. Si vous souhaitez également écouter les demandes IPv4, vous devrez créer un AF_INETsocket et écouter 0.0.0.0également. Heureusement, la valeur par défaut bindv6onlyest 0, donc il y a très peu de chances que vous ayez à gérer cela (sauf si vous utilisez Debian, qui est en fait par défaut bindv6only = 1).

Tout cela est pratique à savoir pour vérifier si un service est compatible IPv6 et s'il est également compatible IPv4. Voici mon serveur SSH:

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

Comme vous pouvez le voir, SSH n'écoute que sur le ::port 22. Cependant, il n'écoute pas uniquement les clients IPv6 - il fonctionne très bien à partir des clients IPv4, en raison de la liaison compatible IPv4. Pour le prouver, si vous regardez ceci:

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

bindv6onlyest désactivé (par défaut). Si c'était le cas 1, je devrais encourager SSH à écouter 0.0.0.0également (ou à la place).

Toutes mes excuses pour n'avoir aucune information sur Mac OS X. Je l'ai utilisé dans le passé, mais je préfère l'esthétique de GNOME, donc je ne l'ai pas utilisé depuis très longtemps. Cependant, je suppose que le comportement est le même que celui de Linux.

J'espère que cela t'aides.

Jeremy Visser
la source
4

Ce n'est pas possible, car un segment de l'espace d'adressage IPv6 est identique à l'espace IPv4, donc même si vous pouviez désactiver les sockets IPv4, vous seriez toujours en mesure d'envoyer des paquets IPv4 au socket IPv6. Consultez la section de transition IPv4 dans la page wikipedia IPv4 .

Edit: Ah, un peu plus bas, cela dit:

Certaines piles IPv6 courantes ne prennent pas en charge la fonction d'adresse mappée IPv4, soit parce que les piles IPv6 et IPv4 sont des implémentations distinctes (Microsoft Windows avant Vista / Longhorn: par exemple XP / 2003), ou en raison de problèmes de sécurité (OpenBSD). Sur ces systèmes d'exploitation, il est nécessaire d'ouvrir un socket distinct pour chaque protocole IP à prendre en charge. Sur certains systèmes (par exemple, Linux, NetBSD, FreeBSD), cette fonctionnalité est contrôlée par l'option de socket IPV6_V6ONLY comme spécifié dans la RFC 3493
David Pashley
la source
-1

Vous pourriez probablement le faire avec votre ID réseau, AAAA: BBBB: CCCC: DDDD :: ou quoi que ce soit pour vous. Cela garantirait que seules les interfaces IPv6 le capteraient. Je pense. Je ne suis pas un maître IPv6.

Matt Simmons
la source