遠端主機已強制關閉一個現存的連線
Server A 一直有一隻運行的很正常的 API 提供給 Server B 和 Server C 呼叫,在某一天忽然 Server B 就呼叫失敗了,同一時間 Server C 以及我的 local 環境仍然可以正常使用那隻 API。查看 Server B log 後發現顯示的錯誤是:
|
|
由於是比較古老的服務了,最近一段時間都沒有修改過兩邊的程式碼,所以先排除了改壞了的可能性。把錯誤訊息拿去 google 後,看到通常是因為終止 TLS 1.0、1.1 的服務所導致,只要加上這段程式碼就可以運行了:
|
|
Client Hello & Server Hello
剛好最近重新拾起網路協定的相關書籍閱讀中,書裡有一些使用 Wireshark 的範例,抱持著將就試試看的心態,就打開了 Wireshark 來研究看看到底從我 local 端發送出去的請求和 Server B 到底有甚麼不同。
從上面這張截圖的比較可以看到,左邊 local 端有出現 Client Hello 和 Server Hello,但右邊 Server B 卻只出現了 Client Hello。但這兩個互相說哈囉的東西是什麼?
TLS 交握
在網際網路的事件中,應該很多人都聽說過三項交握,全名應該是 TCP 三項交握(TCP Three-Way Handshake),透過這個過程建立連線。
但是這個連線建立後是沒有加密的狀態,因此要透過 TLS 交握 來確保雙方能安全地交換加密金鑰,並確定加密的協定版本和加密算法。詳細的步驟是:
- 客戶端發送
ClientHello
訊息,告知伺服器客戶端這邊支援的 TLS 版本以及密碼套件。 - 伺服器回應
ServerHello
訊息,選擇使用的加密算法和協定版本,並傳送伺服器證書等資訊來證明身份。 - 雙方交換加密金鑰和一些安全參數,完成加密通訊的準備。
- 客戶端和伺服器確認所有訊息交換無誤後,TLS 握手結束,通信開始進入加密的數據傳輸階段。
由於 TLS 的目的就是確保資料在傳輸過程中的機密性、完整性及身份驗證,只要有一個步驟缺失就代表無法建立安全的連線,因此連線就被中斷。從剛剛的截圖可以看到 Server B 確實沒有等到 ServerHello
的訊息,為了確定是不是這個問題,我決定要分別看看這三台 Server 的 TLS 版本以及密碼套件有哪些。
檢查允許的密碼套件:Qualys Labs
Qualys Labs 這個網站主要是針對 SSL 安全性做的掃描,掃描出的內容剛好包含我們所需要的密碼套件清單。操作的方式也很簡單:
透過這個網站的比對,我確定了這次 Server B 遇到的問題:由於那陣子剛做完弱點掃描,Server A 被掃出了 Weak SSL Protocol 的問題,所以我使用 IIS Crypto 把一些不安全的過時協議關閉,但 Server B 太過古老,沒辦法支援新的協議,這就導致了這次的問題,Server B 只能使用不安全的密碼套件,但 Server A 不允許使用,在沒辦法挑出可用套件的情況下,自然也就沒辦法回覆 ServerHello
的訊息。
參考資料