Mono容器无法访问自签名证书API:MonoBtlsException证书验证失败
解决Mono容器内WebClient无法验证自签名证书的问题
问题背景
使用mono:6.12.0.182容器通过host.testcontainers.internal:[PORT]对接.NET 10 API做集成测试:
- API通过Kestrel初始化,自动分配端口,为
host.testcontainers.internal生成自签名证书并暴露给容器 - 容器内通过
trust-self-signed.sh脚本导入证书,系统CA已更新,Mono密钥存储(含BTLS)显示导入成功 curl、openssl可正常访问API,但Mono的WebClient抛出MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
解决方案
1. 手动同步证书到Mono BTLS存储
Mono 6.x的BTLS(BoringSSL)使用独立的证书目录,需将自签名证书复制到对应路径并生成哈希链接:
# 假设证书已保存为/api-cert.crt cp /api-cert.crt /usr/share/mono/btls/ cd /usr/share/mono/btls/ # 生成证书哈希并创建软链接 ln -sf api-cert.crt $(openssl x509 -hash -noout -in api-cert.crt).0
2. 使用Mono官方工具导入证书
update-ca-certificates不会自动同步到Mono的证书存储,需用certmgr手动导入到信任根CA:
certmgr -add -c Trust /api-cert.crt
3. 强制Mono使用系统CA证书(临时方案)
通过环境变量让Mono跳过自身BTLS存储,直接读取系统CA bundle:
export MONO_TLS_PROVIDER=legacy export MONO_CERTIFICATE_FILE=/etc/ssl/certs/ca-certificates.crt
可在Testcontainers初始化容器时注入这些环境变量。
4. 测试环境临时禁用证书验证(不推荐生产)
如果仅为集成测试场景,可在客户端代码中临时跳过证书校验:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
关键原因
Mono 6.x的BTLS实现拥有独立的证书存储,与系统OpenSSL的CA存储不自动同步。即使update-ca-certificates更新了系统证书,Mono的BTLS仍会读取自身目录下的证书列表,导致验证失败。
内容的提问来源于stack exchange,提问作者Alexander Ivanov
相关产品推荐
相关产品推荐

