Nginx proxy_set_header 理解

场景:

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

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

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

请看 Nginx proxy_set_header:

Nginx proxy_set_header

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

proxy_set_header Host       $proxy_host;

proxy_set_header Connection close;

如果启用缓存,来自之前请求的头字段“If-Modified-Since”, “If-Unmodified-Since”, “If-None-Match”, “If-Match”, “Range”, 和“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又向前进了一步。

时间: 2024-12-19 16:10:24

Nginx proxy_set_header 理解的相关文章

对Nginx的理解 --相对于Apache

概要:nginx的源码安装,参数配置,make,nginx与Apache的区别,四层均衡负载均衡,七层负载均衡.线程与进程 首先,我们还是通过实验对Nginx的配置进行剖析,了解Nginx都可以实现什么功能. 第一部分:实验 ##获得nginx包,并解压: README文件是自述文件.也就是服务该如何配置的文件,相当于使用指南: 他说要到网上查看如何安装和配置: 首先指导我们进行源代码安装: 解压后文件是6.2M: 用帮助查看怎么用源代码安装: 帮助里会告诉我们怎么安装我们需要的服务,比如ssl

nginx.conf 理解

一个大型的网站通常会有很多下属的站点,有各自的服务器提供相应的服务,在 nginx 中我们可以通过一个叫虚拟主机的概念来将这些不同的服务配置隔离,这就是上面配置中的 server 的含义.举例来说 google 旗下有翻译和学术两款产品我们就可以在 nginx 的配置文件中配置两个 server,servername 分别为 translate.google.com 和 scholar.google.com,这样的话不同的url请求就会对应到nginx相应的设置,转发到不同的后端服务器上.这里的

NGINX 配置文件理解 之二

[[email protected] conf]# cat nginx.conf | grep -v '#' | grep -v '^$' worker_processes 1; #worker 进程的数量 events { #事件区块开始 worker_connections 1024; #每个worker进程支持的最大连接数 } #事件区块结束 http { #Http区块开始 include mime.types; #Nginx 支持的媒体类型库文件包含 default_type appl

谈一下你对 uWSGI 和 nginx 的理解??

1.uWSGI 是一个 Web 服务器,它实现了 WSGI 协议.uwsgi.http 等协议.Nginx 中HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换.WSGI 是一种 Web 服务器网关接口.它是一个 Web 服务器(如 nginx,uWSGI 等服务器)与 web 应用(如用 Flask 框架写的程序)通信的一种规范.要注意 WSGI / uwsgi / uWSGI 这三个概念的区分.WSGI 是一种通信协议.uwsgi 是一种线路协议而不是通信协议,在此常用于

谈一下你对uWSGI和 nginx的理解(原理)

要注意 WSGI / uwsgi / uWSGI 这三个概念的区分. WSGI是一种通信协议. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信. uWSGI是实现了uwsgi和WSGI两种协议的Web服务器. nginx是一个开源的高性能的HTTP服务器和反向代理: 1.作为web服务器,它处理静态文件和索引文件效果非常高: 2.它的设计非常注重效率,最大支持5万个并发连接,但只占用很少的内存空间: 3.稳定性高,配置简洁: 4.强大的反向代理和负

学习Nginx之理解正向代理和反向代理

正向代理的概念 正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器这个代理服务器呢,他能访问那个我不能访问的网站于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容代理服务器去取回来,然后返回给我 从网站的角度,只在代理服务器来取内容的时候有一次记录有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站 结论就是 正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了

如何使用Nginx和uWSGI或Gunicorn在Ubuntu上部署Flask Web应用

我在很多的博客中都看过有关Flask应用的部署,也有很多博主在开博后都记录了部署的教程,因为其中的坑可以说不少.一开始我在网上看到相比较与Ubuntu,CentOS因为更新少作为服务器的操作系统会更加稳定.所以在第一次购买云服务器时,我选择了CentOS,后来由于CentOS不同发行版的Nginx缘故,我又换成了Ubuntu的镜像 首先呢,我们先来了解下关于Web服务器与Web应用还有WSGI之间的联系 一.介绍 WSGI(Web Server Gateway Interface),翻译为Pyt

nginx根据域名做http,https分发

omcat端口:8080 做好虚拟主机 参照我的另一篇文章nginx端口:80 根据域名分派 在conf/nginx.conf中的http中增加 include www.huozhe.com.conf 新建conf/www.huozhe.com.conf,内容如下: server {listen 80;server_name www.huozhe.com; location / {    proxy_pass http://127.0.0.1:8080;    proxy_set_header

nginx proxy https

server {listen 443;server_name mail.jb51.net; ssl on;ssl_certificate server.crt;ssl_certificate_key server.key; location / { proxy_pass https://192.168.0.2:443; proxy_set_header Host $host:443; proxy_set_header X-Real-IP $remote_addr; proxy_set_heade