web-dev-qa-db-ja.com

「基になる接続が閉じられました。送信時に予期しないエラーが発生しました。」 SSL証明書あり

問題:私のログでは、 "予期せぬ接続が閉じられました:予期せぬエラーが送信中に発生しました"という例外が発生し、[1時間 - 4時間]からランダムな時期にOEMとEメールマーケティングシステムとの統合が壊れています。

私のウェブサイトはIIS 7.5.7600のWindows Server 2008 R2でホストされています。このWebサイトには多数のOEMコンポーネントと包括的なダッシュボードがあります。私たちのダッシュボード内でiframeソリューションとして使用している私たちのEメールマーケティングコンポーネントの1つを除いて、すべてはウェブサイトの他のすべての要素でうまく機能します。それが機能する方法は、私はすべての資格情報を使用してhttpWebRequestオブジェクトを送信し、私は戻ってくるiframeに入れてそれが機能するURLを取得します。しかしそれはしばらくの間働きます[1時間 - 4時間]そしてそれから私は次の例外を得ます「予期しない接続が閉じられました:予期せぬエラーが送信されました」そしてシステムがhttpWebRequestそれからURLを得ようとしても同じ例外で失敗します。それを再び機能させる唯一の方法は、アプリケーションプールをリサイクルすることであるか、何かがweb.configで編集されます。私は私が考えることができるすべてのオプションを本当に使い果たしています。

オプションが試されました

明示的に追加、keep-alive = false

keep-alive = true

タイムアウトを増やしました:<httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />

このページを非SSL Webサイトにアップロードして、本番サーバー上のSSL証明書がなんらかの方法でドロップするように接続しているかどうかを確認しました。

解決への方向は大歓迎です。

コード:

Public Function CreateHttpRequestJson(ByVal url) As String
    Try
        Dim result As String = String.Empty
        Dim httpWebRequest = DirectCast(WebRequest.Create("https://api.xxxxxxxxxxx.com/api/v3/externalsession.json"), HttpWebRequest)
        httpWebRequest.ContentType = "text/json"
        httpWebRequest.Method = "PUT"
        httpWebRequest.ContentType = "application/x-www-form-urlencoded"
        httpWebRequest.KeepAlive = False
        'ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

        'TODO change the integratorID to the serviceproviders account Id, useremail 
        Using streamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
            Dim json As String = New JavaScriptSerializer().Serialize(New With { _
            Key .Email = useremail, _
            Key .Chrome = "None", _
            Key .Url = url, _
            Key .IntegratorID = userIntegratorID, _
            Key .ClientID = clientIdGlobal _
            })

            'TODO move it to the web.config, Following API Key is holonis accounts API Key
            SetBasicAuthHeader(httpWebRequest, holonisApiKey, "")
            streamWriter.Write(json)
            streamWriter.Flush()
            streamWriter.Close()

            Dim httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
            Using streamReader = New StreamReader(httpResponse.GetResponseStream())
                result = streamReader.ReadToEnd()
                result = result.Split(New [Char]() {":"})(2)
                result = "https:" & result.Substring(0, result.Length - 2)
            End Using
        End Using
        Me.midFrame.Attributes("src") = result
    Catch ex As Exception
        objLog.WriteLog("Error:" & ex.Message)
        If (ex.Message.ToString().Contains("Invalid Email")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Email Taken")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Invalid Access Level")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Unsafe Password")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Invalid Password")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Empty Person Name")) Then
            'TODO Show message on UI
        End If
    End Try
End Function


Public Sub SetBasicAuthHeader(ByVal request As WebRequest, ByVal userName As [String], ByVal userPassword As [String])
    Dim authInfo As String = Convert.ToString(userName) & ":" & Convert.ToString(userPassword)
    authInfo = Convert.ToBase64String(Encoding.[Default].GetBytes(authInfo))
    request.Headers("Authorization") = "Basic " & authInfo
End Sub`
89
Arvind Morwal

私にとってはtls12でした。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
150
Lanklaas

.Net 4.0で行き詰まっていて、ターゲットサイトがTLS 1.2を使用している場合は、代わりに次の行が必要です。 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

source: TLS 1.2 and .NET Support:接続エラーを回避する方法

50
Tochi

以下のコードで問題を解決しました

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3
18
Arvind Morwal

私の場合は、接続しているサイトがTLS 1.2にアップグレードされています。その結果、私はそれをサポートするために私のウェブサーバーに.net 4.5.2をインストールしなければなりませんでした。

11
aboy021

私は何日も同じ問題を抱えていましたが、その統合も「以前は動作していた」ものでした。

全くのうつ病から、私はちょうど試した

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

統合は厳密にSSLv3のみを利用しますが、これは私のためにそれを解決しました。

Fiddlerが「空のTLSネゴシエーション暗号」またはそれに類するものがあると言って以来、何かがおかしくなっていることに気づいた。

うまくいけばそれは動作します!

9
Medismal

Web.config/App.configに移動して、使用している.NETランタイムを確認してください。

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>

これが解決策です。

  1. .NET 4.6以上TLS 1.2をサポートするために追加の作業を行う必要はありません。デフォルトでサポートされています。

  2. .NET 4.5。 TLS 1.2はサポートされていますが、これはデフォルトのプロトコルではありません。使用するにはオプトインする必要があります。次のコードはTLS 1.2をデフォルトにします。安全なリソースに接続する前に必ずそれを実行してください:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

  1. .NET 4.0 TLS 1.2はサポートされていませんが、システムに.NET 4.5以上がインストールされている場合は、アプリケーションフレームワークでサポートされていなくてもTLS 1.2を選択できます。唯一の問題は、.NET 4.0のSecurityProtocolTypeにTLS1.2のエントリがないことです。そのため、この列挙値の数値表現を使用する必要があります。

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

  1. .NET 3.5以下TLS 1.2はサポートされておらず(*)、回避策はありません。アプリケーションを最新バージョンのフレームワークにアップグレードします。
8
Guo Huang

これは、コードをデプロイしているサーバーに、TLS 1.1またはTLS 1.2をサポートしていない古い.NET Frameworkがインストールされていることを示す兆候であることがわかりました。修正する手順

  1. 最新の.NETランタイムを運用サーバー(IISおよびSQL)にインストールする
  2. 開発用マシンに最新の.NETDeveloper Packをインストールします。
  3. Visual Studioプロジェクトの "ターゲットフレームワーク"設定を最新の.NETフレームワークに変更します。

このURLから最新の.NET Developer PackおよびRuntimeを入手できます。 http://getdotnet.azurewebsites.net/target-dotnet-platforms.html

6
Patrick

APIにアクセスしているWebサイトが「基礎となる接続が閉じられました:送信時に予期しないエラーが発生しました」というメッセージが表示されるという問題がありました。

それらのコードは.NET 3.xと2.2が混在していたため、TLS 1.0を使用していることがわかります。

以下の回答は、TLS 1.0、SSL 2、およびSSL3を有効にすることで問題を診断するのに役立ちますが、非常に明確にするために、これらのプロトコルの3つすべてとして、そのような長期的なことはしたくない安全でないとみなされ、 使用されなくなった

API呼び出しに応答するIISを取得するには、IISのサーバーにレジストリ設定を追加して、TLSのバージョンを明示的に有効にする必要がありました-注:Windowsサーバーを再起動する必要があります(IISサービス)これらの変更を行った後:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

それでも解決しない場合は、SSL 2.0のエントリを追加することもできます。

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

明確にするために、これはニースの解決策ではありません、正しい解決策は発信者にTLS 1.2を使用させることですが、上記はそれを診断するのに役立ちますこれが問題です。

このPowerShellスクリプトを使用すると、これらのregエントリの追加を高速化できます。

$ProtocolList       = @("SSL 2.0","SSL 3.0","TLS 1.0", "TLS 1.1", "TLS 1.2")
$ProtocolSubKeyList = @("Client", "Server")
$DisabledByDefault = "DisabledByDefault"
$Enabled = "Enabled"
$registryPath = "HKLM:\\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"

foreach($Protocol in $ProtocolList)
{
    Write-Host " In 1st For loop"
        foreach($key in $ProtocolSubKeyList)
        {         
            $currentRegPath = $registryPath + $Protocol + "\" + $key
            Write-Host " Current Registry Path $currentRegPath"
            if(!(Test-Path $currentRegPath))
            {
                Write-Host "creating the registry"
                    New-Item -Path $currentRegPath -Force | out-Null             
            }
            Write-Host "Adding protocol"
                New-ItemProperty -Path $currentRegPath -Name $DisabledByDefault -Value "0" -PropertyType DWORD -Force | Out-Null
                New-ItemProperty -Path $currentRegPath -Name $Enabled -Value "1" -PropertyType DWORD -Force | Out-Null    
    }
}
 
Exit 0

これは、Microsoftヘルプページの VMMのTLSのセットアップ のスクリプトの修正バージョンです。この basics.netの記事 は、これらの設定を確認するアイデアを最初に与えてくれたページでした。

3
tomRedox

追加するだけです:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

2
M.Qudah

HTTPデバッグプロキシを使用すると、これが発生する可能性があります - Fiddlerなど。

私はローカルファイル(Apple.comへの認証)からPFX証明書をロードしていました、そして、Fiddlerがこの証明書を渡すことができなかったので、それは失敗しました。

チェックするためにFiddlerを無効にしてみてください。それが解決策である場合、おそらくあなたのマシンに証明書をインストールする必要があります。

1
Simon_Weaver

以下のコードは私の問題を解決しました:

request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
0

4.0から4.6などのアプリケーションバージョンを変更し、それらのコードを公開するだけです。

以下のコード行も追加します。

httpRequest.ProtocolVersion = HttpVersion.Version10; 
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
0
Viresh

誰かを助けてくれるのなら、証明書が見つからないという問題がありました。環境は.Net 4.6のWindows Server 2016 Standardです。

Service.Open()がエラーなしで実行する、自己ホスト型のWCFサービスhttps URIがあります。別のスレッドが https:// OurIp:443/OurService?wsdl にアクセスし続けて、サービスが利用可能であることを確認します。 WSDLにアクセスすると失敗していました。

基になる接続が閉じられました:送信時に予期しないエラーが発生しました。

適切な設定でServicePointManager.SecurityProtocolを使用しても機能しませんでした。サーバーの役割や機能を試しても役に立ちませんでした。それからJaise George、SE、数分で問題を解決しました。 JaiseはIISに自己署名証明書をインストールしていたため、この問題が起こりました。これは彼が問題を解決するためにしたことです:

(1)IIS manager(inetmgr)を開きます。(2)左パネルのサーバノードをクリックし、[サーバ証明書]をダブルクリックします。 (3)右側のパネルにある「自己署名証明書の作成」をクリックして、フレンドリ名に必要なものを入力します。 (4)左パネルの[既定のWebサイト]をクリックし、右パネルの[バインド]をクリックして[追加]をクリックし、[https]をクリックして、作成した証明書を選択して[OK]をクリックします。 httpsのURL、アクセス可能なはずです。

0
DiligentKarma