42

わかりました。小さな認証の問題があります。私の Web サービスでは、ユーザー名とパスワードを使用して HTTP 経由で API に接続できますが、この接続は特定の IP アドレスに制限することもできます。

これは、$_SERVER['REMOTE_ADDR']が正しくない可能性があることを意味します。私は、IP 情報が真に信頼できるものではないことをすでに知っています。私は、別のセキュリティ層を追加しようとしているだけです。

これが私の Web サーバーへのリクエストの一般的な概要である場合:

clientSERVER => clientPROXY => myPROXY => mySERVER

次に、これは、mySERVERREMOTE_ADDRがクライアントの代わりに myPROXY を表示し、クライアントの実際の IP を として送信することを意味しますHTTP_X_FORWARDED_FOR

これを克服するために、私の Web サービスには「信頼できるプロキシ」IP アドレスのリストがありREMOTE_ADDR、これらの信頼できる IP アドレスの 1 つからのものである場合、実際の IP アドレスが の値であることを Web サービスに伝えますHTTP_X_FORWARDED_FOR

問題は clientPROXY にあります。これは、(非常に頻繁に) mySERVER がHTTP_X_FORWARDED_FOR複数の IP アドレスを持つ値を取得することを意味します。ドキュメントによるとHTTP_X_FORWARDED_FOR、値は IP アドレスのコンマ区切りリストであり、最初の IP は実際の真のクライアントの IP アドレスであり、他のすべての IP アドレスはプロキシの IP アドレスです。

したがって、HTTP_X_FORWARDED_FOR複数の値があり、サービスが IP 制限されている場合、許可された IP リストに対して の「最後の」値をチェックしHTTP_X_FORWARDED_FOR、実際のクライアント IP を無視する必要がありますか?

許可された IP アドレスのリストを設定する必要があるシステムでは、ホワイトリストに登録された IP アドレスは、プロキシの背後にある IP ではなく、プロキシの IP アドレスである必要があると想定しています (ローカルホストの IP であり、頻繁に変更される可能性があるため)。 .

そして何のHTTP_CLIENT_IP

4

7 に答える 7

35

この関数を使用して、適切なクライアント IP を取得できます。

public function getClientIP(){       
     if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)){
            return  $_SERVER["HTTP_X_FORWARDED_FOR"];  
     }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) { 
            return $_SERVER["REMOTE_ADDR"]; 
     }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
            return $_SERVER["HTTP_CLIENT_IP"]; 
     } 

     return '';
}
于 2014-05-13T05:56:59.150 に答える
24

Hrishikesh の回答が気に入っています。追加するのはこれだけです...途中で複数のプロキシが使用されたときにコンマ区切りの文字列が表示されるので、爆発を追加して最終値を取得する必要があることがわかりました。これ:

$IParray=array_values(array_filter(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])));
return reset($IParray);

array_filter は、空のエントリを削除するためにそこにあります。

于 2014-06-17T23:45:42.993 に答える
0

データベースで使用する場合、これは良い方法です。

データベースの ip フィールドを varchar(250) に設定し、これを使用します。

$theip = $_SERVER["REMOTE_ADDR"];

if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
    $theip .= '('.$_SERVER["HTTP_X_FORWARDED_FOR"].')';
}

if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
    $theip .= '('.$_SERVER["HTTP_CLIENT_IP"].')';
}

$realip = substr($theip, 0, 250);

次に、データベースの ip フィールドに対して $realip をチェックするだけです

于 2014-08-07T23:24:43.107 に答える
-4

HTTP_CLIENT_IP は、ユーザーの IP アドレスを取得する最も信頼できる方法です。次は HTTP_X_FORWARDED_FOR で、REMOTE_ADDR が続きます。isset($_SERVER['HTTP_CLIENT_IP'])最初に設定されたもの (変数が設定されている場合は true を返す) が正しいと仮定して、3 つすべてをこの順序で確認します。さまざまな方法を使用して、ユーザーがプロキシを使用しているかどうかを個別に確認できます。これをチェックしてください。

于 2013-06-17T02:55:32.083 に答える