在 Linux (CentOS) 主機運作多時的 .NET Core 3.1 排程這幾個月失效,初步檢查是呼叫自訂 WebAPI 時出錯,錯誤訊息如下:

Unhandled exception. System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)

判斷問題與 TLS 憑證有關,問題 WebAPI 在 Nginx + Certbot 整合容器執行,每三個月會自動更新 Let's Encrypt 憑證,我在 Windows 開瀏覽器檢查 WebAPI 網站測試正常,目前使用中的憑證簽發於 10 月,明年 1 月到期,代表 Certbot 有自動更新憑證,而在 Linux 主機上跑 curl https://web-api.my-host.com 也正常。

.NET Core 3.1 的 TLS 支援過舊?雖然可能性極低,但還是先更新到 .NET 6 再說,果不其然,胡鬧瞎試很少出現奇蹟,問題依舊。決定寫個小 Console 程式檢測:(用 .NET 6 寫,Program.cs 只要這幾行就能跑,簡單程式格外能突顯 Top-Level Statements 的好 )

var http = new HttpClient();
var url = "https://web-api.my-host.net/Service/DoSomething";
var res = http.GetAsync(url).GetAwaiter().GetResult();
Console.WriteLine(res);

.NET 6 單純測試也失敗了,但得到較明確錯誤訊息:

Unhandled exception. System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: NotTimeValid

用 NotTimeValid 關鍵字爬文,查到解答

Let's Encrypt 原本使用的 DST Root CA X3 憑證於 2021/9/30 起失效,改用另一張 ISRG Root X1 根憑證 (有效期限到 2035)(但有使用新舊憑證 Cross-Sign),主流瀏覽器都已信任 ISRG Root X1,所以不會有問題。但我的 CentOS 沒更新 CA 根憑證信任清單,因此 Let's Encrypt 9/30 舊 CA 憑證失效之後,便會因 TLS 憑證無效連線出錯。

知道原因一切好辦,執行 sudo update ca-certificates -y 更新 CentOS 的信任 CA 憑證清單,問題煙消雲散。

A case that .NET Core 3.1 program on Linux failed to connect to the web with Let's Encrypt certificates. The problem solved after trusted CA certificates updated.


Comments

Be the first to post a comment

Post a comment