Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HTTP/2の仕様にハマった話 / HTTP2 to HTTP11

OPTiM
October 24, 2019

HTTP/2の仕様にハマった話 / HTTP2 to HTTP11

OPTiM

October 24, 2019
Tweet

More Decks by OPTiM

Other Decks in Programming

Transcript

  1. Copyright © OPTiM Corp. All Right Reserved. 3  名前

    • 木村  所属 • 技術統括本部プラットフォーム事業部 • 通称:IDMチームに所属  直近の趣味 • 読書(蔵書はもうそろそろで大台に乗りそうです。) • 自転車  特色 • MySQLでケーキを焼きました。 自己紹介
  2. Copyright © OPTiM Corp. All Right Reserved. 4  MySQLでケーキを焼きました。

    • 何言ってるんだと思ったあなた! • ググってみてください。 - https://gihyo.jp/dev/serial/01/mysql-road-construction-news/0087 • 焼きました(物理) • 画像は右に置いときますね。  今回はこの話はしません。 特色に関して
  3. Copyright © OPTiM Corp. All Right Reserved. 5  今回のタイトルを振り返ってみる

    • HTTP/2の仕様にハマった話 • 新しいマイクロサービスのリリース時にサービスが上手く動かなかったため調査した時のお話です。 • 調査してみて面白いかったので紹介します。  ちょっとややこしいです。 • ごめんなさい ><; 閑話休題
  4. Copyright © OPTiM Corp. All Right Reserved. 6  新規のサービスをステージング環境にリリースした時に既存のサービスと通信が出来なかった。

    • 共通利用されているマイクロサービスを利用するためのリクエストの途中で失敗していた。 • 内部通信ではなくインターネット回線を利用しての接続でした。  構成は以下のような感じでした。 何が起こったのか? 新規サービス WAF リバース プロキシ 既存のサービス どこかがおかしい?
  5. Copyright © OPTiM Corp. All Right Reserved. 7  開発環境では上手く動作していました。

    • 開発環境との差分を確認してみる。 原因を調査してみる 1/5 新規サービス WAF リバース プロキシ 既存のサービス 新規サービス リバース プロキシ 既存のサービス 開発環境 本番環境
  6. Copyright © OPTiM Corp. All Right Reserved. 9  どう考えても疑いたくなります。

    • WAFを外してみると、確かに動作をした。 • どうやらWAFを入れたことによって何かが変わった模様。 原因を調査してみる 2/5 新規サービス WAF リバース プロキシ 既存のサービス
  7. Copyright © OPTiM Corp. All Right Reserved. 10  そもそも通信できていないのはどうして?

    • 既存のサービスのログにはアクセスが表示がされていなかった。 • 前に一つ戻ってリバースプロキシのログを調べてみた。 原因を調査してみる 3/5 新規サービス WAF リバースプ ロキシ 既存のサービス 何も来てないよ!
  8. Copyright © OPTiM Corp. All Right Reserved. 11  リバースプロキシのログを調べてみた。

    • Upstream先(既存サービスの通信先)が見つからなくて404 Not Foundを返していた。 • ここで接続が出来なくなってた。 原因を調査してみる 4/5 新規サービス WAF リバース プロキシ 既存のサービス どこ送ったら良いの?
  9. Copyright © OPTiM Corp. All Right Reserved. 13  WAFを挟むとリバースプロキシが何故か既存サービスを見つけられず404になっている

    • 不思議! • 何が違うのか調査をしてみる。 • プロキシのログをあさり上手くいったリクエストと失敗したリクエストを集めて比較してみた。  結論 • HTTPリクエストのHostヘッダーの値が異なっていた。 • うまくいくリクエストの例 - example.com • 失敗するリクエストの例 - example.com:443 • しかし、今回は全てhttpsで接続しているのでどちらでも良いはず? - well known portは443なので同等のはずでは? 原因を調査してみる 5/5
  10. Copyright © OPTiM Corp. All Right Reserved. 14  とりあえず、「:443」を付けて開発環境でリクエストしてみる。

    • 接続が出来ないことが判明!  使っていたリバースプロキシのドキュメントを確認してみると…? • upstream先は完全一致で記載が必要な事がわかった! • つまりwell known portの省略をすると別のサイトとして扱われることがわかった! • example.comとexample.com:443は別物として扱われていた!  そりゃ繋がらないわけですよね… ところが残念それが罠だよ!
  11. Copyright © OPTiM Corp. All Right Reserved. 15  当然WAFが何をしているのかが気になります。

    • ただし、外部のソリューションだったため、パケットキャプチャを内部に仕込むとかは出来ない。 • 新規サービス側とリバースプロキシにパケットキャプチャを仕込んでみました。 残る疑問「:443」はどこから来たのか? 新規サービス WAF リバース プロキシ 既存のサービス Wireshark で監視
  12. Copyright © OPTiM Corp. All Right Reserved. 16  WAFの前後でHTTPの通信の形式が変わっていた。

    • WAFは、HTTP/2を受け付けてHTTP/1.1に変換してリバースプロキシに渡していました。 • そもそも新しいライブラリでは、HTTP/2の通信にHostヘッダーを付けて無かった! • HTTP/1.1の時のHostヘッダーはどこから錬成されているのか? 結果 新規サービス WAF リバース プロキシ 既存のサービス HTTP/2 HTTP/1.1
  13. Copyright © OPTiM Corp. All Right Reserved. 17  An

    intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by copying the value of the ":authority" pseudo-header field.  簡単に要約すると • HTTP/2からHTTP/1.1に変換する時にHostヘッダーが無かったら:authorityヘッダーをコピーして絶対 に使うよ。  authorityヘッダの仕様は? • Host名:port • これだ… HTTP2の仕様を読んで見る http://www.rfc-editor.org/rfc/rfc7540.txt 8.1.2.3. Request Pseudo-Header Fields より抜粋
  14. Copyright © OPTiM Corp. All Right Reserved. 18  不幸な事故でした。

    • 原因はリバースプロキシが仕様と少し違う実装だったため。 • 組み合わせによっては起こらない問題。 • (規格|製品)の仕様を理解してないと結構危険。 • 特に仕様と外れた部分はちゃんと理解してないと危険。  根本的な原因を特定することが出来ました。 • 将来の障害に繋がる可能性も完全に断てたので良かった。  しっかりと腰を据えて原因を追求できたので非常に面白かったです。 • とりあえずの解決策に頼らず、原因の追求を行えたので安心して今後の開発が出来るようになりました。 まとめ