一次 Nginx proxy_set_header 故障问题解析和延升
本文会先由一个问题引入,然后再进行多种情况进行分析。
一、问题和排查步骤
1.1 问题基本信息
我们应用程序从代码层面收到的 Header 中的 Host 的值是 upstream 的 名称。 我们程序是需要获取到实际的值。所以这里存在一个问题。
我们先看看我们的 nginx 配置。
upstream open-hz8443{
server 10.60.6.184:8000 max_fails=1 fail_timeout=3s weight=10;
}
server{
server_name 192.168.80.132;
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_next_upstream error timeout invalid_header http_404 http_502 http_504 http_500;
location / {
proxy_pass http://open-hz8443;
}
location ^~ /wss/v1
{
proxy_pass http://open-hz8443;
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
tcp_nodelay on;
}
}
我们请求 http://192.168.80.132/wss/v1, 我们可以在后端(10.60.6.184:8000)获取到 Host 的值为 open-hz8443。
这个是我们做了一个 脚本,用于获取请求的所有的数据的。 脚本具体内容在文末。
Connection: upgrade
Host: open-hz8443 # 获取到的Host 是 open-hz8443
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
10.210.20.43 - - [04/Jan/2021 15:54:46] "GET /wss/v1 HTTP/1.0" 200 -
1.2 问题解析
首先这里有知识点:
我们在 Server 配了
proxy_set_header Host $host;, 我们在 location 是只配置了proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
我们的 Host 最初我认为是会继承 Server 配置的
proxy_set_header Host $host;, 但是明显是没有继承的,而是直接拿的upstream的名称。说明没有继承,那么这里是有一个什么规则? 我们往下看。查询
Nginx官方文档。http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
Allows redefining or appending fields to the request header passed to the proxied server. The value can contain text, variables, and their combinations. These directives are inherited from the previous configuration level if and only if there are no proxy_set_header directives defined on the current level. By default, only two fields are redefined:
大概意思就是当我们没有设置
proxy_set_header才会从上一层级继承,当我们设置了proxy_set_header,也就意味着我们不从上面 server 的proxy_set_header Host $host;进行继承。那为什么会显示
open-hz8443, 是因为有一个默认值proxy_set_header Host $proxy_host;
这个
proxy_host,- 当我们设置了
upstream的话,也就是上面的例子$proxy_host就是 upstream的名称值. - 当我们直接使用的
proxy_pass http://10.60.6.184:8000的话,那么$proxy_host表示的就是10.60.6.184:8000
- 当我们设置了
1.3、解决办法
在 location ^~ /wss/v1 下面增加配置 proxy_set_header Host $host;。
location ^~ /wss/v1
{
proxy_pass http://open-hz8443;
proxy_set_header Host $host;
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
tcp_nodelay on;
}
二、扩展-各种情况对比
默认两项
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
proxy_set_header 其他项等
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
| Server 设置 proxy_set_header 其他项 | Server 设置 proxy_set_header 默认两项 | location 设置 proxy_set_header 默认两项 | location 设置 proxy_set_header 其他项 | 默认值生效 | 默认值不生效 |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 继承location | |
| 1 | 1 | 0 | 1 | 1(不继承Server) | |
| 1 | 1 | 1 | 0 | 1 继承location | |
| 1 | 1 | 0 | 0 | 1 继承server | |
| 1 | 0 | 1 | 0 | 1 继承location | |
| 1 | 0 | 0 | 0 | 1 默认 | |
| 1 | 0 | 0 | 11 | 1 默认 | |
| 1 | 0 | 1 | 1 | 1 继承location | |
| 0 | 1 | 0 | 0 | 1 继承server | |
| 0 | 1 | 0 | 1 | 1 默认 | |
| 0 | 1 | 1 | 0 | 1 继承location | |
| 0 | 1 | 1 | 1 | 1 继承location | |
| 0 | 0 | 0 | 1 | 1 默认 | |
| 0 | 0 | 1 | 0 | 1 继承location | |
| 0 | 0 | 1 | 1 | 1 继承location | |
| 0 | 0 | 0 | 0 | 1 默认 |
总结
- location 设置了 proxy_set_header 就不继承,但继承默认值,默认值优先级低于 location设置。
- location 未设置了proxy_set_header ,就往上继承,直到默认值。
只要调用了 proxy_set_header,并没有设置 host 和 connection ,默认重写host、connection两个头。
三、扩展 ->脚本
proxy_set_header $host $proxy_host $http_host 各个变量含义
记录一次 Nginx 配置 proxy_pass 后 返回404问题
python 获取请求所有数据信息脚本
#!/usr/bin/env python
import SimpleHTTPServer
import SocketServer
PORT = 8000
class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
print(self.headers)
self.send_response(200, "")
def do_POST(self):
print(self.headers)
content_length = self.headers.getheaders('content-length')
length = int(content_length[0]) if content_length else 0
print(self.rfile.read(length))
self.send_response(200, "")
Handler = GetHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()
一次 Nginx proxy_set_header 故障问题解析和延升的更多相关文章
- Nginx(六):配置解析之location解析
nginx成为非常流行的代理服务软件,最根本的原因也许是在于其强悍性能.但还有一些必要的条件,比如功能的完整,配置的易用,能够解决各种各样的实际需求问题,这些是一个好的软件的必备特性. 那么,今天我们 ...
- Nginx缓存了DNS解析造成后端不通--代理
文章转载自:https://segmentfault.com/a/1190000022365954 1 问题现象 我们使用 Nginx 的时候,经常会用到 Proxy 功能,为了方便管理,后端站点或者 ...
- Nginx重要结构request_t解析之http请求的获取
请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 本文主要参考为<深入理解nginx模块开发与架构解析>一书,处理用户请求部分,是一篇包含作者理解的读书笔记.欢迎指正,讨论. ...
- nginx源代码分析--配置文件解析
ngx-conf-parsing 对 Nginx 配置文件的一些认识: 配置指令具有作用域,分为全局作用域和使用 {} 创建其他作用域. 同一作用域的不同的配置指令没有先后顺序:同一作用域能否使用同样 ...
- nginx文件类型错误解析漏洞
漏洞介绍:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也可以非常好的支持PHP的运行.80sec发现 其中存在一个较为严重的安全问题,默认情况下可能导致服务器错误的将 ...
- (转)Web服务器磁盘满故障深入解析
Web服务器磁盘满故障深入解析 原文:http://blog.51cto.com/oldboy/612351 ############################################# ...
- 再提供一种解决Nginx文件类型错误解析漏洞的方法
[文章作者:张宴 本文版本:v1.2 最后修改:2010.05.24 转载请注明原文链接:http://blog.zyan.cc/nginx_0day/] 注:2010年5月23日14:00前阅读本文 ...
- Nginx入门篇(二)之Nginx部署与配置文件解析
一.Nginx编译安装 ()查看系统环境 [root@localhost tools]# cat /etc/redhat-release CentOS Linux release (Core) [ro ...
- 附002.Nginx代理相关模块解析
一 ngx_http_proxy_module模块 1.1 proxy_pass配置 proxy_pass URL; Context: location, if in location, limit_ ...
随机推荐
- Python特殊序列\d能匹配哪些数字?
在缺省语言环境下,老猿对\d的匹配范围做了个测试,下面的数字包含半角数字.全角数字.中文数字,测试语句如下: >>> m=re.search(r'(\d*)(\D*)(\d*)',' ...
- PyQt(Python+Qt)学习随笔:formLayout的layoutRowWrapPolicy属性
Qt Designer的表单布局(formLayout)中,layoutRowWrapPolicy用于控制表单布局中表单行的标签和输入部件之间是否换行.如图: 上图中蓝色标记圈起来的下拉列表数据是其可 ...
- 一台电脑上同时安装python2和python3
被python2的编码问题整的快晕了,python3对编码问题解决的不错 所以想安装下python3,但由于目前企业大多还是用python2,所以不想卸载2,让python2和python3共存. 本 ...
- 百度前端技术学院-基础-day2
2020.9.15 今天是学习前端基础技术的第二天,今天制作了一个在线简历,纯html的那种.帮助我复习了以前的基础知识,也增加了新的知识点,比如制作列表可以用fieldset来整合数据. 我的在线简 ...
- 一份平民化的MySQL性能优化指南
前言 近期在重新学习总结MySQL数据库性能优化的相关知识,本文是根据自己学习以及日常性能测试调优过程中总结的经验整理了一份平民化的优化指南,希望对大家在进行MySQL调优分析时有帮助! MySQ ...
- 【学习笔记】最小直径生成树(MDST)
简介 无向图中某一点(可以在顶点上或边上),这个点到所有点的最短距离的最大值最小,那么这个点就是 图的绝对中心. 无向图所有生成树中,直径最小的一个,被称为 最小直径生成树. 图的绝对中心的求法 下文 ...
- 自定义3D地图
基于echarts的3D地图进行,直接将这代码粘贴到echarts的demo中即可呈现效果 var mygeo = { // 标准的geojson格式 "type": " ...
- centos安装scrapy
安装scrapy centos 7 安装scrapy报错说找不到scrapy需要的Twisted13.0以上版本? Collecting Twisted>=13.1.0 (from Scrapy ...
- js下 Day12、案例
一.垃圾分类 效果图: 功能思路分析: 1. 鼠标按下 (1) 获取鼠标到元素的距离(e.offsetX) (2) 开启开关变量 (3) 获取事件源 (4) 记录垃圾初始位置 2. 鼠标移动 ( ...
- vue第十八单元(单向数据流 vuex状态管理)
第十八单元(单向数据流 vuex状态管理) #课程目标 1.理解什么是数据管理模式 2.什么是vuex 3.什么时候使用vuex 4.vuex安装及工作原理 5.vuex语法 #知识点 1.首先来看下 ...