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


119

問題:ログにこの例外「基になる接続が閉じられました:送信時に予期しないエラーが発生しました」が発生し、[1時間-4時間]からランダムに変化するときに、OEMと電子メールマーケティングシステムの統合が壊れています。

私のWebサイトは、IIS 7.5.7600を搭載したWindowsサーバー2008 R2でホストされています。このWebサイトには、多数のOEMコンポーネントと包括的なダッシュボードがあります。ダッシュボード内のiframeソリューションとして使用しているメールマーケティングコンポーネントの1つを除き、すべてがWebサイトの他のすべての要素で正常に機能します。それが機能する方法は、すべての資格情報を使用して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`

これを理解したことはありますか?
Brett G

11
はい、このコードServicePointManager.SecurityProtocol = SecurityProtocolType.TlsまたはSecurityProtocolType.Ssl3
Arvind Morwal

私は同じ問題で死ぬところだった。同じ問題で苦労して数時間かかりました。あなたのコメントをありがとう、それは私の日を救った。
Sameers Javed 2015

2
@ user3458212コメントに回答を追加する必要があります
icc97

2
私の場合、Visual Studio 15でWebサイトを実行するとすべてがうまくいきますが、サーバーのフレームワークをアップグレードできず、TLS 1.2を強制してキープアライブを無効にできないため、中間段階をセットアップする必要がありました。接続をドロップするターゲットWebサーバーをプロキシするWebサーバー。
ホセ・ロベルト・ガルシア・チコ

回答:


193

私にとってそれはtls12でした:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

42
この変更はAppDomainに対してグローバルであり、TLS 1.2を提供していないサイトへの呼び出しが失敗するため、注意が必要です(トランスポートされるデータが本当に機密である場合は、これが優先される場合があります)。TLS 1.2を好むが、それでも1.1と1.0を許可するには、それらのORを持っている:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ダスティ

同じように、あなたは私の命を救い、RestSharpの何が問題かを理解するために多くの時間を費やしました
darul75

このソリューションは、RestSharpを使用していない場合や、ServicePointManagerを使用していない場合にも機能します。上記の行をコピーして、WebRequest呼び出しまたは要求を行うために使用しているものの前に貼り付けてください。上記の理由により、最初はこのソリューションを無視しました。
goku_da_master 2017

または、すでにあるものに追加する... System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
uosjead '19

8
:そのように一緒にそれらを「バイナリか」、PowerShellでこれを行うには[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
アダムS

62

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

ソース:TLS 1.2および.NETサポート:接続エラーを回避する方法


5
驚くばかり!(SecurityProtocolType)768「Tls11」(つまりTLS 1.1)に使用できるものを追加します。
ソロモンルツキー2017年

2
これは本当に役立ちます。それは私の日を救った。.Net 2.0を使用する必要があります。
Hao Nguyen

22

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

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3

5
これは機能しますが、これはServicePointManager.SecurityProtocol静的オブジェクトであるため、この値を変更するとすべてのサブシーケンスWebRequestまたはWebClient呼び出しに影響することに注意してください。別の設定にするAppDomain場合は、個別に作成できServicePointManagerます。詳細については、stackoverflow.com / questions / 3791629 /…を参照してください。
stack247

1
:このコードが何をしているかを理解するために役立つ追加の読み取りstackoverflow.com/questions/26389899/...を
ジョン・シュナイダー

@Marneeアプリケーションのコンポジションルートに配置したため、I / Oが発生する前に設定されます
SDのJG

@Marnee静的コンストラクタに入れて、クラスに初めてアクセスしたときに1回だけ実行されるようにします。ただし、すべてのケースをカバーするために、すべてのプロトコルを有効にする必要がありました。
Nyerguds

14

私は何日も同じ問題を抱えていますが、これも「以前は機能していた」統合です。

全くのうつ病から、私は試してみました

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

統合は厳密にSSLv3のみを使用しますが、これで解決しました。

Fiddlerが「空のTLSネゴシエーション暗号」などがあると報告して以来、何かがオフになっていることに気付きました。

うまくいけばうまくいきます!


コードでTLSが必要ない場合でも、コードがDOESと通信している場合、TLSとネゴシエートしようとし、できない場合は失敗することに注意してください。空のTLSネゴシエーション暗号は、最終的に提供したTLSプロトコル交換を予期していたスロットでした。サーバー管理者が、アプリケーションが通信しているサーバーでTLSを有効にした可能性があるため、「以前は機能していた」可能性があります。
vapcguy

13

私の場合、接続しているサイトはTLS 1.2にアップグレードされています。その結果、.net 4.5.2をサポートするために自分のWebサーバーにインストールする必要がありました。


これは、マシンのレジストリレベルで実行できますか?私はすべてのSSLプロトコルを無効にして、TLS 1.0、1.1、1.2を残しましたが、PCIに準拠するためには、TLS 1.2未満のものはすぐに削除する必要があることを理解しています。
brendo234

12

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はサポートされておらず(*)、回避策はありません。アプリケーションをフレームワークの最新バージョンにアップグレードします。

6

これは、コードをデプロイしているサーバーに、TLS 1.1またはTLS 1.2をサポートしていない古い.NETフレームワークがインストールされていることを示しています。修正する手順:

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

次のURLから最新の.NET開発者パックとランタイムを入手できます。http://getdotnet.azurewebsites.net/target-dotnet-platforms.html


ターゲットフレームワークを4.5.2から4.6.1に変更し、動作を開始しました。パトリックに感謝します。
Vivek Sharma

4

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

彼らのコードは.NET 3.xと2.2の混合でした。私が理解しているように、これは彼らがTLS 1.0を使用していることを意味します。

以下の回答は、TLS 1.0、SSL 2、SSL3を有効にすることで問題を診断するのに役立ちますが、明確にするために、 するために、これらの3つのプロトコルはすべて安全でないと見なされ、もはやそうすべきではないため、長期間実行することは望ましくありません。中古

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

[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の記事は、もともと私にこれらの設定を確認するアイデアを与えたページでした。


私たちの問題は、Live Cityの証明書を変更したときに突然停止した、Team City経由のリリースパイプラインに関するものでした。私たちはすでにTLS1.2のみを使用するようにサーバーを変更しており、Team Cityパイプラインは機能しなくなりました...夢のように動作しました... regエントリを追加してサーバーを再起動しました... BOOM !!! tomRedoxに感謝!!
グワショッパ

@Gwasshoppa、上記は問題を診断するための単なる一時的なギャップであることを繰り返します。これでTLSバージョンの問題であることがわかりました。解決策は、リリースパイプラインを変更してTLS1.2で動作し、TLS <1.2とSSL 2および3を再びオフにすることです。それを強調するために、上記の回答を少し更新しました。
tomRedox

4

追加するだけです:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;


1
答えを説明してください。
ワード

4
この答えは、以前の答えにも何も追加しません。
Arvindh Mani

2

それが誰かを助けるなら、我々の証明書が欠落している問題でした。環境は、Windows Server 2016 Standardと.Net 4.6です。

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

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

適切な設定でServicePointManager.SecurityProtocolを使用しても機能しませんでした。サーバーの役割と機能を操作しても効果がありませんでした。次に、SEのJaise George参加し、数分で問題を解決しました。JaiseはIISに自己署名証明書をインストールし、問題を回避しています。これは彼が問題に対処するためにしたことです:

(1)IISマネージャー(inetmgr)を開きます。(2)左パネルのサーバーノードをクリックし、[サーバー証明書]をダブルクリックします。(3)右側のパネルにある[自己署名証明書の作成]をクリックし、わかりやすい名前を入力します。(4)左パネルの「デフォルトのWebサイト」をクリックし、右パネルの「バインディング」をクリックして、「追加」をクリックし、「https」を選択して、作成した証明書を選択し、「OK」をクリックします(5)アクセスhttps URL、それはアクセス可能でなければなりません。


ただし、サーバー管理者がSSL証明書を追加していると思っていたかもしれません。ああ!笑:)私はこれが起こっているのを見ることができます-または更新を必要とする期限切れの証明書がより適切なシナリオになるでしょう。
vapcguy

2

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

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

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

1

HTTPデバッグプロキシを使用すると、これを引き起こす可能性があります(Fiddlerなど)。

ローカルファイル(Apple.comに対する認証)からPFX証明書を読み込んでいましたが、Fiddlerがこの証明書を渡すことができなかったために失敗しました。

Fiddlerを無効にして確認し、それが解決策である場合は、おそらくマシンに証明書をインストールするか、Fiddlerが証明書を使用できるようにする必要があります。


0

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

request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.