2026年10月20日

2026年10月20日

ApacheでのHTTPSリダイレクトループ修正

はじめに

ApacheでHTTPS化したサイトにアクセスすると「ERR_TOO_MANY_REDIRECTS(リダイレクトが多すぎます)」というエラーで表示できないトラブルは、特にCloudflare・AWS ELB・Nginxを前段に置いたリバースプロキシ構成でよく発生します。原因のほぼ全ては「Apacheが受信したリクエストをHTTPだと判定し続け、無限にhttpsへリダイレクトしてしまう」ことにあります。

本記事では、Apacheの mod_rewrite でHTTP→HTTPSリダイレクトを書いた際の典型的なループ要因を切り分け、フロントプロキシの X-Forwarded-Proto ヘッダを正しく扱うための設定例を紹介します。

SetEnvIf・RewriteCond を組み合わせた直接設定と、WordPressの wp-config.php での補助設定までを含めて解説します。

症状・背景

  • ブラウザで「リダイレクトが多すぎます」と表示される
  • 単体のApacheでは問題ないがCloudflare経由でループする
  • curl -IL で Location: https://... が何度も返ってくる
  • WordPressの管理画面ログインでループが発生する

手順・設定方法

ステップ1: ループしているか確認

まずリダイレクトの連鎖を可視化します。

# リダイレクトを追跡して何回ジャンプするか確認
curl -sIL https://example.com/ | grep -E '^(HTTP|Location)'

# 詳細ログでリクエスト/レスポンスを見る
curl -sv https://example.com/ 2>&1 | head -n 40

# Apacheのアクセスログをリアルタイム監視
sudo tail -f /var/log/apache2/access.log

ステップ2: X-Forwarded-Protoを尊重する書き方に修正

リバースプロキシ配下のApache設定を修正します。

# 悪い例(ループの原因):
# RewriteCond %{HTTPS} off
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# 良い例: X-Forwarded-Proto を見る
sudo tee /etc/apache2/conf-available/force-https.conf > /dev/null <<'EOF'
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteCond %{HTTP:X-Forwarded-Proto} !=https
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
EOF

sudo a2enconf force-https
sudo systemctl reload apache2

ステップ3: SetEnvIfでHTTPSフラグを補完

Apache内部の %{HTTPS} を正しく扱えるようにします。

# mod_setenvif を有効化
sudo a2enmod setenvif

# /etc/apache2/conf-available/proxy-https.conf
sudo tee /etc/apache2/conf-available/proxy-https.conf > /dev/null <<'EOF'
SetEnvIf X-Forwarded-Proto "^https$" HTTPS=on
EOF

sudo a2enconf proxy-https

# 構文チェックして反映
sudo apache2ctl configtest
sudo systemctl reload apache2

ステップ4: WordPress側の補助設定

WordPress利用時はphp側でもプロキシヘッダを尊重させます。

# wp-config.phpに追記
sudo tee -a /var/www/html/wp-config.php > /dev/null <<'EOF'

/* Reverse proxy HTTPS support */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
    $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}
EOF

# WordPressのURL設定確認(http://が残っているとループ要因に)
sudo -u www-data wp option get siteurl --path=/var/www/html
sudo -u www-data wp option update siteurl 'https://example.com' --path=/var/www/html
sudo -u www-data wp option update home 'https://example.com' --path=/var/www/html

注意事項

  • Cloudflareの「Flexible SSL」モードはオリジンとの通信がHTTPになるため、Apache側でHTTPSへリダイレクトすると必ずループします。最低でも「Full」モードを使います
  • mod_remoteip を併用する場合、RemoteIPHeader X-Forwarded-For だけでなく信頼するプロキシIPも明示します
  • .htaccess と VirtualHost 両方にリダイレクト設定があると重複でループしやすいため、片方にまとめます
  • WordPressの siteurl / home が http のままだと、ページ内リンクからループに陥ります

まとめ

1. curl -IL で可視化: 何回 Location が返るかで構成のどこが原因か推測

2. X-Forwarded-Proto を見る: RewriteCond %{HTTP:X-Forwarded-Proto} !=https が鉄則

3. SetEnvIfで補完: Apache内部の %{HTTPS} を on に揃える

4. WordPressは2箇所: wp-config.phpの判定 + siteurl/homeをhttpsに統一

5. Cloudflare等のSSLモード: Flexibleは厳禁、最低Fullを使う

関連記事:

お気軽にご相談ください

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