docs: 重構 SSL 憑證管理為完整 SOP

- tmp/ 重命名為 ssl_certs/,存放憑證相關檔案
- ssl_deploy_guide.md 改寫為 8 步驟標準作業流程
- .gitignore 排除私鑰與 fullchain 等敏感檔案

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-09 10:19:23 +08:00
parent e747efe9ee
commit 87234b458a
5 changed files with 163 additions and 54 deletions

View File

@@ -1,100 +1,131 @@
# SSL 憑證部署指南 - tpesupporter.tpech.gov.tw
# SSL 憑證部署 SOP - tpesupporter.tpech.gov.tw
## 前置確認
## 概述
新憑證GCA G3與舊私鑰HiPKI**不匹配**,需要找到申請 GCA 憑證時產生的私鑰
hospital_web (106.105.181.70) 使用 Nginx Proxy Manager 管理 SSL
憑證檔案存放於本機 `ssl_certs/` 目錄,部署目標為遠端 `/opt/php/data/custom_ssl/npm-1/`
### 確認金鑰配對
## 目錄結構
```
ssl_certs/
├── *.cer # 伺服器憑證GCA 發給你的 zip 解開後的檔案)
├── GCA_G3_intermediate.pem # 中繼憑證(已下載好)
├── privkey.pem # 私鑰(申請憑證時產生,需自行放入)
└── fullchain.pem # 組合後的完整憑證鏈SOP 步驟 3 產出)
```
---
## SOP 流程
### 步驟 1取得憑證
從 GCA 收到的 zip 檔解壓後,將 `.cer` 放入 `ssl_certs/`
```bash
# 私鑰 modulus
cd ssl_certs/
unzip XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.zip
```
### 步驟 2放入私鑰
將申請 GCA 憑證時產生的私鑰放入 `ssl_certs/privkey.pem`
確認金鑰與憑證配對:
```bash
# 兩個 md5 必須一致
openssl rsa -in privkey.pem -modulus -noout | md5sum
# 憑證 modulus
openssl x509 -in 952453E16C4AD7E7F6845225F3468EDA.cer -modulus -noout | md5sum
# 兩者 md5 必須一致才是配對的
openssl x509 -in *.cer -modulus -noout | md5sum
```
## 部署步驟
### 步驟 3下載中繼憑證如需更新
### 1. 準備檔案
需要三個檔案:
- `privkey.pem` — 私鑰(申請 GCA 憑證時產生的)
- `952453E16C4AD7E7F6845225F3468EDA.cer` — 伺服器憑證
- `GCA_G3_intermediate.crt` — GCA G3 中繼憑證
### 2. 下載 GCA G3 中繼憑證
中繼憑證已放在 `ssl_certs/GCA_G3_intermediate.pem`
若需重新下載URL 來自憑證 AIA 欄位):
```bash
# 政府憑證管理中心 G3 中繼憑證
curl -o GCA_G3_intermediate.crt https://gca.nat.gov.tw/download/GCA_OCA.crt
curl -o IssuedToThisCA.p7b http://gca.nat.gov.tw/repository/Certs/IssuedToThisCA.p7b
openssl pkcs7 -in IssuedToThisCA.p7b -inform DER -print_certs -outform PEM -out GCA_G3_intermediate.pem
rm IssuedToThisCA.p7b
```
> 如上述連結失效,請至 https://gca.nat.gov.tw 下載「GCA 憑證鏈」
### 3. 組合 fullchain.pem
### 步驟 4組合 fullchain.pem
```bash
# 將伺服器憑證轉 PEM如果是 DER 格式)
openssl x509 -in 952453E16C4AD7E7F6845225F3468EDA.cer -inform DER -out server.pem 2>/dev/null \
|| cp 952453E16C4AD7E7F6845225F3468EDA.cer server.pem
# 憑證轉 PEMDER 格式自動轉換PEM 格式直接複製
openssl x509 -in *.cer -inform DER -out server.pem 2>/dev/null \
|| cp *.cer server.pem
# 合併成 fullchain順序:伺服器憑證 → 中繼憑證
cat server.pem GCA_G3_intermediate.crt > fullchain.pem
# 合併:伺服器憑證 → 中繼憑證
cat server.pem GCA_G3_intermediate.pem > fullchain.pem
rm server.pem
```
### 4. 備份舊憑證
### 步驟 5備份遠端舊憑證
```bash
ssh hospital_web "sudo cp -r /opt/php/data/custom_ssl/npm-1 /opt/php/data/custom_ssl/npm-1.bak.$(date +%Y%m%d)"
ssh hospital_web "sudo cp -r /opt/php/data/custom_ssl/npm-1 /opt/php/data/custom_ssl/npm-1.bak.\$(date +%Y%m%d)"
```
### 5. 上傳新憑證至伺服器
### 步驟 6上傳並替換
```bash
# 上傳 fullchain.pem 和 privkey.pem
scp fullchain.pem hospital_web:/tmp/
scp privkey.pem hospital_web:/tmp/
# 替換
ssh hospital_web "sudo cp /tmp/fullchain.pem /opt/php/data/custom_ssl/npm-1/fullchain.pem"
ssh hospital_web "sudo cp /tmp/privkey.pem /opt/php/data/custom_ssl/npm-1/privkey.pem"
# 清理
ssh hospital_web "rm /tmp/fullchain.pem /tmp/privkey.pem"
ssh hospital_web "
sudo cp /tmp/fullchain.pem /opt/php/data/custom_ssl/npm-1/fullchain.pem
sudo cp /tmp/privkey.pem /opt/php/data/custom_ssl/npm-1/privkey.pem
rm /tmp/fullchain.pem /tmp/privkey.pem
"
```
### 6. 重啟 NPM
### 步驟 7重啟 NPM
```bash
ssh hospital_web "cd /opt/php && sudo docker compose restart app"
```
### 7. 驗證
### 步驟 8驗證
```bash
ssh hospital_web "echo | openssl s_client -connect localhost:443 -servername tpesupporter.tpech.gov.tw 2>/dev/null | openssl x509 -noout -dates -subject -issuer"
ssh hospital_web "echo | openssl s_client -connect localhost:443 \
-servername tpesupporter.tpech.gov.tw 2>/dev/null \
| openssl x509 -noout -dates -subject -issuer"
```
預期結果:
- issuer 應為「政府憑證管理中心 - G3
- notAfter 應為 2028-04-01
- `issuer`政府憑證管理中心 - G3
- `notAfter` → 新憑證到期日
## 或者:透過 NPM 管理後台上傳
檢查憑證鏈是否完整:
1. SSH 連線 `ssh hospital_web`(會自動建立 port forwarding
```bash
ssh hospital_web "echo | openssl s_client -connect localhost:443 \
-servername tpesupporter.tpech.gov.tw 2>&1 \
| grep 'Verify return code'"
```
預期:`Verify return code: 0 (ok)`
---
## 替代方案:透過 NPM 管理後台
1. `ssh hospital_web`(自動建立 port forwarding
2. 瀏覽器開啟 `http://localhost:8181`
3. SSL Certificates → Add SSL Certificate → Custom
4. 貼上 fullchain.pem 內容Certificate
5. 貼上 privkey.pem 內容Certificate Key
4. 貼上 `fullchain.pem` 內容Certificate
5. 貼上 `privkey.pem` 內容Certificate Key
6. 儲存後套用至對應的 Proxy Host
## 目前憑證狀態
---
| 項目 | 舊憑證(目前使用中) | 新憑證(待部署) |
|---|---|---|
| 簽發者 | HiPKI OV TLS CA - G1中華電信 | 政府憑證管理中心 - G3GCA |
| 有效期迄 | 2026-04-23 | 2028-04-01 |
| 私鑰位置 | /opt/php/data/custom_ssl/npm-1/privkey.pem | **待確認** |
## 憑證歷史紀錄
| 期間 | 簽發者 | 到期日 | 備註 |
|---|---|---|---|
| 2025-04 ~ 2026-04 | HiPKI OV TLS CA - G1中華電信 | 2026-04-23 | 憑證鏈不完整,缺中繼 CA |
| 2026-04 ~ 2028-04 | 政府憑證管理中心 - G3GCA | 2028-04-01 | 待部署,私鑰待確認 |