Nginx 擔任 Web Proxy 傳遞真實 IP 的設定方式
困擾很久經過 Nginx 擔任的 Proxy 無法傳遞 Real IP 到 Web Server 的問題終於找到解法.
- 首先要確認 Nginx 編譯時是否有 –with-http_realip_module 確認方式如下
nginx -V
[root@ct-wiki ~]# nginx -V nginx version: nginx/1.14.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
如果 configure arguments: 後面有出現 –with-http_realip_module 就表示目前執行的 nginx 編譯時有納入該模組
- 官網提供給 CentOS 7 的版本預設就有納入 –with-http_realip_module
- 實際設定驗證環境:
- CloudFlare CDN → Nginx Proxy (192.168.11.234) → Nginx Web Server(192.168.11.233)
設定方式
Nginx Proxy (192.168.11.234)
- 編輯 Proxy 內轉給 www.ichiayi.com 的設定檔 www_ichiayi.conf
vi /etc/nginx/conf.d/www_ichiayi.conf
server { server_name www.ichiayi.com; access_log /var/log/nginx/www.ichiayi.com.access.log main; error_log /var/log/nginx/www.ichiayi.com.error.log; # Cloudflare IP List 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 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; 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 2c0f:f248::/32; set_real_ip_from 2a06:98c0::/29; # use any of the following two #real_ip_header CF-Connecting-IP; real_ip_header X-Forwarded-For; location / { set_real_ip_from 192.168.11.0/24; real_ip_header X-Forwarded-For; real_ip_recursive on; proxy_pass http://192.168.11.233:80; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_redirect off; proxy_buffering 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; : :
- 設定完成後看到的 log 檔就可看到來源實際 IP, 不會是 CloudFlare 的 Proxy IP
: 46.229.168.142 - - [11/Feb/2019:18:46:51 +0800] "GET /wiki/bicycle/20100422?do=media&image=tech%3Aditaa_concept_e2c8f1a6d825fe2154e6ca46354651b5.png&ns=tech&tab_details=view&tab_files=files HTTP/1.1" 200 18868 "-" "Mozilla/5.0 (compatible; SemrushBot/3~bl; +http://www.semrush.com/bot.html)" "46.229.168.142" 46.229.168.129 - - [11/Feb/2019:18:46:59 +0800] "GET /wiki/tech/kvm?do=media&image=tech%3Aclientca%3Acca_07.png&ns=tech%3Aclientca&tab_details=view&tab_files=upload HTTP/1.1" 200 5487 "-" "Mozilla/5.0 (compatible; SemrushBot/3~bl; +http://www.semrush.com/bot.html)" "46.229.168.129" :
- CloudFlare 傳遞過來出現的 log 最後面本來也會出現實際來源 IP Exp. “46.229.168.129”
Nginx Web Server (192.168.11.233)
- 編輯 Web Server 內 www.ichiayi.com 的設定檔 default.conf
vi /etc/nginx/conf.d/default.conf
server { listen 80; server_name www.ichiayi.com; autoindex off; client_max_body_size 15M; client_body_buffer_size 128k; index index.html index.htm index.php doku.php; access_log /var/log/nginx/wiki.ichiayi.com/access.log; error_log /var/log/nginx/wiki.ichiayi.com/error.log; root /var/www/html; set_real_ip_from 192.168.11.234/32; # use any of the following two #real_ip_header CF-Connecting-IP; real_ip_header X-Forwarded-For; location / { try_files $uri $uri/ @wiki; } location ~ ^/wiki/lib.*\.(gif|png|ico|jpg)$ { expires 30d; } : :
- 設定完成後看到的 log 檔就可看到來源實際 IP, 不會是 Proxy IP 192.168.11.234
: 46.229.168.142 - - [11/Feb/2019:18:46:51 +0800] "GET /wiki/bicycle/20100422?do=media&image=tech%3Aditaa_concept_e2c8f1a6d825fe2154e6ca46354651b5.png&ns=tech&tab_details=view&tab_files=files HTTP/1.0" 200 18825 "-" "Mozilla/5.0 (compatible; SemrushBot/3~bl; +http://www.semrush.com/bot.html)" 46.229.168.129 - - [11/Feb/2019:18:46:59 +0800] "GET /wiki/tech/kvm?do=media&image=tech%3Aclientca%3Acca_07.png&ns=tech%3Aclientca&tab_details=view&tab_files=upload HTTP/1.0" 200 5468 "-" "Mozilla/5.0 (compatible; SemrushBot/3~bl; +http://www.semrush.com/bot.html)" :
- 和 Proxy 內的 Log 相同, 只是少了 CloudFlare 提供最後的 IP 欄位
- 一開始設定是使用 CF-Connecting-IP 但發現透過 vpn 內部連線無法轉回 vpn IP 而是 Proxy IP, 所以改成 X-Forwarded-For 就可以看到來自 vpn 的 IP.