web-dev-qa-db-ja.com

デュアルスタックOSでの::および0.0.0.0のセマンティクス

IPv4のみの時代に戻ると、netstat0.0.0.0をリッスンしていると表示されるLISTEN接続は、システム内の任意のIPv4インターフェイス上の接続に応答していました。

私が理解しているように、新しいIPv6イディオム::は、使用可能なすべてのIPv6 および IPv4インターフェイスでリッスンします。これはすべてのOS(Unix、Windows、Mac)で正しいですか? IPv6インターフェイスだけでリッスンするイディオムはありますか?

10
Alex J

残念ながら、これは使用しているオペレーティングシステムによって異なります。

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/bindv6only1に設定されている場合、上記は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と同じだと思います。

お役に立てれば。

17
Jeremy Visser

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によって制御されます。
4
David Pashley