I-Dを提出した。draft-momoka-v6ops-ipv6-only-resolver

TLDR;

Internet DraftをIETFへ提出してみました。提出が楽だったのは以下のテンプレートのおかげです。

github.com

 

 

 

題名のとおりInternet DraftをIETFへ提出してみました

www.ietf.org

リンクはこちら。内容について意見をいただけると嬉しいです。

(内容についてはいつか書く)

 

Internet Draftはだれでも提出することができます。

 

 

internet draft の書き方/提出の仕方。

「internet draft 提出ってとても難しいんじゃないの?」と思っていました。

想像以上に簡単だったので共有します。

テンプレートのおかげでとてもとても楽に提出できました。GitHub Actions という魔法がすべてやってくれました。よくわからないけどすごい。

3ステップでできます。

 

1. リポジトリを作る。

説明:https://github.com/martinthomson/i-d-template/blob/main/doc/REPO.md

こちらに従ってリポジトリを作ってpushするとなんか、GitHub Actions が動いて

https://momoka0122y.github.io/draft-momoka-ipv6-only-resolver/draft-momoka-v6ops-ipv6-only-resolver.html

上記のurlのようにgithub アカウントにいい感じのgithub.io ページが作られて、いい感じにdraftっぽくなります。 (Internet Draft を実際に提出するまでの間はこちらを草稿として人に送ることができました)

 

2. draftの中身を書く

マークダウンで書けるのでとても楽でした。

今回書いたマークダウンはこちらです。

https://github.com/momoka0122y/draft-momoka-ipv6-only-resolver/blob/main/draft-momoka-v6ops-ipv6-only-resolver.md

(こちらにPRをもらうことで複数人一緒にdraftが書けますね)

 

3. 提出する。

本来は

https://datatracker.ietf.org/submit/ からXMLファイルを提出するのですが、これもgithub actions が全て勝手にやってくれました。

説明:https://github.com/martinthomson/i-d-template/blob/main/doc/SUBMITTING.md

実際行ったのは git tag を行い、pushするだけ。これでGitHub Actions が提出をしてくれました。以下二つのコマンドで終わりでした。

$ git tag -a draft-momoka-v6ops-ipv6-only-resolver-00 
$ git push origin draft-momoka-v6ops-ipv6-only-resolver-00
そしたら数分後に

Confirm submission of I-D draft-momoka-v6ops-ipv6-only-resolver

と言うメールがおくられ、同意をしたら完了していました。

 

完成!!

datatracker.ietf.org

 

 

 

+ 最後にwgのメーリスにdraftを提出した旨を送った。

mailarchive.ietf.org

 

DNSを学ぶために再帰的にdigる。

以下のように問い合わせる。

  1. 答えを知っていそうなネームサーバに問い合わせる。(最初はrootから)
  2. 返事を確認

    1. ANSWER SECTION を確認し、もしアドレスが含まれていたら完了                  
    2. AUTHORITY SECTION を確認し、NSレコードが含まれていれば、次に問い合わせるべきベームサーバのドメイン名を知ることができる。
    3. ADDITIONAL SECTIONを確認し、AUTHORITY SECTIONにあったNSが"glue record"に含まれていれば次に問い合わせるべきネームサーバのIP Addressがわかる。1へ(新たなネームサーバに問い合わせる)。
      もし、glue recordがなければ、AUTHORITY SECTIONのNSをまず調べる。調べたら1へ(新たなネームサーバに問い合わせる)。
    4. もし、AUTHORITY SECTIONでNSが含まれていなければ困った!失敗!

 

wikipedia.orgを名前解決してみる。

まず、rootに聞く。

% dig wikipedia.org @m.root-servers.net.

; <<>> DiG 9.10.6 <<>> wikipedia.org @m.root-servers.net.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32887
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 13
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;wikipedia.org.         IN  A

;; AUTHORITY SECTION:
org.            172800  IN  NS  a0.org.afilias-nst.info.
org.            172800  IN  NS  b2.org.afilias-nst.org.
org.            172800  IN  NS  b0.org.afilias-nst.org.
org.            172800  IN  NS  a2.org.afilias-nst.info.
org.            172800  IN  NS  c0.org.afilias-nst.info.
org.            172800  IN  NS  d0.org.afilias-nst.org.

;; ADDITIONAL SECTION:
d0.org.afilias-nst.org. 172800  IN  A   199.19.57.1
c0.org.afilias-nst.info. 172800 IN  A   199.19.53.1
b2.org.afilias-nst.org. 172800  IN  A   199.249.120.1
b0.org.afilias-nst.org. 172800  IN  A   199.19.54.1
a2.org.afilias-nst.info. 172800 IN  A   199.249.112.1
a0.org.afilias-nst.info. 172800 IN  A   199.19.56.1
d0.org.afilias-nst.org. 172800  IN  AAAA    2001:500:f::1
c0.org.afilias-nst.info. 172800 IN  AAAA    2001:500:b::1
b2.org.afilias-nst.org. 172800  IN  AAAA    2001:500:48::1
b0.org.afilias-nst.org. 172800  IN  AAAA    2001:500:c::1
a2.org.afilias-nst.info. 172800 IN  AAAA    2001:500:40::1
a0.org.afilias-nst.info. 172800 IN  AAAA    2001:500:e::1

;; Query time: 13 msec
;; SERVER: 2001:dc3::35#53(2001:dc3::35)
;; WHEN: Sun Sep 25 13:57:37 JST 2022
;; MSG SIZE  rcvd: 447

 

ADDITIONAL SECTION に glue recordsが含まれていたためそのうちひとつ

d0.org.afilias-nst.org. 172800 IN A 199.19.57.1

から次は199.19.57.1に問い合わせる。

 

% dig wikipedia.org @199.19.57.1

; <<>> DiG 9.10.6 <<>> wikipedia.org @199.19.57.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24037
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 3, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;wikipedia.org.         IN  A

;; AUTHORITY SECTION:
wikipedia.org.      3600    IN  NS  ns2.wikimedia.org.
wikipedia.org.      3600    IN  NS  ns1.wikimedia.org.
wikipedia.org.      3600    IN  NS  ns0.wikimedia.org.

;; ADDITIONAL SECTION:
ns0.wikimedia.org.  3600    IN  A   208.80.154.238
ns1.wikimedia.org.  3600    IN  A   208.80.153.231
ns2.wikimedia.org.  3600    IN  A   91.198.174.239

;; Query time: 12 msec
;; SERVER: 199.19.57.1#53(199.19.57.1)
;; WHEN: Sun Sep 25 13:57:47 JST 2022
;; MSG SIZE  rcvd: 154

 

ADDITIONAL SECTION に glue recordsが含まれていたためそのうちひとつ

ns0.wikimedia.org. 3600 IN A 208.80.154.238

から208.80.154.238に問い合わせる。

 

% dig wikipedia.org @208.80.154.238

; <<>> DiG 9.10.6 <<>> wikipedia.org @208.80.154.238
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63701
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1024
;; QUESTION SECTION:
;wikipedia.org.         IN  A

;; ANSWER SECTION:
wikipedia.org.      600 IN  A   103.102.166.224

;; Query time: 184 msec
;; SERVER: 208.80.154.238#53(208.80.154.238)
;; WHEN: Sun Sep 25 13:58:03 JST 2022
;; MSG SIZE  rcvd: 58

そして名前解決をすることができた!

;; ANSWER SECTION: wikipedia.org. 600 IN A 103.102.166.224

 

 

 

dig +trace すると再帰的に問い合わせる様子が見える。

% dig wikipedia.org. +trace

; <<>> DiG 9.10.6 <<>> wikipedia.org. +trace
;; global options: +cmd
.           280571  IN  NS  b.root-servers.net.
.           280571  IN  NS  f.root-servers.net.
.           280571  IN  NS  m.root-servers.net.
.           280571  IN  NS  g.root-servers.net.
.           280571  IN  NS  a.root-servers.net.
.           280571  IN  NS  j.root-servers.net.
.           280571  IN  NS  d.root-servers.net.
.           280571  IN  NS  h.root-servers.net.
.           280571  IN  NS  l.root-servers.net.
.           280571  IN  NS  e.root-servers.net.
.           280571  IN  NS  c.root-servers.net.
.           280571  IN  NS  i.root-servers.net.
.           280571  IN  NS  k.root-servers.net.
.           280571  IN  RRSIG   NS 8 0 518400 20221005040000 20220922030000 20826 . DO8gA3Mjxp+8mxytLZ0ITfEjQcb0O1QUO2n7igWF7D/xnbK7HjHJRHc0 3m3mAXz0ZuFdx7i8A+A1fhhhUkvz74DA+zTfImByVRr9/zvF2nG+P5we ZSJNJ00y5/+/88bIRpVb5o3jeYVzKzIP46pfGQ68N8D9qaHVS4syhUma ylq+FlrFMW0qfhcIWXLLp3giqd7reD6w94Pyk+V9rblYO4zdiwVx99EX hVha/+6/4kiPa6C7SIT9vt9RsS3IhkYJtWSXecU/5hji6mbY250B7ipi vXVn7e8JUss7snW+0D1OCmuSLRpM/DY4uNuzwYwW83ywTSalG6BdUcp0 agS28w==
;; Received 525 bytes from 240b:10:b420:3c00:5a52:8aff:fe57:b959#53(240b:10:b420:3c00:5a52:8aff:fe57:b959) in 17 ms

org.            172800  IN  NS  b0.org.afilias-nst.org.
org.            172800  IN  NS  b2.org.afilias-nst.org.
org.            172800  IN  NS  c0.org.afilias-nst.info.
org.            172800  IN  NS  d0.org.afilias-nst.org.
org.            172800  IN  NS  a0.org.afilias-nst.info.
org.            172800  IN  NS  a2.org.afilias-nst.info.
org.            86400   IN  DS  26974 8 2 4FEDE294C53F438A158C41D39489CD78A86BEB0D8A0AEAFF14745C0D 16E1DE32
org.            86400   IN  RRSIG   DS 8 1 86400 20221007160000 20220924150000 20826 . ZsBhfjLoUwkO1rC8+cqrs+JF1fCwQhXnTkEU+K4a0k49klJ9dzge2OrM 0+B/CcZ3wku4hyQrmRUXzfkESepx2tVvInW9PeGuHS5O1Ub++kui5Hw9 mn4a7E6QeCdeW1A0p0hC3N0K90crEKMNnoTUj4hlCH4SdUh1gvnl8yuS GNK6MqzI18JNyv3lNKhZJGypUXUy24gw8Uf0RvCXn22ndX9A9Kib55zD WFHxhW2jKqp12QTULgQOKR2/PyUVIZjE6QIPQpIpBK2bWokMv0XcJv2h VF0Hl4QEkeq59I2Qs04Y7c/hE5ZpITCE7kSV/aMHMcACqCiLx7bQY51C JTsGuQ==
;; Received 782 bytes from 2001:dc3::35#53(m.root-servers.net) in 12 ms

wikipedia.org.      3600    IN  NS  ns0.wikimedia.org.
wikipedia.org.      3600    IN  NS  ns1.wikimedia.org.
wikipedia.org.      3600    IN  NS  ns2.wikimedia.org.
gdtpongmpok61u9lvnipqor8lra9l4t0.org. 3600 IN NSEC3 1 1 0 332539EE7F95C32A GDTREA8KMJ2RNEQEN4M2OGJ26KFSUKJ7  NS SOA RRSIG DNSKEY NSEC3PARAM
gdtpongmpok61u9lvnipqor8lra9l4t0.org. 3600 IN RRSIG NSEC3 8 2 3600 20221016050244 20220925040244 56124 org. cr4LvNKu3sqDukgIMyPf57HDfZONHGCelMlTsKXZQW/2DsWnzig6gjwJ yUwz4ht5y8xVWOTk/aaVlwitoXvImGuE5asNt5XRQnTIQRtfhuXoasCt 9h6tTKcI6hb04uTX0a1+sVZ303keKfCNqhO+70KWcppbrnlf+ktYvg5q NWM=
tpeahq77pcfqu9h00c3mh570ah1f4g65.org. 3600 IN NSEC3 1 1 0 332539EE7F95C32A TPEESGJUPU0G7LLLUQEA296C6EAUG5AU  NS DS RRSIG
tpeahq77pcfqu9h00c3mh570ah1f4g65.org. 3600 IN RRSIG NSEC3 8 2 3600 20221008152354 20220917142354 56124 org. fdnmYd7gnrhlwf0xkHHmybh/CheOIGWo/hIJ19En1f0xF6Ldf7sjitzZ PZpiwj0pQKRX4rQoJ6DBzBT/N9hdMzvzgJ4eK5GukwG6Qf4knPUnqZ36 zWqyQtqm3HEu+wXqmw+TI14p8tljdvqCemN0qNMKbz2ZhiBiiLHgxQ// A18=
;; Received 655 bytes from 199.19.56.1#53(a0.org.afilias-nst.info) in 12 ms

wikipedia.org.      600 IN  A   103.102.166.224
;; Received 58 bytes from 208.80.153.231#53(ns1.wikimedia.org) in 151 ms

 

chromium DNSTask めも (overriding the DNS configuration)

 

chromiumにはいくつかDNSを行う方法がある。

 

chromiumの //net/dns/README.mdに色々書いてある。

https://source.chromium.org/chromium/chromium/src/+/main:net/dns/README.md

 

もっとあるが、大事なのは以下の三つかと勝手に思う。

1. system resolver

2. async resolver (not DoH)

3. async resolver (DoH)

 

system resolver 

実装は net::HostResolverManager::ProcTask にある。OSのリゾルバを使用する。

async resolver がうまくできないときに使われる。

 

async resolver (not DoH)

実装は net::HostResolverManager::DnsTask にある。

chrome自らDNSキャッシュサーバにパケットを送る。OSのリゾルバをそのまま使わないが、DNS configurationは読み込むため、同じDNSキャッシュサーバにアクセスする。(もし 8.8.8.8 に設定されていたらそれに聞くし、ISPの提供するDNSキャッシュサーバが設定されていたらそれを使う。

async resolver (DoH)

あまりよくわかっていないけど、DoHを使う。DoHなので tcpdump port 53 で出てこないし、さらに、tcpdump host [設定されてるDNSキャッシュサーバ] をしてもパケットが表示されなかった。

もうしょっとコードを読む。

 

async resolver は まだMacOSのみかな。

linux

https://bugs.chromium.org/p/chromium/issues/detail?id=1350321

windows

https://bugs.chromium.org/p/chromium/issues/detail?id=1317948

 

 

 

chromiumのコードを変更して、async resolverの問い合わせ先を変更してみた。

遊びです。変更した箇所は以下のファイル。開発環境Mac

https://source.chromium.org/chromium/chromium/src/+/main:net/dns/public/resolv_reader.cc

absl::optional<std::vector<IPEndPoint>> GetNameservers() の中に

IPEndPoint ipe;
ipe = IPEndPoint(IPAddress(1,1,1,1), 53);
nameservers.push_back(ipe);

を追記した。

 

これで、async resolver (not DoH) のときに 1.1.1.1に問い合わせがされるをを確認できた。わいわい。1.1.1.1に聴きに行くようにこの3行でできた。

system resolver の時には変化なし。

async resolver (DoH) の時は何をどう見れば確認できるのかわからなかった。もともとtcpdump host [設定されてるDNSキャッシュサーバ] をしてもパケットが表示されなかった。

ここら辺のコード読んで勉強します。

 

 

 

 

GSoC chromium: IP address synthesis for an IPv6 only network to connect to an IPv4 address literal.

TLDR;

When a client is in an IPv6 only environment it utilises the NAT64 and DNS64 in the network to connect to IPv4 only servers. However, when chrome tries to connect to an IPv4 literal (such as when an IPv4 address is directly written in the search bar) it doesn't use the DNS64 and fails to connect to the address.

With this change Chrome will now append the IPv4 to IPv6 translation prefix (Pref64::/n) to the IPv4 address, in order for the packet to use the NAT64 in the network.

 

Code: 

chromium.googlesource.com

How the NAT64 and DNS64 works


There is a translation technology called NAT64/DNS64 which enables IPv6-only clients to access IPv4-only servers. 

This is great but it does not work for IP address literals because DNS will not be used.

How my implementation works

First, when chrome tries to access a IPv4 literal it checks if it is on an IPv6-only network.

If it is, it resolves the AAAA record of domain ipv4-only.arpa. This is a special domain that only contains an A record.  If this name is resolved inside an IPv6-only network that has a DNS64, the DNS64 will return an answer to the AAAA request that contains the synthesized IPv6 address(in many cases 64:ff9b::192.0.0.170). (Step1)

With this answer received chrome now knows that there is a DNS64 in the network, which means by using the translation prefix we can utilize the NAT64. Chrome will now synthesise an IPv6 address by combining the translation prefix obtained in Step 1 and the original IPv4 address literal. (Step 2)

chrome will now be able to utilize the NAT64 and access the server via a IPv4 address literal even on a IPv6-only network.

Codebase

Made changes in the below files in chromium.

  • net/base/ip_address.c

    net/base/ip_address.h

    net/base/ip_address_unittest.cc

    net/dns/host_resolver_manager.cc

    net/dns/host_resolver_manager.h

    net/dns/host_resolver_manager_unittest.cc

    net/dns/host_resolver_nat64_task.cc [Added]

    net/dns/host_resolver_nat64_task.h [Added]

In host_resolver_manager, when an IP literal is passed it checks if the network is IPv6 only, and if so calls the HostResolverNat64Task that I have created.

In the HostResolverNat64Task it does 3 things. 

  • Resolve the IPv6 address of ipv4only.arpa
  • Extract the IPv4 to IPv6 translation prefix (Pref64::/n) from the returned address
  • Synthesise the IPv4 literal address to IPv6 using the Pref64::/n

 

Actual Code: 

https://chromium-review.googlesource.com/c/chromium/src/+/3691238

 

Releases from chrome 108. (Tue, Nov 29, 2022)

 

Before, accessing 1.1.1.1 from an IPv6-only network.

Can't access server when using IPv4 address literal.

after

 

Can successfully access the server by using IPv4 address literal.

 

QUIC の initial鍵生成に使用する initial_salt と QUIC version

QUICでinitial packetを送る前に client/server initial key, IV, header protection key の6つの鍵を作成する必要があります。これらの鍵を作成するためにclient_initial_secret, server_initial_secretを作成する必要があります。そしてそれらを作成するためにinitial_secretを作成する必要があり、initial_secretを作成するためにinitial_saltとクライアントが送る initial Destination Connection ID(8 bytes of random data)を使用します。

以下のように鍵を生成します。

initial_salt = 0x38762cf7f55934b34d179ae6a4c80cadccbb7f0a

initial_secret = HKDF-Extract(initial_salt, client_dst_connection_id)

client_initial_secret = HKDF-Expand-Label(initial_secret, "client in", "", Hash.length)
server_initial_secret = HKDF-Expand-Label(initial_secret, "server in", "", Hash.length)

client_key = HKDF-Expand-Label(key: client_secret, label: "quic key", ctx: "", len: 16)
server_key = HKDF-Expand-Label(key: server_secret, label: "quic key", ctx: "", len: 16)
client_iv = HKDF-Expand-Label(key: client_secret, label: "quic iv", ctx: "", len: 12)
server_iv = HKDF-Expand-Label(key: server_secret, label: "quic iv", ctx: "", len: 12)
client_hp_key = HKDF-Expand-Label(key: client_secret, label: "quic hp", ctx: "", len: 16)
server_hp_key = HKDF-Expand-Label(key: server_secret, label: "quic hp", ctx: "", len: 16)

 

HKDF-Extract はソルトと数バイトの鍵素材を与えると、256ビット(32バイト)の新しい鍵素材を作成するもので

RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) section2.2 で説明されています。

HKDF-Expand-Labelは鍵素材、ラベル、コンテキストデータを入力から、要求された長さの新しい鍵を作成するもので、

RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 section7.1で説明されています。

 

initical salt については以下のように書かれています。

Future versions of QUIC SHOULD generate a new salt value, thus ensuring that the keys are different for each version of QUIC. This prevents a middlebox that recognizes only one version of QUIC from seeing or modifying the contents of packets from future versions.

RFC 9001 - Using TLS to Secure QUIC

QUICの将来のバージョンは新しいソルト値を生成すべきであり[SHOULD]、 その結果、鍵はQUICの各バージョンで異なることが保証される。これは、QUICの一つのバージョンだけを認識するミドルボックスが、 将来のバージョンからのパケットのコンテンツを見たり修正したりすることを防ぐ。

つまり将来のQUICの硬直化(ossification)の問題を緩和するために格バージョンごとにソルト値を変えます。将来新しいバージョンのQUICが出た時、そのバージョンに対応していない(そのバージョンのソルトを知らない)実装は、初期パケットを読めないようにしています。

QUIC version 2 では新しいソルトの値を記しています。

3.3.  Cryptography changes

3.3.1.  Initial Salt

   The salt used to derive Initial keys in Section 5.2 of [QUIC-TLS]
   changes to:

   initial_salt = 0xa707c203a59b47184a1d62ca570406ea7ae3e5d3

datatracker.ietf.org

QUIC Version 2やQUICの硬直化の対策について詳しくはゆきさんのブログで。

asnokaze.hatenablog.com

 

 

 

RFC9001 に書かれているQUIC v1 のソルトは

initial_salt = 38762cf7f55934b34d179ae6a4c80cadccbb7f0a

ですが、この値"38762cf7f55934b34d179ae6a4c80cadccbb7f0a"はGoogleが見つけた初めてのSHA1衝突の値らしいです。

security.googleblog.com

nakedsecurity.sophos.com

 

 

 

 

QUIC が RFCとして標準化せれる前のdraft段階ではdraftごとに変更が入っていました。

RFC9001の元となったdraft draft-ietf-quic-tlsの変更履歴をgithub上で眺めるとsaltが変更されているのがわかります。

github.com

 

Dec 8, 2020 現在のsaltになる。

github.com

 

draft29 draft-ietf-quic-http-29 で変更

github.com

C.5.  Since draft-ietf-quic-tls-28

   *  Defined limits on the number of packets that can be protected with
      a single key and limits on the number of packets that can fail
      authentication (#3619, #3620)

   *  Update Initial salt, Retry keys, and samples (#3711)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.5

 

draft23 で変更

github.com

C.11.  Since draft-ietf-quic-tls-22

   *  Update the salt used for Initial secrets (#2887, #2980)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.11

 

draft21 で変更

github.com

C.13.  Since draft-ietf-quic-tls-20

   *  Mandate the use of the QUIC transport parameters extension (#2528,
      #2560)

   *  Define handshake completion and confirmation; define clearer rules
      when it encryption keys should be discarded (#2214, #2267, #2673)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.13

 

draft17

github.com

*  Update the salt used for Initial secrets (#1970)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.16

 

 

draft13

github.com

(たくさんこの一つのコミットで変更が入ってる)

*  Changes to integration of the TLS handshake (#829, #1018, #1094,
      #1165, #1190, #1233, #1242, #1252, #1450)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.18

 

draft9

github.com

C.21.  Since draft-ietf-quic-tls-09

   *  Cleaned up key schedule and updated the salt used for handshake
      packet protection (#1077)

https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.21

 

draft7

github.com

面白いことに上記のコミットのコミットメッセージから分かる通り、今回のソルト

quic_version_1_salt = afc824ec5fc77eca1e9d36f37fb2d46518c36639

draft06のコミットハッシュです。

https://github.com/quicwg/base-drafts/commit/afc824ec5fc77eca1e9d36f37fb2d46518c36639

 

 

draftを追いながらQUICを実装していた方々はinitial saltに変更があるたびに変更を入れていたようです。

google/quicheを眺めると

https://source.chromium.org/chromium/chromium/src/+/main:net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc;l=149

const uint8_t kDraft29InitialSalt = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
const uint8_t kRFCv1InitialSalt = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};

 

drart29, RFC QUIC v1, QUIC v2 draft の initial saltが設定されています。

 

 

 

 

 

 

HTTPS DNS レコードのalpn情報からHTTP/3に繋げに行くchromiumのUseDnsHttpsSvcbAlpn feature

TLDR;

chrome://flags#use-dns-https-svcb-alpnから有効化できるUseDnsHttpsSvcbAlpn機能を紹介します。

この機能を有効にすると、HTTP/3 をサポートすることを示す HTTPS DNS レコードを受信した場合、Chrome は HTTP/3 プロトコルを使用してサーバーに接続します。

chrome 105 からこのコミットが反映されるっぽい。

 

いろいろ間違っていたらすいません。

DNS HTTPSレコード

DNS HTTPS Records を用いたHTTP/3 接続

あるサイトにはじめて接続する場合、HTTP/3 (QUIC) で動作するのかどうか知らないためHTTP/2 で接続してからAlt-SvcヘッダによってAlternate ServiceとしてHTTP/3の存在を教えてもらってから、次のリクエストからHTTP/3につなげに行く。

従来は一度 HTTP/2 で接続してからAlt-SvcヘッダによってAlternate ServiceとしてHTTP/3の存在を教えてもらってからHTTP/3につなげに行く。これはいきなり HTTP/3 でリクエストしても QUICに対応しているかわからないため、このような仕様になっている。*1 

 

もし最初のリクエストから HTTP/3 で接続させたければ、リクエストよりも先に HTTP/3 がサポートされている旨を知る必要があります。ここで活躍するのが DNSDNS HTTPS Recordsです。

draftはdraft-ietf-dnsop-svcb-https

datatracker.ietf.org

DNS HTTPSレコード

DNS HTTPSレコードはいくつかの利点があります。勝手に重要だと思ったものを挙げると

  • 平⽂ HTTP による接続を防⽌ (http: → https:) 
  • はじめから HTTP/3 (QUIC) による接続を可能に (alpn) 
  • ECH (Encrypted Client Hello) の公開鍵等の取得 (ech)

今回は上記のうち二つ目の利点、はじめから HTTP/3 (QUIC) による接続を可能に (alpn) というところを用いています。

 

自分の理解が追いついていないのでいつかちゃんとdraftを読んでブログを書きたいです。

参考になりそうな yuki さんのブログ。

asnokaze.hatenablog.com

自分のサイトを対応させたJxckさんの話

自分のサーバをHTTP3 対応し、Alt-Svc ヘッダおよび DNS HTTPS Resource Record によってそれをアドバタイズするJxckさんの話。

blog.jxck.io

## HTTPS Resource Record の章から HTTP/3 に最初っからつなげに行くように設定した話があります。勉強になりました。

 

他のブラウザの状況

Safari (iOSmacOS) は対応済みでとくに何もしなくても使えるらしいです。

Firefox実装済みだが、Firefox の設定画面から DoH を有効にする必要があるらしいです。

(自分で試してないのでよくわかりません)

 

chromium の UseDnsHttpsSvcbAlpn feature

chromium DNS HTTPS Records

もともとDNS HTTPS Recordsについては以下のDesign Doc を見ることができます。(オープンになってるdocumentよめるchromiumすごい!)

docs.google.com

今回該当する話が書かれているのはそのうちのProtocol upgradeの箇所

 

Curret Status

Intent to Ship: HTTP->HTTPS redirect for HTTPS DNS records

ericorth@chromium.orgさんの昨日(8/5)のnet-devメーリスへのメール

Current status: We are partway through a gradual rollout of the feature, to be complete in approximately one month.  So Chrome will currently request HTTPS records and perform scheme upgrades accordingly for some but not all users.

commit: Support HTTP/3 protocol upgrade for HTTPS DNS records

commit: 

https://chromium.googlesource.com/chromium/src.git/+/d81149603836e06f5a3aa0ba048eb376f81fa92c

 

コミット文より

Support HTTP/3 protocol upgrade for HTTPS DNS records

This CL introduces UseDnsHttpsSvcbAlpn feature which can be enabled at chrome://flags#use-dns-https-svcb-alpn. When this feature is enabled, Chrome will connect to the server using the HTTP/3 protocol if Chrome receives a HTTPS DNS record indicating HTTP/3 support.

This CL changes the behavior of HttpStreamFactory::JobController as follows:

Currently, if Chrome has received an Alt-Svc header from the origin, JobController creates two Jobs to compete for connection establishment. [1] Main job for HTTP/1 or HTTP/2 [2] Alternative job for HTTP/3 (Note: This job can use HTTP/2 when the enable_http2_alternative_service parameter is enabled. But this parameter is not enabled in Chrome.) The main job waits for a while before starting the race if Chrome knows that QUIC works on the current network. The waiting time is determined based on recent QUIC connection performance in QuicStreamFactory::GetTimeDelayForWaitingJob().

This CL introduces a new Job. [3] DNS alpn job: This job tries to use HTTP/3 noly if Chrome receives a HTTPS DNS record indicating HTTP/3 support. Otherwise it fails with ERR_DNS_NO_MACHING_SUPPORTED_ALPN. This DNS alpn job is created only when the new UseDnsHttpsAlpn feature is enabled, and the URL scheme is HTTPS, and QUIC is enabled, and proxy is not used, and the alternative job can’t use an existing Quic session, and Chrome has not recognised that the QUIC connection to the server is broken. If the DNS alpn job can use an existing QUIC session, other jobs are canceled. Additionally, if the destination of both the alternate job and the DNS alpn job are the same, the DNS alpn job is canceled to avoid redundant jobs. The main job waits for a while before starting, just like its current behavior.

いままでchromeには

  1. HTTP/1 か HTTP/2 で繋げに行くメインジョブ
  2. 既存のQuicセッションがある場合に繋ぎに行くHTTP/3ジョブ

の二つが競争をしていました。

今回の変更により

が追加されました。DNS alpn job は HTTPS レコード情報よりHTTP/3が使用可能であることを知っているので初めからQUICで繋ぎにいきます。

  1. HTTP/1 か HTTP/2 で繋げに行くメインジョブ
  2. 既存のQuicセッションがある場合に繋ぎに行くHTTP/3ジョブ
  3. DNS alpn job

の三つのjobが存在しますが、実際に繋ぎに行くときは以下のようになるかと思います。

 

1. 初めてのサイトでHTTP/3 へ繋げられることをHTTPSレコードによって広告していない場合

  • HTTP/1 か HTTP/2 で繋げに行くメインジョブ のみ

 

2. 初めてのサイトでHTTP/3 へ繋げられることをHTTPSレコードから得られる場合

  • HTTP/1 か HTTP/2 で繋げに行くメインジョブ
  • DNS alpn job

の2つのジョブが競争。

 

3. 以前QUICで繋ぎに行ったサイトに繋ぎに行くとき

  • HTTP/1 か HTTP/2 で繋げに行くメインジョブ
  • 既存のQuicセッションがある場合に繋ぎに行くHTTP/3ジョブ

の2つのジョブが競争。(DNS alpn jobは余分なjobを減らすためキャンセルされる)

 

2. 3. 二つの場合において、HTTP/1 か HTTP/2 で繋げに行くメインジョブ はHTTP/3 を優先させるために少し待ちます。この待ち時間はQuicStreamFactory::GetTimeDelayForWaitingJob() から得られる直近のQUICコネクションパフォーマンスによって決められます。

 

せっかくなので3つのジョブが作られる場所のコードを見てみましょう。

この3つのジョブは chromium の net/http/http_stream_factory_job_controller.cc というファイルの HttpStreamFactory::JobController::DoCreateJobs() という関数内でそれぞれ作られています。

https://source.chromium.org/chromium/chromium/src/+/main:net/http/http_stream_factory_job_controller.cc;l=793

  • main_job_ = job_factory_->CreateJob(
  • alternative_job_ = job_factory_->CreateJob(
  • dns_alpn_h3_job_ = job_factory_->CreateJob(

と書いてある部分でjobが作成されているのが確認できます。

commit: Support HTTPS records aliased by CNAME records

上記のcommitのみでは CNAME レコードによってaliaseされたHTTPSレコードには対応できていなかったので対応させたというコミット。(まだきちんと理解できていないのでまた読み直したい)

コミット文

Support HTTPS records aliased by CNAME records

Currently Chrome can't use the alpn information of HTTPS records which
are aliased by CNAME records. This is because ExtractHttpsResults() is
ignoring the aliased HTTPS records.

To support such case, this CL do the followings:
  1. Change ExtractHttpsResults() to allow the HTTPS record which
     service name is the canonical name of the record.
  2. Introduce ConnectionEndpointMetadata.target_name which keeps the
     target of the metadata.
  3. Introduce HostCache.Entry.canonical_names which keeps the canonical
     names of A/AAAA records.
  4. Change HostCache::Entry::GetEndpoints() to return the metadata only
     when A and AAAA records are at the same canonical name and that
     matches the metadata target name.

 

UseDnsHttpsSvcbAlpn featureをchromeで使うためには

バージョン105以のchromiumが必要です。

chrome canary から手に入れれます。

(か、いつも使ってる Google Chrome が 105になるまで待つ。今現在は104で105は8月 30日にリリースされるらしいですね)

 

chrome://flags/ に行く。

(直接このフラグを変える場合は chrome://flags/#use-dns-https-svcb-alpn )

Version 105.0.5164.0 (Developer Build) よりスクショ

DefaultをEnabledに変える。

 

 

*1:Happy Eyeballsアルゴリズムによって最初っからつなげに行くことについて議論してる論文もある Network | Free Full-Text | Implementation and Evaluation of HTTP/3 Connectivity Check Using Happy Eyeballs Algorithm

IETF-114, Philadelphia 見たいやつ

気になったやつ

関連draft一ミリも読んでないwgとかは結局聞かない可能性高いけど。



23:00-01:00 Tuesday Session I

 

IPv6 Operations

2022-06-22 , <draft-buraglio-v6ops-ula>

WebTransport

https://datatracker.ietf.org/meeting/114/materials/agenda-114-webtrans-01

docs.google.com

 

 

 

23:00-01:00 Wednesday Session I

Media Over QUIC

 

 

23:00-01:00 Thursday Session I

QUIC

https://datatracker.ietf.org/meeting/114/materials/agenda-114-quic-00

WG Items
Other (aka "As Time Permits")

02:30 (+1)-04:30 (+1)Thursday Session II

HTTP

Active Drafts

See also the extensions listing

Other Topics

 

Side Meetingあるらしい

19:00-20:30 - Wednesday - Salon 9

AltSvc, HTTPS RR and Friends

This session is focused on the space currently occupied by AltSvc and the HTTPS RR. The expectation is that it will produce proposals to take to the WG on Thursday regarding the scope of AltSvcBis and any additional work necessary.

 

 

Path Aware Networking RG

datatracker.ietf.org

15:35 85m SCION Components Analysis (draft-rustignoli-panrg-scion-component) and open mic discussion Nicola Rustignoli, Chairs
17:00 15m Overlay Routing Problem Statement, draft-deng-overlay-routing-ps Geng Li/Shangling Deng
17:15 15m Separation of Data Path and Data Flow Sublayers in the Transport Layer, draft-asai-tsvwg-transport-review B. Serracanta

 

Separation of Data Path and Data Flow Sublayers in the Transport Layer,

draft-asai-tsvwg-transport-review

transport layer を Data Path と Data Flow に分けて考えるってdraft

 

23:00-01:00 (+1) Friday Session I

TCP Maintenance and Minor Extensions

Working Group Items
-------------------------------------------------

* Revised Cubic as PS
  https://datatracker.ietf.org/doc/html/draft-ietf-tcpm-rfc8312bis
  Speaker: Vidhi Goel
  Time: 15 mins                                30/120

* Proportional Rate Reduction for TCP
  https://www.ietf.org/archive/id/draft-ietf-tcpm-prr-rfc6937bis-02.html
  Speaker: Yuchung Cheng
  Time: 15 mins                                45/120

* AccECN updates
  https://datatracker.ietf.org/doc/html/draft-ietf-tcpm-accurate-ecn-19  
  Speaker: Bob Briscoe
  Time: 15 mins                                60/120

* A YANG Model for Transmission Control Protocol (TCP) Configuration and State
  https://www.ietf.org/archive/id/draft-ietf-tcpm-yang-tcp-07.html
  Speaker: Mahesh Jethanandani (TBC)
  Time: 10 mins                                70/120


Other Items
-------------------------------------------------

* NG TCP Yang Model
  Speaker: Gyan Mishra
  Time: 15 mins                                85/120

* TCP ACK Rate Request
  https://datatracker.ietf.org/doc/html/draft-gomez-tcpm-ack-rate-request-05
  Speaker: Carles Gomez (remote)
  Time: 15 mins                                100/120