選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
4 分鐘閱讀時間 (736 個字)

Dify Docker Compose SSL 憑證驗證失敗排查與修復指南(Ubuntu 環境實戰)

Dify Docker Compose SSL 憑證驗證失敗排查與修復指南(Ubuntu 環境實戰)

今天原本使用好好的政府 OpenData API (https://gcis.nat.gov.tw) 在 Dify 的 Http 節點中居然出現[SSL:CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1010)的錯誤。
以下紀錄在部署 Dify 至 Ubuntu Docker Compose 環境時,遇到 SSL 憑證驗證失敗的問題,包含台灣政府 CA 安裝、Python certifi 處理、Proxy 設定與完整排查修復流程。

問題場景與解決

先在 Ubuntu 執行 curl 就出現curl: (60) SSL certificate problem: unable to get local issuer certificate的錯誤。

curl -v https://data.gcis.nat.gov.tw/od/data/api/5F64D864-61CB-4D0D-8AD9-492047CC1EA6?$format=json

結果為 curl: (60) SSL certificate problem: unable to get local issuer certificate

Step 1.確認 ubuntu SSL 問題

使用 openssl 檢查憑證鏈:

openssl s_client -connect data.gcis.nat.gov.tw:443

結果如下,

Server certificate
subject=C = TW, L = \E8\87\BA\E5\8C\97\E5\B8\82, O = \E6\94\BF\E5\BA\9C\E6\A9\9F\E9\97\9C-\E8\B3\87\E8\A8\8A\E5\AE\A4, CN = gcis.nat.gov.tw
issuer=C = TW, O = "Chunghwa Telecom Co., Ltd.", CN = HiPKI OV TLS CA - G1
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 7920 bytes and written 448 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE

Verification error: unable to verify the first certificate可以發現沒有 Root CA。

Step 2.安裝 HiPKI OV TLS CA

中華電信公開憑證下載HiPKI OV TLS CA
並放到 /usr/local/share/ca-certificates/目錄中

wget https://epki.com.tw/repository-h/download/OVTLSCA1_b64.crt -O /usr/local/share/ca-certificates/OVTLSCA1_b64.crt

接下來更新系統CA

sudo update-ca-certificates

結果如下,

1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

再使用 openssl 檢查憑證鏈echo | openssl s_client -showcerts -connect data.gcis.nat.gov.tw:443可以發現已經驗證成功,如下,

SSL handshake has read 7920 bytes and written 448 bytes
Verification: OK

完成後,再到 Dify 執行,還是出現[SSL:CERTIFICATE_VERIFY_FAILED]錯誤,
接下來,要來查看 Dify Docker 中到底是什麼問題造成的?

Step 3.查看 Docker Api Log

docker compose logs api

輸出如下,

[ssrf_proxy.py:78] - Request to URL http://data.gcis.nat.gov.tw/od/data/api/5F64D864-61CB-4D0D-8AD9-492047CC1EA6?$format=json&$filter=Business_Accounting_NO eq 22425662 failed on attempt 1: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1010)
[node.py:103] - http request node 1743067744592 failed to run: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1010)

可以發現,跟我們在Dify的Http運行時,錯誤一樣。

Step 4.確認 API Container 的憑證環境

進入 API Container

docker compose exec api bash

確認 Python certifi 使用的憑證:

python3 -c "import certifi; print(certifi.where())"

結果如下,

/app/api/.venv/lib/python3.12/site-packages/certifi/cacert.pem

Step 5.替換 certifi 的憑證檔

ubuntu host 的憑證是 OK 的,所以可以在docker-compose.yaml設定 volume,
修改 dify 的 docker-compose.yaml 在 api 的 volumes 加入以下設定

api:
volumes:
- /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
- /etc/ssl/certs/ca-certificates.crt:/app/api/.venv/lib/python3.12/site-packages/certifi/cacert.pem:ro

  • 將 VM Host 上最新的 CA cert 掛到 container 的 OS 層 /etc/ssl/certs/ca-certificates.crt
  • 將 VM Host 的 CA cert 掛到 Python certifi 套件的 cert 檔案路徑

重新執行docker compose並測試看看,

docker compose down
docker compose up -d

再從 dify 去測試,可以發現 Http 節點,已經可以順利執行成功了。

結語

以上的 SSL 問題排查流程,驗證了一個 Containerized 架構下的典型 SSL 問題:

  1. VM 憑證要先驗證成功。
  2. Docker Container 須確認 CA cert 路徑。
  3. Python 的 certifi 使用獨立 cert,若寫死 verify=certifi.where() 就要特別處理。

參考資源

中華電信公開憑證
SSL Cert Verification
Install a root CA certificate in the trust store
update-ca-certificates 說明

從AIF發佈會看台灣產業AI化的挑戰與轉機
OpenShift 容器平台 SCC 策略:適應隨機 UID 啟動容器

相關文章

 

評論 2

Lifang Wang (王莉方) 於 2025/04/15, 週二 10:05

好詳盡的憑證除錯流程,受益良多!

好詳盡的憑證除錯流程,受益良多!
Rainmaker Ho (何金鎮) 於 2025/04/15, 週二 17:23

很高興對你有幫助,不過真的是花了一段時時,本來還改了 ssr_proxy 這個 docker ,查到最後才知道 dify 是吃 python 的憑證區 ~

很高興對你有幫助,不過真的是花了一段時時,本來還改了 ssr_proxy 這個 docker ,查到最後才知道 dify 是吃 python 的憑證區 ~
已經注冊了? 這裡登入
Guest
2025/04/25, 週五

Captcha 圖像