SQL Server Pre-Login Handshake (error: 31 - Encryption(ssl/tls) handshake failed)

xytpbqjk  于 2023-06-21  发布在  SQL Server
关注(0)|答案(3)|浏览(145)

I have a SQL server version 12.0.6205 and the following code in a .Net Core 3.1 (or 6) Web Api controller:

var builder = new SqlConnectionStringBuilder
{
    DataSource = DataSource,
    UserID = UserID,
    Password = Password,
    InitialCatalog = InitialCatalog,
    ApplicationIntent = ApplicationIntent.ReadWrite,
    
    // Same result if true/true
    Encrypt = false,
    TrustServerCertificate = false
};

var connection = new SqlConnection(builder.ToString());
using (var cmd = new SqlCommand() { Connection = connection, CommandText = "SELECT TOP 1 * FROM [dbo].[Table]" })
{
    connection.Open(); // Breaks here
    var reader = cmd.ExecuteReader();
    Console.WriteLine(reader.HasRows);
}

Locally this code works without issues but when executing in Azure's App service it breaks when opening the connection with:

System.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)

I also have been able to reproduce the error, locally, if creating a docker imaged based on appsvc/dotnetcore (any tag)

FROM mcr.microsoft.com/appsvc/dotnetcore:3.1-latest_20220105.1

ENV ASPNETCORE_URLS=http://+:80  

EXPOSE 8080
WORKDIR /home/site/wwwroot/
COPY . .

ENTRYPOINT ["dotnet", "Test.dll"]
h7appiyu

h7appiyu1#

Like @DraggonDragger said this is a TLS issue but in my specific case I can't rely on the SQL server being updated to allow TLS 1.2 therefore I had to allow TLS 1.0 in the application.

I ended up following this answer: https://stackoverflow.com/a/61523341/17892120;

Essentially, for docker images, adding this line is enough: RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

And for Azure's App Service, we can add sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf && dotnet Test.dll for the startup command.

For future reference, there's also a discussion about this in GitHub, link .

5fjcxozz

5fjcxozz2#

Found a similar issue in GitHub which is TLS HandShake Failure in SQL Server Pre-Login Handshake with Docker Image.

Also, This error typically occurs in client environments like docker image containers, Unix clients, or Windows clients where TLS 1.2 is the minimum supported TLS protocol.

Install the latest updates on supported versions of SQL Server1 and ensure the TLS 1.2 protocol is enabled on the server.

  1. Install the target SQL Server's TLS/SSL certificate in the client environment. It will be validated if encryption is needed.
  2. Set the "Trust Server Certificate = true" property in the connection string.
  3. Generate a new TLS/SSL Certificate for the server whose hash is signed with at-least the SHA-256 hashing algorithm.

Reference: Pre-Login Handshake Error Solution from Microsoft

voase2hg

voase2hg3#

RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

to your Dockerfile right above the ENTRYPOINT

https://github.com/dotnet/SqlClient/issues/633

相关问题