phpfog でのリモート IP アドレスの取得方法

サーバ上で実行するプログラム。

<?php

$output = <<<EOL
<pre>
REMOTE_ADDR              : {$_SERVER['REMOTE_ADDR']}
HTTP_X_FORWARDED_FOR     : {$_SERVER['HTTP_X_FORWARDED_FOR']}
HTTP_CLIENT_IP           : {$_SERVER['HTTP_CLIENT_IP']}
HTTP_CLIENTADDRESS       : {$_SERVER['HTTP_CLIENTADDRESS']}
HTTP_X_REAL_IP           : {$_SERVER['HTTP_X_REAL_IP']}
HTTP_X_REAL_FORWARDED_FOR: {$_SERVER['HTTP_X_REAL_FORWARDED_FOR']}
EOL;

echo $output;

手許の PC 上で実行するテストプログラム。

<?php

$uri = 'http://___.phpfogapp.com/test.php';

// no additional headers
$page = file_get_contents($uri);
echo 'No headers:      ';
echo $page, "\n";

// send X-FORWARDED-FOR
$opt = array(
             'http'=> array(
                            'header' => 'X-FORWARDED-FOR: 88.88.88.88',
                      )
       );
$context = stream_context_create($opt);
$page = file_get_contents($uri, 0, $context);
echo 'X-FORWARDED-FOR: ';
echo $page, "\n";

// send CLIENT-IP
$opt = array(
             'http'=> array(
                            'header' => 'CLIENT-IP: 99.99.99.99',
                      )
       );
$context = stream_context_create($opt);
$page = file_get_contents($uri, 0, $context);
echo 'CLIENT-IP:       ';
echo $page, "\n";

// send X-REAL-IP
$opt = array(
             'http'=> array(
                            'header' => 'X-REAL-IP: 77.77.77.77',
                      )
       );
$context = stream_context_create($opt);
$page = file_get_contents($uri, 0, $context);
echo 'X-REAL-IP:       ';
echo $page, "\n";

テスト結果。

No headers:      <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.245.219.15

X-FORWARDED-FOR: <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 88.88.88.88, 211.1.YYY.XXX, 10.245.219.15

CLIENT-IP:       <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 88.88.88.88, 211.1.YYY.XXX, 10.245.219.15

X-REAL-IP:       <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 88.88.88.88, 211.1.YYY.XXX, 10.245.219.15

テスト結果。別のパターン。

CLIENT-IP:       <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 99.99.99.99
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.245.219.15

X-REAL-IP:       <pre>
REMOTE_ADDR              : 211.1.YYY.XXX
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 99.99.99.99
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.245.219.15

テスト結果。別のパターン。

No headers:      <pre>
REMOTE_ADDR              : 10.86.199.140
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.220.254.110

X-FORWARDED-FOR: <pre>
REMOTE_ADDR              : 10.86.199.140
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.220.254.110

CLIENT-IP:       <pre>
REMOTE_ADDR              : 10.86.199.140
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.220.254.110

X-REAL-IP:       <pre>
REMOTE_ADDR              : 10.86.199.140
HTTP_X_FORWARDED_FOR     : 211.1.YYY.XXX
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 211.1.YYY.XXX
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.220.254.110


まとめると、

REMOTE_ADDR              : グローバル IP または ローカル IP
HTTP_X_FORWARDED_FOR     : グローバル IP
HTTP_CLIENT_IP           : 偽造可能
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : グローバル IP
HTTP_X_REAL_FORWARDED_FOR: 偽造追加可能

ということで、結果が一定していないので、さらに別のパターンの結果がある可能性は否定はできませんが、リモートホストのグローバル IP アドレス(通常の REMOTE_ADDR)を phpfog で取得するには、HTTP_X_FORWARDED_FOR または HTTP_X_REAL_IP を使うのがいいみたいな感じです。

(2012/01/13 追記) HTTP_X_REAL_IP、HTTP_X_FORWARDED_FOR 共に 10 で始まる IP アドレスになることがありました。HTTP_X_REAL_FORWARDED_FOR の最初のアドレスはグローバル IP でした。しかし、この値は偽造可能ですね。困りました。

(2012/01/25 追記) HTTP_X_REAL_IP がプライベートアドレスの場合のテスト結果。

No headers:      <pre>
REMOTE_ADDR              : 10.210.206.107
HTTP_X_FORWARDED_FOR     : 10.210.206.107
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 10.210.206.107
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.210.206.107, 10.90.198.14
X-FORWARDED-FOR: <pre>
REMOTE_ADDR              : 10.210.206.107
HTTP_X_FORWARDED_FOR     : 10.210.206.107
HTTP_CLIENT_IP           : 
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 10.210.206.107
HTTP_X_REAL_FORWARDED_FOR: 88.88.88.88, 211.1.YYY.XXX, 10.210.206.107, 10.242.86.251
CLIENT-IP:       <pre>
REMOTE_ADDR              : 10.210.206.107
HTTP_X_FORWARDED_FOR     : 10.210.206.107
HTTP_CLIENT_IP           : 99.99.99.99
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 10.210.206.107
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.210.206.107, 10.90.198.14
X-REAL-IP:       <pre>
REMOTE_ADDR              : 10.210.206.107
HTTP_X_FORWARDED_FOR     : 10.210.206.107
HTTP_CLIENT_IP           : 99.99.99.99
HTTP_CLIENTADDRESS       : 
HTTP_X_REAL_IP           : 10.210.206.107
HTTP_X_REAL_FORWARDED_FOR: 211.1.YYY.XXX, 10.210.206.107, 10.90.198.14

(2012/4/21) あるロードバランサーが App サーバと通信できないとき、別のロードバランサーに転送するのが原因ではないかとの情報がありました。