HSTS preloadの設定~「Error: No HSTS header」の対策
先日、HSTS preloadの設定を行う機会があり、少しハマったので、設定の注意点をここに記載します。
HSTSについて
HSTS preloadの説明と設定方法は、以下の記事がわかりやすいです。
・HSTSとは?推奨される理由とプリロードリスト登録方法 – ブロギングライフ
https://www.blogging-life.com/hsts-preload/
・How to configure HSTS on www and other subdomains – Daniel Morell Blog
https://www.danielmorell.com/blog/how-to-configure-hsts-on-www-and-other-subdomains
HSTS preloadは、すごくざっくりいうと、Webサイト常時SSL化(フルHTTPS化、完全HTTPS化)の強化版ですね。
Webサーバー側でHSTSの設定を行うことで、ユーザー(ブラウザ)がWebサイトに一度アクセスすると、2回目以降は必ずHTTPSでアクセスするようになります。
さらに、ドメインをHSTS preloadリストに登録することで、ユーザーがそのドメインおよびサブドメインのWebサイトにアクセスすると、初回から必ずHTTPSでアクセスするようになります。
つまり、「HSTS preloadはルートドメインに対して設定する」というのが重要なポイントです。
HSTS preloadの設定の注意点
今回の例では、HSTS preloadの設定を行いたいWebサイトを https://www.example.jp/ とします。
HSTS preloadの登録サイト(https://hstspreload.org/) によると、preloadリスト登録の要件は以下のとおりです。
1. Serve a valid certificate.
2. Redirect from HTTP to HTTPS on the same host, if you are listening on port 80.
3. Serve all subdomains over HTTPS.
– In particular, you must support HTTPS for the www subdomain if a DNS record for that subdomain exists.
4. Serve an HSTS header on the base domain for HTTPS requests:
– The max-age must be at least 31536000 seconds (1 year).
– The includeSubDomains directive must be specified.
– The preload directive must be specified.
– If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS header (rather than the page it redirects to).
これらの要件を満たすため、(見落とされがちな)ポイントは次のとおりです。
P1. HSTS preloadはルートドメインに対して設定する。
P2. サブドメインのWebサイトをすべて常時SSL対応する。
P3. HTTPポートを公開しているときは、同じホスト名のHTTPSにリダイレクトさせる。
P4. リダイレクトさせるときは、HTTPレスポンスヘッダーにHSTSヘッダーを含ませる。
今回の https://www.example.jp/ の例で説明します。
P1. については、
HSTS preload は、www.example.jp ではなく、ルートドメインである example.jp に対して設定します。
HSTS preloadリストに登録するホスト名は example.jp です。
また、ApacheやNginxなどの設定では、ホスト名 example.jp のところで、HSTSヘッダーの設定を記述します。
P2. については、
サブドメイン *.example.jp のすべてのWebサイトで、常時SSL化が必要です。
ひとつでも、(HTTPSではなく)HTTPで運用したいWebサイトがあれば、preloadリストへの登録はしてはいけません。
P3. については、
サーバーがHTTPポート(TCP/80)を公開しているときは、http://example.jp/ でアクセスできるようにする必要があります。
また、http://example.jp/ から、https://example.jp/ へのリダイレクト設定が必要となります。
ここはハマりやすいポイントですが、http://example.jp/ から、直接wwwありのHTTPS https://www.example.jp/ にリダイレクト設定すると、preloadリストへの登録がエラーとなります。
このときのエラーメッセージは以下のとおり。
Error: No HSTS header Response error: No HSTS header is present on the response. Error: HTTP redirects to www first`http://example.jp` (HTTP) should immediately redirect to `https://example.jp` (HTTPS) before adding the www subdomain. Right now, the first redirect is to `https://www.example.jp/`. The extra redirect is required to ensure that any browser which supports HSTS will record the HSTS entry for the top level domain, not just the subdomain.
http://example.jp/ から、https://example.jp/ にリダイレクトし、さらに、https://example.jp/ から https://www.example.jp/ にリダイレクト、と、二段階のリダイレクト設定が必要となります。
P4.については、
リダイレクトさせるときに、HTTPSレスポンスヘッダ―からカスタムヘッダーであるHSTSヘッダーが削除されてしまう(されないこともある?)ので注意しましょう、ということですね。
例えば、Apache Config(もしくは .htaccess)で、以下のようにHSTSヘッダーの追加設定を行ったとします。
<VirtualHost *:443> ServerName example.jp:443 ... # HSTS preload Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" ...
これで、preloadリストへの登録を行うと、以下のエラーとなりました。
Error: No HSTS header Response error: No HSTS header is present on the response.
この場合、Apache ConfigのHSTSヘッダーの追加設定に「always」条件を含めると、リダイレクト時のHTTPSレスポンスヘッダ―から、HSTSヘッダーが削除されなくなります。
<VirtualHost *:443> ServerName example.jp:443 ... # HSTS preload Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" ...
なお、preloadリストに登録すると、
「Status: example.jp is pending submission to the preload list.」
となります。
「承認待ち」ということですね。
承認が完了し、登録済みになると、
「Status: example.jp is currently preloaded.」
となります。
「申請して登録済みとなるまで few weeks かかる」というメッセージが表示されましたが、僕が申請したときは、5日で登録済みとなりました。
おわりに
HSTS preloadの設定の注意点について、まとめました。
HSTS preloadは、サブドメインもすべて常時SSL化が必要なので、少しハードルが高いと思います。
preloadリストへの登録でエラーとなったときに、「Header always set~」によって解決する方法は、ほとんど見つけられなかったので、記事を書いてみました。
(関連記事)
・自社WordPressサイトを完全HTTPS化しました。
https://inaba-serverdesign.jp/blog/20160502/move_wordperss_website_https.html