Semantyka :: i 0.0.0.0 w systemach operacyjnych z dwoma stosami

10

Już za dni IPv4 połączenie SŁUCHAWKA wyświetlane netstatjako nasłuchiwanie 0.0.0.0odpowiadałoby na połączenia na dowolnym interfejsie IPv4 w systemie.

Jak rozumiem, nowy idiom IPv6 ::nasłuchuje na wszystkich dostępnych interfejsach IPv6 i IPv4. Czy to prawda, dla wszystkich systemów operacyjnych (Unix, Windows, Mac)? Czy jest jakiś idiom do słuchania tylko na interfejsach IPv6?

Alex J.
źródło

Odpowiedzi:

17

Niestety różni się to w zależności od używanego systemu operacyjnego.

W systemie Microsoft Windows powiązanie gniazda ::tylko z portami IPv6. Tak więc, aby wysłuchać wszystkich adresów na IPv4 i IPv6, trzeba wiązać się 0.0.0.0jak ::. Poniższy fragment pochodzi z systemu Vista:

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

Podany przykład to port 445, używany dla ruchu SMB, gdy NetBIOS nie jest używany. Jak widać, jest on wiążący dla obu 0.0.0.0i ::sprawia, że ​​odpowiednio działają zarówno klienci IPv4, jak i IPv6.

W systemie Linux ::zawiera adresy zgodne z IPv4, jak poprawnie zgadłeś, więc powiązanie z nimi 0.0.0.0również nie jest konieczne. Napisałem prosty program w języku Python, który wiąże się tylko z AF_INET6gniazdem ::. Mimo że nie powiązałem również z AF_INETgniazdem (IPv4), nadal przyjmuje połączenia od klientów IPv4. Jeśli, powiedzmy, 10.1.1.3łączy się z nim, pojawi się jako połączenie z ::ffff:10.1.1.3.

Tyle że robi się owłosiony. Powyższe nie dotyczy Linuksa, jeśli /proc/sys/net/ipv6/bindv6onlyjest ustawione na 1, w takim przypadku zachowanie jest dokładnie takie samo jak Windows - powiązanie z ::nasłuchuje tylko żądań IPv6. Jeśli chcesz nasłuchiwać również żądań IPv4, musisz utworzyć AF_INETgniazdo i nasłuchiwać 0.0.0.0. Na szczęście domyślną wartością bindv6onlyjest 0, więc istnieje bardzo niewielka szansa, że ​​kiedykolwiek będziesz musiał sobie z tym poradzić (z wyjątkiem sytuacji, gdy używasz Debiana, który tak naprawdę jest domyślnie ustawiony bindv6only = 1).

Wszystko to jest przydatne przy sprawdzaniu, czy usługa obsługuje IPv6 i czy obsługuje również IPv4. Oto mój serwer SSH:

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

Jak widać, SSH nasłuchuje tylko na ::porcie 22. Jednak nie tylko nasłuchuje klientów IPv6 - działa dobrze z klientami IPv4, ze względu na powiązanie kompatybilne z IPv4. Aby to udowodnić, jeśli spojrzysz na to:

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

bindv6onlyjest wyłączone (domyślne). Gdyby to było ustawione 1, musiałbym zachęcić SSH również do słuchania 0.0.0.0(lub zamiast tego).

Przepraszamy za brak informacji po stronie Mac OS X. Używałem go w przeszłości, ale wolę estetykę GNOME, więc nie używałem go od bardzo dawna. Jednak zgaduję, że zachowanie jest takie samo jak w Linuksie.

Mam nadzieję że to pomoże.

Jeremy Visser
źródło
4

Nie jest to możliwe, ponieważ segment przestrzeni adresowej IPv6 jest taki sam jak przestrzeń IPv4, więc nawet gdybyś mógł jakoś wyłączyć gniazda IPv4, nadal będziesz mógł wysyłać pakiety IPv4 do gniazda IPv6. Sprawdź sekcję przejścia IPv4 na stronie wikipedii IPv4 .

Edycja: Ach, kawałek dalej mówi:

Niektóre typowe stosy IPv6 nie obsługują funkcji adresu mapowanego IPv4, ponieważ albo stosy IPv6 i IPv4 są osobnymi implementacjami (Microsoft Windows wcześniejszy niż Vista / Longhorn: np. XP / 2003), lub z powodów bezpieczeństwa (OpenBSD). W tych systemach operacyjnych konieczne jest otwarcie osobnego gniazda dla każdego protokołu IP, który ma być obsługiwany. W niektórych systemach (np. Linux, NetBSD, FreeBSD) ta funkcja jest kontrolowana przez opcję gniazda IPV6_V6ONLY, jak określono w RFC 3493
David Pashley
źródło
-1

Prawdopodobnie możesz to zrobić za pomocą swojego identyfikatora sieci, AAAA: BBBB: CCCC: DDDD :: lub cokolwiek to jest dla Ciebie. Zagwarantowałoby to, że tylko interfejsy IPv6 mogłyby je odebrać. Myślę. Nie jestem mistrzem IPv6.

Matt Simmons
źródło