要約:クイック修正
ログがプロキシのIPで埋め尽くされている場合は、ngx_http_realip_moduleが必要です。通常はhttpまたはserverブロック内に以下の行を追加して、どのソースを信頼するかをNginxに伝えます。
# CloudflareのIP範囲を信頼する
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
# ... 必要に応じて他の範囲を追加 ...
# 実際のIPが含まれているヘッダーを定義
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
sudo nginx -s reloadを実行して変更を適用します。
なぜこの現象が起きるのか?
NginxをCloudflareやAWS Load Balancerのようなサービスの背後に配置すると、直接のTCP接続はプロキシのIPから行われます。デフォルトでは、Nginxはこの直近の接続元をクライアントとして記録します。その結果、実際にサイトを閲覧している人物ではなく、172.x.x.xや10.x.x.xのアドレスがログに表示されることになります。
通常、プロキシは元のIPを特別なHTTPヘッダーに含めて渡します。一般的なものにはX-Forwarded-ForやCF-Connecting-IPがあります。あなたの役割は、プロキシのIPを無視し、代わりにそのヘッダーの値を使用するようNginxに設定することです。
ステップバイステップの設定方法
1. モジュールのサポートを確認する
ほとんどのモダンなNginxビルドには、最初からreal_ipモジュールが含まれています。以下のコマンドを実行して確認できます。
nginx -V 2>&1 | grep --color 'with-http_realip_module'
出力に--with-http_realip_moduleがハイライトされていれば、準備完了です。そうでない場合は、nginx-extrasパッケージをインストールするか、ソースから再コンパイルする必要があります。
2. 信頼できるプロキシをホワイトリストに登録する
ここではセキュリティが重要です。実際に管理または使用しているソースからのIPヘッダーのみを信頼するようにしてください。ホワイトリスト化することで、悪意のあるユーザーが偽のヘッダーを送信して身元を隠す「IPスプーフィング(なりすまし)」を防ぐことができます。
シナリオA:Cloudflareを利用している場合
Cloudflareは特定のIP範囲を使用しています。管理しやすくするために、/etc/nginx/conf.d/cloudflare.confに専用の設定ファイルを作成します。
# Cloudflare IPv4範囲(例として一部を抜粋)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
# Cloudflare IPv6範囲
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
# Cloudflareは常にこのヘッダーで実際のIPを送信します
real_ip_header CF-Connecting-IP;
シナリオB:AWS ALBやHAProxyの背後にいる場合
内部ロードバランサーを使用している場合は、VPC CIDR(例:172.31.0.0/16)またはバランサーの特定のプライベートIPを使用します。
set_real_ip_from 172.31.0.0/16; # AWS VPC範囲の例
set_real_ip_from 10.0.0.0/8; # 内部ネットワーク
real_ip_header X-Forwarded-For;
real_ip_recursive on;
**プロのヒント:**CloudflareがAWS ALBにリクエストを送り、それがさらにNginxに送られるような多層構造の場合は、常にreal_ip_recursive on;を使用してください。これにより、Nginxはヘッダー内のIPリスト全体を確認し、信頼できるリストに含まれていない最後のIP(=本来のクライアントIP)を選択するようになります。
3. ログフォーマットの調整
real_ipが有効になると、標準の$remote_addr変数は自動的に更新されます。カスタムログフォーマットを使用している場合は、それが$remote_addrを参照していることを確認してください。nginx.confでの一般的な設定は以下のようになります。
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
修正の確認方法
アクセスログを確認する
ターミナルを開き、リアルタイムでログを監視します。
tail -f /var/log/nginx/access.log
スマートフォンやVPNからウェブサイトにアクセスしてください。ローカルの10.x.x.xアドレスではなく、実際のパブリックIP(例:1.2.3.4)が表示されるはずです。
スクリプトによる方法
ウェブディレクトリに簡単なinfo.phpファイルを配置して、Nginxがアプリケーションに何を渡しているかを確認します。
<?php
echo "Real IP: " . $_SERVER['REMOTE_ADDR'];
?>
避けるべき一般的な間違い
- **全世界を信頼する:**決して`set_real_ip_from 0.0.0.0/0;`を使用しないでください。これを行うと、誰でもリクエストに`X-Forwarded-For`ヘッダーを追加するだけでIPアドレスを偽装できてしまいます。
- **IPv6を忘れる:**訪問者がIPv6を使用していても、IPv4の範囲しかホワイトリストに登録していない場合、それらのユーザーのログはプロキシIPの表示に戻ってしまいます。
- **古いIPリスト:**Cloudflareは数ヶ月ごとに範囲を更新します。`https://www.cloudflare.com/ips-v4`から最新のIPを自動的に取得するスクリプトの使用を検討してください。

