天天看點

nginx擷取真實ip

執行個體環境:

使用者IP 120.22.11.11

CDN前端 61.22.22.22

CDN中轉 121.207.33.33

公司NGINX前端代理 192.168.50.121(外網121.207.231.22)

1、使用CDN自定義IP頭來擷取

假如說你的CDN廠商使用nginx,那麼在nginx上将$remote_addr指派給你指定的頭,方法如下:

1

proxy_set_header remote-user-ip $remote_addr;

2

3

4

<?php

    $ip = getenv("HTTP_REMOTE_USER_IP");

    echo $ip;    

?>

通路getRemoteUserIP.php,結果如下:

120.22.11.11 //取到了真實的使用者IP,如果CDN能給定義這個頭的話,那這個方法最佳

2、通過HTTP_X_FORWARDED_FOR擷取IP位址

一般情況下CDN伺服器都會傳送HTTP_X_FORWARDED_FOR頭,這是一個ip串,後端的真實伺服器擷取HTTP_X_FORWARDED_FOR頭,截取字元串第一個不為unkown的IP作為使用者真實IP位址, 例如:

120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121(使用者IP,CDN前端IP,CDN中轉,公司NGINX代理)

getFor.php

    $ip = getenv("HTTP_X_FORWARDED_FOR");

    echo $ip;

通路getFor.php結果如下:

120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121

如果你是php程式員,你擷取第一個不為unknow的ip位址,這邊就是120.22.11.11.

3.使用nginx自帶子產品realip擷取使用者IP位址

安裝nginx之時加上realip子產品,我的參數如下:

    ./configure --prefix=/usr/local/nginx-1.4.1 --with-http_realip_module

真實伺服器nginx配置

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

    server {

        listen       80;

        server_name  www.ttlsa.com;

        access_log  /data/logs/nginx/www.ttlsa.com.access.log  main;

        index index.php index.html index.html;

        root /data/site/www.ttlsa.com;

        location /

        {

                root /data/site/www.ttlsa.com;

        }

        location = /getRealip.php

                set_real_ip_from  192.168.50.0/24;

                set_real_ip_from  61.22.22.22;

                set_real_ip_from  121.207.33.33;

                set_real_ip_from 127.0.0.1;

                real_ip_header    X-Forwarded-For;

                real_ip_recursive on;

                fastcgi_pass  unix:/var/run/phpfpm.sock;

                fastcgi_index index.php;

                include fastcgi.conf;

    }

getRealip.php内容

    <?php

        $ip =  $_SERVER['REMOTE_ADDR'];

        echo $ip;    

    ?>

通路www.ttlsa.com/getRealip.php,傳回:

    120.22.11.11

如果注釋 real_ip_recursive on或者 real_ip_recursive off

121.207.33.33

很不幸,擷取到了中繼的IP,real_ip_recursive的效果看明白了吧.

set_real_ip_from:真實伺服器上一級代理的IP位址或者IP段,可以寫多行

real_ip_header:從哪個header頭檢索出要的IP位址

real_ip_recursive:遞歸排除IP位址,ip串從右到左開始排除set_real_ip_from裡面出現的IP,如果出現了未出現這些ip段的IP,那麼這個IP将被認為是使用者的IP。例如我這邊的例子,真實伺服器擷取到的IP位址串如下:

在real_ip_recursive on的情況下

61.22.22.22,121.207.33.33,192.168.50.121都出現在set_real_ip_from中,僅僅120.22.11.11沒出現,那麼他就被認為是使用者的ip位址,并且指派到remote_addr變量

在real_ip_recursive off或者不設定的情況下

192.168.50.121出現在set_real_ip_from中,排除掉,接下來的ip位址便認為是使用者的ip位址

如果僅僅如下配置:

    set_real_ip_from   192.168.50.0/24;

    set_real_ip_from 127.0.0.1;

    real_ip_header    X-Forwarded-For;

    real_ip_recursive on;

通路結果如下:

   121.207.33.33

4、三種在CDN環境下擷取使用者IP方法總結

4.1 CDN自定義header頭

優點:擷取到最真實的使用者IP位址,使用者絕對不可能僞裝IP

缺點:需要CDN廠商提供

4.2 擷取forwarded-for頭

優點:可以擷取到使用者的IP位址

缺點:程式需要改動,以及使用者IP有可能是僞裝的

4.3 使用realip擷取

優點:程式不需要改動,直接使用remote_addr即可擷取IP位址

缺點:ip位址有可能被僞裝,而且需要知道所有CDN節點的ip位址或者ip段

轉載:http://www.ttlsa.com/nginx/nginx-get-user-real-ip/

本文轉自  亮公子  51CTO部落格,原文連結:http://blog.51cto.com/iyull/1864375

繼續閱讀