.NET 8独立模式Linux Azure函数混合连接TLS握手失败问题
我通过.NET 8(独立模式)Linux Azure函数调用本地部署的API,已在本地服务器配置Azure混合连接管理器(Azure Hybrid Connection Manager)。但部署后运行函数时出现以下TLS相关错误:
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error
- SSL_ERROR_SSL. ---> Interop+Crypto+OpenSslCryptographicException: error:0A000410:SSL routines::sslv3 alert handshake failure
将函数切换为.NET 6(独立模式)并更新Azure函数配置后,该错误消失。两种配置下,最低入站TLS版本均设为1.2,最低TLS密码套件均为TLS_RSA_WITH_AES_128_CBC_SHA。我尝试使用HybridConnectionDebugUtility.exe,无论.NET版本如何都能捕获请求。
简化代码示例如下:
[Function("TestFunction")] public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) { var result = string.Empty; using var handler = new HttpClientHandler { SslProtocols = SslProtocols.None }; using var client = new HttpClient(handler); client.Timeout = TimeSpan.FromMinutes(1); client.DefaultRequestHeaders.Add("key1", "value1"); client.DefaultRequestHeaders.Add("key2", "value2"); var uri = "https://sample.com/api/resources/list"; try { var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri); using var response = client.SendAsync(httpRequestMessage).Result; response.EnsureSuccessStatusCode(); result = response.Content.ReadAsStringAsync().Result; } catch (Exception ex) { result = ex.ToString(); } return new OkObjectResult(result); }
1. 明确指定TLS协议版本
代码中设置SslProtocols = SslProtocols.None会让系统自动选择协议,但.NET 8与.NET 6的TLS协议默认选择逻辑存在差异,尤其Linux环境依赖OpenSSL时更明显。手动指定TLS 1.2:
using var handler = new HttpClientHandler { SslProtocols = SslProtocols.Tls12 };
2. 启用目标TLS密码套件
.NET 8依赖的OpenSSL版本更高,TLS_RSA_WITH_AES_128_CBC_SHA这类旧套件可能被默认禁用,可通过两种方式启用:
- 在Azure函数应用设置中添加环境变量
COMPlus_TlsCipherSuiteOverride,值设为TLS_RSA_WITH_AES_128_CBC_SHA - 代码中通过
CipherSuitesPolicy指定允许的套件:
var policy = new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA }); handler.CipherSuitesPolicy = policy;
3. 本地复现并抓包对比
在本地搭建.NET 8独立模式环境复现问题,抓包对比.NET 6和.NET 8的TLS握手流程,确认协议协商、套件选择环节的差异,定位具体失败点。
4. 检查函数运行时配置
确保Linux Azure函数的.NET 8运行时配置正确:
- 确认
FUNCTIONS_EXTENSION_VERSION设为~4(对应.NET 8) - 排查其他环境变量是否对.NET运行时的TLS行为造成限制
内容的提问来源于stack exchange,提问作者lijevosmetalo

