.NET 6 Worker Service调用HTTPS接口时SSL连接建立失败(连接被对等方重置)问题求助
我最近遇到一个头疼的问题:我的.NET 6(C#)Worker Service在调用一个HTTPS接口时,突然开始报错,之前一直运行得好好的。具体错误信息如下:
The SSL connection could not be established, see inner exception.The SSL connection could not be established, see inner exception.
内部异常是:
System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer
我猜测是目标接口的服务器把我的请求给拒绝了,但问了运维同事,他们说没有做任何拦截配置。更奇怪的是,我用curl命令调用这个接口完全正常,浏览器访问也能看到SSL证书是有效的,只有我的Worker Service调用时会出问题。
我的环境信息:
- 操作系统:Debian 10
- .NET版本:6.0
我目前已经做的排查:
- 翻了一堆Stack Overflow的相关帖子,尝试了各种常见的解决方案(比如检查证书信任、调整TLS版本),但都没解决问题
一些可能的排查方向和解决建议
我之前也碰到过类似的诡异问题,给你几个具体的排查点,你可以挨个试试看:
强制指定TLS版本:有时候.NET默认的TLS版本和服务器端不兼容,你可以在Worker Service发起请求前显式指定TLS 1.2或1.3,代码大概是这样:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;把这段代码放在
Program.cs初始化部分或者Worker的构造函数里就行,要确保在HTTP请求之前执行。检查Debian系统的证书信任链:Debian 10的根证书存储和浏览器、
curl用的可能不是同一套,你可以先试试在代码里临时跳过证书验证(仅限测试,生产环境绝对不能这么干),看看能不能正常请求:var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true }; using var client = new HttpClient(handler);如果跳过验证后能正常访问,那就是系统证书信任的问题,这时候需要把目标服务器的SSL证书导入到Debian的信任根目录(比如放到
/usr/local/share/ca-certificates/后,运行update-ca-certificates命令更新)。简化HttpClient配置测试:看看你是不是给
HttpClient加了特殊的请求头、代理或者其他自定义配置,有时候这些额外配置会触发服务器端的安全拦截。可以先创建一个最基础的HttpClient实例,只做最简单的GET请求,排除配置干扰。启用.NET网络详细日志:开启.NET的网络调试日志,能看到SSL握手过程中的具体错误细节。你可以在
appsettings.json里添加如下配置:{ "Logging": { "LogLevel": { "System.Net.Http": "Debug", "System.Net.Security": "Debug" } } }启动服务后查看日志输出,应该能找到更精准的失败原因。
再麻烦运维查下服务器端日志:虽然之前运维说没拦截,但可以让他们帮忙查下服务器的防火墙、WAF或者应用日志,看看你的Worker Service的IP是不是因为请求格式、频率或者其他规则被拦截了——毕竟
curl和程序的请求头、连接方式可能不一样,服务器端的规则说不定只针对特定请求特征。
备注:内容来源于stack exchange,提问作者darkcloudbird

