Webサーバのリダイレクトループ『Web/DBの話⑧』
URLにアクセスすると、
読み込み中のまま終わらない/ERR_TOO_MANY_REDIRECTS。
Webサーバは生きているし、設定も入っている。
原因は リダイレクト設定のループ。
HTTPS化やURL正規化の“ついで”で、踏んでしまう罠だ。
冒頭の一言要約
リダイレクトは“行き先を一意に決めないと無限ループ”。
http↔https、www有無の組み合わせが典型。
症状(あるある)
ブラウザで「リダイレクトが繰り返されています」
curl すると 301/302 が延々返る
特定のURLだけ表示されない
HTTPSだけ/HTTPだけ失敗
LB配下だけ発生(直アクセスはOK)
cookie を消すと一瞬直る(が再発)
原因と仕組み(なぜ起きるか)
http→https と https→http を同時に設定
www 付与と www 削除の条件が衝突
LB(終端SSL)とWebサーバのリダイレクト二重化
X-Forwarded-Proto を考慮していない
正規化ルールが vhost ごとに不一致
rewrite の条件式が広すぎる
図:典型的なリダイレクトループ
http://example.com
│ 301
▼
https://example.com
│ 301(条件ミス)
▼
http://example.com
↑
└── 無限ループ
切り分け(最短コース)
実際のレスポンスを確認
curl -I http://example.com curl -I https://example.com
Location ヘッダの遷移を追う
curl -IL https://example.com
LB配下か直アクセスかを切り分け
LB経由/Web直で挙動が違うか
Webサーバ設定の該当箇所を確認
Apache: RewriteRule / Redirect
Nginx: return 301 / rewrite
プロトコル判定の条件確認
HTTPS / $scheme / X-Forwarded-Proto
今すぐ効く対処(テンプレ)
Nginx(HTTPS強制・LB配下想定)
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;
# 本処理
}
※ www→non-www と https 強制を“同時に1箇所”で定義。
Apache(X-Forwarded-Proto 考慮)
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]
恒久対策/再発防止チェックリスト
正規URL(scheme/host)を1つに決める
リダイレクトは“入口で一度だけ”
LB有無で判定条件を分ける
X-Forwarded-Proto を明示的に考慮
www有無の正規化を一箇所に集約
301/302 の意図をコメントで残す
変更後は curl -IL で必ず確認
HTTPS化作業の手順書にチェック項目を入れる
落とし穴(やりがちミス)
便利だからと rewrite を複数箇所に書く
LB終端を忘れて $scheme だけで判定
www 有無を別vhostで同時処理
直アクセスだけでテストして本番投入
cookie 依存の挙動に惑わされる
まとめ(行動指針)
リダイレクトは
「正規URLを一意に決め、入口で一回」 が鉄則。
遷移を可視化 → 条件を絞る → 一箇所に集約。
この型を守れば、
リダイレクトループは確実に防げる。
