2026年5月20日

2026年5月20日

WordPressのHTTPからHTTPSへの301リダイレクト設定(.htaccess・Nginx・Cloudflare)

SSL 証明書を入れたら、http:// へのアクセスを https:// に 301 リダイレクトし、URL を1つにそろえます。設定を誤ると「リダイレクトが多すぎます」(ERR_TOO_MANY_REDIRECTS)になったり、www あり・なしの URL が混在したりします。この記事では、作業の順番、Apache(.htaccess)と Nginx の設定、ロードバランサーや Cloudflare を通す構成でループを防ぐ方法、確認のしかたを説明します。

例では、正規の URL を https://example.com(www なし)とします。www ありに統一する場合の書き方も併記します。

作業の順番

  1. HTTPS で表示できることを先に確かめる: https://example.com/ がブラウザで証明書の警告なしに開けることを確認します。www ありの URL もリダイレクトするなら、証明書に www.example.com も含まれている必要があります。
  2. WordPress の URL を https にする: 管理画面の「設定」→「一般」で「WordPress アドレス (URL)」と「サイトアドレス (URL)」を https://example.com に変えます。
  3. サーバーでリダイレクトを設定する: 後述の .htaccess か Nginx の設定を入れます。
  4. 確認する: curl で、すべての入口が1回の 301 で正規 URL に届くことを確かめます。

作業前に、ファイルとデータベースのバックアップを取っておきます。

現状を確認する

まず、今どう応答しているかを見ます。-I はヘッダーだけを表示するオプションです。

# 応答コードと転送先だけを表示する
curl -sI http://example.com/ | grep -iE '^(HTTP|location)'

# 転送をたどって最終的な URL と回数を表示する(ループしていると上限で止まる)
curl -sIL --max-redirs 10 -o /dev/null -w '%{http_code} %{num_redirects} %{url_effective}\n' http://www.example.com/

WordPress 側の設定

「設定」→「一般」の URL を変える

「WordPress アドレス (URL)」と「サイトアドレス (URL)」を https:// で始まる URL にします。保存後にログイン画面が表示された場合は、https の URL でログインし直します。WP-CLI が使える場合は次のコマンドで確認と変更ができます。

wp option get home
wp option get siteurl
wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'

wp-config.php に WP_HOME や WP_SITEURL が書かれていると、そちらが優先され、管理画面の欄は変更できません。その場合は wp-config.php の値を https に直します。

サイトが HTTPS で表示できる状態になると、「ツール」→「サイトヘルス」に HTTPS へ切り替えるためのボタンが表示されることがあります。

本文中の http の URL を置き換える

過去の投稿に http://example.com/wp-content/uploads/... のような画像 URL が残っていると、混在コンテンツ(Mixed Content)の警告が出ます。WP-CLI で置き換える場合は、先に --dry-run で件数を確認します。

wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# 件数を確認してから実行する
wp search-replace 'http://example.com' 'https://example.com' --all-tables

Apache(.htaccess)でリダイレクトする

ルートの .htaccess の、# BEGIN WordPress の行より前に書きます。WordPress のブロックの中に書くと、パーマリンク設定の保存などで上書きされます。

www なしに統一する

http のアクセスと www ありのアクセスを、どちらも1回の 301 で https://example.com に送ります。

# HTTP、または www 付きのアクセスを https://example.com に1回で301リダイレクトする
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
</IfModule>

%{REQUEST_URI} にはパスが入り、クエリ文字列(?x=1 など)は mod_rewrite が自動で引き継ぎます。

www ありに統一する

# HTTP、または www なしのアクセスを https://www.example.com に1回で301リダイレクトする
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
</IfModule>

ロードバランサーやプロキシの後ろにある場合

ロードバランサーや CDN で HTTPS を終端し、サーバーには HTTP で転送してくる構成では、サーバーから見ると常に HTTP なので %{HTTPS} off が毎回成立し、ループします。この場合は、プロキシが付ける X-Forwarded-Proto ヘッダーで判定します。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

ヘッダーが付かないアクセス(ロードバランサーのヘルスチェックなど)もリダイレクトされるため、ヘルスチェックが 301 で失敗扱いになる場合は、そのパスを除外する条件を加えます。

Nginx でリダイレクトする

HTTP 用の server ブロックで HTTPS へ送り、www ありの HTTPS も正規ホストへ送ります。

# HTTP は www の有無に関係なく https://example.com へ
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# https://www.example.com も https://example.com へ
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name www.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    return 301 https://example.com$request_uri;
}

# 本体
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    # root、location、PHP-FPM などの通常の設定
}

http2 on; は Nginx 1.25.1 以降の書き方です。それより古い Nginx では listen 443 ssl http2; と書きます(新しい版で listen ... http2 と書くと非推奨の警告が出ます)。www ありに統一する場合は、2つ目と3つ目の server_name を入れ替え、return の転送先を https://www.example.com にします。

設定を変えたら、文法を確認してから再読み込みします。

sudo nginx -t && sudo systemctl reload nginx

リダイレクトループを防ぐ

プロキシの後ろで WordPress に HTTPS を伝える

ロードバランサーや Cloudflare などの後ろでは、PHP から見ると HTTP の接続になるため、WordPress は自分が HTTP で表示されていると判断し、管理画面などで https へ転送し続けることがあります。プロキシが X-Forwarded-Proto を付けている場合は、wp-config.php の /* That's all, stop editing! */ より前に次を書きます。

<?php
// プロキシが HTTPS で受けたリクエストを、WordPress に HTTPS として扱わせる
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
	$_SERVER['HTTPS'] = 'on';
}

// 管理画面とログインを HTTPS に限る
define( 'FORCE_SSL_ADMIN', true );

このヘッダーは誰でも付けられるため、サーバーへの直接のアクセスを許していない(プロキシ経由でしか届かない)構成で使います。

Cloudflare の SSL/TLS 設定

Cloudflare の SSL/TLS 暗号化モードが「Flexible」だと、Cloudflare からサーバーへは HTTP で接続します。この状態でサーバー側にも HTTPS へのリダイレクトを入れると、HTTP で来るたびに HTTPS へ送り返すことになりループします。サーバーに証明書を入れたうえで「Full (strict)」にします(2026年10月時点の Cloudflare の表記)。

それでもループする場合

次の順に切り分けます。

# 1. WordPress の URL が https になっているか
wp option get home
wp option get siteurl

# 2. .htaccess を一時的に外してループが止まるか
mv .htaccess .htaccess.bak

# 3. プラグインをすべて止めてループが止まるか(止まったら1つずつ有効化して原因を探す)
wp plugin list --status=active --field=name > active-plugins.txt   # 先に有効なものを控える
wp plugin deactivate --all
wp plugin activate plugin-slug   # plugin-slug は active-plugins.txt に控えた名前に置き換える

切り分けが終わったら .htaccess.bak を元の名前に戻し、止めたプラグインも有効化し直します。SSL 化やリダイレクト系のプラグインを使っている場合、サーバー側のリダイレクトと二重になってループすることがあるため、どちらか一方にします。

設定を確認する

正規 URL を https://example.com にした場合、次の3つの入口がすべて1回の 301 で正規 URL に届き、正規 URL は 200 を返すのが正しい状態です。

for u in http://example.com/ http://www.example.com/ https://www.example.com/; do
  curl -sI "$u" | grep -iE '^(HTTP|location)'
done
curl -sI https://example.com/ | grep -iE '^HTTP'

期待される結果は次のとおりです。

アクセス先 応答 転送先
http://example.com/ 301 https://example.com/
http://www.example.com/ 301 https://example.com/
https://www.example.com/ 301 https://example.com/
https://example.com/ 200 なし

301 はブラウザにキャッシュされるため、試行錯誤の間は R=302 や return 302 で確かめ、正しく動いてから 301 に変える方法もあります。ブラウザで確かめるときは、シークレットウィンドウを使うとキャッシュの影響を受けにくくなります。

まとめ

  • 先に HTTPS で表示できることを確かめ、「設定」→「一般」の2つの URL を https にしてから、サーバーでリダイレクトする
  • Apache は # BEGIN WordPress より前に、http と www ありを1回の 301 で正規 URL へ送る規則を書く
  • Nginx は HTTP 用の server ブロックと www 用の server ブロックで return 301 を使う
  • プロキシや Cloudflare の後ろでは X-Forwarded-Proto で判定し、Cloudflare は「Full (strict)」にする
  • curl で全部の入口が1回の 301 で正規 URL に届くことを確認する

関連記事

お気軽にご相談ください

お見積りへ お問い合わせへ
▲