最近要给网站上 CDN 于是折腾了下在 NGINX 部分获取客户端真实 IP 的方案。
嘛… 意想不到的简单就是…
安装 realip 模块
如果是 Debian/Ubuntu 系统,直接安装 nginx-extras
这个包即可。包含了很多有用的模块,不需要再自己编译。
如果是其他发行版,且没有提供额外模块的包的话,需要自己编译 NGINX。编译参数加 --with-http_realip_module
即可。
获得前端服务器地址
常见的 CDN 前端 IP 都可以从 CDN 提供商处获得,例如 CloudFlare 的 IP 地址段在这里。
如果需要找到 Google Cloud Platform 的 IP 地址段,可以使用 Google 提供的 TXT 记录查询。
1
| $ dig @8.8.8.8 _cloud-netblocks.googleusercontent.com TXT
|
获得记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ; <<>> DiG 9.11.0-P2 <<>> @8.8.8.8 _cloud-netblocks.googleusercontent.com TXT ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42732 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;_cloud-netblocks.googleusercontent.com. IN TXT
;; ANSWER SECTION: _cloud-netblocks.googleusercontent.com. 3599 IN TXT "v=spf1 include:_cloud-netblocks1.googleusercontent.com include:_cloud-netblocks2.googleusercontent.com include:_cloud-netblocks3.googleusercontent.com include:_cloud-netblocks4.googleusercontent.com include:_cloud-netblocks5.googleusercontent.com ?all"
;; Query time: 51 msec ;; SERVER: 8.8.8.8 ;; WHEN: Wed Feb 08 20:31:29 JST 2017 ;; MSG SIZE rcvd: 331
|
这里面的 _cloud-netblocks1.googleusercontent.com
等地址即是用于保存 GCP IP 段的地址。继续查询:
1
| dig @8.8.8.8 _cloud-netblocks1.googleusercontent.com TXT
|
获得记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ; <<>> DiG 9.11.0-P2 <<>> @8.8.8.8 _cloud-netblocks1.googleusercontent.com TXT ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22867 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;_cloud-netblocks1.googleusercontent.com. IN TXT
;; ANSWER SECTION: _cloud-netblocks1.googleusercontent.com. 3599 IN TXT "v=spf1 ip4:8.34.208.0/20 ip4:8.35.192.0/21 ip4:8.35.200.0/23 ip4:108.59.80.0/20 ip4:108.170.192.0/20 ip4:108.170.208.0/21 ip4:108.170.216.0/22 ip4:108.170.220.0/23 ip4:108.170.222.0/24 ?all"
;; Query time: 55 msec ;; SERVER: 8.8.8.8 ;; WHEN: Wed Feb 08 20:32:39 JST 2017 ;; MSG SIZE rcvd: 270
|
于是得到了一堆 IP 地址。
设置 RealIP 模块
文件 /etc/nginx/snippets/realip.conf
,请注意这个位置在其他发行版未必存在,放在 NGINX 配置目录下即可。
1 2 3 4
| set_real_ip_from 192.168.1.0/24; set_real_ip_from 192.168.2.1; set_real_ip_from 2001:0db8::/32; real_ip_header X-Forwarded-For;
|
然后在 vhost 配置文件中引用这个配置。
1
| include snippets/realip.conf;
|
搞定,重启 NGINX 即可获得客户端真实 IP。
Note:
GCP 的 X-Forwarded-For
的客户端 IP 在第一个 ,
的前面,所以一般需要 split(',')[0]
。