记录:Docker 部署 .NET Web 应用时,因 SQL Server 低版本引发的 SSL 握手异常
本文包含AI辅助创作内容
使用 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 数据库版本,连接成功 ✅
请先 登录后发表评论 ~