Nginx系列之过滤模块以及变量使用

news/2024/5/4 5:55:36/文章来源:https://blog.csdn.net/qiaotl/article/details/127018316

Nginx过滤模块

Nginx的过滤模块是发生在content模块之后,log模块之前,如image_fiter模块,gzip模块就是过滤模块的一部分。过滤模块用于修改返回的响应头和响应的body。如下左图所示,在content阶段生成响应的内容后,执行过滤模块,过滤模块可以对返回的响应header以及body进行修改处理。过滤模块有很多,比较重要的过滤模块有4个,copy_filter模块,postpone_filter模块,header_filter模块,write_filter模块。执行顺序上是先执行copy_filter,最后执行write_filter模块。

除了上面提到的模块外,还有其他过滤模块,如sub模块additional模块,sub模块用于替换返回的响应中的字符串信息,additional模块用于在返回的内容前后添加自定义的内容。如下图所示是sub模块的配置,sub_filter orignal_string replaced_string 配置替换的字符串内容,sub_filter_last_modified打开时,返回的请求中会添加上Last_modified字段。实验结果如下左图所示:

下面是addition模块的使用,add_before_body 和add_after_body指令用于在返回的reponse body前后添加自定义内容。这里/before_action和/after_action,理论上应该通过pass_proxy连接到反向代理服务上,下面的配置为了简便,直接return了内容来模拟。实验结果如下所示,在返回的mirror.txt文件内容的前后都添加了自定义的内容。

需要注意一点:上面使用的sub和addition模块默认不会编译进nginx,需要通过--with编译进去才能使用。--with-http_sub_module --with-http_addition_module。

Nginx的内置变量

Nginx中有很多变量,可以通过读取这些变量获取期望的信息,Nginx官网也列举了内置的很多变量含义,下图按模块分类列举了常用变量。具体如下所示

上面是列举的变量,下面是通过实验方式获取不同的变量值。结果如下所示:

有些变量信息需要在日志中查看,例如body_bytes_sent,bytes_sent等,日志结果如下所示

使用变量进行防盗链实践

某个网站通过url引用了你的页面,当用户在浏览器中点击url时,http请求的头部会通过referer头部,将该网站当前页面的url带上,告诉服务器本次请求是由这个页面发起的。通过referer模块,用invalid_referer变量根据配置判断referer头部是否合法,这样可以拒绝非正常网站访问站点资源。valid_referers指令的参数值可以设置多个,表示多个referer头部都生效。其中,none表示允许缺失referer头部的请求访问,blocked表示允许referer头部没有对应的值的请求访问,server_names表示如果referer中站点域名与server_name中域名匹配,则允许访问,另外在配置valid_referer时支持在前缀和后缀中含有*通配符,也支持正则表达式配置。下面是一段valid_referer的配置。

在nginx.conf中引入上面的配置,通过curl命令验证配置的valid_referers,验证的结果如下所示:

curl -H 'referer:http://www.taohui.org.cn/ttt' taoli.test.pub:8010/
curl -H 'referer:http://www.taohui.tech' taoli.test.pub:8010/
curl -H 'referer:http://image.baidu.com/search/detail' taoli.test.pub:8010/
#以上的配置会返回403错误curl -H 'referer: http://www.taohui.org.cn/nginx/' taoli.test.pub:8010/
#匹配命中了字符串curl -H 'referer: htttp://www.taohui.pub/ttt' taoli.test.pub:8010/
匹配命中了前缀*,因为没有添加/,不是url,只是一个泛域名,故匹配curl taoli.test.pub:8010
#匹配命中了nonecurl 'referer:' taoli.test.pub:8010/
#匹配命中了blockedcurl -H 'referer:http://taoli.test.pub' taoli.test.pub:8010/
#匹配命中了server_namecurl -H 'referer:http://image.google.com/search/detail' taoli.test.pub:8010/
#匹配命中了google的正则表达式配置
#以上的配置会返回valid,即匹配到了valid_referer

前面介绍的referer模块虽然可以防止非法站点的访问,但是,实际情况下,很容易伪造referer字段的值,所以需要更安全的方式,secure_link模块就是防盗链的一种更可靠的解决方案。工作原理是:由某服务器(也可以是nginx)生成加密后的安全链接url,返回给客户端,客户端使用安全url访问nginx,由nginx的secure_link变量判断是否验证通过。因为哈希算法是不可逆的,客户端只能获取到执行过hash算法的URL,仅生成URL的服务器、验证URL是否安全的nginx才存储了执行hash算法前的原始URL字符串,这样就保证了访问的安全性。secure_link值为空字符串则表示验证不通过,值为0则表示URL过期,值为1则表示验证通过,secure_link_expires字段存放过期时间戳。

 

上面定义了secure_link_md5值生成的规范,执行下面的命令即可生成md5值。

echo -n '2147483647/test.txt127.0.0.1 secret' | openssl md5 -binary | openssl base64 | tr +/ -__|tr -d =

通过生成的md5值与expire参数组合,访问nginx服务器上html目录下的test.txt文件,可以看到当输入正确的md5值和expire值时,返回正确的结果,如果修改任意参数,例如expire值,则返回403错误,实验结果如下所示:

除了上面的md5加密方式外,还可以采用仅对URI进行hash的简单做法,原理是将请求URL分为三部分(prefix,hash,原始的link),/prefix/hash/link。Hash生成方式:对“link密钥”做md5哈希求值,用secure_link_secret secret 配置密钥。如上图的配置文件所示"/p/"就是采用这种方式进行配置的。执行下面的命令生成md5值后,访问请求,可以看到上面的实验结果中正确获取到test.txt文件的内容,说明整个配置过程正确。

echo -n 'test.txtmysecret2' | openssl md5 -hex

以上就是利用secure_link进行防盗链的实践,需要注意该模块默认情况下不会编译进nginx,需要通过--with参数编译进去才能使用。 

为复杂业务生成新变量-map模块

在编程语言中可以通过if-else,switch-case等处理复杂业务逻辑,在nginx配置时却不支持编程语言中的语法,所以为了实现复杂逻辑的处理,可以利用map生成新的变量来处理。如下图左边所示,配置文件中$http_host是已有变量,$name是新定义的变量,$mobile也是新定义的变量,利用map可以根据http_host的不同取值,获取到不同的name值,和编程语言里面switch-case非常像。下图右边是实验结果,可以看到,在访问nginx时,设置不同的http_host后,获取到了不同name值

map在定义变量值时匹配规则如下:

  • 如果是字符串,那么进行严格匹配
  • 使用hostnames指令,可以对域名使用前缀*泛域名匹配
  • 使用hostnames指令,可以对域名使用后缀*泛域名匹配
  • ~和~*正则表达式匹配,后者忽略大小写

通过变量指定实现A/B测试

A/B 测试(也被称为对比测试和分桶测试)旨在对比两个版本的内容,识别哪一个版本对于访客/查看者更具吸引力。它将测试对照 (A) 版本与变量 (B) 版本,基于关键指标来衡量哪一个版本更成功。通过split_client模块,可以实现A/B测试。下面是split_client相关配置,这里只是个demo,所以根据请求中http_testcli的值来确定$variant的值,访问nginx后返回$variant的值。

上面只是个演示demo,实际项目中,A/B两个版本是部署在不同的服务器上,那么可以根据请求中的某个字段信息决定发送到A版本的服务,还是B版本的服务。

根据客户端地址创建新变量

geo模块的作用是根据客户端地址创建新变量,语法格式:geo[$address] $variable{...},如果geo指令后不输入$address,那么默认使用$remote_addr变量作为IP地址。{}内的指令匹配规则:

优先最长匹配
1.通过IP地址以及子网掩码的方式定义IP范围,当IP地址在范围内时,新变量使用其后的参数值
2.default指定了当范围内的值都不匹配时,新变量使用默认值
3.通过proxy指令指定可信地址,此时remote_addr的值为X-Forwarded-For头部值中最后一个IP地址的值
4.proxy_recursive,允许循环地址搜索,开启此选项后,会排除掉设置的可信地址(同realip的recursive作用相同)

下面是geo的配置,通过curl命令"curl -H 'X-Forwarded-For: 1.1.1.1,127.0.0.2,2.2.2.2' taoli.test.pub:8001"访问nginx,会返回RU的值。

上面是geo模块简单配置demo,实际项目中存在根据IP地址范围导航用户到不同的网站的场景,例如北美的客户,中国的客户需要导航到不同的网站,那么可以利用geo实现,上图右边是不用地域与IP地址间的映射关系。

以上就是Nginx中过滤模块与变量相关模块的使用。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx系列之负载均衡算法策略

负载均衡实际上是一种网络技术,主要是基于现有的网络结构,增加吞吐量、加强网络数据处理能力、提高应用系统的灵活和可用性。利用Nginx可实现负载均衡,Nginx支持加权Round-Robin负载均衡算法,即加权轮询方式访问server指令指定的后…

CMSC5724-关于条件概率和朴素贝叶斯分类器

文章目录条件概率公式朴素贝叶斯分类器不同假设下的贝叶斯分类贝叶斯分类器候选集相关题目这节课讲述了另一种和概率有关的分类器,老师也改变了讲课方式,直接摆上例子,然我们通过例子将课件上的内容串联起来,减少了纯粹的理论公式…

行人重识别

一、什么是行人重识别 行人重识别(Person Re-identification也称行人再识别,简称为ReID,是利用计算机视觉技术判断图像或者视频序列中是否存在特定行人的技术;或者说,行人重识别是指在已有的可能来源与非重叠摄像机视域…

Stack Smashing

Stack Smashing 当canary被覆盖后,会call到__stack_chk_fail打印argv[0]这个指针指向的字符串,默认是程序的名字,如果我们把它覆盖为其他的地址时,它就会把其他内存地址的信息给打印出来 Example:wdb2018_guess Analyze Arch: amd64-64-little RELRO: Partial RELRO…

3个超实用功能,华为手机负一屏应该这么用

现在越来越多人使用华为手机,但是你知道华为手机的负一屏吗?华为手机负一屏有哪些功能?华为手机的负一屏有以下3个超实用的功能,以后打开手机,你就可以快速找到自己想查看的东西了! 你可能会问华为手机的负…

C语言刷题(二)

✅作者简介:大家好我是:嵌入式基地,是一名嵌入式工程师,希望一起努力,一起进步! 📃个人主页:嵌入式基地 🔥系列专栏:牛客网C语言刷题专栏 💬推荐一…

保姆级, 使用 KotlinScript 构建 SpringBootStarter

因业务需要, 公司内需要使用 SpringBoot Starter 构建 SDK. 不同的是使用了更为灵活的 Kotlin 语言, 构建脚本也换成了 Kotlin Script. .kts本文主要分几个步骤: 用 Kotlin 写一个简单 SpringBoot Starter 进阶一: 复杂配置参数的写法 进阶二: starter 单元测试 使用 Kotlin …

【计算机组成原理】中央处理器(四)—— 控制器的功能和工作原理

【计算机组成原理】中央处理器(四)—— 控制器的功能和工作原理一、前言二、硬布线控制器(一)、安排微操作时序的原则1. 安排微操作时序-取指周期2. 安排微操作时序-间址周期3. 安排微操作时序-执行周期4. 安排微操作时序-间址周期…

Python算法性能分析-时间复杂度

时间复杂度: 算法的运行时间。 什么是大O: 大O用来表示上界的。 数据规模: 在决定使用哪些算法的时候,不是时间复杂越低的越好(因为简化后的时间复杂度忽略了常数项等等),要考虑数据规模&am…

没有项目经验,如何书写漂亮的简历?

嗨,同学 你们是不是也开始 国庆假期倒计时啦!!! 一想到熬过这周,接下来可以嗨7天7夜 就按捺不住自己内心的雀跃! 但是,有人却高兴不起来,因为在这个“金九银十”,一些同学还没找到…

接口(关注我还有后续哦)

👍 棒棒有言:现在学习Java变得比以前容易多了,除了有大量的视频教程外,还有专业的机构,这都使学习变得更加简单化。如果仅仅学了些皮毛,高手写的程序你是望尘莫及的。在学习的过程中,书籍永远是…

后台系统接入udesk在线客服(vue前端方式)

SDK最舒服的一点就是买来服务,直接Ctrl CV脚本进项目基本就能完成目标功能,要做的无非就是自定义属性的添加。 楼上项目组用的是java后端接入,我这儿是vue前端接入,做法略有不同。 简单点做就是复制上面script标签内代码到index.h…

关于SignalR的内容延续:1.协商协议 2.分布式部署

既然项目中用到了,那就搞搞清楚,搞不懂就死 : > 前置内容: 长轮询问题在ABP中的解决方案,SignalR_董厂长的博客-CSDN博客 “SingalR是对webSocekt的封装” ,这句话是片面的。 因为: SignalR支持多…

vue-----组件通信/传值

一 父子组件通信分为父给子传和子给父传 父给子传: 1.在子组件标签中写传入的值 2.在子组件内使用props接收父组件传递的值。 子给父传: 1.在子组件内部使用$emit发射自定义事件和传递给父组件的值 2.在父组件内声明自定义事件接受参数 二 兄弟组件…

真无线蓝牙耳机哪款音质最好?真无线蓝牙耳机音质排行榜

随着蓝牙技术的飞速发展,很多耳机的质量和质量都很好。喜欢音乐的人,往往会沉迷于这种美妙的感觉,也正是因为如此,他们才会对音质有更高的要求。除了音质之外,还有很多新的特性,例如主动降低噪音、声音操控…

全流程调度

目录 Azkaban 配置mysql 配置 Executor Server 配置Web Server Sqoop导出脚本 Azkaban 安装azkaban并改名 配置mysql 启动 [doudouhadoop102 ~]$ mysql -uroot -p123456登陆 MySQL,创建 Azkaban 数据库 mysql> create database azkaban;设置密码有效长度 …

一文入门Qt Quick

很高兴可以来到这一章,终于可以开始讲讲最近几年Qt的热门技术Quick这一块了。希望通过这个比较简短的例子可以带领有兴趣的朋友快速跨过Qt Quick的入门这道槛!以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「englyf」https://www.cnblogs.com/englyf/p/16733…

m基于matlab的光通信的信道估计,均衡,抑制papr误码率仿真,对比ZF,RLS,MMSE三种算法(包括matlab仿真录像)

目录 1.源码获取方式 2.算法描述 3.部分程序 4.部分仿真图预览 1.源码获取方式 使用版本matlab2013b 获取方式1: 点击下载链接(解压密码C123456): m基于matlab的光通信的信道估计,均衡,抑制papr误码…

libxml编译时问题解决记录

在对libxml进行模糊测试时,需要先将其拉去并进行编译,可参考此链接:magma本地编译 或者直接参考这个链接:magma编译libxml2 然而在编译的过程中,拉去完libxml2执行到这一句时报错如下: configure.ac:42: e…

Python骚操作,实现驾考自动答题,这就直接满分了?

Python骚操作来了~ 用Python来实现科目一/四自动答题,100分不要太简单! 最初是表弟最近想买车,但是驾照都没有,买什么车,只能先考驾照~ 看他在网页上练习题目慢吞吞的,我就看不下去了,直接给他…