Nginx proxy_set_header 理解

简介:

 场景:

    用户认证接口:根据客户端IPport,进行IP反查和端口范围确认,如符合则用户认证通过。

    当前使用的是Nginx负载均衡,从客户端到Nginx ipport都对,从Nginx到应有服务器上-port端口变成很奇怪的端口号。

    疑问:Nginx往应有服务器上 是如何 传递 客户端IPport 参数的呢?

    请看 Nginx proxy_set_header:

 

Nginx proxy_set_header

允许重新定义或添加字段传递给代理服务器的请求头。该值可以包含文本、变量和它们的组合。在没有定义proxy_set_header时会继承之前定义的值。默认情况下,只有两个字段被重定义:

 

proxy_set_header Host       $proxy_host;

proxy_set_header Connection close;

 

如果启用缓存,来自之前请求的头字段“If-Modified-SinceIf-Unmodified-SinceIf-None-MatchIf-MatchRange和“If-Range”将不会被代理服务器传递。

一个不会变化的“Host”头请求字段可通过如下方式被传递:

 

proxy_set_header Host       $http_host;

 

然后,当字段不在请求头中就无法传递啦。在这种情况下,可通过设置Host变量,将需传递值赋给Host变量。

 

proxy_set_header Host       $host;    // 获取nginx配置中的server_name值

 

此外,服务器名称和端口一起通过代理服务器传递。

 

proxy_set_header Host       $host:$proxy_port;       // 获取nginx配置中的server_name值和listen 值

 

如果请求头的存在空的字段将不会通过代理服务器传递出去。

 

proxy_set_header Accept-Encoding"";

 

总结:proxy_set_header 就是可设置请求头-并将头信息传递到服务器端。不属于请求头的参数中也需要传递时重定义下就行啦。

 

    测试 不设置 proxy_set_header

   Nginx配置

     #负载均衡

    upstream test {

        server 192.168.220.123:9099;

        server 192.168.220.123:58080;

    }

    server {

        listen    5800;

        server_name  192.168.220.123;

        root        /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        location / {

            proxy_pass http://test;

        }

 

    测试jsp 想获取客户端IP、客户端port、代理服务器IP、代理服务器port

 

   <%@page contentType="text/html; charset=UTF-8"trimDirectiveWhitespaces="true"%>

   <%

     String scheme = request.getScheme();

     String serverName = request.getServerName();

     String remoteName = request.getRemoteAddr();

     String realIP = request.getHeader("X-Forwarded-For");

     String realIP2 = request.getHeader("X-Real-IP");

     String Host = request.getHeader("Host");

     int port = request.getServerPort();

     int portR = request.getRemotePort();

     String requestURIC1 = scheme+"://"+realIP+":"+portR;

     String requestURIC2 =scheme+"://"+realIP2+":"+portR;

     String requestURIC3 = scheme+"://"+remoteName+":"+portR;

     String requestURI =scheme+"://"+serverName+":"+port;

   %>   

    客户端地址1:<%=requestURIC1%>

   <br>

    客户端地址2:<%=requestURIC2%>

   <br>

    客户端地址3:<%=requestURIC3%>

   <br>

    服务器地址1:<%=requestURI%>

   <br>

    服务器地址2:<%=Host%>

   <br>

 

    测试结果

 

    客户端地址1:http://null:58828

    客户端地址2:http://null:58828

    客户端地址3:http://192.168.220.123:58828

    服务器地址1:http://test:80

    服务器地址2:test

 

   Nginx日志

 

   192.168.220.177 -20508---5800 [25/Aug/2016:16:34:13 +0800] "GET/docs/test.jsp HTTP/1.1" 200 223 "-" "Mozilla/5.0 (WindowsNT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106Safari/537.36" "-"

 

    其中客户端IP不能获取到,而通过request.getRemoteAddr();获取的IP是代理服务器IP,而不是客户端IP,而在nginx$remote_addr变量的值是客户端的IP,可见remoteaddr没有传递。

    server_port值也不对,当前值为5800,当前打印出的是80

    而当前代理为http://test所有通过host得到的是test

    客户端port也获取不到值为20508,可传给应用的是58828

 

    测试 设置proxy_set_header

   Nginx 配置

 

    upstream test {

        server 192.168.220.123:9099;

        server 192.168.220.123:58080;

    }

    server {

        listen    5800;

        server_name  192.168.220.123;

        root        /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        location / {

            proxy_pass http://test;

            proxy_set_header Host $host:$server_port;

            proxy_set_header X-Real-IP $remote_addr;

            proxy_set_header X-Real-PORT $remote_port;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }

 

    测试页面改成:

 

   <%@page contentType="text/html; charset=UTF-8"trimDirectiveWhitespaces="true"%>

   <%

     String scheme = request.getScheme();

     String serverName = request.getServerName();

         String remoteName = request.getRemoteAddr();

         String realIP = request.getHeader("X-Forwarded-For");

         String realIP2 = request.getHeader("X-Real-IP");

         String Host = request.getHeader("Host");

         int port = request.getServerPort();

         int portR = request.getRemotePort();

         String portR2 = request.getHeader("X-Real-Port");

         String requestURIC1 = scheme+"://"+realIP+":"+portR;

         String requestURIC2 = scheme+"://"+realIP2+":"+portR;

         String requestURIC3 =scheme+"://"+remoteName+":"+portR;

         String requestURI =scheme+"://"+serverName+":"+port;

   %>

    客户端地址1:<%=requestURIC1%>

   <br>

    客户端地址2:<%=requestURIC2%>

   <br>

    客户端地址3:<%=requestURIC3%>

   <br>

    服务器地址1:<%=requestURI%>

   <br>

    服务器地址2:<%=Host%>

   <br>

    客户端port2:<%=portR2%>

   <br>

 

    测试结果:

 

    客户端地址1:http://192.168.220.177:21548

    客户端地址2:http://192.168.220.177:21548

    客户端地址3:http://192.168.220.123:21548

    服务器地址1:http://192.168.220.123:5800

    服务器地址2:192.168.220.123:5800

    客户端port2:20604

 

   Nging日志:

 

   192.168.220.177 -20604---5800 [25/Aug/2016:16:38:42 +0800] "GET/docs/test.jsp HTTP/1.1" 200 275 "-" "Mozilla/5.0 (WindowsNT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106Safari/537.36" "-"

 

    request.getRemoteAddr();获取的值不对外,其他值都是对的。

   getRemoteAddr获取的是代理的请求地址。

    因重定义了host,所以test值被改写成代理服务器IP

    因重定义了X-Real-PORT-并传递$remote_port,客户端port也获取正确啦。

    弄清楚是怎么传值的,正确的使用Nginx又向前进了一步。

 


本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/1907123,如需转载请自行联系原作者

相关文章
|
23天前
|
运维 前端开发 应用服务中间件
LNMP详解(八)——Nginx动静分离实战配置
LNMP详解(八)——Nginx动静分离实战配置
24 0
|
1月前
|
应用服务中间件 nginx
Nginx中如何配置中文域名?
Nginx中如何配置中文域名?
40 0
|
21天前
|
前端开发 应用服务中间件 nginx
Nginx配置详解Docker部署Nginx使用Nginx部署vue前端项目
Nginx配置详解Docker部署Nginx使用Nginx部署vue前端项目
86 0
|
2天前
|
安全 应用服务中间件 网络安全
SSL原理、生成SSL密钥对、Nginx配置SSL
现在,你的Nginx虚拟主机应该已经配置了SSL,可以通过HTTPS安全访问。确保在生产环境中使用有效的SSL证书来保护通信的安全性。
9 0
|
4天前
|
域名解析 缓存 负载均衡
Nginx正向代理域名的配置
Nginx正向代理域名的配置
|
4天前
|
前端开发 JavaScript 应用服务中间件
修改Jeecg-boot context-path(附加图片+Nginx配置)
修改Jeecg-boot context-path(附加图片+Nginx配置)
12 0
|
15天前
|
应用服务中间件 nginx
nginx进行反向代理的配置
在Nginx中设置反向代理的步骤:编辑`/etc/nginx/nginx.conf`,在http段加入配置,创建一个监听80端口、服务器名为example.com的虚拟主机。通过`location /`将请求代理到本地3000端口,并设置代理头。保存配置后,使用`sudo nginx -s reload`重载服务。完成配置,通过example.com访问代理服务器。
22 0
|
16天前
|
应用服务中间件 网络安全 nginx
nginx配置https访问
nginx配置https访问
26 0
|
25天前
|
应用服务中间件 nginx
nginx配置访问qicaitun.com强制跳转www.qicaitun.com
nginx配置访问qicaitun.com强制跳转www.qicaitun.com
9 0