網站憑證更新自動化 - IIS TLS 憑證設定指令工具
| | | 6 | |
前情提要:網站憑證更新自動化 - 憑證簽署請求檔(CSR)指令工具
我的作業環境以 Windows IIS 為主,做好 CSR 請求檔製作與 PFX 憑證轉轉換的 CLI 工具後,再來就是要設法將 IIS 站台換新憑證動作也轉成指令或程式作業,繼續向 IIS 憑證自動化更新邁進。
比照上次部署及資安審核考量,一樣選擇用 PowerShell 開發,我寫了一個 Set-IISCertificate.ps1,用法如下:
# 列舉 IIS 站台資料
Set-IISCertficate.ps1 ?
# 顯示 IIS 站台憑證設定
Set-IISCertificate.ps1 "Default Web Site"
# 安裝 PFX 憑證並設定 IIS 站台使用 (互動式輸入私鑰密碼)
Set-IISCertificate.ps1 "Default Web Site" "X:\path\cert.pfx"
# 安裝 PFX 憑證並設定 IIS 站台使用 (直接提供私鑰密碼)
Set-IISCertificate.ps1 "Default Web Site" "X:\path\cert.pfx" "priv-key-password"
開發過程復習與補充了一些知識:
- 設定 IIS 需要管理者權限,之前的自動改用管理者身分執行術式派上用場
- PowerShell 世界把許多東西都檔案化,像是
Cert:\LocalMachine\My代表本機的憑證儲存區,可當成資料夾存取 - PowerShell 7 有不少改進,像是 Get-PfxCertificate 增加了 -Password 參數,但為了考量在 PS 5.1 也能跑,只好借用 System.Security.Cryptography.X509Certificates.X509Certificate2 解決讀取 .pfx 需要輸入密碼的問題
找了一台 Windows 2019 IIS 實測,先用 Make-CSR.ps1 產生 CSR,送交 AD DS 簽發憑證後得到 certnew.cer,用 Make-PFX.ps1 產生 certnew.pfx。

先示範查詢 IIS 有哪些站台,以及站台目前使用的 TLS 憑證:

接著,讓我們用一行 Set-IISCertificate.ps1 "MyDemoWeb" "X:\path\certnew.pfx" 把 IIS 憑證換掉。

憑證更換成功!

完整程式已放上 Github,有需要的同學可自取使用。
Automate IIS certificate renewal with PowerShell. Set-IISCertificate.ps1 lists sites, shows certs, and updates certificates via command line for streamlined operations.
Comments
# by 貴
自從用過 win-acme,發現會把憑證放到本機機器的虛擬網站區後,從此幫 IIS 網站匯入憑證時也就都這樣做了 可惜 win-acme 申請的憑證(IIS 網站)不相容 Let's encrypt 的萬用憑證(防火牆的虛擬伺服器使用),查了好久才發現是這原因,但為什麼不相容依舊沒有頭緒 最終還是只能改用 certbot 在 wsl 中先申請好憑證再想辦法弄到 IIS 上
# by IT小弟
黑大,我把?參數的憑證程式,增加顯示憑證資訊的部分,經過測試,如果用憑證管理工具MMC匯入的,參數為?時會列舉不出來-,但是用者這支程式指定站台名稱或匯入IIS的憑證可以列舉得到,是否要額外寫用列舉的站台名稱去比對憑證綁定的站台名稱,才會一併列出來?
# by Jeffrey
to IT小弟,? 模式是去抓已被用在某個 IIS HTTPS 的憑證,只有匯入但沒有綁定到特定 HTTPS 的憑證不會出現在清單裡。由描述看不太出來你卡到的問題點,看能否說一下重現這個問題的操作步驟。
# by IT小弟
黑大, 我在 if ($WebSiteName -eq '?') {...略... }裡面,加上一行:DisplayCertificate "網站現有憑證" $cert, 理論上應該跟 Set-IISCertificate.ps1 "MyDemoWeb" 的效果一樣,會顯示已經綁在MyDemoWeb的現有網站憑證指紋A,執行後卻是顯示 --, 比對憑證匯入過程差異,不能顯示的A,是透過MMC 匯入到主機的個人憑證區並綁定到站台,可以正確顯示的B是用你的指令碼匯入【當前帳號】的個人憑證區 。因此,是否要用列舉的站台名稱去比對搜尋整個主機個人憑證區的所有憑證,才會讓 參數? 跟指定站台名稱的結果一致呢?
# by Jeffrey
to IT小弟,不太明白 Get-WebSite | Select-Object { ... } | Where-Objeject { ... } | ForEach-Object { ... } 迴圈的 $cert 是如何取得的? 迴圈裡原本只有 $_ 變數可用,不會自動產生 $cert 才對。
# by IT小弟
阿,發現我錯在哪了..謝謝黑大。