x-forward-for科学普及


問題の背景:
実際のアプリケーションでは、リモートログインの判断やipアクセス回数の統計など、ユーザのipアドレスを取得する必要がある場合があり、通常requestを使用する.getRemoteAddr()はクライアントipを取得できるが、逆エージェントとしてnginxを使用するとrequestを使用する.getRemoteAddr()はnginxサーバのipのアドレスを取得していますが、この場合どうすればいいですか? 
part 1:ソリューション
私が資料を調べたとき、「実戦nginx」という本がありました.著者の張晏さんは、この本に「逆エージェントを経て、クライアントとwebサーバの間に中間層が増えたため、webサーバはクライアントのipを直接手に入れることができず、$remote_addr変数を通じて手に入れたのは逆エージェントサーバのipアドレスです」という言葉がありました.nginx逆サーバを使用すると、web側でrequestを使用します.getRemoteAddr()(本質的には$remote_addrを取得する)、取得したのはnginxのアドレス、すなわち$remote_addr変数にカプセル化されたのはnginxのアドレスであり、もちろんユーザの真のipを得ることはできないが、nginxはユーザの真のipを得ることができる、すなわちnginxが$remote_addr変数を使用する際に得られるのはユーザの真のipであり、ウェブ側でユーザの真のipを得るためには、nginxでは、次のように値を割り当てる必要があります.
proxy_set_header            X-real-ip $remote_addr;
このうち、このX-real-ipはカスタム変数名で、名前は自由に取ることができ、このようにして完成した後、ユーザーの実際のipはX-real-ipという変数の中に置かれ、その後、web端でこのように取得することができます.
request.getAttribute("X-real-ip")
これで分かりますよね.
part 2:原理紹介
ここではnginxの関連変数を説明します.通常、このような構成が見られます.
server {
        listen       88;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass                  http://backend; 
            proxy_redirect              off;
            proxy_set_header            Host $host;
            proxy_set_header            X-real-ip $remote_addr;
            proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
}

1本ずつ見てみましょう
 proxy_set_header    X-real-ip $remote_addr;

この言葉は前に説明したように,この文があればwebサーバ側でユーザの実際のipを得ることができる.しかし、実際にユーザーの実際のipを得るには、この方法しかないわけではありません.次に見てみましょう. 
 proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

まず、ここにX-Forwarded-For変数があります.これはsquidが開発したもので、HTTPエージェントまたはロードバランサの元のIPを介してWebサーバに接続されたクライアントアドレスを識別するための非rfc規格です.X-Forwardd-Forの設定をすると、proxy転送のたびに記録されます.フォーマットはclient 1、proxy 1、proxy 2で、各アドレスをカンマで区切っています.彼はrfc標準ではないため、デフォルトはありません.強制的に追加する必要があります.デフォルトではproxy転送されたリクエストは、バックエンドではリモートアドレスがproxy端のipであるように見えます.つまりデフォルトではrequestを使用します.getAttribute(「X-Forwarded-For」)はユーザーのipを取得できません.この変数でユーザーのipを取得するには、nginxに次の構成を追加する必要があります.
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

$proxyを1つ追加するという意味ですadd_x_forwarded_forはX-Forwarded-Forに行って、カバーではなく増加することに注意して、もちろんデフォルトのX-Forwarded-For値は空なので、私たちはいつもX-Forwarded-Forの値が$proxy_に等しいと感じます.add_x_forwarded_forの値は、実際にnginxを2台異なるipに構築し、この構成を使用すると、webサーバ側でrequestを通過することがわかります.getAttribute(「X-Forwarded-For」)は、クライアントipと最初のnginxのipを取得します. 
では$proxy_add_x_forwarded_forは何ですか?
$proxy_add_x_forwarded_for変数には、クライアント要求ヘッダの「X-Forwarded-For」と$remote_が含まれます.addrの2つの部分は、カンマで区切られています.
例えば、2つのnginx転送、すなわちユーザが2つのnginxを介してウェブにアクセスするウェブアプリケーションがある.
最初のnginxでは、
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

現在の$proxy_add_x_forwarded_for変数の「X-Forwarded-For」部分は空なので$remote_addr、$remote_addrの値はユーザのipであるため,付与後,X−Forwarded−For変数の値がユーザの真のipアドレスとなる. 
2台目のnginxに着いたら、
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;

現在の$proxy_add_x_forwarded_for変数、X-Forwarded-For部分には、ユーザーの実際のip,$remote_が含まれています.addr部分の値は前のnginxのipアドレスであるため、この付与によって現在のX-Forwarded-Forの値が「ユーザの真実ip、最初のnginxのip」になることが明らかになったでしょう.最後に$http_x_forwarded_for変数、この変数はX-Forwarded-Forであり、デフォルトのこのX-Forwarded-Forは空であるため、proxy_を直接使用するとset_header            X-Forwarded-For $http_x_forwarded_forの場合、webサーバ側がrequestを使用していることがわかります.getAttribute(「X-Forwarded-For」)で得られた値はnullです.リクエストを通過したい場合は.getAttribute(「X-Forwarded-For」)ユーザーipを取得するにはproxy_を先に使用する必要がありますset_header            X-Forwarded-For $proxy_add_x_forwarded_for;これにより,ユーザの実際のipを得ることができる. 
テキストリンク:https://blog.csdn.net/kai_ding/article/details/39575255