Во времена, когда использовался только IPv4, соединение LISTEN отображалось в netstat
как слушать 0.0.0.0
будет отвечать на соединения на любом интерфейсе IPv4 в системе.
Насколько я понимаю, новая идиома IPv6 ::
слушает на всех доступных IPv6 и Интерфейсы IPv4. Это правильно для всех ОС (Unix, Windows, Mac)? Есть ли идиома для прослушивания только интерфейсов IPv6?
К сожалению, это зависит от того, какую операционную систему вы используете.
В Microsoft Windows привязка сокета к ::
связывается только с портами IPv6. Таким образом, чтобы прослушивать все адреса как на IPv4, так и на IPv6, вам необходимо выполнить привязку к 0.0.0.0
так же как ::
. Следующий отрывок взят из коробки Vista:
C:\>netstat -an | find "445"
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP [::]:445 [::]:0 LISTENING
В качестве примера я привожу порт 445, используемый для трафика SMB, когда NetBIOS не используется. Как видите, он привязан к обоим 0.0.0.0
и ::
чтобы заставить работать, соответственно, и IPv4 и IPv6 клиенты.
В Linux ::
включает IPv4-совместимые адреса, как вы правильно догадались, поэтому привязка к 0.0.0.0
также не нужно. Я написал простую программу на Python, которая привязывается только к AF_INET6
розетка на ::
. Хотя я также не привязывался к AF_INET
(IPv4), он по-прежнему принимает соединения от клиентов IPv4. Если, скажем, 10.1.1.3
подключается к нему, он будет отображаться как подключение от ::ffff:10.1.1.3
.
Кроме что это становится волосатым. Вышеуказанное не применяется в Linux, если /proc/sys/net/ipv6/bindv6only
установлен на 1
, и в этом случае поведение точно такое же, как в Windows - привязка к ::
будет слушать только запросы IPv6. Если вы хотите также прослушивать запросы IPv4, вам нужно будет создать AF_INET
сокет и слушай 0.0.0.0
также. К счастью, по умолчанию для bindv6only
является 0
, поэтому очень маловероятно, что вам когда-нибудь придется иметь дело с этим (кроме случаев, когда вы используете Debian, который по умолчанию bindv6only = 1
).
Все это полезно знать при проверке, поддерживает ли служба IPv6 и поддерживает ли она также IPv4. Вот мой SSH-сервер:
$ netstat -64ln | grep 22
tcp6 0 0 :::22 :::* LISTEN
Как видите, SSH прослушивает только ::
порт 22. Однако он не просто прослушивает клиентов IPv6 - он отлично работает с клиентами IPv4 благодаря привязке, совместимой с IPv4. Чтобы доказать это, посмотрите на это:
$ cat /proc/sys/net/ipv6/bindv6only
0
bindv6only
отключено (по умолчанию). Если бы это было установлено на 1
, тогда мне пришлось бы поощрять SSH прослушивать 0.0.0.0
также (или вместо этого).
Приносим извинения за отсутствие информации о Mac OS X. Я использовал его в прошлом, но предпочитаю эстетику GNOME, поэтому я не использовал его очень давно. Однако я предполагаю, что поведение такое же, как у Linux.
Надеюсь это поможет.
Это невозможно, поскольку сегмент адресного пространства IPv6 совпадает с пространством IPv4, поэтому даже если вы каким-то образом можете отключить сокеты IPv4, вы все равно сможете отправлять пакеты IPv4 на сокет IPv6. Ознакомьтесь с разделом перехода IPv4 в Страница википедии IPv4.
Изменить: Ах, немного ниже он говорит:
Некоторые распространенные стеки IPv6 не поддерживают функцию сопоставления адресов IPv4 либо потому, что стеки IPv6 и IPv4 являются отдельными реализациями (Microsoft Windows до Vista / Longhorn: например, XP / 2003), либо из-за проблем безопасности (OpenBSD). В этих операционных системах необходимо открыть отдельный сокет для каждого поддерживаемого IP-протокола. В некоторых системах (например, Linux, NetBSD, FreeBSD) эта функция управляется параметром сокета IPV6_V6ONLY, как указано в RFC 3493
Вероятно, вы могли бы сделать это со своим сетевым идентификатором AAAA: BBBB: CCCC: DDDD :: или как-то иначе. Это гарантировало бы, что только интерфейсы IPv6 воспримут его. Думаю. Я не мастер IPv6.