nginxでX-Forwarded-Forを扱う際、多くの現場で見落とされているのが
real_ip_recursive の正しい理解
です。
「とりあえずonにする」「サンプル通り設定する」
この状態で本番運用すると、
IP制限が突破される重大事故
が起きます。
本記事では、
- real_ip_recursiveの本当の動作
- offとonの違い
- 実際に起きる事故パターン
- 安全な設計方法
- 正しく動作しているかの確認方法
を、構成例付きで解説します。
まず結論:recursiveは「辿り方」を変えるだけ
real_ip_recursive は、
X-Forwarded-Forをどこまで辿るか
を決める設定です。
IPを書き換えるかどうかを決めるのは
set_real_ip_from
です。
動作の正しい理解
前提:X-Forwarded-Forの形式
X-Forwarded-For: client, proxy1, proxy2
左が最初のクライアントIP、右に行くほど後段プロキシです。
① real_ip_recursive off(デフォルト)
XFFの最後のIPを採用します。
つまり:
- LBがXFFを上書きしている単段構成では問題になりにくい
- 多段構成では「意図したIP」にならない場合がある
② real_ip_recursive on
set_real_ip_from で信頼したIPを右から辿り、
最初に現れた“非信頼IP”を採用します。
これが重要です。
事故が起きる典型パターン
事故① set_real_ip_fromが広すぎる
set_real_ip_from 0.0.0.0/0;
real_ip_recursive on;
この場合、
全IPを信頼して辿るため、最左のIPを無条件採用
→ クライアントが自由に偽装可能
事故② CDN + LB + nginx構成で信頼境界が曖昧
例:
client → CDN → LB → nginx
CDNのIPレンジを指定せず、LBだけを信頼した場合、
recursive on でもCDN側のIPで止まる可能性があります。
逆にCDN全体を広く信頼すると、
CDN経由の偽装が可能になります。
事故③ LBを経由しない直アクセスが可能
real_ip_recursive が正しくても、
直アクセスが可能ならXFFを自由に書けます。
FWでLB経由のみ許可しない限り安全ではありません。
安全な設計原則
① 信頼IPは最小限にする
set_real_ip_from 10.0.0.10; # LBのみ
レンジ指定は本当に必要な範囲だけ。
② 必ずdirect accessを遮断する
- nginxはLBからのみ許可
- セキュリティグループで制御
③ recursiveは多段構成でのみ使う
単段LBなら必須ではありません。
構成に応じて使い分けるのが正解です。
正しく動作しているかの確認方法
① ログで検証
log_format test '$remote_addr | $http_x_forwarded_for';
複数パターンでアクセスし、
- LB経由
- 直アクセス
- 偽装XFF付き
それぞれでremote_addrがどうなるか確認します。
② curlで偽装テスト
curl -H "X-Forwarded-For: 1.2.3.4" http://server
これでIPが変わるなら設計は破綻しています。
よくある誤解まとめ
- recursiveをonにすれば安全になる → ❌
- XFFは信頼できる → ❌
- CDN配下なら大丈夫 → ❌
安全かどうかを決めるのは
信頼境界の明確さ
です。
覚えておくべき一文
real_ip_recursiveは“便利機能”ではなく、“信頼境界設計が正しい場合のみ使える機能”。
これを理解していない設定は、
IP制限無効化リスクを抱えています。


