國產化之銀河麒麟.netcore3.1訪問https服務的兩個問題

来源:https://www.cnblogs.com/bossma/archive/2022/04/18/16158101.html
-Advertisement-
Play Games

安裝軟體 pacman -S (軟體名):安裝軟體,若有多個軟體包,空格分隔 pacman -S --needed (軟體名):安裝軟體,若存在,不重新安裝最新的軟體 pacman -Sy (軟體名):安裝軟體前,先從遠程倉庫下載軟體包資料庫 pacman -Sv (軟體名):輸出操作信息後安裝 p ...


背景

某個項目需要實現基礎軟體全部國產化,其中操作系統指定銀河麒麟,資料庫使用達夢V8,CPU平臺的範圍包括x64、龍芯、飛騰、鯤鵬等。

考慮到這些基礎產品對.NETCore的支持,最終選擇了3.1版本。主要原因就是龍芯搞了自研CPU架構,用戶量不夠大,.NET官方並沒有專門針對龍芯的支持,而龍芯團隊只對.netcore3.1做了適配(目前.net6適配測試中),至於其它的國產CPU則是基於Arm64和x64的,.NET官方都有支持。

環境

  • 主機操作系統:Windows 10
  • 虛擬化工具:QEMU
  • 虛擬機CPU:cortex-a53(ARMv8架構,支持Arm64)
  • 虛擬機操作系統:銀河麒麟 v4 (未安裝桌面)

問題

問題一:無法驗證xxx的由yyy頒發的證書

這個錯誤是在開發環境出現的,通過wget請求https服務時拋出異常:

e6c9d24ely1h1di5e7jvoj20rl04h3zq

具體錯誤提示如圖所示,使用HttpClient發起請求一樣會報錯,這是因為安裝的操作系統沒有自帶根CA證書。安裝 ca-certificates 就可以解決:

sudo apt-get install -y ca-certificates

至於錯誤信息中的建議:使用"--no-check-certificate"。使用https就是為了安全,直接無視就好了。

問題二:The SSL connnection could not be established

這個錯誤是在生產環境出現的,已經排除第一個問題。

img

錯誤的關鍵詞還有:AuthenticationException: The remote cert is invalid according to the validation procedure. 簡單點說就是:被訪問服務的證書無效。

這裡先貼出解決方案,一會再說原因。增加一個環境變數:

export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER = 0

建議還是把它寫到 /etc/profile 中,然後用 source /etc/profile 生效。

下麵來分析下這個問題產生的原因

在微軟的官方文檔中可以找到關於這個配置的說明:

https://docs.microsoft.com/en-us/dotnet/api/system.net.http.socketshttphandler?view=net-6.0

https://docs.microsoft.com/zh-cn/dotnet/core/runtime-config/networking

大概就是說.NET Core 2.1之後,HttpClient內部預設使用新寫的SocketsHttpHandler,但是也允許切換到之前的舊Handler,在Linux上之前使用的是CurlHandler,從這個名字上看應該是使用了libcurl這個庫,這個庫使用C語言寫的,.NET調用的時候會有一點性能損失,所以後來.NET拋棄了libcurl,自己實現了Http網路棧的處理,也就是SocketsHttpHandler。通過設置環境變數,將Http網路棧的處理回退到了CurlHandler。

那麼為什麼CurlHandler可以,SocketsHttpHandler卻不行呢?

在dotnet的github倉庫中有一些關於這個錯誤的issue:

https://github.com/dotnet/runtime/issues/26494
https://github.com/dotnet/runtime/issues/35880

我這裡總結核心問題就是SocketsHttpHandler驗證證書功能變數名稱的問題,證書的功能變數名稱中大小寫混合、包含下劃線、使用通配符等等會導致異常,有些問題可以通過修複SocketsHttpHandler解決,有些問題是因為依賴了OpenSSL,比如OpenSSL認為功能變數名稱不應該包含下劃線,.NET這邊遇到此類的功能變數名稱就會報錯,.NET也不會主動去解決。另外文中還提到舊版本的OpenSSL是沒問題的,新版本的OpenSSL才這樣,因為開發者認為新版本的做法更規範。.NETCore依賴的OpenSSL版本可以在這裡找到:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-ubuntu#dependenciesDocs

至於我遇到的是哪個問題,因為在本地環境沒有遇到這個問題,生產環境是別人去維護的,上線後也不方便去搞,所以暫時無法定位到具體原因。猜想可能有兩個原因:生產環境的OpenSSL相關庫版本比較新,而開發環境的OpenSSL庫版本比較舊;生產環境用到的證書功能變數名稱不規範,測試環境用到的證書功能變數名稱規範。

還有為什麼使用了CurlHandler就沒有問題呢?因為我這裡的curl沒有依賴openssl,在銀河麒麟v4中,curl依賴的是gnutls(SSL support is provided by GnuTLS.),如果已經安裝了curl可以使用這個命令看它依賴的包:apt-cache depends curl 我這裡顯示的是:

curl
  依賴: libc6
  依賴: libcurl3-gnutls
  依賴: zlib1g

如果沒有安裝curl,可以看看libcurl3-gnutls這個包是否存在:dpkg -s libcurl3-gnutls,如果存在這個包,則會顯示它的詳細信息。

最後如果你想知道自己遇到了什麼錯誤,可以通過下邊的代碼來獲取:

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => {
    if (errors == SslPolicyErrors.None)
    {
        return true;
    }

    // todo: 在這裡輸出errors到日誌

    throw new AuthenticationException($"Ssl certificate validation failed when trying to connect to {message.RequestUri}, Error: {errors}.");
}

var client = new HttpClient(httpClientHandler);

以上就是本文的主要內容了,如有問題,歡迎反饋。

收穫更多架構知識,請關註微信公眾號 螢火架構。原創內容,轉載請註明出處。
掃描二維碼關註公眾號


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 緣起 概述:發現現如今網上關於Java、前端、Android、Golang...等相關技術的學習資料,面試指南一搜都是一大把,但是我們大.NET/C#的相關學習資料,面試指南和一些常見的面試題都是寥寥無幾,並不是沒有人寫,而是因為網上的資料和文章太零散了,缺少一個彙總的知識庫。因此作為.NET開發中 ...
  • 描述給定一個單鏈表和數值x,劃分鏈表使得所有小於x的節點排在大於等於x的節點之前。你應該保留兩部分內鏈表節點原有的相對順序。 樣例 1: 輸入: list = null x = 0 輸出: null 解釋: 空鏈表本身滿足要求 樣例 2: 輸入: list = 1->4->3->2->5->2->n ...
  • 為了寫入Bootloader, 要開啟SSH, 要開啟SSH, 就需要將小米路由器的 ROM 更新為開發版. 在小米的 miwifi 下載頁面找到路由器對應的開發版 ROM(R3G ROM 開發版). ROM 的升級有兩種方式 登陸路由器後臺線上升級 如果前一個方式不行, 可以將其拷貝到U盤根目錄... ...
  • linux伺服器網路配置 環境:ubuntu 18.04 配置IP地址 通過ifconfig命令查看網卡信息 chen@ubuntu:~$ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.16. ...
  • 如果一個任務獲取信號量失敗,該任務就必須等待,直到其他任務釋放信號量。本文的重點是,在Linux中,當有任務釋放信號量之後,如何喚醒正在等待該信號量的任務。 信號量定義如下: struct semaphore { raw_spinlock_t lock; unsigned int count; st ...
  • Centos 7 開機進入選擇系統界面 按e選擇進入系統,一般預設第一個(進入系統過程中可以持續按上下鍵,避免跳過此頁面) 修改Grud 進入界面後往下找,找到以linux16開頭的一串命令,在此行末尾添加 init=/bin/bash 在同一行命令中找到ro 改成 rw 讓用戶有寫許可權,修改密碼用 ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 環境需求 環境配置 ①配置靜態地址、主機名 vi /etc/sysconfig/network-scripts/ifcfg-eth0 BOOTPROTO=static IPADDR=192.168.153.70 NETMASK=255.255.2 ...
  • 針對MIPS指令集本身的講解,主要是它上層的彙編表示和下層的機器表示,以及它的訪存方式、操作數等等。同時也對MIPS指令集日落西山表示感慨。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...