不知道你有没有在.NET Core/.NET 5的Docker访问MS SQL Server数据库,如果有,那么很有可能会遇到这个错误。

1 SSL版本错误

最近在公司用.NET 5重构部分业务服务,由于之前老系统使用了MS SQL Server数据库,因此本次重构也决定继续使用。但是,在将.NET 5应用部署到Docker中通过Swagger测试时,却报了以下一个错误:

Microsoft.Data.SqlClient.SqlException (0x80131904):
A connection was successfully established with the server,
but then an error occurred during the pre-login handshake.
(provider: TCP Provider, error: 35 - An internal exception was caught)
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.

从字面意思来看,看不出来是啥,只能定位这一句 SSL_ERROR_SSL。搜索一番,发现在.NET Core/.NET 5的容器镜像中的OpenSSL的最低协议版本要求为TLSv1.2,而我们的MS SQL Server所用的版本较低,不支持TLSv1.2只支持TLSv1

我们可以进入容器内部去验证下:

# docker exec -it <docker-name> /bin/bash
# cat /etc/ssl/openssl.cnf .......
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2

因此,明确了问题,直接在容器内部更改一下:将TLSv1.2改为TLSv1即可

# docker exec -it <docker-name> /bin/bash
# vi /etc/ssl/openssl.cnf .......
[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT@SECLEVEL=2

更改完成后,再次访问接口,就不会报错了。

2 修改Dockerfile

上面的方法只是一个临时方案,重新打镜像运行又会恢复为TLSv1.2。因此,我们需要更改Dockerfile,让其在源镜像中就更改为TLSv1。

这里以一个简单的Dockerfile为例,只需要在微软.NET 5镜像源的层中增加一行指令即可:

RUN sed -i 's/TLSv1.2/TLSv1/g' /etc/ssl/openssl.cnf

完整Dockerfile示例:

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
RUN sed -i 's/TLSv1.2/TLSv1/g' /etc/ssl/openssl.cnf
EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["AuthCenter.API/AuthCenter.API.csproj", "AuthCenter.API/"]
RUN dotnet restore "AuthCenter.API/AuthCenter.API.csproj"
COPY . .
WORKDIR "/src/AuthCenter.API"
RUN dotnet build "AuthCenter.API.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "AuthCenter.API.csproj" -c Release -o /app/publish FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AuthCenter.API.dll"]

其他相关联的OpenSSL错误:

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

这个错误和上面的error: 35类似,也是TLS协议版本较高,而SQL Server不支持。修改方法也是改为TLSv1,这里需要注意的是,我发现网上很多文章都是建议改为TLSv1.0,也就是下面的指令:

RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf

对于网上大多数童鞋,上面的语句是适用的,但是也有一些和我一样的,即使使用了上面的语句还不行。一番搜索发现,需要改为TLSv1(即去掉小数点)才能工作。

3 关于TLS协议

TLS是在TCP传输层之上,应用层之下实现的网络安全方案。在TCP/IP四层网络模型中属于应用层协议。TLS协议在两个通信应用程序之间提供数据保密性和数据完整性,另外还提供了连接身份可靠性方案。

UDP则使用DTLS协议实现安全传输,和TLS协议类似。

TLS协议的设计目的如下:

(1)加密安全:TLS应用于双方之间建立安全连接,通过加密,签名,数据摘要保障信息安全。

(2)互操作性:程序员在不清楚TLS协议的情况下,只要对端代码符合RFC标准的情况下都可以实现互操作。

(3)可扩展性:在必要时可以通过扩展机制添加新的公钥和机密方法,避免创建新协议。

(4)相对效率:加密需要占用大量CPU,尤其是公钥操作。TLS协议握手完成后,通过对称密钥加密数据。TLS还集成了会话缓存方案,减少需要从头建立连接的情况。

TLS协议所处的位置如下所示:

更多关于TLS协议的介绍:点此阅读

4 总结

在要求安全性越来越高的前提下,TLSv1.2被广泛应用,为了适配MS SQL Server的低版本,可以选择在Dockefile中降低TLS协议最低版本要求来解决问题。不过,这毕竟是一个不安全的方法,如果有条件,还是建议升级MS SQL Server所在服务器的TLS配置,使其支持TLSv1.2。

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

.NET 5在Docker中访问MSSQL报错的更多相关文章

  1. hue中访问impala报错

    hue中访问impala报错:Could not connect to node03:21050 原因:impala服务未启动. 解决方法:在3个节点上都启动impala: 主节点node03启动以下 ...

  2. hue中访问hdfs报错

    在hue中访问hdfs报错: Cannot access: /. Note: you are a Hue admin but not a HDFS superuser, "hdfs" ...

  3. 项目中访问controller报错:HTTP Status 500 - Servlet.init() for servlet spring threw exception

    直接访问controller路径http://localhost:8080/index报错: HTTP Status 500 - Servlet.init() for servlet spring t ...

  4. ASP.NET Global Application_Error事件中访问Session报错 解决

    报错信息:会话状态在此上下文中不可用 protected void Application_Error(object sender, EventArgs e) { //以此判断是否可用Session ...

  5. Navicat连接Docker中的mysql报错:client does not support authentication

    1.进入mysql容器中 docker exec -it mysqltest(mysql容器名称) bash 2.进入mysql数据库 mysql -uroot -p 3.输入mysql密码 4.远程 ...

  6. docker中启动mysql报错

    [root@5416ec39653b init.d]# /etc/init.d/mysqld start /etc/init.d/mysqld: line 23: /etc/sysconfig/net ...

  7. docker中运行envoy 报错 cannot bind '0.0.0.0:80': Permission denied

    docker-compose文件 version: '3' services: envoy: image: envoyproxy/envoy-alpine:v1.15-latest volumes: ...

  8. 【原创】大叔经验分享(49)hue访问hdfs报错/hue访问oozie editor页面卡住

    hue中使用hue用户(hue admin)访问hdfs报错: Cannot access: /. Note: you are a Hue admin but not a HDFS superuser ...

  9. php中各种http报错的状态码分析

    HTTP会经常遇见错误,本文主要和大家分享php中各种http报错的状态码,希望能帮助到大家. HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无 ...

  10. docker安装mtproto及报错解决方案

    安装docker:curl -sSL https://get.daocloud.io/docker | sh 给权限:usermod -aG docker [current_user] 启动:syst ...

随机推荐

  1. 【JVM之内存与垃圾回收篇】垃圾回收概述

    垃圾回收概述 概念 这次我们主要关注的是黄色部分,内存的分配与回收 垃圾收集 垃圾收集,不是 Java 语言的伴生产物.早在 1960 年,第一门开始使用内存动态分配和垃圾收集技术的 Lisp 语言诞 ...

  2. SMU Autumn 2024 Trial 1

    A. Load Balancing 很明显题意要的就是让我们把每个数往平均值靠,这样就保证最大值-最小值最小 但是当sum%n !=0的时候就说明无法每个数都等于sum/n,所以处理的方法就是,先计算 ...

  3. MYSQL数据库 MariaDB断电恢复总结

    背景:本次是机房异常断电,导致数据库文件损坏.在数据库自启动之后频繁宕机,在多次尝试以后,总结了一下几种方法,及供参考. 1.mariadb服务器断电重启之后Missing MLOG_CHECKPOI ...

  4. C# LINQ 快速入门实战指南,建议收藏学习!

    前言 因为咱们的.NET EF Core快速入门实战教程经常会用到 LINQ 去查询和操作 MySQL 中的数据,因此我觉得很有必要对 LINQ 的一些使用技巧.常用方法.特性做一个详细的介绍,让大家 ...

  5. Selenium+pytest 页面对象模型框架

    下载地址:https://gitee.com/xiaopo1998/web_ui_test.git Selenium 页面对象模型框架使用说明 本框架基于 Selenium WebDriver 实现了 ...

  6. element ui select组件 实现鼠标悬浮 自动展开选项

    利用鼠标悬浮事件: 同样的原理也可以设置鼠标移开自动关闭

  7. Android编译时动态插入代码原理与实践

    本文同步发布于公众号:移动开发那些事:Android编译时动态插入代码原理与实践 Android开发中,编译时动态插入代码是一种高效,并且对业务逻辑是低侵入性的方案,常用于增加通用的埋点能力,或者插入 ...

  8. Windows下将QT打包为可执行文件(exe)的完整流程,包含第三方库。

    打包我的 Qt/C++ 视觉应用:从依赖部署到单文件 EXE 的踩坑之旅 一.前言 最近完成了一个基于 Qt/C++ 的桌面视觉应用项目(proj_ai_vision_app).这个项目功能还挺复杂, ...

  9. 浏览器js如何获取系统信息?

    在浏览器中,JavaScript 无法直接获取完整的系统级信息(如硬件配置.操作系统版本等),但可以通过以下 API 获取部分与设备和浏览器相关的信息: ​​1. 使用 navigator 对象​​ ...

  10. Windows路径或者Linux路径映射成web路径进行访问代码

    package com.soft.mpms.zframe.config; import java.io.File; import org.springframework.context.annotat ...