Skip to content
Coding

不常見的遠端主機已強制關閉連線

不常見的遠端主機已強制關閉連線

事情是這樣的,Server A 一直有提供一隻 API,Server B 原本也都使用這支 API 使用得好好的,結果有一天莫名其妙不 work 了,錯誤訊息如下。

基礎連接已關閉: 傳送時發生未預期錯誤,遠端主機已強制關閉一個現存的連線。
The underlying connection was closed: An unexpected error occurred on a send.

上面這個錯誤訊息是寫網頁的時候常常會遇見的其中一個 BUG,通常把這串中文或英文餵給 Google,得到的解答都是叫你幫程式使用指定的 TLS 版本,基本上就會解決這個問題。

但我怎麼測試就是不 work !(翻桌)而且同一時間,local 端甚至是其他台 Server 都可以去正常執行這支 API 的。原本想著搞不好放著放著他就會自己好起來(畢竟他是莫名其妙就忽然不能 call 了),但人還是要面對現實的,放置了快一個月之後又回頭重新找了一遍,依然沒有解答。


網路協定

剛好重新拾起這個問題的時候正在研究網路協定的相關書籍,有一些使用 Wireshark 的範例,找解答找到崩潰的我決定死馬當活馬醫,來研究看看到底從我 local 端發送出去的請求和 Server B 到底有甚麼不同。

左邊為 local 端,右邊為 Server B

結果還真的有差!從圖上面可以觀察到在三項交握之前,分別都有出現 Hello 的請求,並且 local 端多了一個 Server Hello。

可是你是誰啊!

我超困惑,過去我的認知中,網際網路的出發點是三項交握,接著就可以開示正式的互相溝通,在我的世界觀裡這兩個 Hello 我真的是前所未聞,於是把這兩個關鍵字(還是四個?)餵給了 Google,找到了一些內容。


TLS 握手

啟動 TLS 加密通信工作階段的過程。在 TLS 握手過程中,雙方會指定他們將要使用的 TLS 版本以及密碼套件,通過伺服器的公開密鑰和 SSL 憑證頒發機構的電子簽名驗證伺服器的身份,生成工作階段金鑰,以便在握手完成後使用對稱加密。

其中,Client Hello 和 Server Hello 就是最開始的兩個步驟。Client Hello 會發送他所支援的 TLS 版本以及密碼套件清單,接著 Server 會選擇一個他可以使用的密碼套件,將這個訊息和他的 SSL 憑證一起包在 Server Hello 內回傳給 Client 端,接著繼續進行後續的動作。

很明顯的,Server B 就是卡在 Server A 沒有辦法選出一個他可以使用的密碼套件來進行溝通,於是連線就被關閉了。但我要怎麼知道 Server A 上有允許哪些密碼套件呢?


IIS Crypto

有進行過弱點掃描修復的人應該都不陌生的一套工具,可以把 Weak SSL Protocol 這項問題給解決掉。

其實,Weak SSL Protocol 的問題就是希望你關閉那些不能提供足夠安全性的過時協議來保護 Server 的安全。而剛好 Server B 沒有辦法 call API 的時間點就是在弱掃修復之後!

於是利用各種工具(我是用 Qualys Labs 的免費檢測工具看的)找到 Server A 支援的加密套件清單之後,找了一個他支援但較不安全的密碼套件補在 Server B 上,果然 API 就通了!可喜可賀!

(不針對 Server A 不安全的清單做修改是因為 Server A 上有許多重要的服務,加上設備沒有很好,修改後的重新開機時間難以估計,加上之後會有更新的計畫,所以選擇先開啟 Server B 上較不安全的協定)


這個問題難的地方在於我沒有網路協定的背景知識…… QQ 白白浪費了好多時間在做無意義的搜尋,不過也學到很寶貴的知識,希望這篇文章可以幫助到更多還在維護老舊 Server 的人,遇到同樣 Bug 的時候可以有點解決方向!

參考資料:TLS 握手中發生了甚麼事?、那些關於SSL/TLS的二三事、TLS-wireshark-抓包记录