使用pyodbc+ODBC Driver 18连接SQL Server报错0x2746(10054)求助
错误原因分析
错误代码0x2746 (10054)本质是TCP连接被远程主机重置,结合ODBC Driver 18的上下文,核心诱因是TLS版本协商失败:
- 你的Dockerfile中通过
sed -i "s|TLSv1.2|TLSv1.0|g" /etc/ssl/openssl.cnf强制将系统默认TLS版本改为1.0,而近期SQL Server端大概率禁用了TLS 1.0/1.1(出于安全合规要求),导致连接握手时被拒绝。 - Python3.8镜像的底层系统(如Debian 12)默认使用OpenSSL 3.x,该版本默认禁用了TLS 1.0/1.1,即使修改
openssl.cnf也无法生效;而Python3.11镜像可能保留了兼容的TLS配置或依赖库版本,因此能正常连接。
解决方法
1. 恢复系统默认TLS配置
删除Dockerfile中这行强制修改TLS版本的命令:
RUN sed -i "s|TLSv1.2|TLSv1.0|g" /etc/ssl/openssl.cnf
ODBC Driver 18默认支持TLS 1.2,符合当前SQL Server的安全要求。
2. 清理Dockerfile冗余配置
当前Dockerfile存在重复添加微软源、重复安装驱动的问题,容易引发依赖冲突,整理后的Dockerfile如下:
FROM python:3.8 # 安装基础依赖并添加微软源 RUN apt-get update \ && apt-get install -y curl gnupg gcc g++ unixodbc unixodbc-dev libgssapi-krb5-2 \ && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \ && curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list \ && apt-get update \ # 安装ODBC驱动和工具 && ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean # 添加mssql-tools到PATH(确保容器启动时生效) ENV PATH="$PATH:/opt/mssql-tools18/bin"
说明:
- 统一使用Debian 11的微软源(匹配python:3.8的底层系统)
- 合并重复的安装命令,减少镜像层数和冗余
- 使用
ENV而非RUN export,保证环境变量在容器运行时生效
3. 验证连接字符串参数
确保连接字符串中ENCRYPT=no的配置与SQL Server端一致,如果SQL Server强制要求加密,需改为ENCRYPT=yes并按需调整TrustServerCertificate参数:
cnxn = pyodbc.connect( 'DRIVER={ODBC Driver 18 for SQL Server};SERVER=' + server + ';DATABASE=' + db + ';UID=' + username + ';PWD=' + password + ';ENCRYPT=no', autocommit=True )
4. 强制指定TLS版本(临时应急方案,不推荐)
如果必须使用TLS 1.0(仅适用于SQL Server仍允许旧版本的场景),需在OpenSSL配置中明确启用,修改Dockerfile添加:
RUN echo -e "\nMinProtocol = TLSv1.0\nCipherString = DEFAULT@SECLEVEL=1" >> /etc/ssl/openssl.cnf
该配置会降低系统安全性,仅作为临时修复手段。
内容的提问来源于stack exchange,提问作者Álvaro Navarro Navarro
相关产品推荐
相关产品推荐

