県境環境は極力HTTPSで作ったほうがいい
タイトルの通りです。
自分が最近やったことで、ハマったことがあったので、残しておきたいと思います。
自分の身に起きたこと
HTTPにおける圧縮について検証をしていました。
そもそもHTTPの圧縮とは、HTTPでは平文でHTMLやCSSが送られてきているわけではなく、サーバ側でコンテンツを圧縮していることが多々あります。
圧縮状態でクライアントにデータを送れば、データの転送量が減ることになるというメリットがあります。
ただし、クライアントがそもそもなんの圧縮方式をサポートしているのか、圧縮でコンテンツが送られてくることを許容するのか、ということをサーバが知らなければ意図しないデータの形式で通信が行われてしまいます。
圧縮方式はいくつかあり、MDNに記載されている圧縮方式には以下があります。
- gzip
- compress
- deflate
- br
ネゴシエーションの方法は、クライアント側からサポートしている圧縮方式を提示しています。
https://developer.mozilla.org/ja/docs/Web/HTTP/Content_negotiation
検証の目的は、各ブラウザで対応している圧縮方式とサーバサイドの実装方法の確認でした。
ブラウザの仕様が公開されていなかったので、ブラウザの[開発者ツール]の[ネットワーク]タブから、リクエスト内容を確認していました。
この結果を見た私はGoogle Chromeはgzipとdeflateしかサポートしていないものの、Firefoxはbrがサポートされているのだと思っていました。
後日、たまたま見たサイトに、この知見を得るきっかけがあったのでした。
https://dev.classmethod.jp/articles/why-browser-suppot-brotli-only-https-connection
つまり、HTTPSではなかったため、brが圧縮方式として提示されていなかったのです。
ほかのケースを考えてみる。
エンタープライズの環境を含めて、HTTPで検証が失敗するケースはざっと以下があると思います。
- Cookieのセキュア属性の不備が発生する。
- Mixed Contentの発生を事前に気づくことができない。
- 証明書更新など、実運用に必要な事項の洗い出しミス
検証と本番環境で手間やコストから省略する部分があると思いますが、HTTPとHTTPSは省略するべきではありません。
手元レベルでの検証であれば、自分で証明書を生成すればよいです。
証明書生成コマンド※本番環境では絶対に使わないでください。
(証明書を配置するディレクトリに移動したうえで)
openssl req -x509 -nodes -days 10000 -newkey rsa:2048 -keyout server.key -out server.crt -subj "/C=JP/ST=Tokyo/L=Shibuya/O=Example Inc/OU=IT/CN=localhost"
-x509: 自己署名証明書を生成する指定。
-nodes: 秘密鍵を暗号化せずに保存(パスフレーズなしで利用可能)。
-days 365: 証明書の有効期限を365日間に設定。
-newkey rsa:2048: RSA 2048ビット長の新しい秘密鍵を生成。
-keyout server.key: 出力される秘密鍵のファイル名。
-out server.crt: 出力される証明書のファイル名。