. NET 5 error reporting when accessing MSSQL in Docker

I wonder if you have accessed the MS SQL Server database in the Docker of. NET Core/.NET 5. If so, you are likely to encounter this error.

1 SSL version error

Recently, some business services were reconstructed with. NET 5 in the company. Because the old system used MS SQL Server database before, this reconstruction also decided to continue to use it. However, when deploying the. NET 5 Application to Docker and passing the Swagger test, the following error is reported:

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.

From the literal meaning, I can't see what it is. I can only locate this sentence_ ERROR_ SSL. After searching, it is found that the minimum protocol version of OpenSSL in the container image of. NET Core/.NET 5 is TLSv1.2, while the version of our MS SQL Server is lower and does not support TLSv1.2, only TLSv1.

We can go inside the container to verify:

# docker exec -it <docker-name> /bin/bash
# cat /etc/ssl/openssl.cnf

.......
[system_default_sect] 
MinProtocol = TLSv1.2 
CipherString = DEFAULT@SECLEVEL=2

Therefore, to clarify the problem, change it directly inside the container: change TLSv1.2 to TLSv1

# docker exec -it <docker-name> /bin/bash
# vi /etc/ssl/openssl.cnf

.......
[system_default_sect] 
MinProtocol = TLSv1 
CipherString = DEFAULT@SECLEVEL=2

After the change is completed, access the interface again, and no error will be reported.

2. Modify Dockerfile

The above method is only a temporary scheme. Re mirroring will restore TLSv1.2. Therefore, we need to change the Dockerfile to TLSv1 in the source image.

Here, take a simple Dockerfile as an example. You only need to add a line of instructions in the Microsoft. NET 5 image source layer:

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

Complete Dockerfile example:

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"]

Other associated OpenSSL errors:

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)

This error is similar to the above error: 35. The TLS protocol version is higher and SQL Server does not support it. The modification method is also changed to TLSv1. It should be noted that many articles on the Internet suggest changing to TLSv1.0, that is, the following instructions:

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

For most children's shoes on the Internet, the above sentence is applicable, but there are some like me, even if the above sentence is used. A search found that it needs to be changed to TLSv1 (i.e. remove the decimal point) to work.

3 about TLS protocol

TLS is a network security scheme implemented above TCP transport layer and below application layer. It belongs to application layer protocol in TCP/IP four layer network model. TLS protocol provides data confidentiality and data integrity between two communication applications. In addition, it also provides a connection identity reliability scheme.

UDP uses DTLS protocol to realize secure transmission, which is similar to TLS protocol.

The design purpose of TLS protocol is as follows:

(1) Encryption security: TLS is used to establish a secure connection between both parties and ensure information security through encryption, signature and data summary.

(2) Interoperability: programmers can achieve interoperability without knowing the TLS protocol, as long as the peer code complies with the RFC standard.

(3) Scalability: when necessary, new public key and secret methods can be added through the extension mechanism to avoid creating new protocols.

(4) Relative efficiency: encryption requires a lot of CPU, especially public key operation. After the handshake of TLS protocol is completed, the data is encrypted by symmetric key. TLS also integrates a session caching scheme to reduce the need to establish a connection from scratch.

The location of TLS protocol is as follows:

More about TLS protocol: Click here to read

4 Summary

On the premise of higher and higher security requirements, TLSv1.2 is widely used. In order to adapt to the low version of MS SQL Server, you can choose to reduce the minimum version requirements of TLS protocol in Dockefile to solve the problem. However, this is an unsafe method after all. If possible, it is recommended to upgrade the TLS configuration of the server where MS SQL Server is located to support TLSv1.2.

Posted on Thu, 02 Dec 2021 14:11:17 -0500 by carmasha