From 87234b458a1df95ea95173cf9b5a72e8608a12c0 Mon Sep 17 00:00:00 2001 From: Timmy Date: Thu, 9 Apr 2026 10:19:23 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E9=87=8D=E6=A7=8B=20SSL=20=E6=86=91?= =?UTF-8?q?=E8=AD=89=E7=AE=A1=E7=90=86=E7=82=BA=E5=AE=8C=E6=95=B4=20SOP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tmp/ 重命名為 ssl_certs/,存放憑證相關檔案 - ssl_deploy_guide.md 改寫為 8 步驟標準作業流程 - .gitignore 排除私鑰與 fullchain 等敏感檔案 Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitignore | 3 + README.md | 2 + .../952453E16C4AD7E7F6845225F3468EDA.cer | Bin 0 -> 1661 bytes ssl_certs/GCA_G3_intermediate.pem | 73 +++++++++ ssl_deploy_guide.md | 139 +++++++++++------- 5 files changed, 163 insertions(+), 54 deletions(-) create mode 100644 ssl_certs/952453E16C4AD7E7F6845225F3468EDA.cer create mode 100644 ssl_certs/GCA_G3_intermediate.pem diff --git a/.gitignore b/.gitignore index 3b71a8a..fe290c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *.tar.gz +*.zip php/ +ssl_certs/privkey.pem +ssl_certs/fullchain.pem diff --git a/README.md b/README.md index d663d15..98c14aa 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ | `ssh_config.md` | SSH 連線架構與跳板機設定 | | `docker-compose-note.md` | Docker Compose 服務架構筆記 | | `ssl_cert_note.md` | SSL 憑證資訊與待處理事項 | +| `ssl_deploy_guide.md` | SSL 憑證部署 SOP | +| `ssl_certs/` | SSL 憑證檔案(.cer、中繼憑證) | | `reset_npm_password.sh` | NPM 管理員密碼重設腳本 | ## 伺服器架構 diff --git a/ssl_certs/952453E16C4AD7E7F6845225F3468EDA.cer b/ssl_certs/952453E16C4AD7E7F6845225F3468EDA.cer new file mode 100644 index 0000000000000000000000000000000000000000..15d6b083518852c320c92372353d2731c4a42153 GIT binary patch literal 1661 zcmXqLVyiT0Vo6-U%*4pVB*-vTCHP^E*Y)S$T7pzRyY<~N;AP{~YV&CO&dbQi&B|cl zX~=EB$;KSY!Y0fV5^gADAOPZU@o>Ia*z;`4{+BZs8LAnmfW(-2WPt)tcg=a$Hu1&U z&gbhEKA+I`WXIa4`rb47MZX~xg;(q2}awQbq5 zGYNLnrz*Zp6qGL!+JD@Ftw-#AfbzZ%ne4k?H%Cw3xl7MaNmxgbt2*>tY4rXJ4m}^( zFHPB1^ZQ}&*R8>KlTTH>-s8S`TDr83W%%xUbw~1Vt52WoQ!?k&R*|XJ9$b%wnRecO z;l7eb@=?ixldWqP`>$|xy|7i<)lf;mtx`_Qc6GGGI=5h$xgS~zfZpK)QJ7x6fJJeNvpD|ZM{Ml&AZzbRX#a#a>j2L zhd{}P3box#`HN@hgx+qd)cg0O?4U~Zl>jsQC`Be_Mh3>kO^knmA@b8e9vFW!rzWl7wz1vGBBr2@iV;~Dsz{euSB9h8@^5UKA_CGb*mLzsEmk9pm z5Q;TuoWjPT&Bn;e%Ff8h(%5d$*ka%c6ER?Fv&<+dDX`MlPft$N%S$YQMxTCBYC(Q+ zW=VcgrM`1&QAx4BXK`_9YD!3cNJeI{v!h;td6I!O+!)3-eeA|0r)TOWW#;MoI|m0C z>*psI7sMB*7L}zI8SsHz&CkgApM`~)iFJX29Eh*LB5oiG%r5K+ZDpwp%*+NHY;5U` zJiv?w&LXmcEV2gDO}JAXI91ijjbSy?^)RI)NZcq-ARR#H9 z%s>Pdkj#v5787z70Tv|8O-zgoT{gi}m1XZ8OuGKa_P9nc->jNXS63YE3Rla!AlJU( zecN7^iFa@1_7{cJebnyDmg=s_J+8>Xd|%Ex?&dM&G=V*JucgCZ=={0!BVe1=k-LhL zx0!Z7Y3`oEH_O_)-rV}|J-MrgUis~Df60B#AtY1zuFm>c4`0SV!Lp(6xc_&(KOwPH z*UQi8bEHSoiRA7Yy9NBxPdh5^e-+JpuO=&7e|XJFHr_QKesiDMQ8BaEM4;O@)#~xq3U-=w&qDhILRz_Eqpj)E<;)ae2gR03!FCsgn zTqj=Gy?w`>M1iXP*$35<`3o}A`ZG_;sO8#|mnR=-H1J#LFL@CrFzxBN{&(V~ z$t7238wqZ-N#d3HrMSC#b*cNC<8Hsz6DqRh{_wX+3MZ{UsCReGf*x&;54uUhOxHAS zJ&;Nf-51Pot*}S%u0~?*PMygw*B8fs^4ehZZcF;k&t@C%8fUHGZxPOR+t9=4_F!h! zoKqH+o#I)ld;5HAZZY-NYQ59@t#-ig!O|TaJB?(|lpGN9>tMLc86;z-xn#%QzNxNr zM1F>z`{L(nT66n;!nT;Q=?V7h);{Na?Z4w*#J;kgtCEkNZ@>PAufM<~C|y(bLj~ua qiBjD?_a(lB7IxLIv=iyamQHafdjrnX5;?gjujz;na^ literal 0 HcmV?d00001 diff --git a/ssl_certs/GCA_G3_intermediate.pem b/ssl_certs/GCA_G3_intermediate.pem new file mode 100644 index 0000000..1dfb836 --- /dev/null +++ b/ssl_certs/GCA_G3_intermediate.pem @@ -0,0 +1,73 @@ +subject=C=TW, O=行政院, OU=政府憑證管理中心 +issuer=C=TW, O=Government Root Certification Authority +-----BEGIN CERTIFICATE----- +MIIFLzCCAxegAwIBAgIQMe5Y77XBpI+a7fR13bilwTANBgkqhkiG9w0BAQsFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTEzMDEzMTAzMjIzNFoXDTMzMDEzMTAzMjIzNFow +RDELMAkGA1UEBhMCVFcxEjAQBgNVBAoMCeihjOaUv+mZojEhMB8GA1UECwwY5pS/ +5bqc5oaR6K2J566h55CG5Lit5b+DMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAtX7xPZUtp5iBGQvqYghJUoLeyCJJoaTcc1bcOGHij64WUBYpDu8KKEQK +R1y3zjcDXrLcZX483tmNs92DXSNuBHlx+we1aFyuLpKQVCji97ys3KeMxAEcaXqo +3cZu8nY3g//zkvX80G4RoCyDR86Z420R3mb0GlVw/9TEK8+oduZqAArEdfionpbE +K5zZ/8qaaHafgqMBQGuzfccDKLoWRcTzu3S0IvOpVU6pcB0rJOtc4F7c16tQdXfo +a8sjfcveKKbUQF6AklwugRufHdLqEVpOiGRcDPaHtT6SHJ7D/t+A/rAXMPidcksQ +rea/E+5+lehqEMHSA/gSLa9Ph+/gDQIDAQABo4IBIDCCARwwHwYDVR0jBBgwFoAU +1Wcd4Jx6LJzLxZjnHQcmKobsdM0wHQYDVR0OBBYEFNEYZ8NX/hKakWtfXzHqPsKE +h/u9MA4GA1UdDwEB/wQEAwIBBjA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vZ3Jj +YS5uYXQuZ292LnR3L3JlcG9zaXRvcnkvQ1JMMi9DQS5jcmwwVgYIKwYBBQUHAQEE +SjBIMEYGCCsGAQUFBzAChjpodHRwOi8vZ3JjYS5uYXQuZ292LnR3L3JlcG9zaXRv +cnkvQ2VydHMvSXNzdWVkVG9UaGlzQ0EucDdiMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HgYDVR0gBBcwFTAJBgdghnZlAAMDMAgGBmeBDAECAjANBgkqhkiG9w0BAQsFAAOC +AgEAs3KvqDSIq6GERR/SonDfYnrpF/IdZLM9gBfsIIafNeeWjFCIuC5Ah7LEIhZY +PP/D8y00OCRlZ7GoY4JZIvTFA1fb2umEmKC/ssCwQdUxyd52JfbqBL5N0cP2eU1x +1ZG8d1z8uIq7ItyfO5ML1eAboYMHsO7c10pLmtufZj8VZ4zp4DTRxVzROPKwlIbR +QSKNlymWgAop+Eg9b40lfBMBxFppb3R4IZpijCpy0RbPOzvtmDpen3WZmJ+vsCqc +08b8JqDeRG5zQI1sIeV15qqGZuV8oL5gFi4niltkLNS3fGYAr4+LXVojMWIO/Noe +Ji+i3AtfhnN/w3Ixzhxi39pN+hYzFGtsZNioUC2MQexFJS+AQ4s8D41cRCMwovfi +0erTbWKhTPoQXirUDV/ZSUjUlLDbXzdiUB+mxWd2k16HYcvMFUevxbNzJAxP355T +q9tliZpM/7MVq0/Bw4SGxxQRQF1uVQjMBtEsRYHKVZ1IBBJVOe8jZhc81Sw3jDmm +Ttyjx1o2m8VVImsiIP2iPI3hlw/UCwCGRg5xvqqW72w2niT9pXdvZowBVbhP24wt +umuA45M5h4UNZRNo4/NG3UwS9eLKtfB06YFf3DcBban/Drf8LX8OGvF++Im3SeGJ +6zhUlYOVJcTHpR6TToXoKzvuzegRL2vQ4k22B++JtOQgsAg= +-----END CERTIFICATE----- + +subject=C=TW, O=行政院, CN=政府憑證管理中心 - G3 +issuer=C=TW, O=行政院, CN=Government Root Certification Authority - G3 +-----BEGIN CERTIFICATE----- +MIIGajCCBFKgAwIBAgIRANihslJZ4Numk5pLcvKuQaIwDQYJKoZIhvcNAQELBQAw +WDELMAkGA1UEBhMCVFcxEjAQBgNVBAoMCeihjOaUv+mZojE1MDMGA1UEAwwsR292 +ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzMwHhcNMjIw +NjA3MDMwNzE0WhcNNDIwNjA3MTU1OTU5WjBJMQswCQYDVQQGEwJUVzESMBAGA1UE +CgwJ6KGM5pS/6ZmiMSYwJAYDVQQDDB3mlL/lupzmhpHorYnnrqHnkIbkuK3lv4Mg +LSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALMbyTROOXM9HCYl +LMLoGsxd8b7fbS6ulH/482zJIWTaQ+toRwEG8AALiH/lNE1RfmVW3kmMd6hI5nUf +jmbb9zf+r33Q/2l8LGBIH0MeJMBHXr0C/PQxAEtzhFn3QDJMyfzxtOI8hAeTN9fA +ysxdFHZckcc/yGWUwr4d9r2XOp7NJPIEMFXsGzr/aKPbiJEZOdKzkSSbOnq0ijJg +c1+q+EYKKwZ5xWgjWh7Bz8xILKgE9lvFmj65aF/uH/HEcEPhaXXABr/TCOJLyrKJ ++qRQNOBmHOVSEV5YE+4c8VWPD9Mq+CAeTQ8GVC19hSJXloFqwvKC/1N3YK8K5Mma +PX5sz2lK8lSeIedYWRf/3GPbRrMhy7XNA+7CKQYhna0YRAmLQJqrMLnMGLKFLZi6 +sGc9IGUyPaX5pH3v2jicTNjPo+WTChY5YXRxU6QDRYg7cm0Ou67F4nbQxGRPdO8Y +UYUkeCyHHPBxfXLTRghskuhy88989z0EaTnzGSOHpkYniVIIm/+lNryoCd6QucfM +XY9uqN/OIlnFpWQjuMrQrjmAqjG1Dcfz9Q+jPEUygp8r6VKEFcNVqKnJvD/NT/Bp +bjydUL8wBajp0yCSoVuKmJk7NdJBBHqiOXQEY5d9jF1lvMTLeaefVPd7XFBa5hrn +mu2XpAfWsEVAkTMcTKUhf95ANB6bAgMBAAGjggE8MIIBODAfBgNVHSMEGDAWgBQ6 +kI7nQUcZc9ycvaN+2D0+gwkfAzAdBgNVHQ4EFgQUD/vWuMskS0g3p80y3tukkGEg +rrwwDgYDVR0PAQH/BAQDAgGGMD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly9ncmNh +Lm5hdC5nb3YudHcvcmVwb3NpdG9yeS9DUkwzL0NBLmNybDB8BggrBgEFBQcBAQRw +MG4wPgYIKwYBBQUHMAKGMmh0dHA6Ly9ncmNhLm5hdC5nb3YudHcvcmVwb3NpdG9y +eS9DZXJ0cy9HUkNBRzMuY3J0MCwGCCsGAQUFBzABhiBodHRwOi8vb2NzcC5ncmNh +Lm5hdC5nb3YudHcvT0NTUDASBgNVHRMBAf8ECDAGAQH/AgEAMBQGA1UdIAQNMAsw +CQYHYIZ2ZQADAzANBgkqhkiG9w0BAQsFAAOCAgEASFPAouzRMDf0zdPg1GvWszZm +ng5TDu+2GD+zSpYVsvG9jOZOR0EWJcy6gH95rOzayxTC3TAeX6OyrVc76Pyhae2B +Y/9YlFI/10nUjdBScDlywHXc6uAnbPJkuSPlrRXHSifzwEAgV2bNsRQYx76deVlo +5cPfSKihvP6t2XQgUoIIu/akPDEZsiXtqiECRz/QY2ums7Vz+1GiILR6sOlRF2Bb +L70DZ6KrSRONoKwKiOZdgCuKb+QuZUZop0JZrsiMOXGoL0cmNhc/WiVwJ34YtPSb +aH/fBQdTSPwIizZjefPIsBifGfg52bT6ubMn6HOzaeWQHwKnSQ2RjnRBxO8Wf6is +YtsMoe5oUFV7ftNX8A49fRMxLGAoS6lvJqC4eALphNMiZxcQ+Qsj/DWtkRPwKUT2 +IrT1Z6Jftxnoo0kmHm4SPtJrHJSDotkAc8vi67Q2nFCy7lSA1gfi/vDFLrivRq3v +9UfWmrpw+SRJgWaNxUcy6CiLfFmncH7d1zDimZrIv7gRUUM3bIBngJ5y+gHpGN/4 +h/fmvnvmIiW3QfcKyc9MrFgtowLvLg992B9ZFX3CYJr3+3h+DD2dEzKbbQIrg39r +hsEWh9Gfgc/p8N/gxPc8ZaNRvLMewKo2xJHh+9xi7ydlT7Zth929PN7BXAoLPA1g +/Rkg2o42MPvzBmPLtw8= +-----END CERTIFICATE----- + diff --git a/ssl_deploy_guide.md b/ssl_deploy_guide.md index e5590b7..1a88a7f 100644 --- a/ssl_deploy_guide.md +++ b/ssl_deploy_guide.md @@ -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 +# 憑證轉 PEM(DER 格式自動轉換,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(中華電信) | 政府憑證管理中心 - G3(GCA) | -| 有效期迄 | 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 | 政府憑證管理中心 - G3(GCA) | 2028-04-01 | 待部署,私鑰待確認 |