Nginx多级代理,获取客户端真实请求IP以及每级代理IP
转载:http://blog.csdn.net/simonchi/article/details/53944308
如图所示,每一级nginx里的location配置里需要加上对应的配置,最后一级nginx是直接到应用,测试时为了方便,直接用echo模块去测试,打印IP地址。
原理分析:
只有客户端直接请求到的那个nginx能够拿到客户端的真实IP,所以第一级nginx配置了
proxy_set_header X-Real-IP $remote_addr;
这个配置就会将客户端IP放到http的header里,这样到最后的应用里可以通过request.getHeader去拿到客户端真实IP了
[java]
view plain
copy
- public String getRemoteIp() {
- String ip = request.getHeader(“X-Forwarded-For”);
- if (isEffective(ip) && ip.indexOf(“,”) > –1) {
- String[] array = ip.split(“,”);
- for (String str : array) {
- if (isEffective(str)) {
- ip = str;
- break;
- }
- }
- }
- if (!isEffective(ip)) {
- ip = request.getHeader(“Proxy-Client-IP”);
- }
- if (!isEffective(ip)) {
- ip = request.getHeader(“WL-Proxy-Client-IP”);
- }
- if (!isEffective(ip)) {
- ip = request.getHeader(“HTTP_CLIENT_IP”);
- }
- if (!isEffective(ip)) {
- ip = request.getHeader(“HTTP_X_FORWARDED_FOR”);
- }
- if (!isEffective(ip)) {
- ip = request.getRemoteAddr();
- }
- return ip;
- }
- private boolean isEffective(String remoteAddr) {
- if ((null != remoteAddr) && (!“”.equals(remoteAddr.trim()))
- && (!“unknown”.equalsIgnoreCase(remoteAddr.trim()))) {
- return true;
- }
- return false;
- }
如何拿到用户从请求源头到应用所经过的各个代理IP呢?
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
通过如上配置,将每级代理IP与$remote_addr用逗号分隔开
所以从上述情况来看,整体的流程很清晰了:
客户端请求(172.23.11.251) –>172.23.26.130–>172.23.26.132–>172.23.26.133–>172.23.30.100(具体应用)
但是我们发现上面IP貌似打印少了一个133的地址,我们在100上修改下echo测试
这里打印出了133的地址
nginx的安装包里有一个http_realip_module模块,在编译的时候可以编译此模块
./configure –prefix=/home/nginx/install –with-pcre=../pcre-8.36 –with-zlib=../zlib-1.2.8 –with-openssl=../openssl-1.0.2 –add-module=/root/nginx/echo-nginx-module-0.60 –with-http_realip_module && make && make install
新的配置如下:
set_real_ip_from 172.23.0.0/16; IP段,指定接收来自哪个前端发送的 IP head 可以是单个IP或者IP段
set_real_ip_from 192.168.1.1; 单个IP
real_ip_header X-Real-IP; IP head 的对应参数,默认即可,含义是客户端真实IP从哪个头取?
real_ip_recursive on; 是否递归解析real_ip_header
本文来源 爱码网,其版权均为 原网址 所有 与本站无关,文章内容系作者个人观点,不代表 本站 对观点赞同或支持。如需转载,请注明文章来源。