何が起きているのか
ブラウザでサイトを開こうとすると、こんな壁に当たります:
You cannot visit this site right now because it uses HSTS.
Network errors and attacks are usually temporary, so this page will probably work later.
ブラウザが壊れているわけではありません。指示通りに動いているだけです。HSTS(HTTP Strict Transport Security)とは、ブラウザに対して「このドメインへは平文のHTTPで絶対に接続するな、HTTPSのみ使え」と命令するセキュリティポリシーです。以前の訪問時、またはブラウザ自体に組み込まれたHSTSプリロードリストによってその命令が設定されると、HTTPSが絶対的に強制されます。HTTPリクエストはマシンを出る前にすべて遮断されます。
このエラーは2つの状況で発生します:
- HSTSを有効にした後でHTTPSを壊してしまった開発者——証明書の期限切れ、リダイレクトの設定ミス、TLSなしで動いているローカル開発環境。
- 以前のセッションで有効なHSTSヘッダーを送信したドメイン、またはブラウザのハードコードされたプリロードリストに掲載されているドメインにアクセスしている場合。
根本原因
HSTSの強制は、まったく異なる2つの場所から来ます:
- ブラウザのHSTSキャッシュ:
Strict-Transport-Securityヘッダーを送信するサイトをブラウザが訪問すると、そのポリシーをローカルに保存します。以降のすべての訪問でHTTPが自動的にHTTPSにアップグレードされます。HTTPSが失敗すると、ブラウザはこのエラーを表示します——平文のHTTPにフォールバックすることはありません。 - プリロードリスト:Chrome、Firefox、Edge、Safariはすべて、HTTPSにロックされたドメインのハードコードされたリストを搭載して出荷されます。あなたのドメインがリストに載っていれば、真新しいブラウザのインストールでもHTTPをブロックします。リストはブラウザのバイナリにコンパイルされており、キャッシュをクリアしても何も変わりません。
どのケースに当てはまるかを診断する
ChromeのHSTSキャッシュを確認する
Chromeを開いて以下にアクセスします:
chrome://net-internals/#hsts
Query HSTS/PKP domainの下に、ドメイン(例:example.com)を入力してQueryをクリックします。結果が表示されれば、ChromeがそのドメインのHSTSをキャッシュしています。
出力のstatic_sts_domainフィールドを確認してください。trueと表示されていれば、そのドメインはプリロードリストに載っています。キャッシュのクリアは意味がありません——修正3の対応が必要です。
FirefoxのHSTSステータスを確認する
FirefoxにはChromeのような内部ページはありません。最も手早い方法はhstspreload.orgです——ドメインを貼り付けると、そのドメインがプリロードされているかどうか、どのブラウザでかを即座に教えてくれます。
ローカルにキャッシュされたHSTS(プリロードではない)については、Firefoxのサイト設定をクリアすることで削除できます。以下の修正1を参照してください。
修正1:ブラウザのHSTSキャッシュをクリアする(ユーザー向け)
これはドメインがプリロードリストに載っていない場合のみ有効です。載っている場合は修正3に直接進んでください。
Chrome
chrome://net-internals/#hstsにアクセス- Delete domain security policiesまでスクロール
- ドメインを入力(例:
example.com)——http://やhttps://は不要 - Deleteをクリック
- Queryを再実行して確認——何も返ってこなければ成功
Firefox
- 対象サイトのタブをすべて閉じる
- 履歴メニューを開く→最近の履歴を消去
- 期間をすべてに設定
- アクティブなログインとサイト設定にチェックを入れる
- 今すぐ消去をクリック
HSTSデータを保持しているのはサイト設定です。「キャッシュ」だけをクリアしてもHSTSレコードには触れません——よくある間違いです。
Edge
edge://net-internals/#hsts
Chromeと同じ手順です。Delete domain security policiesを探し、ドメインを入力して削除します。
Safari(macOS)
SafariにはこのためのUIがありません。ファイルを直接削除する必要があります:
- Safariを完全に終了する
- HSTSデータベースを削除する:
rm ~/Library/Cookies/HSTS.plist
- Safariを再起動する
修正2:サーバー側のHSTS設定を修正する(開発者向け)
HSTSを有効にした後でHTTPアクセスが必要になった場合——ローカル開発、ドメイン移行、証明書の期限切れ——自分のユーザーをロックアウトせずに元に戻す方法を説明します。
HSTSを削除する前にmax-ageを下げる
HSTSヘッダーをいきなり削除しないでください。ブラウザはmax-ageが切れるまで古いポリシーをキャッシュするため、既存のユーザーは関係なくブロックされたままです。まずmax-age=0を設定して、古いキャッシュが期限切れになるにつれて新しい訪問者がHSTSの強制を停止するようにします:
# Nginx
add_header Strict-Transport-Security "max-age=0" always;
# Apache
Header always set Strict-Transport-Security "max-age=0"
元のmax-age期間が切れるまで待ちます——max-age=31536000を設定していた場合は最大365日です。その後、ヘッダーを完全に削除します。
SSL証明書が期限切れまたはHTTPSが壊れている場合
まずHTTPSを修正してください。それが動くまで他は何も意味がありません。証明書を更新します:
# Let's Encrypt / Certbot
sudo certbot renew
sudo systemctl reload nginx
# 証明書が有効か確認する
curl -I https://yourdomain.com
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates
HTTPSなしのローカル開発
ローカル開発には本番ドメインではなく別のホスト名を使いましょう。myapp.localのようなものであれば、HSTSを完全に回避できます。ローカルでHTTPSが本当に必要な場合は、mkcertを使えば1分以内にブラウザが信頼するローカル証明書を生成できます:
mkcert -install
mkcert localhost 127.0.0.1 myapp.local
修正3:HSTSプリロードリストから削除する(長期プロセス)
ブラウザキャッシュをクリアしてもまだブロックされている?そのドメインはプリロードリストに載っています。キャッシュのクリアはここでは無意味です。出口は1つしかありません:
- HTTPSを動作させ続けてください。プリロードリストのメンテナーは、HTTPSが壊れている状態では削除リクエストを処理しません。
- HSTSヘッダーから
preloadディレクティブを削除します:
# 変更前(preloadあり)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# 変更後(preloadディレクティブを削除)
Strict-Transport-Security: max-age=31536000; includeSubDomains
- hstspreload.org/removalで削除リクエストを送信する
- 待つ——削除には数ヶ月かかります。実際にユーザーに反映されるにはChromeのアップデートが必要です。
古いバージョンのブラウザを使用しているユーザーはその間ずっとブロックされたままです。これは恒久的なレベルのコミットメントです。HTTPに戻す可能性が少しでもあるドメインには、絶対にpreloadを追加しないでください。
確認方法
修正を適用したら、以下のチェックを実行します:
# サーバーから現在のHSTSヘッダーを確認する
curl -sI https://yourdomain.com | grep -i strict
# HTTPが正しくリダイレクトされるか確認する
curl -sI http://yourdomain.com | grep -i location
# TLSチェーン全体をテストする
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
Chromeに戻り、chrome://net-internals/#hstsにアクセスしてドメインをクエリします。キャッシュのクリアが成功していれば何も返ってきません。static_sts_domain: trueがまだ表示される場合、そのドメインはプリロードされています——ブラウザキャッシュは最初から問題ではありませんでした。
予防策
HSTSは一方通行のドアです。スイッチを入れる前にそのことを認識してください——特にpreloadについては。
- HSTSを有効にする前にSSL証明書の自動更新をセットアップしてください。CertbotのsystemdタイマーはLet's Encryptを自動的に処理し、AWS ACMは自動で更新します。証明書が切れてHSTSが有効だと、ユーザーはすぐに脱出できない状態でロックアウトされます。
- まず短い
max-ageでテストする——max-age=300なら1年のコミットをする前に問題を発見するための5分間の猶予があります。 - HTTPに戻す可能性が少しでもあるドメインには絶対に
preloadを追加しないでください。脱出プロセスだけで数ヶ月かかります。 - 証明書の期限切れを積極的に監視してください。ユーザーがHSTSエラーを報告する頃には、証明書はすでに十分長い時間死んでいて被害が広がっています。
ファイアウォールルールとルーティングが絡むSSLやHTTPSの問題を追いかけているとき、CIDRレンジがよく出てきます。ToolCraftのSubnet Calculatorならすぐに処理できます——完全にブラウザ内で動作し、データはどこにも送信されません。
得られた教訓
- HSTSは意図的に元に戻しにくく設計されています。ブラウザはサーバーが今何を言っていようとキャッシュされたポリシーを信頼します——それがセキュリティモデルの全体的な目的です。
- プリロードリストはブラウザキャッシュではありません。これらは異なる修正方法を持つ異なるメカニズムです。キャッシュのクリアはプリロードエントリを削除しません。
- HSTSをテストするときは
max-age=300から始めてください。完全にコミットしてHTTPSが安定してから初めて、1年に引き上げてpreloadを追加してください。 - HSTSの問題を抱えたドメインを引き継いだ?すぐにhstspreload.orgを確認してください。修正に数時間かかるのか数ヶ月かかるのかを最初から教えてくれます。

