IPv4のみの時代に戻ると、netstat
に0.0.0.0
をリッスンしていると表示されるLISTEN接続は、システム内の任意のIPv4インターフェイス上の接続に応答していました。
私が理解しているように、新しいIPv6イディオム::
は、使用可能なすべてのIPv6 および IPv4インターフェイスでリッスンします。これはすべてのOS(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で、NetBIOSが使用されていないときにSMBトラフィックに使用されます。ご覧のとおり、0.0.0.0
と::
の両方にバインドされていますそれぞれ、IPv4クライアントとIPv6クライアントの両方を機能させます。
Linuxでは、正しく推測したように、::
にはIPv4互換アドレスが含まれているため、0.0.0.0
へのバインドも不要です。 AF_INET6
の::
ソケットにのみバインドする単純なPythonプログラムを作成しました。AF_INET
(IPv4)にもバインドしていませんが)ソケット、IPv4クライアントからの接続を引き続き受け入れます。たとえば、10.1.1.3
がそれに接続すると、::ffff:10.1.1.3
から接続しているように表示されます。
例外毛むくじゃらになること。 /proc/sys/net/ipv6/bindv6only
が1
に設定されている場合、上記はLinuxには適用されません。この場合、動作は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 OSX側の情報がないことをお詫びします。過去に使用したことがありますが、GNOMEの美学が好きなので、あまり長い間使用していません。ただし、動作はLinuxと同じだと思います。
お役に立てれば。
IPv6アドレス空間のセグメントはIPv4空間と同じであるため、これは不可能です。したがって、何らかの方法でIPv4ソケットを無効にできたとしても、IPv4パケットをIPv6ソケットに送信することはできます。 IPv4ウィキペディアページ のIPv4移行セクションを確認してください。
編集:ああ、少し下にそれは言う:
一部の一般的なIPv6スタックは、IPv6スタックとIPv4スタックが別々の実装であるため(Vista/Longhornより前のMicrosoftWindows:XP/2003など)、またはセキュリティ上の懸念(OpenBSD)のため、IPv4マップアドレス機能をサポートしていません。これらのオペレーティングシステムでは、サポートされるIPプロトコルごとに個別のソケットを開く必要があります。一部のシステム(Linux、NetBSD、FreeBSDなど)では、この機能は RFC 349 で指定されているソケットオプションIPV6_V6ONLYによって制御されます。