要約
- RFC 3493では、
AF_INET6socketがIPv4-mapped IPv6 addressを通じてIPv4 peerと通信できた。IPV6_V6ONLYはそれをIPv6に限定したが、RFC上のdefaultは無効だった。 - したがってsocket family名やwildcard bindの成功だけでは、到達できるpeer familyも別のIPv4 listenerが同じportを所有できたかも証明しない。optionの実効値、各bind結果、実際の受信を別々に確認する必要がある。
二つのserver processを用意した場面から考える。一つはIPv6、もう一つはIPv4、port番号は同じである。IPv6側が先にwildcard bindを行い、次のIPv4側がaddress in useで失敗することがある。名前上は二つの担当がいても、kernelが最初のlistenerへ与えた領域が二族分なら、実際の分離は成立していない。
RFC 3493の互換手段はIPv4-mapped IPv6 addressだった。IPv4 addressを固定の::ffff: prefixの下、128-bit構造の下位32 bitへ収める。applicationはAF_INET6 socketでIPv4 nodeへ接続でき、受信時にはkernelがmapped peerをsockaddr_in6として返せる。区別が必要ならIN6_IS_ADDR_V4MAPPED()を使う。
これはapplicationとkernelの間の表現である。remote hostがnative IPv6を使う証拠でも、pathがIPv6だけだった証拠でも、同じ認可policyが適用された証拠でもない。構造体のfamilyとnetwork realityは同じ層にない。
RFC 3493 section 5.3はIPV6_V6ONLYを明示した。有効にするとAF_INET6 socketはIPv6通信だけに限定される。文書はdefaultを無効と定めたので、当時の契約では一つのIPv6 wildcard listenerがnative IPv6とmapped IPv4の双方を扱えた。
RFCが示す利用例はportの分割である。optionを有効にすれば、同じserverの二つの版が同じportを使い、一方をIPv6、他方をIPv4にできる。つまりoptionは注釈ではない。一つのbindが二族を占めるか、別socketのために一族分を残すかを左右するresource controlだった。
このためprocess監視だけでは足りない。二つとも起動済みに見えても、一方のbindが失敗しているかもしれない。socket一覧もAF_INET6をIPv6-onlyと読むなら誤る。family、IPV6_V6ONLYのread-back値、bind address、namespace、return code、native/mapped peerの受信実績を一組にして初めて境界を説明できる。
mapped表現にも但し書きがある。RFC 3493は、SIITによって有効なIPv6通信としてnodeへ入るmapped addressにはこのoptionが影響しないと述べる。RFC 6052とRFC 6145のembedded addressやpacket translationはlocal dual-stack socketとは別の仕組みだ。見た目だけで変換地点を決めてはならない。
名前解決はさらに手前の段階である。getaddrinfo()はfamilyやflagに応じて候補を返す。RFC 6724はdefault selectionを、RFC 8305はIPv6とIPv4候補の競争を扱う。候補取得、listener所有、接続、認可、service完了は別のreceiptだ。
なお、default無効という記述は2003年の歴史的契約である。RFC 3493はInformationalでRFC 2553をobsoleteし、正式なsocket標準の所在も別に示した。現在のOS、runtime、container platformが同じdefaultやbind conflictを持つとは限らない。現在値は測定すべきで、歴史から推測してはならない。
scopeも別の証拠である。sockaddr_in6のsin6_scope_idは、link-localなどのaddressをどのinterface集合で解釈するかを実装へ渡す。一つの数値addressが見えても、適切なzoneを欠けば利用可能なpathは決まらない。family、mapping、scope、route、listenerは連続するが同一ではない。だから監査では、address文字列だけを保存せず、受信interfaceとlocal endpoint、remote endpoint、namespaceを同じeventに結び付ける必要がある。
また、成功したbindは外部からの到達性を証明しない。host firewall、containerのport公開、load balancer、routing、service discoveryが後段に残る。反対に外部probeの成功だけでは、どのdescriptorが接続を受け、mapped peerをどのpolicy branchへ渡したかは分からない。起動時の設定証跡と実通信の観測を結び、途中の変換点を明示して初めて、意図した分離が実在したと言える。
残る教訓は、宣言されたfamilyではなく、実効option、bind範囲、port所有、peer表現、application policy、service結果を順に記録することだ。「IPv6 listener」という一語ではIPv4入口も、起動できなかったIPv4 processも見えない。
出典
- https://www.rfc-editor.org/rfc/rfc3493.html
- https://www.rfc-editor.org/rfc/rfc3493.txt
- https://www.rfc-editor.org/info/rfc3493
- https://datatracker.ietf.org/doc/rfc3493/
- https://datatracker.ietf.org/doc/rfc3493/history/
- https://www.rfc-editor.org/errata_search.php?rfc=3493
- https://www.rfc-editor.org/rfc/rfc2553.html
- https://www.rfc-editor.org/rfc/rfc2133.html
- https://www.rfc-editor.org/rfc/rfc4291.html
- https://www.rfc-editor.org/rfc/rfc4007.html
- https://www.rfc-editor.org/rfc/rfc4038.html
- https://www.rfc-editor.org/rfc/rfc3542.html
- https://www.rfc-editor.org/rfc/rfc6052.html
- https://www.rfc-editor.org/rfc/rfc6145.html
- https://www.rfc-editor.org/rfc/rfc6724.html
- https://www.rfc-editor.org/rfc/rfc8305.html
- https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml
- https://learn.microsoft.com/en-us/windows/win32/winsock/dual-stack-sockets
- https://heng.lu/minimum-initial-specification-localized-future-decision-voluntary-adoption-internet-coordination-system/
- https://heng.lu/on-reality-layers-symbolic-power-and-why-clarity-feels-so-hostile/
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
