location ^~ /modules/abm/ { proxy_ssl_server_name on; proxy_ssl_name 域名; proxy_set_header Host 域名; proxy_pass https://abtest_management_api_backend/modules/abm/; proxy_read_timeout 1800s; proxy_set_header Origanization-Id qiancheng; proxy_set_header X-Real-IP $clientRealIp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass_header X-Accel-Buffering; } upstream abtest_management_api_backend { server 域名:443; }
Nginx反向代理Https域名时,请求报错502问题排查
问题解决,搞定!!
四、原因分析
仔细查看nginx error日志日志如下:
2023/07/07 00:03:56 [error] 29533#29533: *115403747 SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40) while SSL handshaking to upstream, client: 192.168.73.157, server: localhost, request: "HEAD /modules/abm/_sendata_ab_testing/nm_rc-virtual-list-_c6c90.73efda43.js HTTP/1.1", upstream: "https://114.80.1xxx1:443/modules/abm/_sendata_ab_testing/nm_rc-virtual-list-_c6c90.73efda43.js", host: "www.sxzhongrui.com"
报错分析:在本地环境直接请求域名正常;但使用了nginx反向代理,在请求时DNS域名进行解析,真正请求出去的为IP与端口,但对方系统是多个域名对应一个公网ip,这个一个公网IP下映射到了多个项目和服务,通过nginx的server_name进行区分,故直接请求不通。
所以能成功请求方式有两种:
1、直接域名请求。
2、IP端口请求,但请求时需添加host。
即在nginx配置项中增加。
proxy_ssl_server_name on。
或者设置请求头。
proxy_ssl_server_name on。
proxy_ssl_name 域名。
proxy_set_header Host 域名。
(当你的nginx服务器作为反向代理,将client的请求转发到一个SSL服务器时,需要在HTTP请求头中包含SSL服务器的名称,这样SSL服务器才能正确地响应该请求。proxy_ssl_name指令就是设置proxy_pass指令所代理的SSL服务器的名称,即www.sxzhongrui.com。这样,在转发请求时,nginx就会在请求头中添加"Host: www.sxzhongrui.com"的参数,保证请求被正确地路由到目标SSL服务器。)
小知识:1.多个域名访问不同系统,使用同一个公网IP的情况;可以多个域名配置同一个公网IP和端口,映射到不同服务的nginx代理上,通过nginx配置server_name识别源域名,判定访问来源,进行请求处理。2.反向代理https请求,nginx编译安装时需要增加配置模块--with-http_ssl_module 3.使用阿里云的SLB作为负载均衡,证书可以配置在SLB上,但是要选择七层负载均衡。4.为啥添加host的时候只能写域名,不能通过变量获取。
proxy_set_header可以设置Host为、host与$http_host。
host的值设置为$proxy_host,是指nginx.conf的proxy_pass中设置的host值,也就是192.168.1.3,也就是服务器的IP地址。
不是一个固定的变量,他其实是http_HEADER通配后的结果。
http_content_type表示请求头里content-type属性的值,同理,$http_host指的就是请求头里的host属性。
$host是core模块内部的一个变量。
当请求头里不存在Host属性或者是个空值,$host则等于server_name
如果请求头里有Host属性,那么host就是www.sxzhongrui.com
变量 | 是否显示端口 | 值是否存在 |
host | 否 | "Host:value"显示值为a:b的时候,只显示a |
http_host | 是 | "Host:value",value存在就显示 |
proxy_host | 默认80不显示其他端口显示 | "Host:value"显示 |
- 参考文档 https://www.sxzhongrui.com/faberbeta/p/nginx012.html https://www.sxzhongrui.com/post/nginx反向代理当后端为https时的一些细节和原理/。