ロードバランサ(LB)やプロキシ配下でnginxを使う場合、
real_ip_header / set_real_ip_from の設計を誤ると、IP制限が簡単に突破されます。
にもかかわらず、
- とりあえずX-Forwarded-Forを使う
- サンプル設定をそのまま流用する
といった導入が非常に多いのが実情です。
本記事では、
- この2つのディレクティブが何をしているのか
- なぜ設計を誤ると危険なのか
- 安全な設定例と判断基準
- 正しく動いていることの確認方法
を、実務レベルで解説します。
目次
まず結論:信頼境界を明確にしない設定は危険
real_ip_header / set_real_ip_from は、
「どのIPから来たX-Forwarded-Forを信頼するか」
を定義する仕組みです。
ここが曖昧だと、
誰でも送信元IPを偽装できる状態になります。
それぞれの役割
① real_ip_header
どのHTTPヘッダを「本当のクライアントIP」として扱うかを指定します。
real_ip_header X-Forwarded-For;
つまり、
「XFFの値でremote_addrを書き換える」
という意味です。
② set_real_ip_from
そのヘッダを
「信頼してよい送信元IP」
を指定します。
set_real_ip_from 10.0.0.0/24;
ここに書かれていないIPから来たXFFは無視されます。
最も危険な誤設定
❌ 例1:set_real_ip_from を書いていない
この状態でreal_ip_headerを有効にすると、
全てのXFFを信頼する状態になります。
つまり、
curl -H "X-Forwarded-For: 127.0.0.1" http://example.com
でIP偽装が可能になります。
❌ 例2:0.0.0.0/0 を指定
set_real_ip_from 0.0.0.0/0;
これは「全世界を信頼する」という意味です。
実質的にセキュリティ無効化です。
安全な設計の基本原則
- 信頼できるLB / ProxyのIPだけを書く
- 直接アクセス経路を遮断する
- 上書き動作を理解する
安全な設定例(LB配下構成)
set_real_ip_from 10.0.0.10; # LBのIP
real_ip_header X-Forwarded-For;
real_ip_recursive on;
ポイント解説
- LBのIPのみ信頼
- direct accessはFWで遮断
- real_ip_recursive on で多段プロキシ対応
real_ip_recursive の意味
XFFが複数IPを持つ場合、
X-Forwarded-For: client, proxy1, proxy2
recursiveがoffだと、
最後のIPだけを見る
可能性があります。
onにすると、
信頼できるIPを辿り、最初の非信頼IPを採用
します。
正しく設定できているかの確認方法
① remote_addr の確認
log_format test '$remote_addr - $http_x_forwarded_for';
ログで、
- remote_addr が期待IPになっているか
- XFFと整合性が取れているか
を確認します。
② 直接アクセス時の挙動
LBを経由せずアクセスし、
XFFが無視されることを確認
します。
設計判断まとめ
- real_ip_header は「IP書き換えスイッチ」
- set_real_ip_from は「信頼境界」
- 境界を曖昧にするとIP偽装可能
この2つは便利ですが、
“どの経路を信頼するか”を明確に定義できる場合のみ使うべき
です。
まとめ(覚えておくべき一文)
set_real_ip_from は「信頼する装置だけ」を書く。広く書かない。
この原則を守れば、
X-Forwarded-Forは安全に扱えます。
あわせて読みたい


X-Forwarded-Forを信頼してはいけないケース(誤判定・事故を防ぐ判断基準)
ロードバランサ(LB)配下のHTTP/HTTPS構成で、 「クライアントIPはX-Forwarded-Forを見ればいい」 と説明されることは非常に多いです。 しかし実務では、 IP制限がすり…
あわせて読みたい


ロードバランサ配下で戻り通信が消える典型パターンと切り分け方法
ロードバランサ(LB)配下のシステムで、次のような現象に遭遇したことはないでしょうか。 クライアントからの通信はLBに届いている バックエンドサーバにも到達してい…
