Nginx的allow、deny配置负载均衡真实IP的方法

先说一下故事背景:nginx前端有一个阿里云SLB,然后外界从443进入SLB,SLB将流量转到nginx的80端口,同时80做了一个反向代理到同机器的8082端口服务。8082服务的配置文件如下:
抱光妹

但是这样的配置发现了一个问题:虽然已经allow 127.0.0.1,但是在浏览器里还是能正常打开/status界面,如图:
抱光妹

原因是deny和allow后面跟着的IP都是$remote_addr,而我这个环境里后端8082的服务,看到的$remote_addr就是127.0.0.1,所以才会出现这样子。那么如何解决呢?

一般来说遇到这种有代理的情况,我们都是用http_x_forwarded_for来获取后端的真实IP,但是如何让deny和allow去搭配http_x_forwarded_for呢?用real_ip_header

首先先nginx -V查看一下是否有--with-http_realip_module的模块,如果没有,那么需要重新编译nginx,如下:

1
2
./configure  --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --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-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g'
make && make install

然后将上面文件的status|ping那段location改成如下:

1
2
3
4
5
6
7
8
9
10
11
location ~ ^/(status|ping)$ {
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
real_ip_recursive on;
allow 准许访问的IP地址1;
allow 准许访问的IP地址2;
allow 准许访问的IP地址3;
deny all;
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}

解释一下语法:

  1. real_ip_header X-Forwarded-For表示从哪个header头检索出要的IP地址;
  2. set_real_ip_from真实服务器上一级代理的IP地址或者IP段,不过经过我的反复试验,发现这个代理地址无法确定。不过我胆子大,写了0.0.0.0/0,这代表所有转发的IP都会被承认;
  3. real_ip_recursive的用途:递归的去除所配置中的可信IP,排除set_real_ip_from里面出现的IP。如果出现了未出现这些IP段的IP,那么这个IP将被认为是用户的IP;

重启nginx之后,就OK了。

不过问题还是有两个:

  1. http_x_forwarded_for是可以伪造的,因为这个值是通过获取HTTP头的X_FORWARDED_FOR属性取得,那有没有比它更准确的方法?
  2. set_real_ip_from后面填写的IP究竟是不是http_x_forwarded_for多个IP后面的值?

https://blog.51cto.com/wks97/2084302

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------