.NET 5 Error Accessing MSSQL in Docker

Posted by sean14592 on Wed, 01 Dec 2021 20:21:33 +0100

I don't know if you have Docker access to the MS SQL Server database in.NET Core/.NET 5, and if so, you will most likely encounter this error.

1 SSL version error

Recently, some business services were refactored with.NET 5 in the company. Because the old system used MS SQL Server database, this refactoring also decided to continue. However, when deploying the.NET 5 Application to Docker and passing the Swagger test, the following error was 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.

Literally, you can't see what it is. You can only locate this sentence of SSL_ERROR_SSL. After a search, it was found that the minimum protocol version of OpenSSL in the container image of.NET Core/.NET 5 requires TLSv1.2, whereas our MS SQL Server uses a lower version and does not support TLSv1.2 only.

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, clarify the problem and 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

Once the changes are made, the interface will be accessed again without error.

2 Modify Dockerfile

The above method is only a temporary solution, and re-mirroring will revert to TLSv1.2. Therefore, we need to change the Dockerfile so that it changes to TLSv1 in the source image.

For a simple Dockerfile example, just add a line of instructions to the layer of Microsoft.NET 5 mirror source:

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

Full 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 error: 35 above and is a higher version of the TLS protocol, which is not supported by SQL Server. The modification method is also changed to TLSv1. It should be noted here that I find many articles on the Internet are suggested to change to TLSv1.0, which 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 statement is applicable, but there are also some like me, even if the above statement is not enough. A search has found that TLSv1, which removes decimal points, needs to be changed to work.

3 About TLS protocol

TLS is a network security scheme implemented above the TCP transport layer and below the application layer. It is an application layer protocol in the TCP/IP four-layer network model. The TLS protocol provides data confidentiality and data integrity between two communication applications, as well as a connection identity reliability scheme.

UDP uses DTLS protocol for secure transmission, similar to TLS protocol.

The TLS protocol is designed for the following purposes:

(1) Encryption security: TLS is used to establish a secure connection between the two parties, which ensures information security through encryption, signature and data digest.

(2) Interoperability: Programmers can interoperate as long as the end-to-end code complies with RFC standards without knowing the TLS protocol.

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

(4) Relative efficiency: Encryption requires a large amount of CPU, especially public key operations. After the TLS protocol handshake is completed, the data is encrypted by the symmetric key. TLS also integrates session caching schemes to reduce the need for connections from scratch.

The TLS protocol is located in the following location:

More about TLS protocol: Read here

4 Summary

TLSv1.2 is widely used with increasing security requirements. In order to adapt to the low version of MS SQL Server, you can choose to lower the minimum version requirement of TLS protocol in Dockefile to solve the problem. However, this is an unsafe method after all, and it is recommended that you upgrade the TLS configuration of the server on which MS SQL Server resides to support TLSv1.2 if conditions permit.

 

Author: Zhou Xulong

Source: https://edisonchou.cnblogs.com

Copyright of this article is owned by both the author and the blog park. Reproduction is welcome, but this statement must be retained without the author's consent, and a link to the original text is provided in an obvious place on the article page.

Topics: ASP.NET Docker