PHPでアクセスしてきたユーザーのIPアドレスを取得するには、基本的に $_SERVER["REMOTE_ADDR"] を使います。しかし、アクセス経路にプロキシやCDNなどが入っている場合は、この方法だけでは本来の接続元IPアドレスが取得できないことがあります。
この記事では、IPアドレスを正確に取得する方法と、それに伴う注意点を解説します。
REMOTE_ADDRの基本動作
$ip = $_SERVER["REMOTE_ADDR"];
この方法で取得できるのは、「サーバーに直接接続してきたクライアントのIPアドレス」です。通常の環境であれば、これがユーザーのIPになります。
しかし、リバースプロキシ(例:NginxやCloudflare)やロードバランサを挟んでいる場合、REMOTE_ADDR はプロキシのIPになってしまいます。
クライアントのIPを取得する方法(X-Forwarded-For など)
多くのプロキシは、HTTPヘッダーに元の接続元IPを埋め込んでくれます。代表的なヘッダーは以下のとおりです。
| ヘッダー名 | 内容 |
|---|---|
X-Forwarded-For | 経由したIPアドレスのリスト(カンマ区切り) |
X-Real-IP | 最初の接続元IPのみ |
Forwarded | 標準化された新しい形式(RFC 7239) |
最もよく使われているのは X-Forwarded-For です。
実装例:信頼できるプロキシを前提としたIP取得
function getClientIP() {
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// 複数ある場合、最初のIPがクライアントIP
$ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
return trim($ipList[0]);
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
このコードは、X-Forwarded-For を優先的に使用し、なければ REMOTE_ADDR を使う構成です。
セキュリティ上の注意点
X-Forwarded-For や X-Real-IP はHTTPヘッダーなので偽装可能です。たとえば、悪意あるユーザーが curl で以下のように送信すれば簡単に偽装できます:
bashコピーする編集するcurl -H "X-Forwarded-For: 1.2.3.4" https://example.com/
したがって、以下のような対策が重要です:
- 信頼できるプロキシ(自社のNginx、CDNなど)からのヘッダーだけを使う
- プロキシがある前提で、
REMOTE_ADDRがプロキシIPのときのみX-Forwarded-Forを採用する
Nginx側の設定例(プロキシとして動作させる場合)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
このように正しく設定されたリバースプロキシを使えば、PHP側で X-Forwarded-For を信頼できるようになります。
まとめ
| 方法 | 説明 |
|---|---|
$_SERVER["REMOTE_ADDR"] | 最もシンプルだが、プロキシがあると不正確 |
X-Forwarded-For | 本来のクライアントIPを取得可能(注意が必要) |
| 信頼性確保にはプロキシ制御が必須 | 偽装対策として重要 |
プロジェクトやインフラ構成に応じて、どの方法を採用すべきか判断し、安全性と正確性のバランスを保つことが重要です。

コメント