Nginx 從 Cloudflare 獲得用戶真實 IP

前言

當你正在使用 Cloudflare 時,由於是代理的關係,因此你在自己網頁伺服器的 Log 看不到用戶的真實 IP 位址,取而代之的則是 Cloudflare 的代理 IP 位址。所以我們必須使用 Nginx 的 set_real_ip_from 來取得。

Cloudflare 將 IP 放在哪裡

事實上,Cloudflare 在每次向你的伺服器發送請求時,他都會帶上用戶真實的 IP 位址。Cloudflare 將其放在標頭,在欄位 CF-Connecting-IP 中。所以如果你使用 PHP 的話,你甚至可以直接這樣使用。

$_SERVER["HTTP_CF_CONNECTING_IP"]

對於 Nginx 設定

那如果我們是想直接讓 Nginx 讀到這個標頭呢?例如我們想讓他在 Log 中看到。

我們必須先知道 Cloudflare 的所有 IP 段,你可以點 這裡 找到他。接著則需要設定 Nginx 文件,這些文件通常放在 /etc/nginx/sites-enabled/ 裡面。

以下是一個範本:

server {
        listen 80;
        server_name www.example.com;

        # Cloudflare IPv4
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        set_real_ip_from 104.16.0.0/13;
        set_real_ip_from 104.24.0.0/14;
        set_real_ip_from 172.64.0.0/13;
        set_real_ip_from 131.0.72.0/22;

        # Cloudflare IPv6
        set_real_ip_from 2400:cb00::/32;
        set_real_ip_from 2606:4700::/32;
        set_real_ip_from 2803:f800::/32;
        set_real_ip_from 2405:b500::/32;
        set_real_ip_from 2405:8100::/32;
        set_real_ip_from 2a06:98c0::/29;
        set_real_ip_from 2c0f:f248::/32;

        # Cloudflare IP Header
        real_ip_header CF-Connecting-IP;

        location / {
                try_files $uri $uri/ =404;
        }
}

接者,你可以使用 sudo nginx -t 來確定配置是否有問題。再使用 sudo systemctl restart nginx 重啟網頁伺服器即可。

結語

操作到這邊,你就算是完成囉!接著你可以在 /var/log/nginx 底下的 access.log 看到產出的 Log 為真實的用戶 IP 位址!