nginx(八十一)rewrite模块指令再探之(三)重定向

news2024/12/23 18:14:02

一  return和rewrite重定向再探

 ①  前言

多种重定向跳转方式的差异

nginx与Location响应头细节探讨

本为'不涉及'讨论如下的'绝对'重定向

1) return 301 http://www.wzj.com:6443/url?name=wzj

2) rewrite ... http://www.wzj.com:6443/url 

2) rewrite ... http://www.wzj.com:6443/url  permanent

②  return和rewrite相对重定向探究

1) return 比 rewrite 效率更'高',但是'rewrite'可以利用'正则'完成更复杂功能

  补充: 'rewrite'会隐式的带查询参数,可以通过'?'进行调整;但是'return'必须显示指定$args

2) 重点: 只探究'相对'路径时,哪些因素影响重定向'Location'形式?

  思考方向:'$scheme、$host、$port、$args'

  涉及手段:'return code'、'rewrite ... ...["不涉及协议"] permanent|redirect'

  强调:建议显示指定'全路经'的重定向

3) 补充: 暂时'不考虑'以下场景

  [1]、proxy模块涉及'proxy_redirect',以及后端'30(1|2|7|8)',及自定义Location响应头

  [2]、'目录资源'导致301重定向: 默认'目录资源'nginx'301'重定向;'try_files $uri/'导致

port_in_redirect off的两个应用场景   nginx 的port_in_redirect 问题解决

1) Location'响应头'常见的组成: 

  [1]、$scheme://$host:$port$request_uri --> "全路径",最'常见'的形式

  [2]、$request_uri                      --> "带查询参数,相对路径"

  [3]、$uri                              --> "纯uri"

备注1: 实际可以加上'#'锚点数据,但是一般'不指定,最终返回的Location响应头是相对的还是绝对'

备注2: '$status'和'Location'共同作用'重定向'

2) absolute_redirect['总开关'] on  

  备注: relative url没有'协议'、'主机名'、'端口号'

3) server_name_in_redirect['host来源'] off

  需求:可以为被代理服务器发出的'相对重定'向增加'主机名'

  存在的'问题'1: 原始是通过'ip正向代理访问'的,可能'域名'无法解析、防火墙'不通'

  存在的'问题'2: 获取的'$server_name'是一个带正则的'字符串',客户端'无法'解析'所谓'域名

4) port_in_redirect['port来源'] on  --> "是否携带端口"、"携带谁的端口"

  1、默认的情况下,是会在重定向的url后'自动添加nginx 处理server块当前站点监听'的端口

  2、会对服务器造成'潜在'的威胁,'后端端口暴露'出来,可能会被人直接对这个端口进行诸如CC类攻击

5) 补充'说明'

  1、这几种'配置'方式不能显示随心所欲的'指定'

  2、通过改变'port'、'host',可能导致'重定向后'匹配一个新的'server'块

6) 本次关注'$schme',经常会出现'如下报错':

400 Bad Request The plain 'HTTP' request was sent to 'HTTPS' port

根因: 'nginx'对应的'端口'监听的是'https',但是却用'http'访问

  场景1、nginx正常'配置 https 443',但是用户错误'http://www.wzj.com:443'访问

  场景2、nginx的'proxy_pass'是'https',但是后端只支持'http',导致转发'报错'

  $scheme是'http',但是'listen port'为443

7) 浏览器如何处理'多个'Loation响应头 --> "待验证"

案例1: 'rewrite ^ kafka redirect;' 和 'rewrite ^ /kafka redirect;' 等价

备注: 客户端['浏览器'、'curl']根据'上次'请求的'scheme、host、port'+'相对url'发起请求

案例2: 多个重复'Location'响应头,浏览器和'curl'命令行'处理行为'不一样

③  The palin HTTP request was sent to HTTPS port 

目的: 必须明确'原理',也即'为什么'重定向后'https'变成了'http'?

openssl非交互的生成自签名证书   利用openssl -config生成自签名证书

需求:openssl'非交互'生成'私钥'和'证书'

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \

-keyout server.key -out server.crt -subj \

"/C=CN/ST=HeNan/L=XinYang/O=devops/OU=unicorn/CN=ssl.wzj.com"

说明: 对于'自签名'证书,'curl'访问必须使用'(-k|--secure)'声明

补充: https非'443[6443]'端口的时候,必须指定'port_in_redirect on','不要修改'默认行为

报错原因:'HTTP请求'被发送到'HTTPS端口'

排错手段: 看'配置文件'、看'请求方式'是否错误
​
#版本1.15.0及以下
listen 443;
ssl on;
 
#版本1.15.0以上
listen 443 ssl;
listen 80;      #这种可以'不同端口'监听同一服务 

问题点: redirect涉及https跳转到http,这是一个'$scheme'非期望原因之一

Kong X-Forwarded-Port 8443 问题

base标签导致The palin HTTP request was sent to HTTPS port

nginx不同版本ssl配置导致The plain HTTP request was sent to HTTPS port

proxy_paas协议错误导致The plain HTTP request was sent to HTTPS port

++++++++++  "不谈网站架构和需求都是流氓"  ++++++++++

问题现象: 请求'proxy1.wzj.com/kafka'

报错: 'Client sent an HTTP request to an HTTPS server.'

网站架构:用户 --> 'http' --> '反向代理' --> 'proxy_paas:http' --> 'nginx' 

案例'模拟'场景: proxy_paas http://ssl.wzj.com:6443 -->但是'后端'只支持'https'协议

补充现象: 被'代理'服务'报错'502,注意观察'error.log'的日志

nginx访问https跳转到http的解决方法 

++++++++++++++ "涉及proxy模块解决$scheme的问题" ++++++++++++++

解决: 通过'nginx'访问https'跳转到http'的解决

方式1:需要'同时修改'nginx配置和程序 --> '不推荐'

1) 在nginx代理中增加一个'proxy_set_header X-Forwarded-Proto $scheme'

 说明: 标志'用户请求'是http还是https

2) 后端获取header决定'跳转'到http/https页面

方式2: nginx代理中配置'proxy_redirect'

proxy_redirect http:// $scheme://; 或 proxy_redirect http:// https://;

场景: nginx的'proxy_pass'是'https',但是后端只支持'http',导致转发'报错'

+++++++++ '题外话' +++++++++

1) Jenkins根据请求头'proxy_ser_header X-Forwarded-Port $server_port'确定重定向端口

2) mesher优先根据'proxy_ser_header X-Forwarded-Port $server_port'来进行'端口转发'

案例2: 不同的'url'访问,'proxy_redirect default'行为导致重定向的'协议$scheme'不一样

测试说明: 由于'proxy_redirect'只剩下'Location: /wzj/kafka',经过'$scheme'等作用

案例3: '上游'Location传递错误的'$scheme',需要'proxy_redirect'对应修改  --> "省略"

遗留: 对于'请求[流]链路'复杂的,需要'多服务协作',或者'抓包定边界'

举例: 如果'上游服务器是nginx',其配置'absolute_redirect off';作为'proxy'的nginx处理?

 你真的理解rewrite吗    章神关于if和set解读

error_page 497 https://$host:$server_port$request_uri;

场景: nginx在'SSL阶段'对自定义的'49x'的特殊处理

nginx同一个端口同时配置支持http和https协议

同一个端口同时支持http和https

三  if和content handler的探究

题外话: 之所以要'看原版英文'解读

  1) '一'是'原汁原味',避免层层传播产生'歧义'

  2) '二'是'掌握'单词',学习计算机'术语'描述

①  if工作原理 

②   知识铺垫:CONTENT阶段模块的执行顺序 

 淘宝对CONTENT阶段的解读     nginx模块执行顺序

关注点:'content handle'、'NGX_HTTP_CONTENT_PHASE'阶段涉及的'模块'和'指令'

1) nginx 'CONTENT'阶段中'默认'服务模块  --> 'static content'  --> '兜底'

  [1]、当一个 location 中'未使用'任何 content 阶段的指令,没有模块注册'内容处理程序'时

  [2]、nginx 一般会在 content 阶段安排'三'个这样的'静态资源服务'模块

  [3]、'依次'是 'index' 模块、'autoindex' 模块、以及 'static' 模块

    1、index模块涉及'index'指令

    2、autoindex模块
   
    3、static模块涉及'root'、'alias'指令

默认'CONTENT'阶段起作用的时机: 
  
    1、location 中'没有'使用运行在 CONTENT 阶段的模块指令

    2、也即'没有'模块'显示注册'这个 location 的"内容处理程序(content handler)"

    3、处理权便'自动'落到了在 CONTENT 阶段'垫底'的那 3 个'静态'资源服务模块

2)  哪些'模快'会显示在CONTENT阶段'注册'内容处理程序? 这些CONTENT阶段模块的执行'顺序'?

  [1]、proxy模块、fastcgi模块、uwsgi模块在 CONTENT 阶段执行

  备注: 一般关注'proxy_pass'指令 

  补充: 将客户端过来的请求体'如果有的话'以'相应协议[转换]'完整的'转发'到后端服务进程

  [2]、ngx_echo 模块

  备注: 涉及'echo'、echo_exec、echo_location

  [3]、ngx_lua模块

  备注:涉及'content_by_lua'、'block_by_lua'等

3) nginx 模块在'向 content 阶段注册配置指令'时一些'原理细节'

 [1]、'本质'上是在当前的'location'配置块中'注册'所谓的"内容处理程序(content handler)"

 [2]、每一个 location 只能有'一'个"内容处理程序"

 [3]、因此,当在 location 中同时使用'多个模块的 content 阶段指令'时

 [4]、只有'其中一个模块'能成功注册"内容处理程序",即只能'解析一条'相同的指令

3) 通过'案例'重点讨论'多'个模块同时注册 content 阶段指令?

  注意: echo 、'proxy_paas'、'content_by_lua'同时出现的的'优先级',与'顺序'有关吗?

  强调: 应当'避免'在同一个 location 中使用'多个模'块的 content 阶段指令

content和filter

③  set和proxy_pass杂谈

could not be resolved (3: Host not found)

+++++++++++++  "小结"  +++++++++++++

1) if block模块'没有'content handler

2) 所以if block模块'继承'了'外部'的`proxy_pass`

3) 最后在'if模块'里执行了这个`proxy_pass`,而不是在'外部'执行的`proxy_pass`

案例来源

④  content handler不同层级

说明: 对比'上面案例'进行理解

  1) 此时'if block' 已经有了 'echo [content handler]';

  2) 不会'继承'外层的'proxy_paas'这个'content handler';

⑤  if中使用break

说明: '对比'案例理解

++++++++++++++++  "这个结论待验证,暂时遗留"  ++++++++++++++++

1) proxy模块在嵌入的'多个location间'的配置的'继承'扮演了关键的角色  --> '上面案例'

2) 但是'其它模块[ngx_echo]'可能不会继承location'内嵌'的content handler -->  '???'

备注: 事实上,'大多数'content handler模块,包括upstream都'不支持'继承    -->  '???'

⑥  content handler相同层级

'临时'结论: 

  1) 同一'层级'的'content handler',由于只会'only 有一个 content handler执行'

  2) 最后的'content handler 覆盖'前面的

  备注: 具体'哪一个模块的指令'会胜出是'不确定'的

  3) 常见'content 指令': 'content_by_lua'、'echo'、'proxy_pass'

  4) 补充:echo 可以'使用多次','content_by_lua'、'proxy_pass'不行

    location /wzj {
      echo hello;
      echo world;
    }

  5) 最佳实践: '禁止'在同一个 location 中使用'多个模块的 content 阶段'指令

ngx_header_more模块的more_set_headers指令也会继承if块隐式创建的location

⑦  rewrite last和break标志位

1) last: 停止'当前'这个请求,并根据rewrite匹配的规则'重新'发起一个请求

  备注: 跳过原始请求'location_rewrite'等后续阶段,'新请求'又从'find_location'开始执行

  补充: 新请求'保留'了原始请求的'什么'信息?

2) break:相对last,break并'不会'重新发起一个请求

  备注:只是'跳过'当前的'rewrite阶段',并执行本请求'后续'的执行'阶段'

1) "内部跳转[internal]"本质上其实就是把当前的请求处理阶段'强行倒退'到 'find-config' 阶段

备注:倒退回find-config阶段动作不是发生在rewrite阶段,而是发生在后面的'post-rewrite'阶段

2) 以便'重新'进行请求 'uri[解码后]' 与 'location 配置块'的配对

3) 如果在'server'配置块中直接使用 rewrite 配置指令对请求uri进行改写,则不会涉及'内部跳转'

原因:因为此时uri改写发生在server-rewrite阶段,'早于'执行location配对的find-config阶段

++++++++++ "404的真正原因" ++++++++++

1) 404的原因'不是'没有定义对应的location,而是没有找到'对应的资源'

2) 404的页面是'谁定义的'?

  [1]、nginx'自身'的默认格式还是'nginx 自定义[nginx配置有没有对404报错的处理]'

  [2]、如果'$upstream_status'为404,则是'后端服务'的

3种语言对nginx配置文件进行格式化    nginx配置文件格式化    变量漫谈

nginx的access日志打印16进制原因

⑧  扩展:了解即可

location /test {
    echo_before_body "before...";
    proxy_pass http://127.0.0.1:8080/foo;
    echo_after_body "after...";
}

location /foo {
    echo "contents to be proxied";
}

请求: /test'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/595514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一分钟学一个 Linux 命令 - pwd

前言 大家好,我是 god23bin。欢迎大家继续围观《一分钟学一个 Linux 命令》,每天只需一分钟,记住一个 Linux 命令不成问题。本篇文章将聚焦于 pwd 命令,一个超级简单又常用的命令。在接下来的内容中,我将快速介绍 pwd…

Elasticsearch总结

详细描述一下 Elasticsearch 搜索的过程? 1、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch; 2、在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执…

chatgpt赋能python:使用Python关闭所有子进程

使用Python关闭所有子进程 如果您使用Python编写了多进程应用程序,那么您可能会遇到一些关闭所有子进程的问题。这种情况可能是您的主进程已经完成了,但是子进程却没有关闭,从而导致资源浪费和程序崩溃。在这篇文章中,我们将讨论…

STM32F1xx -- Systick 系统滴答定时器

1. SysTick 是一个向 CPU 提供定时中断信号的计数器,其计数速率是由 Cortex-M 系列处理器的系统时钟频率和 SysTick 计数器的重载值共同决定的。 1.1 Systick 时钟来源之一,Systick 一般设置为1ms 中断一次,为系统任务调度提供服务&#xff…

R语言:集卡活动概率测算模拟

背景:以支付宝集五福活动为代表的集卡类营销活动背后,每张卡出现的概率测算是非常重要的,假设我们可以预估有多少人参与活动以及大致每人能抽多少次,且限定一共有多少人能够集齐,在这些限定条件下,每张卡出…

CentOS 系统上安装 Jenkins

#######################注意我这里安装jenkins版本要求实际是要安装jdk11版本的~~~我一开始弄错了 您可以按照以下步骤在 CentOS 上安装 JDK: 1. 首先,打开终端并使用 yum 命令更新系统软件包列表。输入以下命令来执行此操作: sudo yu…

chatgpt赋能python:Python为什么闪退?

Python为什么闪退? Python作为一种高级编程语言,已经赢得了世界各地许多开发者的青睐。但是,有时候Python会因为各种原因而突然闪退,给开发者带来极大的困扰。那么,Python为什么会闪退呢? 1. 内存泄漏 内…

环境感知算法——2.CenterNet基于KITTI数据集训练

1. CenterNet简介 CenterNet采用了一种新的检测思路,即以目标中心点为基础,直接回归出目标的位置和大小。而传统的目标检测算法通常会先产生大量候选框(Anchor),再通过分类器进行筛选,这种方法比较复杂。C…

selenium浏览器自动化测试

Selenium是一个用于Web应用程序的自动化测试工具。它直接运行在浏览器中,可以模拟用户在浏览器上面的行为操作。 Selenium入门 下载驱动 查看谷歌浏览器版本 谷歌浏览器输入网址的地方输入:chrome://version 下载与浏览器对应(或相近&#x…

RK3588平台开发系列讲解(驱动基础篇)驱动模块传参

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、驱动模块传参简介二、驱动模块传普通参数三、驱动模块传数组沉淀、分享、成长,让自己和他人都能有所收获!😄 📢在编写应用程序的时候,我们可以给 main 函数传递参数,比如 void main(int argc,char *argv[]…

【ChatGPT】如何利用ChatGPT来快速统计Excel数据?

系列文章目录 老板让你写个PPT没有头绪?没事,ChatGPT来帮你!传送门 文章目录 系列文章目录前言一、不会公式?帮你生成二、不会处理数据?帮你处理写在最后 前言 自从人工智能横空而出,它在人们的生活中产生…

Apache配置与应用与网页安全优化

Apache配置与应用与网页安全优化 构建虚拟Web主机httpd服务支持的三种虚拟机类型基于域名的虚拟主机Options指令解释AllowOverride指令解析 基于IP地址的虚拟主机基于端口的虚拟主机Apache连接保持构建Web虚拟目录与用户授权限制Apache 日志分割AWStats分析系统 网页压缩网页缓…

研发工程师玩转Kubernetes——多Worker Node部署

在之前的系列中,我们都是在单Node上“玩转”kubernetes,熟悉了它很多指令和特性。从本节开始,我们开始探索多Worker Node的相关特性。 部署虚拟机 因为desktop版ubuntu非常占用内存,而且我们已经熟悉了一些基本操作,…

电能质量监测装置在半导体公司“大放异彩”

摘 要:半导体生产制造业在国民经济中起着举足轻重的作用,相关企业的规模也越来越大。其供配电系统稳定、可靠的运维不仅是其安全生产的基本保证,还关系到产品质量和生产的顺利进行。而半导体行业中大部分工艺设备对电能质量比较敏感&#xff…

kafka 的内部结构和 kafka 的工作原理

基本设置 让我们开始安装kafka。下载最新的 Kafka 版本并解压缩。打开终端并启动 kafka 和 zookeeper。 $ cd $HOME $ tar -xzf kafka_<version>.tgz $ cd kafka_<version> $ bin/zookeeper-server-start.sh config/zookeeper.properties # open another termina…

Web安全之常见攻防

前言&#xff1a; 在当下&#xff0c;数据安全与个人隐私受到了前所未有的挑战。如何才能更好地保护我们的数据&#xff1f;接下来分析几种常见的攻击的类型以及防御的方法。 一、XSS&#xff08;Cross Site Script&#xff09; 首先了解最常见的 XSS 漏洞&#xff0c;XSS (Cr…

Nginx的网站服务

Nginx网站服务 一、Nginx与apache的差异二、编译安装Nginx服务三、Nginx命令四、向系统添加nginx服务五、nginx配置文件六、http块的配置 一、Nginx与apache的差异 nginx相对于apache的优点&#xff1a; 轻量级&#xff0c;同样是web服务&#xff0c;比apache占用内存更少及资…

chatgpt赋能python:Python为什么运行不出结果?

Python为什么运行不出结果&#xff1f; 简介 Python是一种高级编程语言&#xff0c;可以帮助程序员快速开发软件应用。不过&#xff0c;在使用Python的过程中&#xff0c;你可能会遇到一些麻烦。其中一个常见的问题是Python运行不出结果。 如果你正在遇到这个问题&#xff0…

DAY18_基础加强-XMLDTDschema注解单元测试

目录 1 xml1.1 概述1.2 标签的规则1.3 语法规则1.4 xml解析1.5 DTD约束1.6 schema约束 2 注解2.1 概述2.2 自定义注解2.3 元注解 3 单元测试3.1 概述3.2 特点3.3 使用步骤3.4 相关注解 1 xml 1.1 概述 万维网联盟(W3C)官网&#xff1a;https://www.w3school.com.cn 万维网联盟…

解释公有云、私有云、混合云、边缘云、分布式云

Author:skate Time:2023/06/01 云计算是一种基于互联网的计算模式&#xff0c;它通过网络提供IT资源和服务&#xff0c;包括计算、存储、网络、应用等&#xff0c;以服务的形式向用户提供&#xff0c;用户可以按需获取和使用这些资源和服务&#xff0c;而无需拥有和管理这些资…