顯示具有 Let's Encrypt 標籤的文章。 顯示所有文章
顯示具有 Let's Encrypt 標籤的文章。 顯示所有文章

2025-12-05

批次建立 win-acme 用 DNS Record 取得憑證的任務

批次建立 win-acme 用 DNS Record 取得憑證的任務

$RecordNames = @();
$RecordNames += "www";

$Domain = "contoso.com";

foreach ($RecordName in $RecordNames) {
    
    $FQDN = ($RecordName + '.' + $Domain);
    write-host ('Request Certificate for ' + $FQDN);

在 Azure DNS Zone 用 DNS Record 來驗證 Let's Encrypt 的 PowerShell Script

前情提要: 在 Microsoft DNS Server 上用 DNS Record 來驗證 Let's Encrypt 的 PowerShell Script

AzureDNSZoneVerification.ps1


# -Step "create" -Identifier "{Identifier}" -RecordName "{RecordName}" -Token "{Token}"
# -Step "delete" -Identifier "{Identifier}" -RecordName "{RecordName}" -Token "{Token}"

param (
[string]$Step,
[string]$Identifier,
[string]$RecordName,
[string]$Token
);

[string]$AzureResourceGroupName = "Infra_Network"
[string]$ZoneName = "contoso.com"
[int]$TTL = 3600

write-host ('Step: ' + $Step);
write-host ('Identifier: ' + $Identifier);
write-host ('RecordName: ' + $RecordName);
write-host ('Token: ' + $Token);

2025-11-26

PowerShell 更新 IIS Site Bind SSL Cert

$PublishedURL = "www.contoso.com"
$IISSiteName = "www.contoso.com"

$PFXPath = "C:\Cert\Cert\"
$Password = "password"

$PFXFullPath = "$PFXPath$PublishedURL.pfx"

$pfx = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$pfx.Import($PFXFullPath, $Password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::EphemeralKeySet)

Import-Module IISAdministration

2024-04-26

Get Web Site SSL Certificate Expired Date

 $Uri = 'https://www.contoso.com';

$request = [System.Net.WebRequest]::Create($Uri);
$request.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$response = $request.GetResponse();
Get-Date((($request.ServicePoint).Certificate).GetExpirationDateString());

其中 ($request.ServicePoint).Certificate.Subject 可以核對 FQDN

參考資料: https://stackoverflow.com/questions/22233702/how-to-download-the-ssl-certificate-from-a-website-using-powershell


From File:

$File = 'C:\Cert\Cert\www.Contoso.com-crt.pem';
$Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($File)
$Cert.NotAfter

2022-09-26

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-3

本系列共三篇:

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-1
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-2
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-3

承上一篇 用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-2

本篇是以 PowerShell 向 Web Server 自動下載憑證的階段 (雙向加密傳輸)

WebRoot/AAPI/Cert/GetCert.php on Web Server

#--------------------------------------------------------------------------------

<?php
header("HTTP/1.1 200 OK");
$Received_JsonContent = file_get_contents('php://input');

if (!function_exists('CloseConnection')) {
include($_SERVER['DOCUMENT_ROOT'].'/API/Cert/Config.php');
};

if (empty($Received_JsonContent)) {
CloseConnection();
exit;
};

ob_clean();

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-2

本系列共三篇:

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-1
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-2
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-3

承上一篇 用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-1

本篇是 Web Server 提供手動下載的階段

WebRoot/Cert/config.php

#--------------------------------------------------------------------------------

<?php
// -----
$Domain = 'contoso.com';
$CertPackagesPath = 'C:/WebSite/z_CertPackage/';
$APIKey = 'lsiMwjc80ptrSoqvBHkTCIYGA6gaxDd7';
#All
$CertManager['UserName1'][]='all';
$CertManager['UserName2'][]='all';
#User
$CertManager['UserName3'][]='www';
$CertManager['UserName4'][]='webmail';
// -----
if (!isset($CertManager)) {
CloseConnection();
exit;
};

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-1

本系列共三篇:

用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-1
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-2
用 DNS Record 驗證 Let's Encrypt 後打包丟給 Web Server 提供下載 Part-3

透過 Microsoft DNS Server 上用 DNS Record 來驗證 Let's Encrypt 的 PowerShell Script 之後
需要將取得的憑證丟給目標伺服器使用,但 DNS Server 本身就不太適合再擔任其他服務腳色,容易因為有漏洞而被攻擊,影響 DNS 服務,進而影響整個 Domain 運作。
因此在取得更新的憑證後,先以 7-Zip 打包,再透過加密的方式傳輸到 Web Server 上提供給各伺服器負責人下載使用。

需要在 DNS Server 上執行 PackCert.ps1
Web Server 上的 API 接收後存起來 (API Path 建議做好 Source IP Filter)
使用者再從網頁手動下載或透過 
GetCert.ps1 下載

相關動作我將拆成三篇來寫
本篇是 DNS Server 打包丟給 Web Server 儲存的階段

PackCert.ps1 on DNS Server

API Key 必須與 Web API 相同
CertPassword 看申請 Let's Encrypt 憑證的時候用什麼密碼就填什麼

#--------------------------------------------------------------------------------

2022-02-23

在 Microsoft DNS Server 上用 DNS Record 來驗證 Let's Encrypt 的 PowerShell Script

在 DNS Server 上透過 PowerShell Script 自動建立/刪除驗證用 Record 的方式來取得 Let's Encrypt 憑證


Updated: 2023.06.09 更新如果不是 A Record 而是 CNAME 時的處理
Updated: 2023.08.23 更新 Create Record 前先檢查,如果 Record 存在就刪除再建立

採用工具: 
https://www.win-acme.com/


2021-11-22

PFX 憑證轉 JKS

先裝好 Java 取得 keytool.exe
接著下指令:

 "C:\Program Files (x86)\Java\jre1.8.0_311\bin\keytool.exe" -importkeystore -srckeystore "C:\Cert\www.contoso.com.pfx" -destkeystore "C:\Cert\www.contoso.com.jks" -srcstoretype PKCS12 -deststoretype jks -srcstorepass "12345678" -deststorepass "12345678"

2021-07-29

Auto Renew Let's Encrypt Certificate for SoftEther

After build up the SoftEther VPN https://youtu.be/Y1F4PJOsWF8


You can manually Import the Certificate


Or try to make it automatically.

Place Cert in C:\Cert\ and write a TXT file (C:\Cert\SoftEtherVPNCertBatch.txt) with the following command:

2020-05-19

使用 PowerShell 自動佈署基於 Let's Encrypt 公開憑證的 Microsoft RDS (VDI/RemoteApp) 環境


使用 Win-ACME 來更新憑證

以下 Script 基於僅有兩台 RDWeb/Gateway 色合一的 FrontEnd Server
僅做到將憑證更新完畢匯入系統,派送新的 RDCB 憑證指紋 (Thumbprints) 參考這篇文章

環境預設禁止 RDWeb/Gateway 主機主動對 Internet 連線
也禁止 Internet 對 RDWeb/Gateway 的 TCP Port 80 連線
因此開始 Renew 之前會先打開防火牆,此外也會先更新 TrustedRootCA

由於此例將 RDWeb、RDGateway、RDCB 全部都用公開憑證
所以必須要將 RDCB HA URL 的 Internet IP 也指到 RDWeb / RDGateway 這台上讓外網連線
實際上 RDCB 不需要對外,所以外網 DNS 對應哪個 IP 沒差
  • 2020.06.10 Updated
    • Script 最後將憑證指紋寫入 Thumbprint.txt 檔存放在 RDWeb 的 wwwroot
      這樣就可以另外寫一隻 Script 以 http get 的方式抓取 寫入 GPO
    • 另外,為了彌補 GPO 更新的時間差
      在憑證即將到期的 15 日內,且為周六或周日
      才執行 RDS 系統更新憑證的指令

# -----------------
# Configuration

$WACSPath = "C:\Cert\"

$WACSEXEFileName = "wacs.exe"
$PFXPath = ($WACSPath + "Cert\")
$RDWebGWURL = "Contoso.com"
$RDCBHAURL = "RDCB.Contoso.com"
$DefaultActivedRDCBMaster = "RDCB-01.Contoso.com"
$TrustedRootCAPath = ($WACSPath + "TrustedRootCA\")
$TrustedRootCAFile = "roots.sst"
$BlockIPs = @("1.0.0.0-9.255.255.255", "11.0.0.0-172.15.255.255", "172.33.0.0-192.167.255.255", "192.169.0.0-255.255.255.255")

2020-05-14

用 Powershell 取得含 Private Key 有密碼憑證的指紋資訊 (或其他資訊)

幾種方式:

第一種 (Password 明碼)


Set-StrictMode -Version Latest

[string] $strPW  = 'password'
[string] $strPFX = 'C:\Cert\www.contoso.com.pfx'
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($strPFX,$strPW,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"DefaultKeySet")

$cert.Thumbprint

只為了 Let's Encrypy 更新憑證而開放的 TCP Port 80 全自動開關 PowerShell

Let's Encrypt 表示才不會公佈我們會用哪些 IP 來對使用者進行驗證咧! 不然我們會被攻擊!
所以我們必須要自己開關 TCP Port 80,無法針對不特定驗證來源 IP 設定白名單
以下設定僅阻擋來自 Public IP 的請求,Pirvate IP 是允許連線的


2020-05-13

Exchange 採用 Let's Encrypt 驗證時遇到 Multi CAS Role NLB 問題的處理

Exchange 扮演 CAS 腳色的機器一般都裝有兩台以上做 NLB 或 Round Robin
此時若在某一台 CAS 進行 Let's Encrypt Renew 的時候會遇到問題:

  • 建立了 .well-know 資料夾與驗證檔案
  • Let's Encrypt 來查詢卻問到別台 CAS
  • 別台 CAS 上面當然沒有 .well-know 資料夾與驗證檔案
  • 於是驗證失敗

為了解決這個問題,用了一些投機取巧、土炮的辦法
也許有更為正確的辦法,但目前沒想到或沒學到,所以就這樣做了,反正也行得通
原理很簡單,就是在開始 renew 之前先開始一個周期性的 robocopy /mir 同步每一台 CAS

採用的 Let's Encrypt ACMEv2 client 
https://www.win-acme.com/

以下是 Batch File 與 PowerShell Script

Updated: 2021.01.26
因應 Let's Encrypt 變更憑證發行單位名稱,增加變更 TLSCertificateName 的部份
Updated: 2021.07.09
如果有 Multi-Domain 且跟 Exchange Online 做 Hybrid,需要確認只有單一 TLSCertificateName
故將 TLSCertificateName 更新的部份加個參數做個判斷式,自己設定 True or False

2019-05-09

使用 Let's Encrypt 來作為 VDI - RDCB 憑證時更新 GPO 派送 Thumbprints 的處理

連接 RemoteAPP 或 VM 的時候會跳出以下訊息
A website is trying to run a RemoteApp Program. Make sure that you trust the publisher before you connect to run the program
This Remoteapp program could harm your local or remote computer.



已知這個必須以 GPO 派送 RDCB 憑證的 Thumbprints
GPO 設定路徑如下:
Windows Components\Remote Desktop Services\Remote Desktop Connection Client
>> Specify SHA1 thumbprints of certificates representing trusted .rdp publishers
但要使用 Let's Encrypt 這種兩、三個月就要更換一次憑證的免費方案的話
還要手動更新 GPO 設定中的指紋太麻煩了,於是找到相關的 PowerShell 指令可以用

搭配服用: 使用 PowerShell 自動佈署基於 Let's Encrypt 公開憑證的 Microsoft RDS (VDI/RemoteApp) 環境

2019-01-30

IIS Reverse Proxy with HTTPS over SSL Cert + Auto Renew IIS Site Binding Let's Encrypt by Powershell

原本的網站沒有走 https 且很難處理
故利用前端 IIS + ARR 來做 Reverse Proxy with HTTPS over SSL Cert
後端的 Server 都不用動,只需要檢查原始碼將有寫 http 絕對連結的 html tag 改掉就好
這樣也可以將 https 加解密的 Loading 從 Web Server 移到 Reverse Proxy 這台來

方法很簡單,只要用 Binding Host Header 的方式掛上憑證就可以了
麻煩的是 Let's Encrypt 需要每三個月更新憑證

查了很久最後找到正確的語法並寫成 Powershell Script

$BindingURL 是憑證的主要名稱
$PublishedURLs 是陣列,填入 IIS Site 所 Binding 的多個 Host Header

*. Let's Encrypt 有提供用一張憑證包含多個 Alternative FQDN 的功能

**. 如果你的憑證存放在 Personal 容器中
就搜尋 Cert:\LocalMachine\WebHosting
改成 Cert:\LocalMachine\My

2018-07-20

Exchange 2016 採用 Let's Encrypt 憑證的方法與 Auto Renew

Let's Encrypt 真是進年度最偉大的服務了
上次用 Let's Encrypt 佈署 Remote Desktop Gateway 後, 這次要來佈署 Exchange 2016

Updated:
2025.02.24
Let's Encrypt 已經改用 https://www.win-acme.com/
PowerShell Script 更新加入 Exchange Online Hybrid 的部分 (TLS Issuer Name)


採用的版本是 LetsEncryptWinSimple.v1.9.11.2 (直接下載連結)
解壓縮後我把他放到 Exchange Server 的 C:\Cert\LetsEncryptWinSimple.v1.9.11.2 路徑
接著執行 letsencrypt.exe



這裡我選 M


2017-04-26

利用 Let's Encrypt 來佈署 Remote Desktop Gateway

本教學利用 Let's Encrypt 來佈署 Remote Desktop Gateway
2018.08.29 更新重寫

有關取得 LetsEncryptWinSimple 的方式請參考以下這篇文章的前半部
Exchange 2016 採用 Let's Encrypt 憑證的方法與 Auto Renew

Auto Renew 的部份:


$PublishedURL = "RDG.Contoso.com"
$LetsEncryptWinSimplePath = "C:\LetsEncryptWinSimple.v1.9.11.2\"
$PFXPath = "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\"

cd $LetsEncryptWinSimplePath
$DateTimeString = Get-Date -format yyyyMMdd_HHmmss
$TranscriptLog = (Get-Item -Path ".\" -Verbose).FullName + "\Logs\" + ("CertRenew_" + $DateTimeString + ".log")
start-transcript -path $TranscriptLog