HSTSとは?設定方法とpreloadの注意点を解説
HSTS(HTTP Strict Transport Security)とは、「このサイトには今後 HTTPS でしかつながないでください」とブラウザに記憶させるためのレスポンスヘッダー(Strict-Transport-Security)です。HTTPS 化したサイトでも、利用者が最初に http:// でアクセスした瞬間は暗号化されていません。HSTS は、その入り口の弱さを減らします。
導入は 1 行ですが、一度ブラウザに記憶させると、HTTPS が使えなくなったときにサイトが開けなくなります。そのため、有効期間(max-age)を短く始めて段階的に延ばすのが基本です。特に preload は取り消しが難しいので、最後まで慎重に判断してください。
この記事では、HSTS の仕組みと各ディレクティブの意味、段階的な導入手順、Apache と Nginx の設定例、HTTPS 化後の 301 リダイレクトと mixed content、証明書の期限切れ対策、TLS バージョンの確認方法を順に説明します。
HSTSとは?HTTPS化だけでは足りない理由
サイトを HTTPS 化しても、利用者が example.com とだけ入力したり、古いブックマークの http:// から訪れたりすると、最初のリクエストは暗号化されない HTTP で送られます。通常はサーバーが 301 で HTTPS に転送しますが、その最初の通信を途中で書き換えられると、偽のサイトに誘導される余地が残ります。
HSTS は、サーバーが HTTPS の応答にこのヘッダーを付けることで、ブラウザに「この期間は、このサイトへの http:// を自動で https:// に書き換えて接続する」と覚えさせます。RFC 6797 は、記憶している間のブラウザの動作として、http の URI を https に書き換えてから接続することを定めています。ポート 80 が指定されている場合は 443 に変換されます。
重要な前提:HTTPS の応答でだけ有効
RFC 6797 では、サーバーは安全でない通信(HTTP)の応答にこのヘッダーを含めてはならず、ブラウザは HTTP で受け取ったヘッダーを無視しなければならないと定められています。MDN も同様に、HTTP で送られたヘッダーは無視されると説明しています。中間者が偽のヘッダーを差し込んで悪用するのを防ぐためです。そのため設定は、HTTPS を受ける側(443 番ポート)の設定に書きます。
HSTS が効く流れ
MDN が示す基本の流れは次のとおりです。
- 最初のアクセスは HTTP。サーバーは 301 で HTTPS へ転送する(この応答に HSTS ヘッダーは付けない)
- ブラウザが HTTPS で再接続し、サーバーが HSTS ヘッダーを返す
- 以降は、max-age の期間中、ブラウザが自動で HTTPS に切り替える
つまり、最初の 1 回目の訪問は保護されません。この弱点を埋めるのが、後述の preload です。
max-age・includeSubDomains・preloadの意味
ヘッダーの値には、次の 3 つのディレクティブを使います。RFC 6797 の構文では、ディレクティブをセミコロンで区切って並べます。
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadmax-age(必須)
ブラウザが HTTPS 専用として記憶する秒数です。HTTPS の応答を受け取るたびに、期限が「現在時刻 + max-age」で更新されます。max-age=0 を HTTPS で受け取ると、ブラウザはその記憶を消します。RFC 6797 でも、0 は HSTS ホストとして扱うのをやめる合図とされています。
よく使う秒数は次のとおりです。
- 300 = 5 分(試験用)
- 86400 = 1 日
- 604800 = 1 週間
- 2592000 = 30 日
- 31536000 = 1 年(preload の最低ライン)
- 63072000 = 2 年(MDN や hstspreload.org の例で使われる値)
includeSubDomains(任意)
そのホスト名のすべてのサブドメインにも HSTS を適用します。MDN の例では、secure.example.com で指定すると login.secure.example.com などにも適用されますが、親の example.com には及びません。社内用や古いシステムが HTTP のままのサブドメインが 1 つでもあると、そこにつながらなくなります。付ける前に、DNS に登録されているサブドメインをすべて洗い出してください。
preload(任意)
ブラウザに最初から組み込まれる「HSTS プリロードリスト」への掲載を希望する意思表示です。リストに載ったドメインは、利用者が一度も訪問していなくても、最初から HTTPS で接続されます。ヘッダーに書くだけでは載らず、hstspreload.org などの公式の申請窓口から申請する必要があります。条件と注意は次の章で説明します。
HSTSの導入手順:max-ageを段階的に延ばす
HSTS は、ブラウザに記憶されると、サーバー側で設定を消しても期限までは元に戻りません。HTTPS に不具合が出たときに利用者が閉め出されないよう、短い期間から始めます。以下は段階的な進め方の一例で、秒数の刻みは状況に合わせて調整してください。
導入前の確認
- すべてのページが HTTPS で正常に表示される
- HTTP から HTTPS への 301 リダイレクトが全 URL で動いている
- 証明書が有効で、更新が自動化されている
- 画像・CSS・JS などが HTTPS で読み込まれている(mixed content がない)
- includeSubDomains を付けるなら、全サブドメインが HTTPS 対応済み
段階の目安
max-age=300(5 分)で付けて、表示とログインを確認するmax-age=86400(1 日)に延ばし、数日様子を見るmax-age=604800(1 週間)、2592000(30 日)と延ばすmax-age=31536000(1 年)にする。サブドメインも対応済みならincludeSubDomainsを追加する- preload を検討する場合のみ、
max-age=63072000; includeSubDomains; preloadにして申請する
各段階で問題が出たら、HTTPS 側の応答で max-age=0 を返すと記憶を消せます。ただし、すでに長い期間を記憶したブラウザが再訪問して、この応答を受け取るまでは消えません。長い期間にいきなり上げないのはこのためです。
preloadの注意点:取り消しが難しい理由
hstspreload.org では、プリロードリストへの掲載条件として次を挙げています。
- 有効な証明書を提供している
- ポート 80 を待ち受けているなら、同じホストで HTTP から HTTPS にリダイレクトする
- サブドメインもすべて HTTPS で提供する(DNS に存在する
wwwを含む) - ベースドメインの HTTPS 応答で、max-age が 31536000 秒(1 年)以上、
includeSubDomainsとpreloadを指定する - HTTPS 側でさらにリダイレクトする場合も、そのリダイレクト応答に HSTS ヘッダーを付ける
そして同サイトは、「掲載は簡単には元に戻せない」と明記しています。削除の申請はできますが、変更が利用者のブラウザに届くまでには、Chrome の更新を経て数か月かかるとされています。さらに、条件を満たし続けられなくなると、将来自動的に削除されることがあるとも書かれています。
preload を使う判断基準
次の条件をすべて満たせる場合に限るのが安全です。
- ドメイン配下のすべてのサブドメインを、今後も HTTPS で運用できる
- 社内システム・検証環境・メール関連の Web 画面などで HTTP の運用が残っていない
- 証明書の更新を確実に自動化している
個人ブログや小規模サイトでは、preload を使わなくても max-age を 1 年にして includeSubDomains を付けるだけで、実用上の効果は大きく得られます。迷うなら preload は見送り、後から追加できる状態にしておくのが無難です。
Apache・Nginxの設定例(HSTSと301リダイレクト)
HSTS は HTTPS を受ける側にだけ書きます。HTTP 側は 301 のリダイレクトに専念させ、HSTS ヘッダーは付けません。以下は最初の段階(5 分)の例です。値は上の手順に合わせて延ばしてください。
Apache
mod_headers が必要です。
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
# SSLEngine や証明書の設定は省略
Header always set Strict-Transport-Security "max-age=300"
</VirtualHost>Nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# ssl_certificate などの設定は省略
add_header Strict-Transport-Security "max-age=300" always;
}Nginx の add_header は、下位ブロック(location など)に別の add_header があると、上位の設定が引き継がれません。location ごとにヘッダーを足している場合は、そこにも HSTS を書くか、実際のレスポンスで確認してください。
確認コマンド
curl -sI https://example.com/ | grep -i strict-transport-security
curl -sI http://example.com/ | head -n 51 行目で HSTS ヘッダーが出ること、2 行目で 301 と Location: https://... が返ることを確認します。
HTTPS化後のリダイレクトとmixed content
HTTP から HTTPS へは 301 で統一する
HTTPS 化(常時 SSL 化)をしたら、http:// の全 URL を、対応する https:// の URL へ 301(恒久的な移動)で転送します。トップページだけでなく、下層ページも同じパスで転送されることを確認してください。www あり・なしを統一し、「http → https」と「www 付け替え」を別々の 301 で二重に連続させないようにすると、転送の手間が減り、HSTS の効き目も確実になります。ただし、HTTPS 側で追加のリダイレクトがあるときは、その応答にも HSTS ヘッダーが必要です(preload の場合)。
mixed content に注意
HTTPS のページが HTTP のリソースを読み込む状態を mixed content と呼びます。MDN によれば、現在のブラウザは、画像・音声・動画は自動で HTTPS に引き上げ、スクリプト、スタイルシート、iframe、fetch や XMLHttpRequest などはブロックします。つまり、HTTPS 化の際にテンプレートや記事本文に http:// が残っていると、表示が崩れたり機能が動かなくなったりします。
対処は次のとおりです。
- 内部リンクや画像のパスは、
https://に書き換えるか、/images/photo.pngのような相対パスにする - 外部の計測タグや埋め込みも HTTPS の URL に更新する
- 応急処置として
Content-Security-Policy: upgrade-insecure-requestsを付けると、HTTP のリクエストを HTTPS に引き上げられる(根本対応ではない) - ブラウザの開発者ツールのコンソールで、mixed content の警告を確認する
HSTS を有効にした後に mixed content が残っていると、HTTP へ戻して逃げることもできないため、先に洗い出しておくことが肝心です。
SSL証明書の期限切れを防ぐ方法
HSTS を有効にしたサイトで証明書が期限切れになると、深刻な事態になります。通常は警告を無視して先へ進めますが、HSTS の対象ホストでは、ブラウザはその警告の回避を許さないのが一般的です(RFC 6797 は、証明書エラー時にユーザーが接続を続けられないようにすることを定めています)。利用者がサイトを開けなくなるため、HSTS と証明書の更新管理は一体で考えてください。
期限の確認方法
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -datesnotAfter が有効期限です。ブラウザでも、アドレスバーの鍵アイコンから証明書の詳細を見られます。
期限切れを防ぐ運用
- 自動更新にする。Let's Encrypt の公式ガイドは、証明書は 90 日有効で、有効期間の残りが 3 分の 1(約 30 日前)になった時点での更新を、バックアップの目安としています。ACME クライアント(certbot など)の自動更新を使います。
- 更新の失敗を通知する。更新が失敗しても気づけるよう、メール通知や監視を入れます。同ガイドも、失敗は管理者に通知して調査するよう勧めています。
- 更新後に Web サーバーを reload する。証明書ファイルを差し替えても、サーバーが読み直さないと古い証明書のままです。
- 期限を外部から監視する。残り 30 日を切ったら警告する仕組みを持ちます。
TLSバージョンの確認方法(1.2 / 1.3)
HTTPS の暗号化通信を支える仕組みが TLS です。MDN は、現在のバージョンは TLS 1.3(RFC 8446)で最も広く使われており、TLS 1.2 は一部のサイトで使われ続けているものの、TLS 1.1 と 1.0 はもう使うべきではないと説明しています。IETF の RFC 8996 は、TLS 1.0 と TLS 1.1 を「使ってはならない(MUST NOT)」と定めています。目標は、TLS 1.2 と 1.3 のみを有効にすることです。
自分のサーバーが対応するバージョンを調べる
OpenSSL のコマンドで、バージョンを指定して接続を試せます。
openssl s_client -connect example.com:443 -servername example.com -tls1_3 </dev/null
openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null
openssl s_client -connect example.com:443 -servername example.com -tls1_1 </dev/null接続できてプロトコル情報が表示されれば、そのバージョンに対応しています。-tls1_1 で接続が失敗する(ハンドシェイクエラーになる)のが望ましい状態です。なお、OpenSSL のビルドによっては古いバージョン自体のオプションが使えない場合があります。curl でも curl -sv --tlsv1.2 --tls-max 1.2 https://example.com/ -o /dev/null のように最大バージョンを固定して試せます。
設定例
# Nginx
ssl_protocols TLSv1.2 TLSv1.3;
# Apache
SSLProtocol -all +TLSv1.2 +TLSv1.3暗号スイートなど細部は、Mozilla の SSL Configuration Generator で、使っているサーバーとソフトのバージョンに合う設定を生成できます(MDN も推奨しています)。外部の診断サービスとしては SSL Labs のテストも使えます。
サイトスカウターのサーバー情報調査で確認できること
サイトスカウターのサーバー情報調査は、対象サイトへ TLS ハンドシェイクを 1 回と HTTP GET を 1 回だけ行い、次の項目を表示します。
- HTTPS 対応:最終的な URL が https かどうかを判定します。
- HSTS ヘッダー:Strict-Transport-Security が返ってきたかどうかを判定します。あれば OK、なければ警告です。max-age の長さや includeSubDomains・preload の有無までは評価しません。
- 証明書の有効性:期限切れ、自己署名、ホスト名の不一致は NG、残り 30 日未満は警告、それ以外は OK です。残り日数も表示します。
- 証明書の詳細:発行者、有効期間、SAN、鍵の種類とビット数、証明書チェーンの数、認証レベル(DV・OV・EV・IV)などを表示します。
- 接続時のプロトコル:ハンドシェイクで実際に選ばれた TLS のバージョンと暗号スイートを表示します。
注意点として、プロトコル欄はその接続で選ばれた 1 つのバージョンです。サーバーが TLS 1.1 など古いバージョンにも対応しているかは、この調査では分かりません。その確認は、前の章のコマンドや外部の診断サービスで行ってください。
また、証明書の期限は検証を自前で行うため、すでに期限切れのサイトでも「期限切れ」として情報を取得できます。
HSTS導入チェックリストとよくある失敗
最後に、導入時にありがちな失敗をまとめます。
- HTTP の応答に HSTS を付けてしまう。ブラウザに無視されます。HTTPS 側に設定します。
- 最初から長い max-age にする。HTTPS の不具合で閉め出されても、期限まで戻せません。短く始めます。
- includeSubDomains の影響を見落とす。HTTP のままのサブドメインがつながらなくなります。
- 証明書の自動更新を確認しない。期限切れになると、HSTS 対象ではブラウザの警告回避ができず、サイトが開けません。
- preload を気軽に申請する。取り消しには数か月かかります。
- mixed content を放置する。スクリプトや CSS が HTTP のままだと、HTTPS ページで読み込まれません。
HSTS は、設定の確認までを含めて一つの作業です。反映後は、実際のレスポンスヘッダーと証明書の残り日数を、定期的に見直してください。
よくある質問
HSTS とは何ですか?
Strict-Transport-Security ヘッダーで、一定期間そのサイトへ HTTPS でしか接続しないようブラウザに記憶させる仕組みです。HTTP でのアクセスをブラウザ側で自動的に HTTPS に書き換えます。
HSTS のヘッダーを HTTP で返すとどうなりますか?
ブラウザに無視されます。RFC 6797 は、HTTP の応答に含めてはならず、ブラウザは無視しなければならないと定めています。HTTPS の応答にだけ付けてください。
max-age はどのくらいに設定すればよいですか?
最初は 300 秒など短くして動作を確認し、1 日、1 週間、30 日と段階的に延ばし、最終的に 1 年(31536000 秒)以上にするのが一般的な進め方です。preload を申請する場合は 1 年以上が必須条件です。
HSTS preload は後から取り消せますか?
削除の申請はできますが、hstspreload.org によると、変更が利用者に届くまで数か月かかります。簡単には元に戻せないため、慎重に判断してください。
TLS のバージョンはどれを使えばよいですか?
TLS 1.2 と 1.3 を有効にし、TLS 1.0 と 1.1 は無効にします。RFC 8996 は TLS 1.0 と 1.1 を使ってはならないと定めています。
出典・参考資料
最終確認日:2026-10-06。制度・仕様は変更されることがあるため、実施前に各一次情報をご確認ください。
- RFC 6797: HTTP Strict Transport Security (HSTS)
- MDN: Strict-Transport-Security
- HSTS Preload List Submission (hstspreload.org)
- MDN: Mixed content
- MDN: Transport Layer Security
- RFC 8996: Deprecating TLS 1.0 and TLS 1.1
- Let's Encrypt: Integration Guide