You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带客户端证书的.NET HttpClient在Linux下异常,求排查方案

问题排查:.NET HttpClient双向SSL握手失败(Windows偶发/Linux必现)

我的请求配置代码如下:

var url = "https://api.the.url.com/path/ver/endpoint";
var certFile = "TheFile.pfx";
var certPass = "ThePassword";

var cert = new X509Certificate2(
    Path.Combine(AppContext.BaseDirectory, certFile),
    certPass, X509KeyStorageFlags.MachineKeySet);

var handler = new SocketsHttpHandler();
handler.SslOptions.ClientCertificates = new X509CertificateCollection();
handler.SslOptions.ClientCertificates.Add(cert);
handler.SslOptions.LocalCertificateSelectionCallback = (_,_,_,_,_) => cert;

var httpClient = HttpClientFactory.Create(handler);
var result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();

该请求在Windows上偶尔失败,在Linux上则始终失败,错误信息:

The SSL connection could not be established, see inner exception.

Unable to write data to the transport connection: Connection reset by peer.

Connection reset by peer

TCP流量分析显示,客户端ACK服务器的Server Key Exchange/Server Hello Done后,握手就停止了,Windows抓包内容如下:

TCP        66    44222 → 443 [SYN, ECE, CWR] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
TCP        66    443 → 44222 [SYN, ACK, ECE] Seq=0 Ack=1 Win=14600 Len=0 MSS=1436 WS=1 SACK_PERM
TCP        54    44222 → 443 [ACK] Seq=1 Ack=1 Win=262656 Len=0
TLSv1.2   328    Client Hello
TCP        60    443 → 44222 [ACK] Seq=1 Ack=275 Win=14874 Len=0
TLSv1.2  1514    Server Hello
TCP      1514    443 → 44222 [ACK] Seq=1461 Ack=275 Win=14874 Len=1460 [TCP segment of a reassembled PDU]
TCP        54    44222 → 443 [ACK] Seq=275 Ack=2921 Win=262656 Len=0
TLSv1.2  1514    Certificate, Server Key Exchange
TLSv1.2   360    Certificate Request, Server Hello Done
TCP        54    44222 → 443 [ACK] Seq=275 Ack=4687 Win=262656 Len=0
TCP       109    443 → 44222 [RST, ACK] Seq=4687 Ack=275 Win=0 Len=55

正常情况下,此时应该收到以下内容而非RST, ACK:

TLSv1.2   2043    Certificate, Client Key Exchange, Certificate Verify, Change Cipher Spec, Encrypted Handshake Message
TCP         60    443 → 44566 [ACK] Seq=4687 Ack=2264 Win=16863 Len=0
TLSv1.2    105    Change Cipher Spec, Encrypted Handshake Message
TLSv1.2    153    Application Data
TCP         60    443 → 44566 [ACK] Seq=4738 Ack=2363 Win=16962 Len=0
TLSv1.2    642    Application Data
TLSv1.2     88    Application Data
TCP         54    44566 → 443 [ACK] Seq=2363 Ack=5360 Win=261888 Len=0
TCP         54    44566 → 443 [RST, ACK] Seq=2363 Ack=5360 Win=0 Len=0

这段代码之前能正常运行,突然就失效了。Linux机器上用等效的cUrl请求可以正常工作,所以问题应该和.NET相关。我试过用RestSharp,但推测它底层还是用HttpClient,所以遇到同样的错误。我已经用nmap --script ssl-enum-ciphers扫描目标URL,并且修改HTTP Handler指定SSL协议和密码套件,但结果没有变化。

请问接下来应该怎么排查?

更新1:
已获取Linux系统的TCP抓包,发现RST是由于ssl handshake timeout exceeded导致。我认为无法通过HttpClient跳过SSL验证,只能忽略验证结果。尝试用SslStream,但这个组件也没有相关设置。

更新2:
已添加事件监听器并在控制台打印日志。同时在Linux虚拟机中运行代码,以便Wireshark捕获虚拟接口的全部流量(此前仅过滤目标IP)。

内容的提问来源于stack exchange,提问作者herme 0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:14:57