System.Data.SqlClient
アセンブリを介してMicrosoft.Netに組み込まれているMicrosoft.Net v4.0 SqlClient接続を使用すると、特定のマシンは特定のサーバーセットに接続できません。接続しようとすると、次のエラーがスローされます。
System.Data.SqlClient.SqlException(0x80131904):サーバーとの接続は正常に確立されましたが、ログインプロセス中にエラーが発生しました。 (プロバイダー:SSLプロバイダー、エラー:0-既存の接続がリモートホストによって強制的に閉じられました。)---> System.ComponentModel.Win32Exception(0x80004005):既存の接続がリモートホストによって強制的に閉じられました System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception、Boolean breakConnection、Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj、Boolean callerHasConnectionLock、.Boolean asyncClose) 。] System.Data.SqlClient.TdsParserStateObject.SNIWritePacket(SNIHandle handle、SNIPacket packet、UInt32&sniError、Boolean canAccumulate、Boolean callerHasConnectionLock) at System.Data.SqlClient.TdsParserStateObject.WriteSni(Boolean canAccumulate) 。] System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode、Boolean canAccumulate) でSystem.Data.SqlClient.TdsParser.TdsLogin(SqlLogin rec) でSystem.Data.SqlClientで。 SqlInte rnalConnectionTds.AttemptOneLogin(ServerInfo serverInfo、String newPassword、SecureString newSecurePassword、Boolean ignoreSniOpenTimeout、TimeoutTimer timeout、Boolean withFailover) at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo、String newPassword、SecureString newSecurePassword、Boolean SqlConnectionString connectionOptions、SqlCredential credential、TimeoutTimer timeout) at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout、SqlConnectionString connectionOptions、SqlCredential credential、String newPassword、SecureString newSecurePassword、[Boolean redirectedUserInstance) .Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity、SqlConnectionString connectionOptions、SqlCredential credential、Object providerInfo、String newPassword、SecureString newSecurePassword、Boolean redirectedUserInstance、SqlConnectionString userConnec System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options、DbConnectionPoolKey poolKey、Object poolGroupProviderInfo、DbConnectionPool pool、DbConnection owningConnection、DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionFactory。at OptionOptions) CreateNonPooledConnection(DbConnection owningConnection、DbConnectionPoolGroup poolGroup、DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection、TaskCompletionSource`1 retry、DbConnectionOptions userOptions、DbConnectionInternal&connection)[.____。 .ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection、DbConnectionFactory connectionFactory、TaskCompletionSource`1 retry、DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) システムで。 Data.SqlClient.SqlConnection.Open() at ConsoleApplication1.Module1.Main()
他のマシンから同じターゲットサーバーに同じバイナリを使用して問題なく接続できます。 Microsoft.Net v2.0に対してバイナリを再コンパイルすると、問題のあるサーバーから接続することもできます。
ターゲットサーバーは失敗したログインを監査するように構成されていますが、この問題の結果としてSQL Serverエラーログに失敗が記録されません-I can無効な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を無効にしてもSSLを使用することを強制しているようです。
何をチェックすべきか?
Microsoft .Net Frameworkバージョン4.6.2をインストールすると、私たちの環境でこの問題が解決され、 この.Net Framework 4.6のMicrosoftドキュメント移行ガイド に示されている問題に関連しているようです。
影響を受けるすべてのマシンには、.Net Frameworkバージョン4.5または4.5.1があり、vfsocklib.dllを通じてVMware vSockets DGRAMおよびvSockets STREAM Base Service Providersがあり、非IFSコンプライアンスを通知します。
特定のSQL Server 2016インスタンスに接続しようとしたときにのみこの問題が発生する理由は未解決のままです。