ホームページ  >  記事  >  バックエンド開発  >  2 層サーバーの 2 番目の層である Nginx でユーザー IP を取得する方法

2 層サーバーの 2 番目の層である Nginx でユーザー IP を取得する方法

WBOY
WBOYオリジナル
2016-08-08 09:31:041390ブラウズ

2層サーバーの第2層であるNginxでユーザーIPを取得する方法

1.以前、nginx サーバーを構成するときに問題が発生しました。以前、サーバーはクライアントの最大同時接続を制限する機能を使用していましたが、この機能の実装はサーバー内のそのような構成に依存していました。ただし、フロントエンド層 (ロード、CDN、ファイアウォール、セキュリティ サービス) サーバーを追加すると、取得されるクライアント IP は、実際のユーザー IP アドレスではなく、フロントエンド サーバーの IP になります。

2.このような問題に直面して、nginx 公式 Web サイトの紹介を何度か読み直したところ、もう 1 つの特に重要な変数を発見しました

$remote-addr

この変数は、クライアント アクセス リクエストの X-forwarded-for フィールドの値です。リクエストにこのフィールドが含まれていない場合、この変数の自動使用は、remote-addr 変数と同等になります。これにより、通常は HTTP リクエスト内のフロントエンド サーバーによって保存されるクライアントの実際の IP アドレスのフィールド (通常は X_FORWARDED_FOR フィールドと呼ばれるもの) を取得でき、このメソッドを通じてさまざまな関数を実装できます。

3つ。以下に簡単なデモンストレーションを示します。不備が多いので修正お願いします。

まず、Nginx 環境をセットアップします。ここでは、1.7 シリーズの最新バージョン 1.7.9 を例として使用します (バージョンに関する質問については、FAQ 1 を参照してください)

ダウンロードと WGET に必要なアドレス http://nginx .org/download/nginx-1.7.9.tar.gz

1. Nginx をダウンロード

[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz

2. 解凍します

[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz

3. 直接コンパイルします (openssl などのプラグインのサポートが必要かどうかを検討する必要があります)

[lugt @localhost mysql]$cd nginx-1.7.9

[lugt@localhost nginx-1.7.9]$ ./configure

[lugt@localhost nginx-1.7.9]$ make

[lugt@localhost nginx-1.7 .9]$ su

[lugt@ localhostnginx-1.7.9]$ make install

4. 次に、nginx.conf 設定ファイルを変更します

[lugt@localhost nginx-1.7.9]$ su

[lugt@ localhost nginx-1.7.9]$cd /usr/local/nginx

[lugt@localhostnginx]$ vi conf/nginx.conf

次に、nginx.conf でこれを見つけて追加し、負荷分散を設定し、CDN を模倣します

$proxy_add_x_forwarded_for

を実行し、8080ポートに仮想サーバーをセットアップし、


upstream dnsnginx1 {
        server[*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名
}
server {
        listen       80;
        server_name 
#access_log  logs/host.access.log  main
        location /{
           proxy_pass          http://dnsnginx1;
            proxy_set_header    Host             $host;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
            proxy_redirect      default;
}
}

を保存しました。次に、設定ファイルの構文をテストします [lugt@localhostnginx]$ ./sbin/nginx –t


サーバーを起動します

[lugt@localhostnginx]$ ./sbin/nginx

IV. ab ツールを使用して効果を確認します。

[lugt@localhost nginx]$ ab –c 10 –n 100 –v 4 http://127.0.0.1/ | grep HTTP/1.1

この行の意味: AB テスト ツールを介してアドレスにアクセスします。同時接続数は 30、テスト合計 300 回、HTTP リターン ヘッダー情報を表示します

ab ツールを使用すると、同時に送信された接続の数に関係なく、正常に 200 を返した唯一の接続が測定できます。 endはnginxで制限していた最大同時接続数なので、IP制限機能が利用可能であることがわかります。参考データについては、FAQ2を参照してください

FAQ 1 バージョンの問題

現在使用しているNginxのバージョンがバージョン1.7.1に達していない場合は、nginxがこの機能をサポートしていない可能性があります

この時点で、を挿入する必要があります。リクエストから x_forwarded_for の値を取得します。

バージョン1.6.1を例にすると、次のようにコードが追加されます。 src/http/modules/ngx_http_limit_conn.c 184行目

limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m;  # 并发设置 空间10M
server {
        listen       8080;
        server_name  [*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名
        limit_conn addr 1; #限制客户端最大并发连接数为 1
            location / {
            root   html;
            index  index.html index.htm;
        }
}

100-v 4 http://127.0.0.1/ | grep HTTP/1.1


HTTP/1.15 03 サービスは一時的に利用できません

HTTP/1.1503 サービスは一時的に利用できません利用できません

HTTP/1.1 503サービスは一時的に利用できません

HTTP/1.1503サービスは一時的に利用できません

HTTP/1.1503サービスは一時的に利用できません

HTTP/1.1503サービスは一時的に利用できません

HTTP/1.1503サービス一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1 200 OK

HTTP/ 1.1503 サービスは一時的に利用できません

HTTP/1.1503 サービスは一時的に利用できません

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

<… repeated 往下均为重复8次HTTP/503 与1次HTTP/200 交替出现>

English Version

How to retrievethe true ip of the client user if there are two layers of servers

Days before, wehave been faced such a difficulty which is we can’t use the variable $remote_addr for gathering the clients’ip address. This problem surfaces when we used a proxy server between the trueserver and client, which is actually a cdn. And that makes our functions oflimiting the maximum connections a client can make to a server at a time. Thissituation can also found if the load balance or any anti-spam service are inuse. So that’s why we can’t use remote_addr variable further.

After I did someresearch on the documentation and the code , I found out that this problem canbe solved by replacing the  

 $remote_addr 

 variable with the  
$proxy_add_x_forwarded_for
  variable. As this variable allows to retrievethe data from the column X_forwarded_for from the request, we can use thisvariable functioning in many ways.

And now I shall makean easy example to practically use this method.

First of all,build up a Nginx server.

Here, I will usethe 1.7.9 version (latest to the written time) for instance, therefore, thereexist some differences between older versions than 1.7.1 (see FAQ 1)

1.      Download A Nginx Copy:

[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz

2.      Decompress the file

[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz

3.      Compile The Code

[lugt@localhostmysql]$ cd nginx-1.7.9

[lugt@localhostnginx-1.7.9]$ ./configure

[lugt@localhostnginx-1.7.9]$ make

[lugt@localhostnginx-1.7.9]$ su

[lugt@localhostnginx-1.7.9]$ make install

4.      And edit the config file nginx.conf

[lugt@localhost nginx-1.7.9]$ su

[lugt@localhostnginx-1.7.9]$ cd /usr/local/nginx

[lugt@localhostnginx]$ vi conf/nginx.conf

There add suchdirectives to the server1 for emulate for an CDN server

upstream dnsnginx1 {
        server[*.*.*.*/yourhostname]:8080 weight=1000; #fill in your ip/hostname
}
server {
        listen       80;
        server_name  [hostname]   #fill your ip/ hostname here
#access_log  logs/host.access.log  main
        location /{
           proxy_pass          http://dnsnginx1;
            proxy_set_header    Host             $host;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
            proxy_redirect      default;
}
}
 
 

After the end ofone server directive, and in the http directive, add so to function the sever2

limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m;  # sample setting
server {
        listen       8080;
        server_name  [*.*.*.*/hostname]:8080 weight=10000; #fill in ip/hostname here
        limit_conn addr 1; # Enablethe limitation of connection per ip at a time to 1.
 
            location / {
            root   html;
            index  index.html index.htm;
        }
}

And then you cansave , test the config file and run nginx

Test your configfile:

    [lugt@localhostnginx]$  ./sbin/nginx –t

Start the nginx server

    [lugt@localhostnginx]$  ./sbin/nginx

Now, the serverhas been set and you can run a test at instance.

/* This CommandMeans to run a tool to connect to server as 10conn/once and 10 conns in total*/

[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1

FAQ 1

There is actuallysome little malfunctions when using elder versions than 1.7.1 (Probably the newversion has it for a new feature).So to use this directive in earlier versions,some code need to be added.

As a Example inthe version 1.6.1

In filesrc/http/modules/ngx_http_limit_conn.c Line around 184

hash =ngx_crc32_short(key.data, key.len);                                                                             
If("" == &ctx->key){                                                             
    If(NULL!= r->main->headers_in->x_forwarded_for->elts){                       
           key.data= *(char*)r->main->headers_in->x_forwarded_for->elts;             
         key.len = 4;                                                                                                                               
hash =ngx_crc32_short(key.data, key.len);                                                                     
    }
}<span style="font-family: Arial, Helvetica, sans-serif;">           </span>

                                                                                                                                                    

FAQ 2 TestingResults

[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1

 

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスは一時的に利用できません

HTTP /1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1503 サービスが一時的に利用できません

HTTP/1.1 200 OK

<… HTTP/503 を 8 回、HTTP/200 を 1 回繰り返します&gた;

上記は、2 層サーバーの 2 層目の Nginx でユーザー IP を取得する方法を、関連する内容も含めて紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:php DOM解析次の記事:php DOM解析