.NET 6 Docker 連接資料庫錯誤 解決方式

在 Docker 中的 ASP.NET Core 6 網站登入時沒有反應,按下登入按鈕後沒有顯示帳號密碼錯誤或是登入成功,而是直接重新整理頁面,一看就想到可能是資料庫連接有問題, 連進 Docker Container 查看 log 時發現確實是連接資料庫時出現問題,錯誤訊息如下:
    
2022-10-15 14:03:45.739 +00:00 [ERR] An error occurred using the connection to database 'ruyut' on server '192.168.0.100'.
2022-10-15 14:03:45.745 +00:00 [ERR] An exception occurred while iterating over the results of a query for context type 'ruyut.Data.ApplicationDbContext'.
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.
    

查看 SqlClient troubleshooting guide 後發現很可能是因為 SQL Server 不支持 TLS 1.2 由於無法調整 SQL Server 的設定,我們只能先查查看容器內的設定

查看容器內的 /etc/ssl/openssl.cnf 檔案,可以在文件的最下面(大約第 360 行)有以下內容,要求最低要 TLSv1.2
    
...

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2
    

將他修改為
    
[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT@SECLEVEL=1
    

儲存後並重新啟動容器就發現可以正常連線到資料庫了。

確認這個修改確實可以解決問題後,接下來就是要讓每次建立 docker image 時可以自動替換內容,只要在 DockerFile 內新增下面這行即可
    
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/' /etc/ssl/openssl.cnf \
&& sed -i 's/CipherString = DEFAULT@SECLEVEL=2/CipherString = DEFAULT@SECLEVEL=1/' /etc/ssl/openssl.cnf
    

留言