- Published on
Deploy LetsEncrypt certificates on Windows Servers
- Authors
- Name
- Jonathan Devere-Ellery
Recently I wanted to replace all of my old Digicert certificates in my lab to Let’s Encrypt certificates. For those that aren't familiar, Let’s Encrypt has a very short 90-day validity for certificates which is better for security, but it also forces admins to make sure that automation is in place to manage certificate renewals.
In order to get a certificate issued, Let’s Encrypt needs to validate ownership of the domain, and will either provision a DNS record (DNS-01 challenge) under example.com, or provision an HTTP resource under a well-known URI (HTTP-01 challenge) on http://example.com/
My lab environment has some firewall restrictions on TCP/80 which makes it difficult for me to use the HTTP validation method, so for me using the DNS method is much more convenient.
On Linux servers we typically use certbot to manage the certificate renewals, and on Windows there is Win-ACME which is a simple ACMEv2 client. I use Chocolatey as a package manager on Windows, so I will use that to manage the installation by running choco install win-acme
.
There are many different cloud providers like Route53, Azure, DigitalOcean or many others, that have plugins that integrate with win-acme. In my case I'm using Cloudflare, so I need to download that plugin to add into my win-acme installation folder:
$path = "C:\ProgramData\chocolatey\lib\win-acme\tools"
$asset = (Invoke-WebRequest https://api.github.com/repos/win-acme/win-acme/releases/latest | ConvertFrom-Json).Assets | Where-Object name -like *cloudflare*
Invoke-WebRequest -Uri $asset.browser_download_url -Out (Join-Path $path $asset.name)
Expand-Archive (Join-Path $path $asset.name) -DestinationPath $path
Order a certificate from Let's Encrypt
$APIToken = "1234567890"
wacs.exe --source manual --host "srv1.contoso.com" --emailaddress "admin@contoso.com" --accepttos --validation cloudflare --cloudflareapitoken $APIToken
# Setup the Task Scheduler to renew certificates automatically
wacs.exe --setuptaskscheduler
Order a certificate to be installed for Remote Desktop Services (RDP)
$path = "C:\ProgramData\chocolatey\lib\win-acme\tools"
wacs.exe --source manual --host "srv1.contoso.com" --certificatestore My --emailaddress "admin@contoso.com" --accepttos --script (Join-Path $path "Scripts\ImportRDSFull.ps1") --scriptparameters "{CertThumbprint}" --validation cloudflare --cloudflareapitoken $APIToken
# View certificates installed in the Personal store for the Local Computer account
Get-ChildItem -Path cert:\LocalMachine\My | FL FriendlyName, Thumbprint, Subject, NotBefore, NotAfter
$WMIpath = (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").__path
Set-WmiInstance -Path $WMIpath -argument @{SSLCertificateSHA1Hash="THUMBPRINT"} # Replace with actual Thumbprint
There are more examples in the win-acme documentation for other examples such as unattended installs for Exchange Server, so if those sound interesting check them out also.