赞
踩
前面的《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的上游服务器健康检测的能力。
本次支持的功能:
暂时不支持的功能:
&ems; 由于本次主要是检验https的链接握手流程,对一些不是特别关键的ssl握手特性暂时不支持主要是为了简化代码逻辑,但是不影响业务流程,这样也便于在本文中将整个实现流程进行阐述。后续可以参照ngx_stream_proxy_module中的实现,继续将这些特性进行完善,以臻于完美。
首先来看一下实现后的效果,有一些感性的认识。
#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 { check type=https interval=3000 rise=2 fall=5 timeout=1000 port=443; check_http_send "GET / HTTP/1.1\r\nHost: www.test.com\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; check_ssl_server_name www.test.com; server 192.168.0.1: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; } } }
以上配置文件中的upstream块中定义了一个https的健康检测类型, check_http_send复用了http的定义,而check_ssl_server_name是新增的指令,用来配置ssl握手设置sni扩展主机host信息。
查看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的检测功能已经可用了。
支持的配置指令如下:
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在解析配置文件的时候出现参数重复的报错。
#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, ssl_server_name), NULL }, #endif
通过以上配置指令,可以将解析到的参数设置到ngx_http_upstream_check_srv_conf_s结构体对应的字段中。其中ngx_upstream_check_ssl_protocols是一个可选协议的列表,定义如下:
#if (NGX_HTTP_SSL)
static ngx_conf_bitmask_t ngx_upstream_check_ssl_protocols[] = {
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
{ ngx_string("SSLv3"), NGX_SSL_SSLv3 },
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
{ ngx_null_string, 0 }
};
#endif
nginx upstream server主动健康监测模块添加https检测功能【完整版】
可以点击进行源码下载
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。