hello foo bar Saba note | X-Forwarded-For IPアドレスの透過

X-Forwarded-For IPアドレスの透過

2017.1.11 (水)

X-Forwarded-ForとかX-Cluster-Client-Ip

LB(ロードバランサー)がかませてあるネットワーク設定ではアクセス元のグローバルIPが変換されてしまってログなんかに記述されるIPアドレスがLBのローカルIPアドレスになってしまうことがあります。
そういう場合にはX-Forwarded-ForとかX-Cluster-Client-Ipなどの特殊な変数でアクセス元のもともとのIPアドレスを取得できることがあります。

ロードバランサー越しにIPアドレスを取る(X-Cluster-Client-Ipの場合)

ロードバランサーの性能というか設定によりけりだと思いますが、X-Cluster-Client-IpでIP取れました。設定するIPアドレスのドットをエスケープするところがミソかなと思います。
httpd.confに以下を追加します。

<Directory "/var/www/html/">
SetEnvIf X-Cluster-Client-Ip "123\.456\.789\.123" allowip
SetEnvIf X-Cluster-Client-Ip "223\.456\.789\.123" allowip
order deny,allow
deny from all
allow from env=allowip
</Directory>

ログの場合はこう。commonでも何でもよし。

LogFormat "%{X-Cluster-Client-Ip}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

X-Cluster-Client-Ipをphpで取得

Apacheでは環境変数のX-Cluster-Client-IpからNAT前のグローバルIPを取得できるのですが、PHPからはレスポンスヘッダーから取得しないとダメという話です。

<?php
$headers = getallheaders();
print $headers['X-Cluster-Client-Ip'];
//var_dump(getallheaders());

こんな感じで値を取得できます。getallheaders()で取得できる値をダンプしてみたほうがいいです。