SQL Server 登录前握手(错误:31 - 加密(ssl/tls)握手失败)

问题描述 投票:0回答:4

我有一个 SQL 服务器版本

12.0.6205
以及 .Net Core 3.1(或 6)Web Api 控制器中的以下代码:

 var builder = new SqlConnectionStringBuilder
{
    DataSource = DataSource,
    UserID = UserID,
    Password = Password,
    InitialCatalog = InitialCatalog,
    ApplicationIntent = ApplicationIntent.ReadWrite,
    
    // Same result if true/true
    Encrypt = false,
    TrustServerCertificate = false
};

var connection = new SqlConnection(builder.ToString());
using (var cmd = new SqlCommand() { Connection = connection, CommandText = "SELECT TOP 1 * FROM [dbo].[Table]" })
{
    connection.Open(); // Breaks here
    var reader = cmd.ExecuteReader();
    Console.WriteLine(reader.HasRows);
}

此代码在本地运行没有问题,但在 Azure 的应用程序服务中执行时,在打开以下连接时会中断:

System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)

如果创建的话,我也能够在本地重现错误 基于

appsvc/dotnetcore
(任何标签)

的 docker 镜像
FROM mcr.microsoft.com/appsvc/dotnetcore:3.1-latest_20220105.1

ENV ASPNETCORE_URLS=http://+:80  

EXPOSE 8080
WORKDIR /home/site/wwwroot/
COPY . .

ENTRYPOINT ["dotnet", "Test.dll"]
c# sql-server azure asp.net-core azure-web-app-service
4个回答
11
投票

就像 @DraggonDragger 所说,这是一个 TLS 问题,但在我的具体情况下,我不能依赖更新的 SQL 服务器来允许 TLS 1.2,因此我必须在应用程序中允许 TLS 1.0。

我最终遵循了这个答案:https://stackoverflow.com/a/61523341/17892120;

本质上,对于 docker 镜像,添加这一行就足够了:

RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

对于 Azure 的应用服务,我们可以添加

sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf && dotnet Test.dll
用于启动命令。

为了将来参考,GitHub 中也有关于此的讨论,link


3
投票
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

到 ENTRYPOINT 正上方的 Dockerfile

https://github.com/dotnet/SqlClient/issues/633


1
投票

GitHub中发现了类似的问题,即 SQL Server Pre-Login Handshake with Docker Image 中的 TLS HandShake Failure。

此外,此错误通常发生在 docker 映像容器、Unix 客户端或 Windows 客户端等客户端环境中,其中 TLS 1.2 是支持的最低 TLS 协议。

在受支持的 SQL Server1 版本上安装最新更新,并确保服务器上启用 TLS 1.2 协议。

  1. 在客户端环境中安装目标 SQL Server 的 TLS/SSL 证书。是否需要加密将会被验证。
  2. 在连接字符串中设置“Trust Server Certificate = true”属性。
  3. 为其哈希至少使用 SHA-256 哈希算法签名的服务器生成新的 TLS/SSL 证书。

参考:微软登录前握手错误解决方案


0
投票

如果您使用的是 Windows 并使用 Docker for SQL Server:

sudo docker run -e "ACCEPT_EULA=Y" -e 'MSSQL_SA_PASSWORD=YourStrongPassword' -p 1434:1433 --name sql1 --hostname sql1 -d mcr.microsoft.com/mssql/server

确保端口映射避免与 Windows 上的其他服务发生冲突。如有必要,请使用不同的外部端口(例如 1434)以避免冲突。请注意,SQL Server 的 SSL 端口默认为 1433。使用映射端口连接 SSMS 并确保相应配置 TLS 设置。

© www.soinside.com 2019 - 2024. All rights reserved.