2013-02-27 14 views
16

ELBの後ろにあるEC2にはPHPサーバーがいくつかあります。私たちは、サーバーに接続するクライアントのIPアドレスでロケール/地域を決定したいと考えています。問題は、PHPサーバだけがELBのIPアドレスを参照することです。私たちはELBを通過したクライアントのIPアドレスを見たいと思います。Amazon ELBの背後にあるクライアントのIPアドレスを確認

答えて

20

をX-転送さ-のリクエストヘッダはあなたが識別するのに役立ちますクライアントのIPアドレス。ロードバランサはクライアントとサーバー間のトラフィックをインターセプトするため、サーバーアクセスログにはロードバランサのIPアドレスのみが含まれます。クライアントのIPアドレスを確認するには、X-Forwarded-Forリクエストヘッダーを使用します。

次のPHPコード(Apacheを仮定)を使用してアクセスすることができます

$http_headers = apache_request_headers(); 
$original_ip = $http_headers["X-Forwarded-For"]; 
+4

セキュリティを気にする人は、ELB以外のWebサーバーとの接続を禁止する必要があります。さもなければ、攻撃者はELBのふりをして、このヘッダーを設定し、真のリモートIPアドレスについてあなたに嘘をつきます。 http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-elb-security-groups.html –

+2

X-Forwarded-Forヘッダには、コンマで区切られたIPアドレスのリストが含まれている場合があります複数のフォワーダ。最初のものは元のクライアントIPです。 http://en.wikipedia.org/wiki/X-Forwarded-For#Format – mmindenhall

+4

クライアントが独自のX-Forwarded-Forを提供した場合、コンマで区切られたIPリストの最初のものになります応用。実際のIPは、明らかに最後の項目です。 –

-2

クライアントにIPアドレスを明示的に報告することはできますか? これをチェックするpostAWS docsによると、ELBは「X-転送さ-について」元のクライアントのIPアドレスを保持するHTTPヘッダー設定する必要があります

+0

場合によっては、クライアントがメール内のリンクをクリックしている可能性があります。最初にサーバーにヒットしたとき、その地域に基づいて表示するコンテンツを決定する必要があります。 – BillR

2

これは大きな問題であるので、この試してください:あなたは、Apacheを使用する場合はD

<?php 
     if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) { 
      $real_client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
     } else { 
      $real_client_ip = $_SERVER["REMOTE_ADDR"]; 
     } 
+0

これは、クライアントがX-Forwarded-For(クライアントがロードバランサであるため)を提供することを信頼することを前提としています。このコードは、REMOTE_ADDRを受け入れ可能なIPのホワイトリストと照らし合わせるか、コードを脆弱性まで開くべきです。 – ZiggyTheHamster

8

を、 mod_remoteipモジュールをご覧ください。これはApache 2.4以降に含まれていますが、2.2のバックポートもあります。

このモジュールは、RemoteIPHeaderディレクティブで設定された要求ヘッダーで報告されたユーザーエージェントIPアドレスとの接続のクライアントIPアドレスを上書きします。

指示に従って置き換えられると、このオーバーライドされたユーザエージェントIPアドレスは、mod_authz_hostに必要なIP機能に使用され、mod_statusによって報告され、mod_log_config%aとcore%aフォーマット文字列によって記録されます。接続の基になるクライアントIPは、%{c}形式の文字列で利用できます。

つまり、使用するヘッダー(X-Forwarded-Forなど)と、どのIPが信頼できるもの(ロードバランサなど)にするかを設定できます。信頼できるIPはヘッダーから削除され、信頼されていない最初のIPが元のクライアントとして使用されます。このIPは、ログのような他のモジュールのApacheで内部的に使用されます。

これは、mod_remoteipがスタック全体を処理するので、PHPでXFFヘッダーを処理するよりも便利です。あなたのアクセスログが正しいかどうか確認してください。

注:このモジュールの前身であるmod_rpafモジュールもあります。はるかに限定されている。たとえば、信頼できるIP範囲を処理することはできません。事前にELBのIPを知らないので、これが必要です。また、Apacheの前にELB before Varnishなどの複数のホップを処理することもできません。私はrpafモジュールをスキップし、代わりにremoteipを使用することをお勧めします。

0
AWS ELBの背後にあるPHPアプリ用

最適なソリューション:

if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    $commaPos = strrchr($_SERVER['HTTP_X_FORWARDED_FOR'], ','); 
    if ($commaPos === FALSE) $remote_addr = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    else $remote_addr = trim(substr($_SERVER['HTTP_X_FORWARDED_FOR'], $commaPos + 1)); 
} else { 
    $remote_addr = $_SERVER['REMOTE_ADDR']; 
} 

注:X-Forwarded-For最後に、プロキシのコンマスペースで区切ったリストを指定できますリスト内のはAWSのELBに接続しているものであるため、偽装されていないと信頼できる唯一のものです。

関連する問題