見出し画像

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
      ↑
      └── 無限ループ

切り分け(最短コース)

  1. 実際のレスポンスを確認

    1. curl -I http://example.com curl -I https://example.com

  2. Location ヘッダの遷移を追う

    1. curl -IL https://example.com

  3. LB配下か直アクセスかを切り分け

    • LB経由/Web直で挙動が違うか

  4. Webサーバ設定の該当箇所を確認

    • Apache: RewriteRule / Redirect

    • Nginx: return 301 / rewrite

  5. プロトコル判定の条件確認

    • 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を一意に決め、入口で一回」 が鉄則。

遷移を可視化 → 条件を絞る → 一箇所に集約。
この型を守れば、
リダイレクトループは確実に防げる。

いいなと思ったら応援しよう!