Using PowerShell to get wildcard certificate from Let’s Encrypt

This is a guide that shows you how to get a publicly trusted wildcard certificate at no cost from Let’s Encrypt using PowerShell.

Requirements:

  • Windows PowerShell 5.1
  • .NET Framework 4.7.2 (link to check)
  • Possibility to add CNAME in DNS

Step by step

Start PowerShell as admin (see information below for non-admin steps)

Verify that PowerShell’s ExecutionPolicy allows running scripts (i.e. RemoteSigned or less)

clip_image002

Otherwise: Set-ExecutionPolicy RemoteSigned

Run:

Install-Module -Name Posh-ACME

Accept warnings about untrusted repositories (that is, if you accept PSGallery, a common module repository):

clip_image003

Run:

New-PACertificate *.tomdemo.se -AcceptTOS -Contact <your-email> -DnsPlugin AcmeDns -PluginArgs @{ACMEServer='auth.acme-dns.io'} -Install

clip_image004

Explanation of the options used:

*.tomdemo.se The name you want in the certificate. You can add additional comma-separated names
AcceptTOS Indicates that you accept the Let’s Encrypt Terms of Service (see https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
Contact Email for expiration notification (optional)
DnsPlugin Which DNS plugin should be used for automatic domain ownership validation. Since my DNS provider Loopia isn’t natively supported by Posh-ACME, I used the ACMEDns option, which requires you to manually add a CNAME record in your DNS provider once, and that can be reused when updating the certificate. Here is a list of DNS providers supported by Posh-ACME: https://github.com/rmbolger/Posh-ACME/wiki/List-of-Supported-DNS-Providers
PluginArgs Options that depends on chosen DNSPlugin
Install This option will install the certificate in the computer’s Certificate Store (requires admin permission, see Getting certificate without admin permission below)

Do not close the PowerShell window!

Add the CNAME record shown in the output of the command you just ran in the DNS registrar for the domain.
Here is an example from Swedish DNS registrar Loopia, but your DNS registrar interface may look different:

clip_image006

Go back to the PowerShell window and press enter to continue.
The script will wait 2 minutes for DNS to propagate:

clip_image007

After that, you should get the certificate:

clip_image008

To see more information about the certificate, you can use the following command:

Get-PACertificate | Format-List

clip_image009

Here you can see basic information about the certificate and that all the relevant files are stored in %LOCALAPPDATA%\Posh-ACME folder, and that it includes a PFX-file if you want to install the certificate on another machine. The default PFX-password is “poshacme”. You can specify your own with the option -PfxPass when running the New-PACertificate command.

Go to the Local Computer certificate store (run certlm.msc) and verify that the certificate has been installed correctly:

clip_image011

clip_image012 clip_image013

Depending on what service you are using the certificate for, you may need to make extra configuration steps in the service to start using the certificate.

You can manually renew the certificate by running the following command:
Submit-Renewal
clip_image014

As you can see, it will not renew certificates that are not about to expire yet (I believe it uses 30 days or less validity time). You can override this by running:

Submit-Renewal -Force

To automate the renewal, you can create a scheduled task that runs this command daily:

Create a file called C:\Cert\AutoRenewal.ps1, containing the command “Submit-Renewal” (not the -Fore option, since you don’t want to renew at every check).

Run the following commands, but first change <password> to your own password
Note: The scheduled task must run in the context of the user requesting the certificate since validation information is stored in that user’s profile.

$Trigger = New-ScheduledTaskTrigger -At 10:00am -Daily
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "C:\Cert\AutoRenewal.ps1"
Register-ScheduledTask -TaskName "Certificate AutoRenewal" -Trigger $Trigger -User "$env:USERDOMAIN\$env:USERNAME" -Password '<password>' -Action $Action -RunLevel Highest –Force

Test certificates

For testing, you can switch the Let’s Encrypt server you send your requests to. The test server does not create a publicly trusted certificate but has no rate limiting.

Read more about rate limiting here: https://letsencrypt.org/docs/rate-limits/

To use test server:

Set-PAServer LE_STAGE

To use production server:

Set-PAServer LE_PROD

It will keep using the specified server until you change it again.

Getting certificate without admin permission

Most steps above work without admin permission, with the exception of installing the certificate in the Computer certificate store.

You might need to restrict the scoop of these commands as well:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Install-Module -Name Posh-ACME -Scope CurrentUser

Then exclude the -Install option in the New-PACertificate command example above.

You will still get a valid publicly trusted certificate, and you can move the created pfx-file to a computer where you want to install it (where you are admin).

Custom Acme-DNS instance

In my example above, I use the public ACME-Dns service. The advantage of that is that your DNS provider does not have to support API access for the Domain Verification part. Instead, you manually create a CNAME record in your DNS provider once that redirects the DNS validation to ACME-Dns.

To increase security, you should use your own instance of Acme-DNS, see here: https://github.com/joohoi/acme-dns

About Tom Aafloen

IT Security Advisor @ Onevinn
This entry was posted in Okategoriserade. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s