web-dev-qa-db-ja.com

AmazonELBの背後にあるクライアントのIPアドレスを決定する

ELBの背後にあるEC2にいくつかのPHPサーバーがあります。サーバーに接続しているクライアントのIPアドレスによってロケール/リージョンを特定したいと思います。問題はPHPサーバーはELBのIPアドレスのみを確認します。ELBを通過したクライアントのIPアドレスを確認したいと思います。

17
Bill Rosmus

AWS docs によると、ELBは元のクライアントIPアドレスを保持する「X-Forwarded-For」HTTPヘッダーを設定する必要があります。

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

次のPHPコード(Apacheを想定)を使用してアクセスできます。

$http_headers = Apache_request_headers(); 
$original_ip = $http_headers["X-Forwarded-For"];
22
Ryan Weir

Apacheを使用している場合は、 mod_remoteip モジュールを確認してください。 Apache 2.4以降に含まれていますが、2.2のバックポートもあります。

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

指示どおりに置き換えられると、このオーバーライドされたユーザーエージェントIPアドレスはmod_authz_Host Require ip機能に使用され、mod_statusによって報告され、mod_log_config%aおよびコア%a形式の文字列によって記録されます。接続の基盤となるクライアントIPは、%{c} a形式の文字列で利用できます。

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

これにより、PHPでX-F-Fヘッダーのみを処理するよりも便利になります。これは、mod_remoteipがスタック全体を処理し、アクセスログが正しいことを確認するためです。

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

9
Martijn Heemels

これは大きな問題なので、これを試してください:D

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

一部の人にとってはmod_cloudflareの方が良いオプションのようです-特にv2.2ユーザーこの章のブログで詳細を読む: http://knowledgevoid.com/blog/2012/01/13/logging-the-correct-ip- address-using-Apache-2-2-x-and-amazons-elastic-load-balancer /

1
Steve Horvath

PHP AWS ELBの背後にあるアプリの最適なソリューション:

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 は、プロキシのコンマスペースで区切られたリストにすることができ、リスト内のlastはAWSのELBに接続したものであり、したがって、スプーフィングされていないと信頼できる唯一のものです。

0
bleater