RFC8174「RFC 2119のキーワードにおける大文字と小文字の曖昧性」

RFCやInternet-Draftを読んだことある人であれば、文中にMUSTやSHOULDといった大文字のキーワードが用いられてるのを見たことあるかと思います。

たとえば、このように

An endpoint MUST treat this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR.


これらのキーワードはプロトコルの仕様の曖昧性を無くすために 「RFC 2119 Key words for use in RFCs to Indicate Requirement Levels」で定義されています。

しかし、微妙な曖昧性があるためRFC 8174で更新されました。

RFC8174 Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words

「MUST」「SHOULD」「MAY」といった要請の程度を示すキーワードを定義するRFC 2119ですが、その文章にはこう書かれています。

「These words are often capitalized」
(これらの語句は、よく大文字になっています) IPAの翻訳より

このoftenによる微妙な表現のため、"must"や"should"といった小文字の場合にどう解釈するか微妙な曖昧性があります。

RFC8174では下記2点が明記されるようになりました

  • これらの語句は全て大文字の場合のみ、この文書で定義された特別な意味をもつ
  • 小文字の場合は通常の英語の意味をもち、この文書の影響はありません

また、絶対にこれらの語句を使用すべきというわけではない旨が追記されたほか
別の文書から参照する時の例が更新されています

      The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
      "MAY", and "OPTIONAL" in this document are to be interpreted as
      described in BCP 14 [RFC2119] [RFC8174] when, and only when, they
      appear in all capitals, as shown here.

TCP Fast Openの闇と、Kernelの緩和コミット

TCP Fast Open

TCP Fast Openと呼ばれる技術があり、RFC 7413として標準化されている。

このTCP Fast Openを使うと、一度コネクションを貼った相手とは、TCPの3ウェイハンドシェイク中にデータを送受信できるようになる。クライアントからSYNとともにデータを送信することで、実際にデータを送受信開始するまでの待ち時間が短縮できる。

Linuxではすでにクライアント/サーバ両方でTCP Fast Openを使用できる。

TCP Fast Openの闇

しかし、数年前よりこのTCP Fast Openには一部のネットワークで奇妙な振る舞いをすることが知られている。Appleの人が実際にデプロイした時に見つけたもので、IETFやNANOGにて報告されており、その時の資料は下記のとおりである

(0.1%の環境で発生したと発表時の質疑にもある)

一部を抜粋すると

TCP Fast OpenのSYN, SYN/ACKは通るが最後のACKがブロックされる
f:id:ASnoKaze:20170509215524p:plain

3ウェイハンドシェイクは完了するが、片方向のみデータ送信に失敗する
f:id:ASnoKaze:20170509215604p:plain

この状態になると、OS的にはハンドシェイクが完了しておりタイムアウトを待ち、その後アプリケーションなどにより再送信されるという繰り返しになりうる(フォールバックされない)。

この問題はクライアントの居るネットワークのファイアウォールやIDSが原因であり、単純にはサーバやクライアントでTCP Fast Openを無効にするという対応をすることになる。

Kernelでの緩和対応

上記問題を緩和するために、Kernelに「net/tcp_fastopen: Disable active side TFO in certain scenarios」というコミットが入った。

基本的には、クライアントサイドにてTCP Fast Openを使ってる時に怪しい挙動があった場合は、globalにTCP Fast Openを無効にする。最初はデフォルトで1時間無効化し、次に失敗したときは2時間と倍々で時間が長くなっていく仕組みになっている。通信に成功した場合は、待ち時間は最初の1時間にリセットされる。待ち時間は、tcp_fastopen_blackhole_timeout_secで設定することも出来る。

globalに無効になるのは、クライアント側のネットワークが原因であることが主なので、全体として向こうにしたほうが良いということだろう。

また怪しい挙動とは

  • クライアント側でTCP Fast Openを利用しており、データが無く、順序が正しくないRSTを受信した時
  • クライアント側でTCP Fast Openを利用しており、順序が正しくないFINを受信した時


コメントを読む限りサーバ側では現状特別なハンドルはしないようだ。大きいサービスだと、TCP Fast Openを有効にするには上記コミットが普及してからの方が良いのだろうか...(TCP Fast Openが悪いってわけじゃないんですけど)

hxxp URIスキームの仕様化

追記 20170510
draft-01 より、hxxpsも予約されました
The "hxxp" and "hxxps" URI Schemes


hxxpの背景

hxxp URIを定義する「The "hxxp" URI Scheme」という仕様が提案されています。

hxxp://... は、例えばセキュリティの話をする際にURLがリンクとして解釈されたり、ブラウザやメーラによって解釈・処理されないようにするために使用されています。

この仕様では、将来的にアプリケーションでこのhxxp:// を使用できないように予約します。

hxxpの定義

hxxp URIによって参照されるリソースは、アプリケーション等によって自動的にパース・処理されないことを意味します。

このリソースは、セキュリティの専門家によって利用されなければなりません(MUST)。

そのた

また、アプリケーション開発者はhxxpスキームURIをHTMLのアンカーやタグで使用しないように推奨されています。

Cookieの仕様改定版、RFC6265bisの議論

追記 10190510
関連して、このような動きもあります。
Cookie の SameSite=Lax をデフォルトにする提案仕様 - ASnoKaze blog

Cookieの仕様と拡張仕様

HTTPのCookieの仕様は RFC 6265 - HTTP State Management Mechanism で定義されております。

2015年頃より、IETFのHTTPbisワーキンググループではCookieのセキュリティを向上させる目的で拡張仕様が3つほど議論されていました。

動作確認用のページもあるようです http://rfc6265.biz/tests/

IETF98でのフィードバック

それぞれの拡張仕様はChromeFirefoxで実装が進められており、先月シカゴで行われたIETF98では各拡張仕様の提案者でもあるGoogleのMike West氏よりそれぞれの使用状況についてのフィードバックがありました。短いですが議事録より確認できます。

  • Cookie Prefixes
    • Googleでは、ChromeにおいてSet-Cookieヘッダで__Host-が0.004%, __Secure-が0.00001%観測されているとのこと
  • Same-site cookies
    • 利用率は0.01%
  • Strict secure
    • 沢山のバグレポートがあった

rfc6265bis

上記3つの拡張仕様はそれぞれを標準化するのではなく、RFC 6265の改訂版である6265bisに組み込む形で標準化されることがMLで話されておりましたが(URL)、4/25に rfc6265bisのdraft01 が提出されました。

RFC 6265からの主な変更点は下記のとおりです

  • エラッタの修正(URL)
  • Cookie2とSet-Cookie2をIANA Considerationsから削除
  • Cookie Prefixes の仕様の取り込み
  • Deprecate modification of 'secure' cookies from non-secure origins の仕様取り込み

Same-site cookiesについては、AuthorがML上で言及しているとおり(URL)、もう少し作業があるようだが、7月に行われるIETF98までに議論すべきものが出て来る形になりそうだ。

WebサーバとのコネクションでDNS通信もする拡張仕様

追記 20170510
この提案仕様は、draft01でauthor自ら廃案とされました。


昨日の「DNS over QUICの提案仕様が出た」引き続きDNS関連の記事

DNSとHTTP

近年注目されている、"DNS over HTTP"は例えば「DNS-over-HTTPS」としてGoogleが提供していたり、IETF97でもdnsoverhttp BarBof(有志によるミーティング)も行われ課題についても議論がされています(議事録URL)。


もちろん仕様としても提案されており、以下などがあります


(IP + Portを見て)外とのDNSの通信がブロックされたりする環境があるようで、これらはDNSをHTTP上で行おうというものです。

Running DNS in Existing Connections

さらに先日、以下の2つのドラフトが提出されています


これらは、Webサービスとの通信といった既存のHTTP/2, QUICコネクション上でさらにDNSのメッセージもやりとり出来るようにする拡張仕様である。サーバ認証も行って確立した暗号路で改ざんを防ぎ、既存のコネクションを使うことでDNS通信がブロックされないようにする。


同じ著者によってHTTP/2とQUICのコネクションを利用するものが別々に提案されているが基本的には、新しくストリームをオープンし、その上でDNSのリクエストとレスポンスを行う。

DNSフレームが定義される

新しくDNSフレーム

   +---------------+
   |Pad Length? (8)|
   +---------------+-----------------------------------------------+
   |                         DNS message (*)                     ...
   +---------------------------------------------------------------+
   |                           Padding (*)                       ...
   +---------------------------------------------------------------+

DNS messageがそのままDNSメッセージであり、1つのストリーム上で問い合わせと応答が実施される

Service Discovery

既存のコネクションを利用しているため、DNSの問い合わせに応答するのはすでに接続しているサーバとなる。もちろんこの拡張に対応しているとは限らないため、下記のようにする。


拡張フレームは対応していない場合は無視されるので、上記拡張hルエームで問い合わせたいクエリ送信する。
もしくはexample.comなどのクエリを問い合わせし、対応していることを確認してから本来確認したクエリを送信するということも出来る。

その他

まだまだエラーハンドリングや、Settingsを使うか、ストリームの遷移・マッピングなど細かい所は決まってはいないが、IETFでのフィードバックにもあった一つのQUICコネクション上で複数のアプリケーションプロトコルという仕組みの提案として面白いと思う。


また、SPDY/4で追加機能として挙げられてはいた「Server push of DNS records」というものを思い出した。
(https://www.chromium.org/spdy/spdy-protocol)

DNS over QUICの提案仕様が出た

2020/04/28 追記
仕様の名前が少々変わりましたが、WG Draftとなり作業は引き続き続けられています。
Specification of DNS over Dedicated QUIC Connections


QUICの標準化とアプリケーションレイヤ

IETFでQUICの標準化が活発に行われており、トランスポート・TLS・HTTP各レイヤのドラフト仕様の改定が進められております。


標準化を行うにあたって当初より、DNSのトランスポートとしてQUICを使用したいという話題は出ていましたが、QUICワーキンググループのチャーターでは、まずはQUICのアプリケーションレイヤとしてHTTPの標準化を行ってから他のアプリケーションプロトコルについて進める旨書かれている。


とはいえDNS over QUICをやりたい人はいるようで、4/11にインターネットドラフトが出されている。共著者にQUICについてよく発表しているGoogleの方や、SalesforceやFastlyの人もいる。

Specification of DNS over QUIC

Specification of DNS over QUIC」として書かれている。


主な目標として下記があげれている

  • DNS over TLS(RFC7858)と同等のプライバシ保護を提供する。DNS通信の保護を議論している、DPRIVE WGで議論している「Authentication and (D)TLS Profile for DNS-over-(D)TLS」を含み、ドメイン名の権威をもつサーバとしての認証を行う。
  • DNS over UDP(RFC1035)と比べて、送信元IPの検証を提供する
  • 経路のMTUによって送れるDNSレスポンスを制限しないようなトランスポートを提供する
  • DNS over UDPDNS over TLSと対比してパフォーマンスの向上を検討する
  • HTTPとは異なるQUICの利用について概説し、QUICプロトコルとそのAPI定義に参加する


上記の目標のために、想定する通信はスタブリゾルバからリカーシブルリゾルバの通信を想定し、ゾーン転送は考慮しない。中間装置によるブロックを考慮しないことが挙げられている。


HTTP同様DNSでもレイテンシを小さくするため、0-RTTセッション再開、ロスリカバリのサポート、マルチストリームでヘッドオブラインブロッキングの回避の機能について言及がある。

仕様

ALPN識別子

ALPNで使用する識別子として、"qd"を使用する。HTTP同様、ハイフン付きでドラフトバージョンを指定する

ポート番号

具体的なポート番号はTBDとなっているが、DNS over UDPDNS over DTLSとの混用を避けるため53, 853の使用は避けるようだ。サーバはそのポートでリッスンし、クライアントはそのポートにつなぎに行く。

ストリーム

各ストリームがDNSのリクエスト/レスポンスに相当する。クライアントから開始するストリームは、3, 5, ... と続く。


DNS Push NotificationsのようなサーバからPUSHメッセージを送ることも可能で、サーバから開始するストリームは2, 4, ...となる。クライアントはそのストリーム上で応答を返す。

プライバシの問題

DNS Privacy Considerations(RFC7626)で言及されていることは、DSN over TLSの場合と変わらないが、0RTT通信と、セッション再開について言及がある。

0-RTT セッション再開の再送攻撃

観測者は0-RTTを利用した問い合わせを再送することができます。これによりリカーシブルリゾルバから権威リゾルバへのクエリをトリガできます。リカーシブルリゾルバの振る舞いを観測できる場合は、0-RTTの問い合わせを再送させることができもともとの問い合わせを推測リスクが高まります。デフォルトでは無効にしとくことが好ましい。

セッション再開

QUICではIPアドレスが変わってもセッションを維持できるため、それらが同じクライアントだと識別可能です。セッション再開や長いセッションはパフォーマンス上有用だが、クライアントは考慮スべき。

マルチパスQUICにおけるOne Way Latencyの考察

QUICの各仕様のdraft-02が出た一方で、マルチパスQUICに関する考察ドラフトが出ています。


マルチパスQUICはマイルストーン上は2017年の後半に拡張の仕様が出て来る予定ですが、それに先立って考察のドラフトが出ている状況です。今後関連するドラフトも出てくるでしょう。


今回提出されているドラフトは、Huaweiの人らが書かれている「One Way Latency Considerations for Multipath in QUIC」というドラフトです。

One Way Latency Considerations for Multipath in QUIC

"One Way Latency"は既にMultiPath TCPでも議論されている概念であり、そちらでもドラフト(URL)が出ています。


そもそも各通信路は、行きと帰りで同じレイテンシとは限りません。そのため複数経路を使用する場合は、RTTではなく片方向のレイテンシ(One Way Latency)を見て送信する経路を選択すべきということになります。RTTの値は輻輳制御やパケロスの検出に利用されますが、同様に複数経路の場合はOne Way Latencyを見るべきです。またレイテンシ同様、輻輳も片方向には輻輳しているが、反対側は輻輳していないというケースがあります。



たとえば、上記図の用に、クライアント・サーバ間で2経路あった場合。RTTだけみれば上の経路のほうが良いですが、クライアントからサーバに送信する場合は下の経路のほうが低レイテンシということもあるわけです。特に動画のキーフレームや重要なシグナル、ロスしたパケットの再送など急ぐものに関しては下の経路で送信したほうが良いということになります。

OWLの測定

このドラフトでは、OWLの測定としてQUICのAckフレームに含まれるタイムスタンプを利用しますが、絶対値を得る方法と、相対値を得る方法について言及しています。


絶対値は各経路の各方向のOWLを計算します。各エンド間で時刻同期している前提になります。NTPといった別のプロトコルを利用して時刻同期を行えば、タイムスタンプを利用してOWLの絶対値が得られます。


相対値は、OWLの絶対値はわかりませんが、各経路の各方向でどの経路のOWLが小さいのかわかれば経路を選択できるようになります。これは時刻同期は必要なく、Ackフレームに含まれるタイムスタンプより計算されます。