当前位置: 首页 > news >正文

nginx upstream server主动健康检测模块添加https检测功能[完整版]

目录

  • 1 缘起
    • 1.1 功能定义
  • 2. 实现后的效果
  • 2.1 配置文件
  • 2.2 运行效果
  • 3. 代码实现
    • 3.1 配置指令
      • 3.1.1 配置指令定义:
      • 3.1.2 配置指令结构体:
      • 3.1.3 配置指令源码定义:
    • 3.2 模块的初始化
    • 3.3 添加新的健康检测类型的定义
    • 3.4 握手完成后的处理
    • 3. 5 发送http请求
    • 3.6 接收http响应
    • 3.7 连接关闭
    • 3.8 ssl上下文的释放

1 缘起

  前面的《nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析》系列已经分析了ngx_http_upstream_check_module的实现原理,并且在借助这个模块的框架实现了一个udp健康检测的新功能。
  但是ngx_http_upstream_check_module还缺乏基于https监测上游服务器健康状况的能力,始终是一个缺憾,因此,本文基于《nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析》和《nginx stream proxy 模块的ssl连接源码分析》两篇博文的分析成果,来实现一个基于https的上游服务器健康检测的能力。

1.1 功能定义

  本次支持的功能:

  • 支持向上游服务器发起https请求功能
  • 请求的报文复用原有的http检测的请求报文定义
  • 响应的状态码检测复用原有的http检测的响应码的定义
  • 支持ssl握手过程中添加sni扩展信息
  • 支持ssl握手协议类型的配置
  • 支持ssl握手协议加密套件的配置

  暂时不支持的功能:

  • 不支持ssl会话复用(会话复用可以降低上游服务器的ssl握手压力)
  • 不支持ssl证书双向验证
  • 不支持服务器端证书有效性验证

&ems;  由于本次主要是检验https的链接握手流程,对一些不是特别关键的ssl握手特性暂时不支持主要是为了简化代码逻辑,但是不影响业务流程,这样也便于在本文中将整个实现流程进行阐述。后续可以参照ngx_stream_proxy_module中的实现,继续将这些特性进行完善,以臻于完美。

2. 实现后的效果

  首先来看一下实现后的效果,有一些感性的认识。

2.1 配置文件


#user  nobody;
worker_processes  1;
daemon off;
master_process off;error_log  logs/error.log;
pid        logs/nginx.pid;load_module  objs/ngx_http_upstream_check_module.so;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  logs/access.log  main;sendfile        on;keepalive_timeout  65;upstream backend {# 开启https健康检测check type=https interval=3000 rise=2 fall=5 timeout=1000 port=443;check_http_send "GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n";check_http_expect_alive http_2xx http_3xx;# 设置sni hostnamecheck_ssl_server_name www.baidu.com;server 183.240.99.24:443;}server {listen       9080;server_name  localhost;# 开启本模块的状态查询接口	location /status {check_status html;}location / {proxy_pass http://backend;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}
}

   这里假设将www.baidu.com作为被代理的上游服务器,以上配置文件中的upstream块中定义了一个https的健康检测类型, check_http_send复用了http的定义,而check_ssl_server_name是新增的指令,用来配置ssl握手设置sni扩展信息中的主机host信息。

2.2 运行效果

  启动tengine后,可以通过查看nginx的error.log日志进行观察, 可以看到如下信息:

2024/02/16 09:31:33 [error] 23638#0: https check failed with return code: 403
2024/02/16 09:31:33 [error] 23638#0: check protocol https error with peer: 192.168.0.1:443
2024/02/16 09:31:45 [info] 23663#0: enable check peer: 192.168.0.1:443

error.log中的前面两条因为服务器响应403报了错误,对应在配置了“check_http_expect_alive http_2xx http_3xx;”的情况。如果配置改成“check_http_expect_alive http_2xx http_3xx http_4xx;” 则报后面那条上游服务器enable的信息。证明https的检测功能已经可用了。
  另外我们可以通过wireshark抓包观察交互的情况,抓包如下:
在这里插入图片描述

  从上述抓包的内容可以看到ssl的握手交互的过程都已经有了。关于如何进行ssl握手的内容不在本文的讨论范围之内,可以参考HTTPS篇之SSL握手过程详解 或者通过Wireshark分析HTTPS握手过程与协议概述

3. 代码实现

  由于https进行ssl握手,需要一些额外的参数,因此在nginx的配置文件http.upstream块中需要新增一些配置指定定义。

3.1 配置指令

3.1.1 配置指令定义:

支持的配置指令如下:

  • check_ssl_ciphers:
        配置加密套件,格式参考proxy_ssl_ciphers
  • check_ssl_protocols:
        和服务器交互采用的ssl协议版本,如TLSv1.1 TLSv1.2等,格式参考proxy_ssl_protocols。
  • check_ssl_server_name:
        和服务器进行ssl握手时候采用的sni扩展host名字,如果不设置并且upstream块中的server是用域名设置的,那么默认就采用设置的服务器名字。
  • check_ssl_verify:[on/off]
        是否校验服务器的证书有效性。(待后续实现)
  • check_ssl_session_reuse: [on/off]
        和上游服务器进行ssl握手的时候是否复用ssl会话信息。(待后续实现)

3.1.2 配置指令结构体:

   为了对上述定义的配置指令进行保存,需要在ngx_http_upstream_check_srv_conf_s结构体中增加对应的参数,包括ssl_ciphers、ssl_protocols、ssl_server_name和ssl四个参数,其中ssl参数用来保存ssl协议配置上下文。


struct ngx_http_upstream_check_srv_conf_s {ngx_uint_t                               port;ngx_uint_t                               fall_count;ngx_uint_t                               rise_count;ngx_msec_t                               check_interval;ngx_msec_t                               check_timeout;ngx_uint_t                               check_keepalive_requests;ngx_check_conf_t                        *check_type_conf;ngx_str_t                                send;union {ngx_uint_t                           return_code;ngx_uint_t                           status_alive;} code;ngx_array_t                             *fastcgi_params;ngx_uint_t                               default_down;ngx_uint_t                               unique;ngx_uint_t                               udp : 1;                       /* 是否udp socket */ngx_int_t                                match_part : 1;                /* 是否只要部分匹配就可以了 */ngx_int_t                                match_offset;                  /* udp响应期望的内容从哪个字节开始匹配 */ngx_str_t                                expect;                        /* udp响应的期望内容 */#if (NGX_HTTP_SSL)ngx_ssl_t                               *ssl;                            /* ssl 配置上下文 */ngx_str_t                                ssl_ciphers;                    /* ssl 加密套件 */ngx_uint_t                               ssl_protocols;                  /* 采用的ssl协议 */ngx_str_t                                ssl_server_name;                /* ssl握手的sni扩展hostname */
#endif
};

  以上添加的ssl_protocols参数在ngx_http_upstream_check_create_srv_conf函数中需要将其设置为NGX_CONF_UNSET_UINT,避免nginx在解析配置文件的时候出现参数重复的报错。

3.1.3 配置指令源码定义:

#if (NGX_HTTP_SSL){ ngx_string("check_ssl_ciphers"),NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,ngx_conf_set_str_slot,NGX_HTTP_SRV_CONF_OFFSET,offsetof(ngx_http_upstream_check_srv_conf_t, ssl_ciphers),NULL },{ ngx_string("check_ssl_protocols"),NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,ngx_conf_set_bitmask_slot,NGX_HTTP_SRV_CONF_OFFSET,offsetof(ngx_http_upstream_check_srv_conf_t, ssl_protocols),&ngx_upstream_check_ssl_protocols },{ ngx_string("check_ssl_server_name"),NGX_HTTP_UPS_CONF|NGX_CONF_FLAG,ngx_conf_set_str_slot,NGX_HTTP_SRV_CONF_OFFSET,offsetof(ngx_http_upstream_check_srv_conf_t

相关文章:

nginx upstream server主动健康检测模块添加https检测功能[完整版]

目录 1 缘起1.1 功能定义2. 实现后的效果2.1 配置文件2.2 运行效果3. 代码实现3.1 配置指令3.1.1 配置指令定义:3.1.2 配置指令结构体:3.1.3 配置指令源码定义:3.2 模块的初始化3.3 添加新的健康检测类型的定义3.4 握手完成后的处理3. 5 发送http请求3.6 接收http响应3.7 连…...

django中admin页面汉化

在Django中,将admin界面汉化为中文需要进行一些配置和翻译文件的添加。下面是一个基本的步骤指南,帮助你实现Django admin的汉化: 一:安装并配置Django: 如果你还没有安装Django,首先通过pip安装它: pip…...

prometheus基于consul的服务发现

文章目录 一、基础二、安装consul下载地址启动consul访问consul 三、编写服务发现文件nodes.json四、prometheus配置consul发现修改prometheus.yml重启Prometheus 参考 一、基础 二、安装consul 下载地址 https://developer.hashicorp.com/consul/install 启动consul mkdi…...

深度学习之pytorch实现线性回归

度学习之pytorch实现线性回归 pytorch用到的函数torch.nn.Linearn()函数torch.nn.MSELoss()函数torch.optim.SGD() 代码实现结果分析 pytorch用到的函数 torch.nn.Linearn()函数 torch.nn.Linear(in_features, # 输入的神经元个数out_features, # 输出神经元个数biasTrue # 是…...

Vue3快速上手(八) toRefs和toRef的用法

顾名思义&#xff0c;toRef 就是将其转换为ref的一种实现。详细请看&#xff1a; 一、toRef 1.1 示例 <script langts setup name"toRefsAndtoRef"> // 引入reactive,toRef import { reactive, toRef } from vue // reactive包裹的数据即为响应式对象 let p…...

《数学建模》专栏导读

文章分类 相关概念入门快速建模相关混合整数线性规划&#xff08;MILP&#xff09;加速技巧数值问题探讨相关问题解决技巧 相关概念入门 文章相关概念离散优化模型的松弛模型线性松弛问题混合整数线性规划MILP问题中增添约束的影响约束的影响 快速建模相关 文章求解器涉及步…...

App启动优化笔记 1

app大致的启动流程。有Launcher进程,system_server进程,zygote进程,APP进程。 Launcher进程:启动activity来启动应用 system_server进程:(ams是其中的一个binder):发送一个socket消息给Zygote。 zygote进程:收到消息后,fork新的进程,---》app进程启动 APP进程:…...

Spring Boot 笔记 027 添加文章分类

1.1.1 添加分类 <!-- 添加分类弹窗 --> <el-dialog v-model"dialogVisible" title"添加弹层" width"30%"><el-form :model"categoryModel" :rules"rules" label-width"100px" style"padding…...

【SQL】sql记录

1、start with star with 是一种用于层次结构查询的语法&#xff0c;它允许我们从指定的起始节点开始&#xff0c;递归查询与该节点相关联的所有子节点。 SELECT id, name, parent_id from test001 START WITH id 1 CONNECT BY PRIOR id parent_id 2、row_number() over pa…...

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第六天-ARM Linux编程之SMP系统 (物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取码&#xff1a;1688 SMP&#xff08;Symmetric Multi-Processing&#xff09;&#xff0c;对称多处理结构的简称&#xff0c;是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系…...

html5播放 m3u8

注意&#xff1a;m3u8地址要为网络地址&#xff0c;直接把代码复制为html直接在本地打开&#xff0c;可能不行&#xff0c;需要放在nginx或者apache或者其他的web服务器上运行。 <!DOCTYPE html> <html> <head><meta charsetutf-8 /><title>测试…...

微信小程序按需注入和用时注入

官网链接 按需注入 {"lazyCodeLoading": "requiredComponents" }注意事项 启用按需注入后&#xff0c;小程序仅注入当前访问页面所需的自定义组件和页面代码。未访问的页面、当前页面未声明的自定义组件不会被加载和初始化&#xff0c;对应代码文件将不…...

iPhone 16 组件泄露 揭示了新的相机设计

iPhone 16 的发布似乎已经等了很长一段时间&#xff0c;但下一个苹果旗舰系列可能会在短短 7 个月内与我们见面——而新的组件泄漏让我们对可能即将到来的重新设计有了一些了解。后置摄像头模块。 爆料者 Majin Bu&#xff08;来自 MacRumors&#xff09;获得的示意图显示&…...

网络工程师学习笔记——IPV6

20世纪80年代&#xff0c;IETF&#xff08;Internet Engineering Task Force&#xff0c;因特网工程任务组&#xff09;发布RFC791&#xff0c;即IPv4协议&#xff0c;标志IPv4正式标准化。在此后的几十年间&#xff0c;IPv4协议成为最主流的协议之一。无数人在IPv4的基础上开发…...

【零基础学习CAPL】——CAN报文的发送(LiveCounter——生命信号)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.CAPL实现5.效果5.1.0~15循环发送5.2.固定值发送6.全量脚本1.概述 本章主要介绍带有生命信号LiveCounter的报文发送脚本 一般报文可使用CANoe的IG模块直接发送,但存在循环冗余…...

git提交代码冲突

用idea2023中的git提交代码&#xff0c;出现 error: Your local changes to the following files would be overwritten by merge: ****/****/****/init.lua Please commit your changes or stash them before you merge. Aborting 出现这个错误可能是因为你的本地修改与远…...

树莓派:使用mdadm为重要数据做RAID 1保护

树莓派作为个人服务器可玩性还是有点的。说到服务器&#xff0c;在企业的生成环境中为了保护数据&#xff0c;基本上都会用到RAID技术。比如&#xff0c;服务器两块小容量但高性能的盘做个RAID-1按装操作系统&#xff0c;余下的大容量中性能磁盘做个RAID-5或者RAID-6存放数据。…...

HTML板块左右排列布局——左侧 DIV 固定宽度,右侧 DIV 自适应宽度,填充满剩余页面

我们可以借助CSS中的 float 属性来实现。 实例&#xff1a; 布局需求&#xff1a; 左侧 DIV 固定宽度&#xff0c;右侧 DIV 自适应宽度&#xff0c;填充满剩余页面。 <!DOCTYPE html> <html><head><meta charset"UTF-8"><meta http-e…...

红旗linux安装32bit依赖库

红旗linux安装32bit依赖库 红旗linux安装32bit依赖库 lib下载 红旗-7.3-lib-32.tar.gz 解压压缩包&#xff0c;根据如下进行操作 1.回退glibc(1)查看当前glibc版本[root192 ~]# rpm -qa | grep glibcglibc-common-2.17-157.axs7.1.x86_64glibc-headers-2.17-260.axs7.5.x86_…...

Stable Diffusion教程——使用TensorRT GPU加速提升Stable Diffusion出图速度

概述 Diffusion 模型在生成图像时最大的瓶颈是速度过慢的问题。为了解决这个问题&#xff0c;Stable Diffusion 采用了多种方式来加速图像生成&#xff0c;使得实时图像生成成为可能。最核心的加速是Stable Diffusion 使用了编码器将图像从原始的 3512512 大小转换为更小的 46…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...