本文记录 Docker 部署 .NET 10.0 应用连接低版本 SQL Server 时 SSL/TLS 握手失败的排查过程,尝试禁用加密和降级 OpenSSL 协议均未奏效,最终定位为协议不兼容问题。

微信扫一扫

记录:Docker 部署 .NET Web 应用时,因 SQL Server 低版本引发的 SSL 握手异常

原创 小俞 爱名网(22科技集团)
关注
54
21小时前
记录 - Docker 部署 .NET Web 应用连接低版本 SQL Server 的 SSL 握手失败


使用 Docker 部署 .NET 10.0 Web 应用,当数据库为外部低版本 SQL Server 时,连接报错。本文记录了排查过程中的多次尝试及最终结论。


问题

应用启动后访问数据库,抛出以下异常:

Microsoft.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)

关键信息:连接已成功建立,但 SSL/TLS 握手阶段失败——低版本 SQL Server 不支持高版本加密协议。


排查过程

尝试一:修改连接字符串禁用加密

在连接字符串中添加参数,试图跳过加密握手阶段:

Encrypt=False;TrustServerCertificate=True;

结果:失败 — 禁用连接字符串层面的加密并不能绕过底层 SSL 握手。


尝试二:降低容器内 OpenSSL 协议版本

先确认容器内 OpenSSL 配置目录:

sudo docker exec <容器名称> openssl version -d

输出显示配置目录为 /usr/lib/ssl/。修改 OpenSSL 配置,将最低协议从 TLSv1.2 降到 TLSv1,安全等级从 2 降到 1:

RUN cat > /usr/lib/ssl/openssl.cnf << 'EOF'
[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = ssl_default_sect

[ssl_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT@SECLEVEL=1

EOF

结果:失败 — 仍然报同样的 SSL 握手错误。


尝试三:降低 .NET 版本为 6.0

将项目目标框架和 SqlClient 依赖降级:

<TargetFramework>net6.0</TargetFramework>
<PackageReference Include="System.Data.SqlClient" Version="4.9.1" />

Dockerfile 中使用 6.0 运行时镜像:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS final

结果:失败 — 仍然报同样的 SSL 握手错误。


尝试四:源码编译安装 OpenSSL 1.1.1 并替换

在 Dockerfile 中从源码编译 OpenSSL 1.1.1w,替换系统默认版本:

RUN apt-get update && apt-get install -y --no-install-recommends \
    wget gcc g++ make perl zlib1g-dev ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /tmp/openssl && cd /tmp/openssl && \
    wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1w.tar.gz && \
    tar -xzf openssl-1.1.1w.tar.gz && \
    cd openssl-1.1.1w && \
    ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib && \
    make -j$(nproc) && \
    make install && \
    cd / && \
    rm -rf /tmp/openssl

RUN ln -sf /usr/local/ssl/lib/libssl.so.1.1 /usr/lib/x86_64-linux-gnu/libssl.so.1.1 && \
    ln -sf /usr/local/ssl/lib/libcrypto.so.1.1 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 && \
    echo "/usr/local/ssl/lib" | tee /etc/ld.so.conf.d/openssl-1.1.1.conf && \
    ldconfig

ENV PATH="/usr/local/ssl/bin:${PATH}"

结果:失败 — 仍然报同样的 SSL 握手错误。


最终结论

尝试 方案 结果
连接字符串禁用加密 ❌ 失败
降低 OpenSSL 协议版本 ❌ 失败
降低 .NET 版本为 6.0 ❌ 失败
源码编译替换 OpenSSL 1.1.1 ❌ 失败

四次尝试均告失败。问题的根本原因是低版本 SQL Server 的 TLS 实现与 .NET 容器环境不兼容,在容器层面无法通过配置绕过。

最终解决方案:升级 SQL Server 数据库版本,连接成功 ✅

分享 0 曝光 606 浏览 54 互动 0

长按识别分享给好友

长按识别分享给好友

获取域名与品牌保护服务

请告诉我在域名、商标、品牌或知识产权保护等需求或遇到的问题,我们会尽快联系您,为您提供最优质的服务。

提交成功,感谢您的参与

支持 反馈 订阅 数据

长按下方二维码,加我微信

微信号
复制微信号

打开微信加我好友

爱名网

通过微信关注公众号