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

# ----------------- Modify Firewall to Allow HTTP connection
write-host ""
write-host "*** Modify Firewall to Allow connection"
write-host ""

$FirewallObject = New-Object -ComObject HNetCfg.FwPolicy2;

$FirewallRuleName = "World Wide Web Services (HTTP Traffic-In)";
$CheckRuleExist = $FirewallObject.rules | where {$_.Name -eq $FirewallRuleName};
$CheckRuleExist.RemoteAddresses = "";
$CheckRuleExist.update;

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

write-host ""
write-host "*** Cert Renew"
write-host ""

$CommandLine = $LetsEncryptWinSimplePath
$CommandLine+="letsencrypt.exe --renew"
cmd /c $CommandLine

# ----------------- Modify Firewall to Deny HTTP connection

write-host ""
write-host "*** Modify Firewall to Deny connection"
write-host ""
$NewAllowIP = @();
$NewAllowIP += "192.168.0.0/16";
$NewAllowIP += "10.0.0.0/8";
$NewAllowIP += "172.16.0.0/12";

$NewAllowIP = $NewAllowIP | select -uniq;
$AddAllowIP = '';
foreach ($IP in $NewAllowIP) {
if ($AddAllowIP -ne '') {
$AddAllowIP += ',';
};
$AddAllowIP += $IP;
};

$CheckRuleExist.RemoteAddresses = $AddAllowIP;
$CheckRuleExist.update;

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

Import-Module RemoteDesktopServices

$PFXFullPath = "$PFXPath$PublishedURL-all.pfx"
$NewCertProperties = Get-PfxCertificate -FilePath $PFXFullPath | Select Thumbprint,NotAfter
$LastCertProperties = Get-ChildItem -Path "Cert:\LocalMachine\My" | where {$_.Thumbprint -eq $(Get-Item -Path "RDS:\GatewayServer\SSLCertificate\Thumbprint").CurrentValue} | select Thumbprint,NotAfter

$NewCertThumbprint = $NewCertProperties.Thumbprint
$NewCertNotAfter = $NewCertProperties.NotAfter
$LastCertThumbprint = $LastCertProperties.Thumbprint
$LastCertNotAfter = $LastCertProperties.NotAfter

write-host
write-host "New  Cert Thumbprint is: $NewCertThumbprint"
write-host "New  Cert NotAfter is: $NewCertNotAfter"
write-host
write-host "Last Cert Thumbprint is: $LastCertThumbprint"
write-host "Last Cert NotAfter is: $LastCertNotAfter"
write-host

if ($NewCertNotAfter -lt $LastCertNotAfter) {
 write-host "New Cert's ExpireDate is Less then the old one, Please check."
 Stop-Transcript
 exit;
}

if ($NewCertThumbprint -eq $LastCertThumbprint) {
 write-host "Cert Doesn't Change, Program Close, Please check."
 Stop-Transcript
 exit;
}

write-host ""
write-host "*** Import New Cert"
write-host ""

$CommandLine = 'C:\Windows\System32\certutil.exe -f -p "" -importpfx "'+$PFXFullPath+'" NoExport'
cmd /c $CommandLine

write-host ""
write-host "*** Enable New Cert on Remote Desktop Gateway"
write-host ""

Set-Item -Path "RDS:\GatewayServer\SSLCertificate\Thumbprint" -Value $NewCertThumbprint

write-host ""
write-host "*** Reset TSGateway"
write-host ""

Restart-Service TSGateway

write-host ""
write-host "*** Remove Last Cert"
write-host ""

Get-ChildItem -Path "Cert:\LocalMachine\My" | where {$_.Thumbprint -eq $LastCertThumbprint} | Remove-Item -Confirm:$false

Stop-Transcript
exit;



以下是 2017 年寫的版本

本教學利用 Let's Encrypt 來佈署 Remote Desktop Gateway
  1. 首先到 Let's Encrypt Win Simple 下載
    以我的例子下載 v1.9.3 版
    2017.10.17 更新 下載 v1.9.7.0 beta6 版
    2017.11.08 更新 下載 v1.9.7.1 版
      
  2. 在 IIS Default Web Site 下建立 .well-known\acme-challenge 資料夾
    絕對路徑就是 C:\inetpub\wwwroot\.well-known\acme-challenge
    這個 C:\inetpub\wwwroot 是 IIS 裝好後的預設路徑
    如果變更過, 就指到你修改過後的 Document Root 去建立這個階層資料夾

      
  3. 資料夾建好後要設定 web.config, 存放的路徑就在 acme-challenge 這一層裡面
    C:\inetpub\wwwroot\.well-known\acme-challenge\web.config
    內容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <staticContent>
                <mimeMap fileExtension="." mimeType="text/plain" />
            </staticContent>
        </system.webServer>
    </configuration>
    如果沒有做這個設定, 會因為不認識 Let's Encrypt 建立的驗證檔案而無法瀏覽, 也就會驗證失敗
    另外, Let's Encrypt 是用 http 連線來驗證, 所以 TCP Port 80 記得開
      
  4. 將 Let's Encrypt Win Simple 下載來的壓縮檔解壓縮,
    以我的例子是放到 C:\LetsEncryptWinSimple

      
  5. 下指令:
    C:\LetsEncryptWinSimple\letsencrypt.exe --accepttos 
    --emailaddress IT@Contoso.com --plugin manual --manualhost Juno.Contoso.com --webroot C:\inetpub\wwwroot
  6. 正確驗證並取得憑證後, 會自動建立一個 Schedule Task 跑 Renew
    程式會問你: Do you want to specify the user the task will run as? (y/n)
    如果你要用別的帳號來跑就按 Y 然後用別的帳號, 我是按 N 就用 Local Administrator 跑
    需要注意的是在這裡如果設定用其他帳號 (不是上述所有操作時使用的帳號) 的話
    需要把以下憑證相關檔案複製到要用來跑 Schedule Task 帳號的相對路徑中
      
  7. 取得的憑證及相關檔案會在以下路徑

    C:\ProgramData\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org

    大概長這樣, 其中 *.pfx 就是最重要的檔案, 包含私鑰的憑證
     
  8. 接著就可以自己運用這個憑證去做 Remote Desktop Gateway 的 SSL 驗證了

  9. 如果往後除了自動 Renew, 還要自動匯入憑證的話,
    將以下的 PowerShell Script 存成 .ps1 檔案, 並取代稍早程式建立 Task 的 Action:
    C:\LetsEncryptWinSimple\letsencrypt.exe --accepttos --notaskscheduler --plugin manual --manualhost Juno.Contoso.com --webroot C:\inetpub\wwwroot
    $PFXPath = "$env:AppData\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\Juno.Contoso.com-all.pfx"
    $PFXPath = "C:\ProgramData\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\Juno.Contoso.com-all.pfx"$CommandLine = 'C:\Windows\System32\certutil.exe -f -p "" -importpfx "'+$PFXPath+'" NoExport'
    cmd /c $CommandLine
    $NewCert = Get-PfxCertificate -FilePath $PFXPath | Select Thumbprint
    Import-Module remotedesktopservices
    Set-Item -Path "RDS:\GatewayServer\SSLCertificate\Thumbprint" -Value $NewCert.Thumbprint
    Restart-Service TSGateway
*. 以上文章中的 Contoso 自然不是真的, 只是方便說明, 畢竟 Contoso,com 網域歸 Microsoft 所有

參考網站: IISでLet's Encrypt を利用してSSLサイトを構築する (letsencrypt-win-simple クライアントを利用)

2017.07.28
  • 上述自動更新的 PowerShell Script 作一些修改, 將 .pfx 檔案的路徑用 $env:AppData 變數來取代, 這樣就不會因為不同使用者執行而有問題, 後續的 Command Line 也因此做了修正
  • 有點搞不清楚的是 Let's Encrypt 的 Renew, 即使已經到了可以 Renew 的日期, Renew 也成功了, 但是卻沒有產生新的檔案, 所以目前實際驗證的時候 Renew 沒用, 先改成步驟 5 申請新的憑證的指令來執行就可以, 但這樣的話應該不要每天去要新的憑證吧, 再研究一下他的 Renew 到底怎麼取得新的憑證
2017.10.17
  • 因為 V 1.9.3 版本在 unattended 更新憑證時仍會跳出以下訊息

    Do you want to replace the existing letsencrypt-win-simple httpsacme-v01.api.letsencrypt.org task? (y/n)


    然後就停在那邊, 所以更新版本到 v1.9.7 beta 6 有支援一個 --notaskscheduler 參數能解決這個問題
  • 語法要加上一個參數  --plugin manual

沒有留言:

張貼留言