本文へスキップ
サイト総合診断

HTTP を HTTPS にリダイレクトする — 常時 SSL 化

常時 SSL 化とは、サイトの全ページを HTTPS で配信し、http でのアクセスを 301 リダイレクトで https へ恒久的に転送する対応です。通信の盗聴・改ざんを防ぎ、ブラウザの「保護されていない通信」警告を消し、検索でもわずかに有利になります。要点は 3 つ。リダイレクトは 302 ではなく 301 を使う、読み込むリソースも含めて全部を https に揃える、そして HSTS で 2 回目以降の http を無くすことです。

執筆: 公開:

常時 SSL 化とは何ですか?

常時 SSL 化とは、サイトの全ページを HTTPS で配信し、http でアクセスされたら 301 リダイレクトで https へ恒久的に転送する構成のことです。トップページだけでなく、画像やスクリプトを含む全リソースを https で揃えるのが要点で、一部でも http が残ると混在コンテンツとして扱われます。証明書さえ用意すれば、費用も難易度も高くありません。

「常時 SSL 化」は、かつて主流だった「ログインフォームや決済ページだけを https にする」部分的な暗号化に対して、サイト全体を常に https で配信する方針を指す言葉です。今は後者が標準で、http で来たアクセスは すべて https へ転送します。やることは大きく 2 つに分かれます。

  • 証明書を用意して https で配信する — サーバーに TLS 証明書を入れ、443 番で応答できるようにする
  • http を https へリダイレクトする — 80 番に来たアクセスを 301 で https 側へ恒久転送する

なぜ常時 SSL 化が必要なのですか?

通信の盗聴と改ざんを防ぎ、利用者に安全なページだと示すためです。http は内容が平文で流れるため、公衆 Wi-Fi などで読まれたり書き換えられたりします。HTTPS はこれを暗号化で防ぎます。加えて Google は HTTPS を軽い順位シグナルとして扱い、ブラウザは http ページを「保護されていない通信」と警告するため、放置は信頼と流入の両方を損ないます。

http は通信内容がそのまま流れるため、経路上の第三者に読まれる(盗聴)だけでなく、書き換えられます(改ざん)。 カフェや駅の公衆 Wi-Fi のような共有回線では、これは机上の空論ではなく現実的な脅威です。HTTPS は通信を暗号化し、 相手が本物のサーバーかを証明書で検証することで、この両方を防ぎます。

効果は安全性だけにとどまりません。Google は HTTPS を軽い順位シグナルとして公表しており、 主要ブラウザは http のページに「保護されていない通信」という警告を出します。フォームのある http ページでは 警告がさらに強くなり、利用者の離脱に直結します。安全・信頼・検索の 3 方向で、常時 SSL 化は今や前提です。

なぜ 302 ではなく 301 で恒久リダイレクトするのですか?

301 は「今後はこちらが正式な URL」という恒久移転の宣言で、検索エンジンは評価を https 側へ引き継ぎ、ブラウザも結果をキャッシュして次回から直接 https にアクセスするからです。302 は一時的な移転を意味するため評価が移らず、毎回 http へ来てリダイレクトが挟まります。常時 SSL 化のように「元へは戻さない」転送では、必ず 301 を使います。

301 と 302 は「どちらでもリダイレクトはされる」ので混同されがちですが、検索エンジンとブラウザの扱いが根本的に違います

301 と 302 の違い
リダイレクト意味評価の引き継ぎ使う場面
301恒久的な移転https 側へ引き継がれる常時 SSL 化はこちら
302一時的な移転引き継がれないメンテナンス画面など、元に戻す前提の一時転送

常時 SSL 化は「もう http には戻さない」転送なので、意味的にも 301 が正しい選択です。302 のままだと、http の URL がいつまでも正規扱いのままで、評価が https 側にまとまりません。

nginx と Caddy ではどう設定しますか?

nginx は http 用の server ブロックで return 301 を返して https 用の server に飛ばし、Caddy はドメイン名を書くだけで証明書取得と http から https へのリダイレクトが自動で有効になります。どちらも www と非 www をどちらか一方へ寄せて統一します。設定後は実際に http へアクセスし、301 で https へ飛ぶことを必ず確認します。

nginx は「http 用」と「https 用」の 2 つの server ブロックを持ち、http 用は転送だけに徹するのが定石です。$request_uri でアクセスされたパスを保ったまま飛ばすと、深いページに来た人も同じページの https 版へ着地します。

/etc/nginx/conf.d/example.conf
# http (80) 用の server は「301 で https へ飛ばすだけ」に徹する
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # アクセスされたパス($request_uri)を保持したまま https へ恒久リダイレクト
    # ★ 302 ではなく 301。恒久であることを検索エンジンとブラウザに伝える
    return 301 https://example.com$request_uri;
}

# https (443) 用。ここで実際のサイトを配信する
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # www を非 www に寄せる(統一しないと評価が 2 つの URL に分散する)
    if ($host = www.example.com) {
        return 301 https://example.com$request_uri;
    }

    # 2 回目以降の http アクセス自体を無くす(HSTS。詳細は security-headers を参照)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /var/www/example.com;
}

Caddy は考え方が逆で、ドメイン名を書くだけで証明書の取得・更新と http からのリダイレクトが自動になります。 明示的にリダイレクトを書く必要はなく、手数が最も少ない選択肢です。

Caddyfile
# Caddy は証明書の取得・自動更新と http から https へのリダイレクトを自動でやる。
# このブロックだけで、80 番へのアクセスは 301 で 443 へ飛ぶ
example.com {
	# www で来たら非 www へ寄せる(統一)。permanent = 301
	@www host www.example.com
	redir @www https://example.com{uri} permanent

	# 2 回目以降の http を無くす(HSTS。詳細は security-headers へ)
	header Strict-Transport-Security "max-age=31536000; includeSubDomains"

	root * /var/www/example.com
	file_server
}

# www 用の証明書も取り、非 www へ 301 で集約する
www.example.com {
	redir https://example.com{uri} permanent
}

どちらの例でも、www と非 www を一方に寄せて統一しています。統一しないと、example.comwww.example.com が別 URL として二重に評価され、被リンクや評価が分散します。 どちらへ寄せても構いませんが、サイト内で首尾一貫させることが大切です。

証明書はどう用意しますか?費用はかかりますか?

証明書は Let's Encrypt などの認証局から無料で取得でき、自動更新も設定できます。nginx なら certbot、Caddy なら組み込み機能が取得と更新を代行するため、有効期限切れで突然 https が使えなくなる事故を防げます。証明書そのものに費用や有償プランは基本的に不要で、常時 SSL 化にかかるコストは実質ゼロに近づきます。

かつて証明書は有償が当たり前でしたが、今は Let's Encrypt が無料で発行し、しかも自動更新できます。 有効期間は 90 日と短めですが、これは自動更新を前提にした設計で、手動での貼り替えを想定していません。

  • nginxcertbot が証明書の取得と、期限前の自動更新(cron / systemd timer)を担う
  • Caddy — 追加ツール不要。組み込み機能が取得も更新も行う

混在コンテンツ(mixed content)とは何が問題ですか?

混在コンテンツとは、https のページ内で画像・スクリプト・CSS などを http のまま読み込んでいる状態です。ブラウザはスクリプトのような能動的リソースをブロックし、画像などは警告を出します。ページの URL を https にするだけでは不十分で、中で読み込む全リソースの URL も https に揃える必要があります。相対パスを使うと防ぎやすくなります。

ページの URL を https にしても、その中で読み込む画像・スクリプト・CSS の URL が http:// のままだと、そのページは「完全な https」ではありません。これが混在コンテンツで、ブラウザは危険度に応じて挙動を変えます。

混在コンテンツに対するブラウザの挙動
リソースの種類http のまま読み込むと
スクリプト・CSS・iframe(能動的)ブロックされ、その機能が動かなくなる
画像・動画・音声(受動的)読み込まれるが、警告が出て鍵マークが外れる

対策はシンプルで、ページ内の全リソースの URL を https に揃えることです。自サイト内の参照は/images/logo.png のような相対パスにしておけば、ページのプロトコルに自動で追従するので混在が起きません。 外部サービスを読み込む場合は、そのサービスが https に対応していることを確認します。

リダイレクトだけで十分ですか?HSTS は必要ですか?

301 リダイレクトに加えて、HSTS で 2 回目以降は http を送らせないようにします。301 だけだと初回は必ず一度 http にアクセスし、その隙を突く SSL ストリッピング攻撃が残るからです。HSTS はブラウザに「このドメインは常に https」と記憶させ、初回以降の http アクセス自体を無くします。ただし設定を誤ると解除に時間がかかるため、詳細は別の解説を参照してください。

301 リダイレクトには、原理的に消せない隙が 1 つ残ります。ブラウザが初めてそのサイトへ来るとき、最初の 1 回は http でアクセスすることです。 この 1 回のリダイレクトを通信経路上で握り潰し、http のまま偽サイトへ誘導するのが SSL ストリッピング攻撃です。

Strict-Transport-Security(HSTS)ヘッダを付けると、ブラウザは「このドメインには次から必ず https で行く」と記憶し、 2 回目以降は http アクセス自体が発生しなくなります。上の nginx・Caddy の例にも 1 行だけ含めてあります。 ただし HSTS は設定を誤ると解除に時間がかかるという別の注意点があるため、max-ageincludeSubDomainspreload の扱いは セキュリティヘッダ 7 種の意味と設定 の HSTS の項で詳しく説明しています。

ありがちな失敗は何ですか?

最も多いのは、302 を使ってしまう・一部リソースが http のまま残る・www と非 www の統一が漏れる、の 3 つです。302 は評価が https へ移らず、混在コンテンツはブロックや警告を招き、www の統一漏れは同じ内容が 2 つの URL に分かれて評価が薄まります。いずれも見た目は普通に動いてしまうため気づきにくく、確認して初めて分かります。

  • 302 を使っている — 一時リダイレクト扱いになり、評価が https 側へ移らない。CMS やホスティングの既定が 302 のことがある
  • 一部リソースが http のまま — 本文は https でも、埋め込み画像や広告タグが http で混在コンテンツになる
  • www と非 www の統一漏れ — 両方が生きていて、同じ内容が 2 つの URL に分かれて評価される
  • http の server を残したまま放置 — リダイレクトを書き忘れ、http と https の両方が同じ内容を返している

共通するのは、どれも見た目は正常に動いてしまうことです。ブラウザで開けば普通に表示されるため、 意識して確認しない限り気づけません。だからこそ、最後に機械的なチェックを挟む価値があります。

正しく常時 SSL 化できたかどう確認しますか?

コマンドや診断ツールで、http が 301 で https へ飛ぶか、混在コンテンツが残っていないかを確認します。curl -I で http にアクセスすればステータスコードとリダイレクト先が分かり、ブラウザの開発者ツールのコンソールには混在コンテンツの警告が表示されます。本ツールの診断でも、HTTPS 化とリダイレクトの状態を検出します。

確認コマンド
# http が 301 で https へ飛ぶか(-I はヘッダのみを取得)
curl -sI http://example.com | grep -iE '^(HTTP|location)'
# → HTTP/1.1 301 Moved Permanently
#    Location: https://example.com/

# www が非 www に集約されるかも確認する
curl -sI http://www.example.com | grep -i location

# 302 を返していないか(一時リダイレクトになっていたら設定ミス)
curl -sI http://example.com | grep -i '301\|302'

コマンドで見るのは「http が 301 で https へ飛ぶか」「www が非 www へ集約されるか」の 2 点です。301 Moved Permanently と正しい Location が返れば成功、302 が返っていたら設定ミスです。 混在コンテンツは、ブラウザの開発者ツールのコンソールに出る警告で確認できます。

リダイレクトと同じくサーバー設定で効かせるセキュリティ強化は セキュリティヘッダ 7 種の意味と設定、 https 化で削れるリダイレクトが速度に与える影響は Core Web Vitals — LCP・INP・CLS の改善 を参照してください。

参考にした一次情報

関連する解説

自分のサイトは、実際どうなっているか

この記事で説明した項目は、すべて無料の診断ツールで実測できます。URL を入れるだけ・登録不要です。

無料で診断する