Sql-Server

0x80131904 - 現有連接被遠端主機強行關閉

  • June 15, 2020

使用通過程序集內置到 Microsoft.Net 的 Microsoft.Net v4.0 SqlClient 連接System.Data.SqlClient,特定機器無法連接到特定的一組伺服器。嘗試連接時,會引發以下錯誤:

System.Data.SqlClient.SqlException (0x80131904):與伺服器建立連接成功,但隨後在登錄過程中出錯。(提供者:SSL Provider,錯誤:0 - 現有連接被遠端主機強行關閉。)---> System.ComponentModel.Win32Exception (0x80004005):現有連接被遠端主機強行關閉
在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 異常,布爾 breakConnection,Action`1 wrapCloseInAction)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布爾呼叫者HasConnectionLock,布爾非同步關閉)
在 System.Data.SqlClient.TdsParserStateObject.SNIWritePacket(SNIHandle 句柄,SNIPacket 數據包,UInt32& sniError,布爾 canAccumulate,布爾呼叫者HasConnectionLock)
在 System.Data.SqlClient.TdsParserStateObject.WriteSni(布爾值 canAccumulate)
在 System.Data.SqlClient.TdsParserStateObject.WritePacket(字節flushMode,布爾canAccumulate)
在 System.Data.SqlClient.TdsParser.TdsLogin(SqlLogin rec)
在 System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo,字元串 newPassword,SecureString newSecurePassword,布爾型 ignoreSniOpenTimeout,TimeoutTimer 超時,布爾型 withFailover)
在 System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo,字元串 newPassword,SecureString newSecurePassword,布爾重定向使用者實例,SqlConnectionString connectionOptions,SqlCredential 憑據,TimeoutTimer 超時)
在 System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer 超時,SqlConnectionString 連接選項,SqlCredential 憑據,字元串 newPassword,SecureString newSecurePassword,布爾重定向使用者實例)
在 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity 標識,SqlConnectionString connectionOptions,SqlCredential 憑據,對象 providerInfo,String newPassword,SecureString newSecurePassword,Boolean redirectedUserInstance,SqlConnectionString userConnectionOptions)
在 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions 選項,DbConnectionPoolKey poolKey,對象 poolGroupProviderInfo,DbConnectionPool 池,DbConnection owningConnection,DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection,DbConnectionPoolGroup poolGroup,DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection,TaskCompletionSource`1 重試,DbConnectionOptions userOptions,DbConnectionInternal& 連接)
在 System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection,DbConnectionFactory connectionFactory,TaskCompletionSource`1 重試,DbConnectionOptions userOptions)
在 System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 重試)
在 System.Data.SqlClient.SqlConnection.Open()
在 ConsoleApplication1.Module1.Main()

我可以使用相同的二進製文件從其他機器連接到相同的目標伺服器而不會出現問題。如果我針對 Microsoft.Net v2.0 重新編譯二進製文件,我也可以從有問題的伺服器連接。

目標伺服器配置為審核失敗的登錄,但是由於此問題,SQL Server 錯誤日誌中沒有記錄任何失敗 -如果我使用無效的 SQL Server 登錄名登錄,我可能會導致審核條目,以確保審核正常工作.

我用來測試這個問題的程式碼是:

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

無論加密設置如何,無論設置如何,都會記錄相同的失敗TrustServerCertificate

即使我通過連接字元串將其禁用,某些東西似乎也在強制這台機器上的 .Net SqlClient v4.0 使用 SSL。

任何想法要檢查什麼?

安裝 Microsoft .Net Framework 4.6.2 版可在我們的環境中解決此問題,並且似乎與此 Microsoft Docs .Net Framework 4.6 遷移指南中提出的問題有關。

所有受影響的電腦都具有 .Net Framework 版本 4.5 或 4.5.1,並通過 vsocklib.dll 具有 VMware vSockets DGRAM 和 vSockets STREAM Base Service Providers,用於宣傳非 IFS 合規性。

為什麼僅在嘗試連接到某些 SQL Server 2016 實例時才會出現此問題仍然是一個懸而未決的問題。

引用自:https://dba.stackexchange.com/questions/219667