====== 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.
===== 參考網址 =====
* https://support.cloudflare.com/hc/en-us/articles/200170706-How-do-I-restore-original-visitor-IP-with-Nginx-
* http://nginx.org/en/docs/http/ngx_http_realip_module.html#directives
{{tag>nginx proxy}}