連接SQL Server報錯

將框架從.NET6升級到8,順便將各種依賴包也升級,容器化部署到測試環境後,SQL Server連接不了了:

[2024-05-13 13:48:10 ERR] [Microsoft.EntityFrameworkCore.Database.Connection] An error occurred using the connection to database 'Demo' on server '127.0.0.1'. 
[2024-05-13 13:48:10 ERR] [Microsoft.EntityFrameworkCore.Query] An exception occurred while iterating over the results of a query for context type 'DemoDbContext'.
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
 ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.

以前也遇到過類似的問題,是通過修改TLS的最低支持版本來解決,但這次是升級了依賴導致的無法連接數據庫,之前的解決方式不起作用,說明對這個問題的理解還不到位。

在github上提了個issue,原來是在EFCore 7這個版本有個breaking change:連接字符串中的Encrypt參數的默認值有False變爲了True,那麼在連接數據庫時就會嘗試建立加密連接,也就是這個過程失敗了。

Encrypt=False,若SQL Server配置了強制使用加密連接也會取嘗試建立加密連接

失敗原因是SQL Server的證書沒有在客戶端通過校驗。下面是本機進行復現的錯誤信息:

 

那麼解決方案有以下幾種:

  • 給SQL Server安裝正確的證書

  • 在連接字符串中添加TrustServerCertificate=True

  • 連接字符串中設置Encrypt=False

後面兩種比較簡單,但官方不推薦

 

關於EncryptTrustServerCertificate參數,可參考:Use TrustServerCertificate

Encrypt connection string/attributeTrust Server Certificate connection string/attributeResult
No/Optional Ignored No encryption occurs.
Yes/Mandatory No Encryption occurs only if there's a verifiable server certificate, otherwise the connection attempt fails.
Yes/Mandatory Yes Encryption always occurs, but may use a self-signed server certificate.
Strict1 Ignored Encryption always occurs and must use a verifiable server certificate, otherwise the connection attempt fails.

 

小結

結合本次及之前遇到的問題,SQL Server連接報錯,有以下幾種原因:

  • 客戶端/服務端間TLS版本不兼容

  • 服務器證書有問題,客戶端校驗不通過

最後附一張HTTPS連接的建立過程圖:

 

參考資料

MSSQL · 最佳實踐 · 使用SSL加密連接

HTTPS介紹及加密的過程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章