
## この記事でわかること

- HSTS（Strict-Transport-Security）が「初回 HTTPS 後は HTTP に戻れない」を強制する仕組みであること
- Cloudflare / Nginx / WordPress（.htaccess）別の具体的な設定手順
- preload 申請の前提と、安易に申請しない方が良い理由
- 事故を防ぐための短期 max-age 検証フロー

## HSTS は「ブラウザに HTTPS を強制させる」仕組み

HSTS（HTTP Strict Transport Security、RFC 6797）は、Web サーバーがレスポンスヘッダで「**このドメインは max-age 秒間、必ず HTTPS で接続して**」と宣言する仕組みです。

```
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```

ブラウザはこの指示をローカルに記憶し、以降は `http://...` をユーザーが入力しても、サーバーに到達する前に強制的に `https://...` に書き換えます。

![HSTS の動作の仕組み](/blog/hsts-settei-houhou/hsts-mechanism.svg)

これにより:
- **中間者攻撃で HTTP に降格させようとするリダイレクトが効かない**
- **公衆 Wi-Fi 等の経路上で HTTP 通信を盗み見られない**
- **HTTPS 必須のサイトで「うっかり http:// のリンクから入る」事故が起きない**

## Cloudflare での設定（最も簡単）

Cloudflare の管理画面から GUI で設定可能。サーバー側のコード変更は不要。

### 手順
1. Cloudflare ダッシュボード → 対象ドメイン
2. **SSL/TLS** → **Edge Certificates** へ
3. **HTTP Strict Transport Security (HSTS)** セクションで **Enable HSTS** をクリック
4. 設定:
   - **Max Age Header (max-age)**: 12 months（31,536,000 秒）
   - **Apply HSTS policy to subdomains**: オン（includeSubDomains）
   - **Preload**: オン（後述）
   - **No-Sniff Header**: オン（X-Content-Type-Options: nosniff も同時に有効化）

所要 1 分。Cloudflare のエッジで自動的にヘッダ付与されます。

## Nginx での設定

サイト設定ファイルに 1 行追加します。

```nginx
server {
    listen 443 ssl;
    server_name example.co.jp;

    # 他の設定 ...

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
```

### ポイント
- **`always` 引数**: 4xx / 5xx エラー応答にもヘッダを付与する。`always` が無いと Nginx は限られた応答コード（200 / 201 / 204 / 206 / 301 / 302 / 303 / 304 / 307 / 308）にしかヘッダを付けないため、エラーページから HSTS が抜けて HTTP 降格を許す原因になる
- 設定後 `nginx -t` で構文確認 → `nginx -s reload` で反映
- 複数の `server` ブロックがある場合は全てに追加

## WordPress（Apache + .htaccess）での設定

WordPress の場合は `.htaccess` か `functions.php` で設定します。

### `.htaccess` で設定する場合（推奨）

```apache
<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>
```

`mod_headers` モジュールが有効である必要があります。多くのレンタルサーバーは標準で有効です。

### プラグインで設定する場合

`.htaccess` の編集が難しい環境（管理画面からのアクセスのみ等）では、以下のプラグインで GUI 設定できます:

- **HTTP Headers**: 各種セキュリティヘッダを GUI 設定
- **Really Simple SSL**: HTTPS 化と HSTS をワンセットで設定

ただしプラグインに依存すると、プラグイン削除時にヘッダも消える点に注意。

![サーバー別の HSTS 設定方法](/blog/hsts-settei-houhou/server-config-comparison.svg)

## 事故を防ぐ「短期 max-age」検証フロー

HSTS の最大の落とし穴は、**一度設定すると max-age 期間中は撤回が困難**な点です。証明書の更新ミスや HTTPS 設定の不備があった場合、ブラウザが頑なに HTTPS を要求し続けるため、warning 画面のまま操作不能になります。

### 推奨フロー

1. **Day 0**: max-age=86400（1 日）で設定して動作確認
   ```
   Strict-Transport-Security: max-age=86400
   ```
2. **Day 1〜7**: 主要ブラウザ・モバイル等で全画面の表示確認
3. **問題なし**: max-age=2592000（30 日）に上げて様子見
4. **Day 30 以降**: max-age=31536000（1 年）に拡大、includeSubDomains 追加
5. **必要なら**: preload 申請（次節）

### includeSubDomains の罠

`includeSubDomains` を入れると、`*.example.co.jp` の**全サブドメイン**にも HSTS が適用されます。

- メインは HTTPS 化済みだが、`legacy.example.co.jp` がまだ HTTP のみ → サブドメインへのアクセスがブロックされる
- マーケ部門が独自に立ち上げたサブドメインで証明書がない → 同様

事前に **保有サブドメインを全棚卸し**してから includeSubDomains を入れるのが安全です。

## preload 申請の前提

`preload` ディレクティブを付け、`hstspreload.org` で申請すると、Chrome 等の主要ブラウザに**初回アクセスの前から HSTS 強制**が焼き込まれます。新規ユーザーや「履歴を消した」ユーザーにも HSTS が効きます。

### 申請の前提条件
- 有効な SSL 証明書が設定されている
- HTTP（80 番）から HTTPS（443 番）への 301 リダイレクトが設定済み
- すべてのサブドメインで HTTPS が動いている（includeSubDomains 必須）
- `max-age` が **31,536,000 秒（1 年）以上**
- `preload` ディレクティブ付き

### 申請後の解除は半年〜1 年以上かかる

申請後にブラウザに焼き込まれるため、後で「やっぱり HSTS を外したい」と思っても、すべての主要ブラウザのリストから消えるまで時間がかかります。**本当に永続的に HTTPS 必須**にするドメインだけ申請しましょう。具体的な登録手続きと撤回時のリスクは [HSTS preload 登録の手続きと撤回リスク](/blog/hsts-preload-touroku-tetsuduki) で解説しています。

## まずは現状を把握しましょう

自社サイトの HSTS 設定状況（max-age / includeSubDomains / preload 適格性）は、ドメイン番人の [Web セキュリティヘッダ 単発チェック](/security-headers/check) で 30 秒で確認できます。

HSTS の安全な段階導入（短期 max-age での検証 → 拡大 → preload 申請判断）のスポット支援は [Web セキュリティヘッダ診断＋設定支援](/contact)（3 万円〜）でご相談いただけます。

他社チェッカー（securityheaders.com / Mozilla Observatory）との違いは [Web セキュリティヘッダのチェッカー比較](/blog/security-headers-checker-comparison) を参照してください。

CSP の入門は [CSP（Content-Security-Policy）とは？Web 担当者のための入門](/blog/csp-content-security-policy-toha)、ブラウザ機能（カメラ / マイク / 位置情報）の制限は [permissions-policy で機能を制限する設定](/blog/permissions-policy-toha) を参照してください。メール認証や SSL も含めた総合点検は [無料のドメイン診断](/diagnose) を、SSL 単独の確認は [SSL 単発チェック](/ssl/check) をご利用ください。
