Usando a conectividade SqlClient do Microsoft.Net v4.0 integrada ao Microsoft.Net por meio do System.Data.SqlClient
assembly, uma máquina específica não pode se conectar a um conjunto específico de servidores. Quando as conexões são tentadas, o seguinte erro é gerado:
System.Data.SqlClient.SqlException (0x80131904): Uma conexão foi estabelecida com sucesso com o servidor, mas ocorreu um erro durante o processo de login. (provedor: Provedor SSL, erro: 0 - Uma conexão existente foi fechada à força pelo host remoto.) ---> System.ComponentModel.Win32Exception (0x80004005): Uma conexão existente foi fechada à força pelo host remoto em System.Data.SqlClient.SqlInternalConnection.OnError(exceção SqlException, booleano breakConnection, Action`1 wrapCloseInAction) em System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) em System.Data.SqlClient.TdsParserStateObject.SNIWritePacket(SNIHandle handle, SNIPacket packet, UInt32& sniError, Boolean canAccumulate, Boolean callerHasConnectionLock) em System.Data.SqlClient.TdsParserStateObject.WriteSni(Boolean canAccumulate) em System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode, Boolean canAccumulate) em System.Data.SqlClient.TdsParser.TdsLogin(SqlLogin rec) em System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) em System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) em System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) em System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo,String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions) em System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) em System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) em System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 nova tentativa, DbConnectionOptions userOptions, DbConnectionInternal& connection) em System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 nova tentativa, DbConnectionOptions userOptions) em System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 nova tentativa) em System.Data.SqlClient.SqlConnection.Open() em ConsoleApplication1.Module1.Main()
Posso me conectar de outras máquinas ao mesmo servidor de destino usando o mesmo binário sem problemas. Também posso me conectar a partir do servidor problemático se recompilar o binário no Microsoft.Net v2.0.
O servidor de destino está configurado para auditar logins com falha, no entanto, nenhuma falha é registrada no log de erros do SQL Server como resultado desse problema - posso causar uma entrada de auditoria se fizer login com um login inválido do SQL Server apenas para ter certeza de que a auditoria está funcionando .
O código que estou usando para testar esse problema é:
Module Module1
Sub Main()
Dim bUseSSL As Boolean = False
If My.Application.CommandLineArgs.Contains("/SSL") Then
bUseSSL = True
End If
If bUseSSL Then
Console.WriteLine("Encryption enabled")
Else
Console.WriteLine("Encryption disabled")
End If
Dim cb As New Data.SqlClient.SqlConnectionStringBuilder
cb.ApplicationName = "SqlClientTest"
cb.DataSource = "<server_name_here>"
cb.IntegratedSecurity = True
cb.Encrypt = bUseSSL
'cb.TrustServerCertificate = True
cb.NetworkLibrary = "dbmssocn"
Try
Using sqlconnection As New System.Data.SqlClient.SqlConnection(cb.ConnectionString)
Try
sqlconnection.Open()
Console.WriteLine("Connected to " & cb.DataSource)
Dim sqlcommand As New System.Data.SqlClient.SqlCommand("SELECT @@SERVERNAME;", sqlconnection)
Dim sqlreader As System.Data.SqlClient.SqlDataReader = sqlcommand.ExecuteReader
While sqlreader.Read
Console.WriteLine(sqlreader.GetString(0))
End While
sqlreader.Close()
Catch ex As Exception
Console.WriteLine(cb.ConnectionString)
Console.WriteLine("")
Console.WriteLine(ex.ToString)
End Try
Console.WriteLine("Press 'q' to quit.")
Dim cki As ConsoleKeyInfo = Console.ReadKey
While cki.KeyChar.ToString.ToLower <> "q"
cki = Console.ReadKey
End While
End Using
Catch ex As Exception
Console.WriteLine(cb.ConnectionString)
Console.WriteLine("")
Console.WriteLine(ex.ToString)
End Try
End Sub
End Module
A mesma falha é registrada independentemente da configuração de criptografia e independentemente da TrustServerCertificate
configuração.
Algo parece estar forçando o .Net SqlClient v4.0 nesta máquina a usar SSL mesmo se eu desativá-lo através da string de conexão.
Alguma ideia do que verificar?
A instalação do Microsoft .Net Framework versão 4.6.2 resolve esse problema em nosso ambiente e parece estar relacionado ao problema apresentado neste guia de migração do Microsoft Docs para .Net Framework 4.6 .
Todas as máquinas afetadas têm o .Net Framework Versão 4.5 ou 4.5.1 e têm os provedores de serviços VMware vSockets DGRAM e vSockets STREAM Base por meio do vsocklib.dll que anunciam a não conformidade com IFS.
Por que esse problema aparece apenas ao tentar conexões com determinadas instâncias do SQL Server 2016 permanece uma questão em aberto.