Skip to content

GitLab Omnibus (Docker) HTTPS 連線失敗排除 SOP

七步驟排除 GitLab Omnibus Docker 部署中 HTTPS 無法連線的問題,含根因診斷、憑證替換與常見陷阱速查。

概述

GitLab Omnibus 採用內建 Nginx 作為前端 Web 伺服器。Nginx 的 SSL 配置並非獨立管理,而是在 gitlab-ctl reconfigure 時由 Omnibus 根據 external_url 的協定自動產生。

external_url 設為 http://... 時,Omnibus 認為 SSL 由外部元件(如 Load Balancer 或反向代理)負責終結,因此不會為 Nginx 產生任何 SSL 配置。這導致一個常見但難以直覺察覺的問題:即使手動放置了憑證檔案,port 443 也永遠無法完成 TLS 握手。

症狀通常表現為 curl 回報 SSL_ERROR_SYSCALLConnection reset——握手在第一個封包就中斷,而不是憑證驗證階段。本 SOP 以七步驟涵蓋從症狀確認到驗證修復的完整流程。

核心內容

external_url 與 SSL 配置的決定性關聯

GitLab Omnibus 的設計哲學是「宣告式配置」:管理者在 gitlab.rb 中描述期望的最終狀態,reconfigure 負責將系統調整至該狀態。external_url 的 scheme 是 Omnibus 判斷是否啟用 SSL 的唯一依據:

  • external_url 'http://...':Nginx 只監聽 port 80,不產生任何 ssl_certificate 配置
  • external_url 'https://...':Nginx 監聽 port 443 並配置 SSL,自動尋找 /etc/gitlab/ssl/<FQDN>.crt.key

因此,只換憑證檔案而不修改 external_url 是無效的——SSL 配置根本不存在。修改 external_url 後,必須執行 gitlab-ctl reconfigure 而非 gitlab-ctl restart nginx,因為 restart 只重啟服務,不會重新產生 conf 檔。

憑證路徑的自動推導規則

Omnibus 從 external_url 中提取 FQDN 作為憑證檔名的依據:

  • external_url 'https://rdgit.wiwynn.com' → 尋找 /etc/gitlab/ssl/rdgit.wiwynn.com.crt.key
  • 若檔名與 FQDN 不符,reconfigure 不會報錯,但 Nginx 啟動時找不到憑證,SSL 仍無法運作

憑證鏈(Certificate Chain)完整性

企業憑證通常由中繼 CA(Intermediate CA)簽發,而非直接由根 CA 簽發。若 .crt 只包含終端憑證而缺少中繼 CA,部分 client 會回報 self signed certificate in certificate chain,即使憑證本身有效。

正確做法是將中繼 CA 串接於終端憑證之後:

bash
cat your_server.crt intermediate.crt > /etc/gitlab/ssl/rdgit.wiwynn.com.crt

Docker Volume 持久化

GitLab Omnibus Docker 部署若未正確掛載 /etc/gitlab/ 為持久 Volume,容器重建後 gitlab.rb 與所有憑證將一併消失。連線問題發生時,應優先確認 Volume 掛載設定,避免花時間排查實際上已正確的配置。

關鍵要點

  • external_url 的 scheme(http vs https)決定 Nginx 是否產生 SSL 配置,這是最常見的根因
  • 憑證檔名必須嚴格對應 FQDN(/etc/gitlab/ssl/<FQDN>.crt
  • 任何 gitlab.rb 修改後,必須 gitlab-ctl reconfigure,不是 restart
  • 多層 CA 架構需串接中繼 CA 憑證至 .crt
  • Docker 部署必須確認 /etc/gitlab/ 有掛載持久 Volume

實際應用

本 SOP 適用於:

  • 初次部署 GitLab Omnibus Docker 後發現 HTTPS 無法連線
  • 憑證更換後連線異常(含年度憑證輪替)
  • 容器重建後需重新配置 SSL

年度憑證輪替時,GitLab Server 憑證應與其他系統同步更新。完整的多系統更新 SOP 詳見維運 SOP:憑證與帳密更新

部署設定參考

以下為實際部署時使用的完整指令,供日後查詢與複製使用。

環境參數

項目
FQDNrdgit.wiwynn.com
external_urlhttps://rdgit.wiwynn.com
憑證路徑/etc/gitlab/ssl/rdgit.wiwynn.com.crt
私鑰路徑/etc/gitlab/ssl/rdgit.wiwynn.com.key
設定檔/etc/gitlab/gitlab.rb
GitLab Server IP10.248.32.101

Step 1:確認症狀(Host 機器)

bash
curl -4vk https://localhost:443
# SSL_ERROR_SYSCALL 或 Connection reset → 進入 Step 2
# 憑證錯誤但握手完成 → 直接 Step 4

Step 2:分層診斷(容器內)

bash
# 2-1. HTTP 是否正常(排除後端問題)
curl -4vk http://localhost:80

# 2-2. Nginx 是否有 SSL 配置
grep -r "ssl_certificate" /var/opt/gitlab/nginx/conf/

# 2-3. Nginx 實際監聽哪些 port
grep -r "listen" /var/opt/gitlab/nginx/conf/

# 2-4. external_url 設定
grep -i "external_url" /etc/gitlab/gitlab.rb | grep -v "^#"

# 2-5. 憑證效期
openssl x509 -in /etc/gitlab/ssl/*.crt -noout -dates -subject 2>/dev/null

診斷判讀表:

結果判定前往
HTTP 80 也不通後端服務異常先排查 gitlab-ctl status
ssl_certificate grep 無結果Nginx 未啟用 SSL→ Step 3
ssl_certificate 有結果但路徑不存在憑證檔案遺失→ Step 4
憑證已過期(Not After 早於今天)憑證過期→ Step 4
以上皆正常key 不匹配或格式問題→ Step 5

Step 3:修復 external_url(最常見根因)

bash
# 3-1. 備份
cp /etc/gitlab/gitlab.rb /etc/gitlab/gitlab.rb.bak

# 3-2. 改 external_url 為 https
sed -i "s|external_url 'http://rdgit.wiwynn.com'|external_url 'https://rdgit.wiwynn.com'|" /etc/gitlab/gitlab.rb

# 3-3. 確認修改結果
grep "external_url" /etc/gitlab/gitlab.rb | grep -v "^#"
# 預期輸出:external_url 'https://rdgit.wiwynn.com'

Step 4:更換或安裝 SSL 憑證

bash
# 4-1. 放置憑證(依實際 FQDN 調整檔名)
cp your_server.crt /etc/gitlab/ssl/rdgit.wiwynn.com.crt
cp your_server.key /etc/gitlab/ssl/rdgit.wiwynn.com.key

# 4-2. 若有中繼 CA 憑證,串接到 crt 檔(避免 chain 不完整)
cat your_server.crt intermediate.crt > /etc/gitlab/ssl/rdgit.wiwynn.com.crt

# 4-3. 設定權限
chmod 644 /etc/gitlab/ssl/rdgit.wiwynn.com.crt
chmod 600 /etc/gitlab/ssl/rdgit.wiwynn.com.key

Step 5:驗證憑證與私鑰匹配

bash
openssl x509 -in /etc/gitlab/ssl/rdgit.wiwynn.com.crt -noout -modulus | md5sum
openssl rsa  -in /etc/gitlab/ssl/rdgit.wiwynn.com.key -noout -modulus | md5sum
# 兩個 md5 值必須完全相同;若不同,需重新取得正確的配對檔案

Step 6:套用配置並驗證

bash
# 6-1. 重新產生所有配置(需數分鐘)
gitlab-ctl reconfigure

# 6-2. 確認 SSL 配置已產生
grep -r "ssl_certificate" /var/opt/gitlab/nginx/conf/
# 預期:指向 /etc/gitlab/ssl/rdgit.wiwynn.com.crt

grep -r "listen" /var/opt/gitlab/nginx/conf/
# 預期:listen *:443 ssl http2

Step 7:驗證修復

bash
curl -4vk https://localhost:443
# 成功標準:
# - TLS 握手完成(SSL connection using TLSv1.x)
# - HTTP 302 導向 /users/sign_in
# - 憑證 subject 與 FQDN 一致

常見陷阱速查

陷阱說明
只換憑證不改 external_urlOmnibus 以 external_url 的 scheme 決定是否產生 SSL 配置,http:// 永遠不會啟用 SSL
憑證檔名與 FQDN 不一致Omnibus 自動尋找 /etc/gitlab/ssl/<FQDN>.crt,檔名必須匹配
缺少中繼 CA 憑證部分 client 無法自動補全 chain,curl 報 self signed certificate in certificate chain
只 restart 不 reconfiguregitlab-ctl restart nginx 不重新產生 conf;external_url 變更後必須跑 reconfigure
Docker 重建後設定遺失確認 /etc/gitlab/ 有掛載 volume,否則容器重建後 gitlab.rb 和憑證都會消失

相關概念

來源