百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

实战:一次“诡异” 的 Nginx 异常排查,真相竟不是证书问题?

haoteby 2025-10-13 20:49 4 浏览

提示:文章前面部分是关于 nginx 下 https 连接 curl 请求被 reset 的处理经历,不想看可以直接跳到最后看nginx快速定位异常,建议收藏!

问题描述

网站上线后,添加了 https 证书,浏览器访问正常,通过 curl 请求,请求被 reset,如上图。

一路艰难

先 curl 请求同域名下 http 的 url,返回正常,说明两边起码 80 端口网络正常

接着 curl 请求网站同服务器下其他 https 域名,返回正常,说明两边 443 端口网络正常。

难道是证书问题?查看证书未到期,通过 myssl.com 查询证书详情,没有问题。

怀疑加密套件配置文件,添加兼容性更高的加密套件后尝试,依然无果

附兼容性加密套件:

"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!a:!e:!EXPORT:!DES:!MD5:!PSK:!RC4" 

仍然无果后,决定 tcpdump 两边抓包,用 wireshark 分析

从发起请求到 reset,总共16个包,看到是两端握手完成,发起数据传输之后,开始传输数据的第一个确认包就被 reset 了,百思不得其解

难道是客户端发送的数据太大,nginx 的 buffer 不够?

修改了 nginx 关于 client 的相关设置如下:

client_header_buffer_size 64k; large_client_header_buffers 4 64k; client_body_buffer_size 20m; keepalive_timeout 120; 

因为从抓包看,还没到fastcgi部分,所以不修改关于fastcgi的buffer部分配置

修改后结果仍然一样,有点方了

虽然知道应该和证书关系不大,但是还是决定更换一个证书看看,因为之前是RSA的证书,那我换个ECC的证书试试。

换过之后有新的发现

curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s). 

无法与对等体安全通信:无通用加密算法

问题没解决,还出来新问题了,猜测ECC算法兼容性问题,通过一番 google 之后,了解到如下信息:

原来 Redhat/CentOS 服务器上 curl 默认是使用 NSS 库的,而在这两个系统上 curl 默认是禁用ECC加密的,虽然服务端加密套件支持 ECC,但是客户端不支持,所以请求失败,需要客户端 curl 通过指定加密套件来请求:

curl --ciphers ecdhe_rsa_aes_128_gcm_sha_256 ... 

指定加密套件后,又回到起点,仍然是原来的错误,看来和证书没有关系。

柳暗花明

没办法,仔细对比了其他网站的 nginx 配置,没什么不一样,只是没有配 ssl_session_cache ,以我对该参数的了解,该参数只是作为 ssl 优化的一个配置,起到缓存的作用,减少握手次数,但是现在已经“穷途末路”了,先配上再说

万万没想到,好了

抑制着想要吃涮羊肉的心情,又去 nginx 官网查了下 ssl_session_cache 参数的解释

总结如下:

ssl_session_cache 有4个可选参数

  • off

    严禁使用session缓存:nginx明确告诉客户端session可能不会被重用

  • none

    session 缓存的使用被禁止:nginx 告诉客户端 session 可能会被重用,但实际上并不会将 session 参数存储在缓存中

  • builtin

    在 OpenSSL 中构建的缓存;仅由一个工作进程使用。缓存大小在 session 中指定。如果没有给出大小,则等于20480个会话。使用内置高速缓存可能导致内存碎片

  • shared

    所有工作进程之间共享缓存。缓存大小以字节为单位指定;一兆字节可以存储大约4000个session。每个共享缓存都应该有一个任意名称。具有相同名称的缓存可以用于多个虚拟服务器

反正就是,你要做缓存的话,就两个参数,builtin 和 shared,而且这两个参数可以同时开启,但是建议只使用 shared,性能要更高一些

但是看完我仍然理解不了,为什么加了这个参数,curl 就不报 reset 了,于是我再次抓包对比并和之前的做对比

在数据传输之前,除了没有做 Server Key Exchange外,其他没有任何不同(reset的连接过程中,多了 Server Key Exchange),通过google查询,拜读了大神的文章《Winreshark抓包理解HTTPS请求流程》了解到,密钥交换阶段,这个步骤是可选步骤,对 Certificate 阶段的补充,只有在这几个场景存在:

  • 协商采用了RSA加密,但是服务端证书没有提供RSA公钥

  • 协商采用了DH(EC Diffie-Hellman)加密,但是服务端证书没有提供DH参数

  • 协商采用了fortezza_kea加密,但是服务端证书没有提供参数

可以从包里看到,是协商使用 Diffie-Hellman 算法

分析到这里,我仍然不知道为什么 ssl_session_cache 参数会影响到 curl 的请求,无奈只能这样了,这里有大神了解的,请留言告知我,感激涕零。

下面是常见 nginx 日志中的 error 日志

1、“upstream prematurely(过早的) closed connection”

请求uri的时候出现的异常,是由于upstream还未返回应答给用户时用户断掉连接造成的,对系统没有影响,可以忽略

2、“recv failed (104: Connection reset by peer)”

(1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;

(2)客户关掉了浏览器,而服务器还在给客户端发送数据;

(3)浏览器端按了Stop

3、“(111: Connection refused) while connecting to upstream”

用户在连接时,若遇到后端upstream挂掉或者不通,会收到该错误

4、“(111: Connection refused) while reading response header from upstream”

用户在连接成功后读取数据时,若遇到后端upstream挂掉或者不通,会收到该错误

5、”(111: Connection refused) while sending request to upstream”

Nginx和upstream连接成功后发送数据时,若遇到后端upstream挂掉或者不通,会收到该错误

6、“(110: Connection timed out) while connecting to upstream”

nginx连接后面的upstream时超时

7、 (110: Connection timed out) while reading upstream”

nginx读取来自upstream的响应时超时

8、“(110: Connection timed out) while reading response header from upstream”

nginx读取来自upstream的响应头时超时

9、 (110: Connection timed out) while reading upstream”

nginx读取来自upstream的响应时超时

10、 (104: Connection reset by peer) while connecting to upstream”

upstream发送了RST,将连接重置

11、 upstream sent invalid header while reading response header from upstream”

upstream发送的响应头无效

12、 upstream sent no valid HTTP/1.0 header while reading response header from upstream”

upstream发送的响应头无效

13、 client intended to send too large body”

用于设置允许接受的客户端请求内容的最大值,默认值是1M,client发送的body超过了设置值

14、 reopening logs”

用户发送kill -USR1命令

15、 gracefully shutting down”

用户发送kill -WINCH命令

16、“no servers are inside upstream”

upstream下未配置server

17、“no live upstreams while connecting to upstream”

upstream下的server全都挂了

18、“SSL_do_handshake failed”

SSL握手失败

19、 ngx_slab_alloc failed: no memory in SSL session shared cache”

ssl_session_cache大小不够等原因造成

20、 could not add new SSL session to the session cache while SSL handshaking”

ssl_session_cache大小不够等原因造成

参考连接:
https://blog.csdn.net/firefile/article/details/80537053

小知识

  • tcpdump抓包可以,分析还是得用 wireshark

  • ECC 证书要比 RSA 证书更小,加解密更快,推荐

END

相关推荐

如何为MySQL服务器和客户机启用SSL?

用户想要与MySQL服务器建立一条安全连接时,常常依赖VPN隧道或SSH隧道。不过,获得MySQL连接的另一个办法是,启用MySQL服务器上的SSL封装器(SSLwrapper)。这每一种方法各有其...

OpenVPN客户端配置_openvpn客户端配置文件解析

...

k8s 证书问题排查_k8s dashboard 证书

从去年开始一些老项目上陆陆续续出现一些列的证书问题,(证书原理这里就不说了,官方文档一堆)多数刚开始的表现就是节点的kubelet服务起不来,节点状态NotReady表现日志如下failed...

企业级网络互通方案:云端OpenVPN+爱快路由器+Win11互联实战

企业级网络互通方案:OpenVPN搭建公有云+爱快路由器+Win11三地互联实战指南「安全高效」三地局域网秒变局域网实施环境说明...

OpenV** Server/Client配置文件详解

Server配置详解...

接口基础认知:关键信息与合规前提

1.核心技术参数(必记)...

S交换机通过SSH登录设备配置示例(RADIUS认证+本地认证独立)

说明:●本示例只介绍设备的认证相关配置,请同时确保已在RADIUS服务器上做了相关配置,如设备地址、共享密钥、创建用户等配置。●通过不同的管理域来实现RADIUS认证与本地认证两种方式同时使用,两...

SSL证书如何去除私钥密码保护_ssl证书怎么取消

有时候我们在生成证书的时候可以加入了密码保护。然后申请到证书安装到了web服务器。但是这样可能会带来麻烦。每次重启apache或者nginx的时候,都需要输入密码。那么SSL证书如何去除私钥密码保护。...

SSL证书基础知识与自签名证书生成指南

一、证书文件类型解析...

S交换机通过SSH登录设备配置示例(RADIUS认证)

说明:本示例只介绍设备的认证相关配置,请同时确保已在RADIUS服务器上做了相关配置,如设备地址、共享密钥、创建用户等配置。假设已在RADIUS服务器上创建了用户名yc123,密码test#123。对...

HTTPS是什么?加密原理和证书。SSL/TLS握手过程

秘钥的产生过程非对称加密...

HTTPS TLS握手流程_进行tls握手

1.客户端向服务器发送`ClientHello`消息,包括支持的TLS版本、加密套件、随机数等信息。2.服务器收到`ClientHello`消息后,解析其中的信息,并根据配置选择一个加密套件。3....

Spring Boot 单点登录(SSO)实现_spring boot 单点登录jwt

SpringBoot单点登录(SSO)实现全指南单点登录(SingleSign-On,SSO)是一种身份验证机制,允许用户使用一组凭证登录多个相关但独立的系统。在微服务架构和企业级系统中,SS...

源码分享:在pdf上加盖电子签章_pdf如何加盖电子公章

在pdf上加盖电子签章,并不是只是加个印章图片,。而是要使用一对密钥中的私钥对文件进行签字。为啥要用私钥呢?很简单,因为公钥是公开的,其他人才可以用公钥为你证明,这个文件是你签的。这就是我们常说的:私...

微信支付商户API证书到期 怎么更换

微信支付商户API证书到期更换是一个非常重要的操作,需要仔细按照流程进行。如果证书过期,所有通过API的支付、退款等操作都会失败,将直接影响您的业务。请按照以下详细步骤进行操作:重要前提:分清...