# SSL 憑證部署 SOP - tpesupporter.tpech.gov.tw ## 概述 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 cd ssl_certs/ unzip XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.zip ``` ### 步驟 2:放入私鑰 將申請 GCA 憑證時產生的私鑰放入 `ssl_certs/privkey.pem`。 確認金鑰與憑證配對: ```bash # 兩個 md5 必須一致 openssl rsa -in privkey.pem -modulus -noout | md5sum openssl x509 -in *.cer -modulus -noout | md5sum ``` ### 步驟 3:下載中繼憑證(如需更新) 中繼憑證已放在 `ssl_certs/GCA_G3_intermediate.pem`。 若需重新下載(URL 來自憑證 AIA 欄位): ```bash 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 ``` ### 步驟 4:組合 fullchain.pem ```bash # 憑證轉 PEM(DER 格式自動轉換,PEM 格式直接複製) openssl x509 -in *.cer -inform DER -out server.pem 2>/dev/null \ || cp *.cer server.pem # 合併:伺服器憑證 → 中繼憑證 cat server.pem GCA_G3_intermediate.pem > fullchain.pem rm server.pem ``` ### 步驟 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)" ``` ### 步驟 6:上傳並替換 ```bash 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 sudo cp /tmp/privkey.pem /opt/php/data/custom_ssl/npm-1/privkey.pem rm /tmp/fullchain.pem /tmp/privkey.pem " ``` ### 步驟 7:重啟 NPM ```bash ssh hospital_web "cd /opt/php && sudo docker compose restart app" ``` ### 步驟 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" ``` 預期結果: - `issuer` → 政府憑證管理中心 - G3 - `notAfter` → 新憑證到期日 檢查憑證鏈是否完整: ```bash ssh hospital_web "echo | openssl s_client -connect localhost:443 \ -servername tpesupporter.tpech.gov.tw 2>&1 \ | grep 'Verify return code'" ``` > 注意:GCA 憑證的根 CA(GRCA G3)不在 Linux 預設信任庫, > 伺服器端會顯示 `Verify return code: 20`,這是正常的。 > 瀏覽器端通常可正常驗證。 ### 步驟 9:更新 NPM 資料庫顯示 直接替換檔案部署時,NPM 後台顯示的到期日不會自動更新(Custom Certificate 無法透過 UI 編輯)。 需手動更新資料庫: ```bash ssh hospital_web 'sudo docker exec nginxproxymanager /opt/certbot/bin/python3 -c " import sqlite3, datetime conn = sqlite3.connect(\"/data/database.sqlite\") c = conn.cursor() now = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\") # 將到期日改為新憑證的到期日 c.execute(\"UPDATE certificate SET expires_on=?, modified_on=? WHERE id=1\", (\"2028-04-01 00:54:36\", now)) conn.commit() print(\"Updated. Rows:\", c.rowcount) conn.close() "' ``` 更新後重新整理 NPM 後台頁面即可看到正確的到期日。 --- ## 憑證歷史紀錄 | 期間 | 簽發者 | 到期日 | 備註 | |---|---|---|---| | 2025-04 ~ 2026-04 | HiPKI OV TLS CA - G1(中華電信) | 2026-04-23 | 已替換 | | 2026-04 ~ 2028-04 | 政府憑證管理中心 - G3(GCA) | 2028-04-01 | 2026-04-09 部署完成 |