ブンブンハロー、はいどーも。
もくじ
HTTPSからHTTPへ
最近、わたしと友達がやっている、妖精⊸ロケット(hexe.net)というウェブサイトをHTTPSからHTTPへ移行しました。HTTPSへの移行ではなく、HTTPへの移行です。暗号化するのを、やめました。
んん??時代に逆行しているような気がしますな。Let’s encryptで無料のSSL証明書が簡単に手に入る時代だというのに、お前は一体なにをやっているんだ!
実をいうとHTTPSにも対応してます。HTTPにリダイレクトするけどな!
「保護されていない通信」ですが、何か?
常時https化が叫ばれて久しいですね!
…たったそれだけの理由で、このサイトも含めてなんとなく流されてHTTPSに対応していましたが、…これ、本当に必要なんでしょうか?
そもそも、一体HTTPSで何を保護しているというのか。わたしたちのウェブサイトには公開鍵で署名をしないといけないような、誰が書いたか(あるいは、書いていないか)が極めて重要な、そんなソーシャルな内容はありません。ついでに、このサイトは等しく公衆に公開されているものですから、盗聴されても困らないはずです。まぁ、パケット書き換えられて勝手に改竄されるのは嫌ですけど。でも、ソーシャルな内容でもないのに、わざわざ改竄する人なんか、いるのだろうか?
っていうか、実は常時HTTPSなんかしてもしょうがないから「検索エンジンでの検索結果の順位を上げます(SEOのためにHTTPS対応してね!)」とかいってHTTPSにするモチベーション作ってるんじゃないの。
疑い始めると止まらない!
うぉー、人間が憎い!
「信用できるHTTPSを売りつけてくる人間」が信用できない!
…というわけでHTTPSからHTTPにしてみました。
なぜかChromeでアクセスできない(Firefoxはできる)
設定自体は簡単です。表のnginxが、裏はgoで書かれたバックエンドに対してリバースプロキシしているという構成なので、表のnginxの設定をHTTPとHTTPSでごそっと入れ替えるだけです。
これで際限なく暗号化する潔癖症から逃れられたと思ったのもつかの間。いつも使っているFirefoxでは何の問題もなくHTTPでも表示できたのですが、Chromeでhexe.netを開いてみるとなぜか全く表示されないことに気づきました:
HTTPの方を開いても、勝手にHTTPSへなぜかリダイレクトされてしまいます。サーバはHTTPへリダイレクトし返すので、そこで堂々巡りが発生して「リダイレクトが繰り返し行われました」となってしまったようです。
元々は301でHTTPからHTTPSへ投げていたわけだから、それがChromeのキャッシュに残っていたのだろうか?と思って消してみても、効果はありませんでした。
開発者ツールの「ネットワーク」で確認してみると、301ではなくて「307 Internal Redirect」だそうな:
な、なんじゃそりゃ。307はTemporary Redirectだったはずですが…。そしてもちろん、サーバーでは307を返す設定なんかしていません。
HSTSってのが悪いのか?
そこで思い至ったのがヘッダに書かれているHSTS、一度HTTPで繋いだ時に、次以降は常にHTTPSを利用するよう要請できるという機能でした。HSTSを設定した覚えは一切ないんですが、ひょっとすると、ほら、まぁ、ね、nginxの設定をコピペし間違えるなどして昔設定したことが無いとは言えない…じゃん?
chrome://net-internals/#hstsからHSTSの設定キャッシュは削除できるはずなのですが、やはり効果はありませんでした。変だなぁと思いながら状態を確認してみると:
dynamicなんとかとstaticなんとかの値があって、staticの方にだけ意味のありそうな値が入ってます。ん…static…?
と思って調べていくと、HSTS Preload Listというものに突き当たりました。
ChromeとFirefoxで中身が違うHSTS Preload List
HSTSを指定する方法には、HTTPリクエストへ対するレスポンスのヘッダで指定する方法の他、HSTS Preloadingという方法もあるそうです。
HTTPで最初に接続した時にHSTSを要請する方法の場合、その定義から初回のリクエストは安全でないHTTPで通信しなければなりません。この初回時に改竄でもされたらオシマイです。そこでHSTS Preload Listの出番なのであります。HSTS Preload List Submissionというサイトに「わたしのサイトはHSTSに対応していますよ」と登録しておくと、なんとブラウザの中にその情報が書き込まれて、最初から安全なTLSで通信できるようになりますよ…と。段々宣伝みたいになってきたのでこの辺でやめておきますが、HSTSのRFCの著者の1人がGoogleの中の人なこと、HSTS Preload List Submissionもいかにも「公共」な雰囲気を纏ってはいますがChromium(実質Google)がやってることは指摘しておきましょう。
ここで登録されたリストは最終的に週一の頻度でChromiumのコードに反映されるようです。見てみると…:
ありました。ここでHSTSが有効とマークされているせいで、ブラウザ側でhttpからhttpsへの自動リダイレクトが行われているのでしょう。原因がわかってすっきり。…身に覚えがないけど…。
git blameしまくった結果、この行は2016年11月18日のコミットで追加されたことがわかりました。その時はまだhexe.netは持って無かった気がするので、前の持ち主の人が設定したのかもしれません。前にも使われていた事があるような短いドメイン名はこういう事もあるのでしょう…。
さて、上記のHSTS Preload List SubmissionのサイトではFirefoxでも使われていると書いてありますが、Firefoxのソースコードを参照する限り、hexe.netは入っていません。これで、FirefoxからはHTTPでも見れることが説明できました。…でも、なんで入ってないんでしょう?管理系統が別なんでしょうか。Mozillaのページには特に説明はなく、コミットが3日おきくらいに粛々となされているのは分かるのですが、この変更のソースがどこから来ているのかはコードレビューを見てもよくわかりませんでいた。コードは読めても社会がわからーーーーん!
HSTS Preload ListはWeb標準じゃないけど、Chromeのシェアは大きいから…
このHSTS Preload Listなんですが、Mozillaのページに書いてあるとおり、実はRFCとかW3C勧告のようなWeb標準ではなく、各々のブラウザが勝手に実装したりしていなかったりする「独自拡張」にすぎません。
ところで、こんなニュースがあります:
グーグル、完全HTTPS接続で安全なアプリ用ドメイン「.app」–早期登録を受付開始 – CNET Japan
.appドメインは、アプリ開発者のウェブ運営向けとして用意するTLD。例えば、「アプリ名.app」「開発者名.app」「開発会社名.app」といったURLでアプリの最新情報やダウンロード用リンク、アプリ内コンテンツなどを提供すれば、ユーザーに覚えてもらいやすい、といったメリットがあるという。
最大の特徴は、.appドメインのウェブサイトが必ずHTTPS接続となること。個別にHSTSなどの設定をする必要がなく、.appドメイン内のサイトは自動的にすべてHTTPS接続される。これにより、アクセスするユーザーの安全を手間なく確保できる。
このニュースに対応するように、Chromeの方でもFirefoxの方でも”app”というエントリが含まれています:
Chrome
# https://cs.chromium.org/codesearch/f/chromium/src/net/http/transport_security_state_static.json?cl=0193585e14d2baf5c9ae96a767c532a13973b011 // gTLDs and eTLDs are welcome to preload if they are interested. { "name": "android", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "bank", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "chrome", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "dev", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "foo", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "gle", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "google", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true, "pins": "google" }, { "name": "insurance", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "new", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "page", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "play", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true }, { "name": "youtube", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
Firefox
# https://hg.mozilla.org/mozilla-central/file/4d15e90af575/security/manager/ssl/nsSTSPreloadList.inc#l3893 ... apothes.is, 1 app, 1 app-at.work, 1 ...
ソースコードは非公開だけどInternet ExplorerとかEdgeとかSafariとかでも似たような設定がされてるでしょう。きっと、たぶん。そうにちがいない。
curlではHTTPでアクセスできるけどきっとこれは何かの間違いでしょう:
% curl -vvv get.app * Trying 216.239.32.29... * TCP_NODELAY set * Expire in 200 ms for 4 (transfer 0xe52310) * Connected to get.app (216.239.32.29) port 80 (#0) > GET / HTTP/1.1 > Host: get.app > User-Agent: curl/7.64.0 > Accept: */* > < HTTP/1.1 302 Found < Location: https://get.app/ < Cache-Control: private < Content-Type: text/html; charset=UTF-8 < X-Content-Type-Options: nosniff < Date: Wed, 13 Mar 2019 03:26:39 GMT < Server: sffe < Content-Length: 213 < X-XSS-Protection: 1; mode=block < <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="https://get.app/">here</A>. </BODY></HTML> * Connection #0 to host get.app left intact
…うーん、なんか胡散臭いと感じてしまう。
今後どうしようか
- HSTS Preload List SubmissionのRemoval formから削除してもらう
- 数カ月後のChromeのリリースで、たぶん接続できるようになる
- HTTPSに戻す
- すべてを放置し、Chromeからは接続できないウェブサイトを運営していく(自称ダークウェブ)
一番最後でも、良いかなぁ。それぐらいで、ちょうどいいのかもしれない。「地獄少女」みたいで面白くない?(どうかな…)
GoogleのクローラーはHSTS Preload Listを使っていない
ちなみに、GoogleのクローラーはたぶんHeadless Chromeを動かしているけれど、HSTS Preload Listは使っていないと思います。
なんでそんなことが分かるのかというと、次の検索結果からです:
この「WebGL not supported.」はJSを実行した結果DOMに追加される文字列なので、おそらくクローラーはHeadless Chromeを動かしていると思われます。が、このメッセージが出せるということはリダイレクト地獄に陥いっていないということなので、HSTS Preload Listは使ってないと思われます。…ってことは検索結果は改竄されてるかもしれないって事だな!(?)