PHPで接続元のIPアドレスを取得する方法と注意点

※当サイトではアフィリエイト広告を利用しています

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-ForX-Real-IPHTTPヘッダーなので偽装可能です。たとえば、悪意あるユーザーが 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を取得可能(注意が必要)
信頼性確保にはプロキシ制御が必須偽装対策として重要

プロジェクトやインフラ構成に応じて、どの方法を採用すべきか判断し、安全性と正確性のバランスを保つことが重要です。

コメント