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