Let’s encrypt Remote Desktop Services

When implementing Microsoft Remote Desktop Services, you need certificates that are trusted by all clients that will connect to your environment.
When implemented only interanlly, that can be done with internal certificates, but when clients need to connect from outside, you need several certicates or a wildcard certificate for your domainname.

With Let’s Encrypt, this can be implemented without having to pay for it. But you want to automate the certificate renewal, because a certificate from Let’s encrypt is only valid for 90 days.
This article outlines the steps for the initial configuration and renewal of the certificates.
For the explanation of these steps, you can click on the links to the website of the used sources.

This article does not explains how to implement Microsoft Remote Desktop Services itself.
The used environment is one server with all the Remote Desktop Services roles needed.

DISCAIMER: Use all commands and scripts at your own risk! Always test it in your own environment. The author can not be held responsible for any mistakes or typos in this article.

First, download Openssl for Windows (x64) from https://indy.fulgan.com/SSL/openssl-1.0.2l-x64_86-win64.zip.
And download ZeroSSL from https://github.com/do-know/Crypt-LE/releases/download/0.23/le64.zip.
Read about ZeroSSL at https://zerossl.com/usage.html

Open a Command Prompt with Administrator Privileges on the Remote Desktop Services server.
Go to the directory where OpenSSL is installed. Run the comment: openssl genrsa -out account.key 4096
You only need to do this once.
Then create the key for each hostname. You need one for the url users connect to from the outside, for example rds.lansingit.nl: openssl genrsa -out rds.lansingit.nl.key 2048
And you need one for the real servername, for example server01.lansingit.nl: openssl genrsa -out server01.lansingit.nl.key 2048

Go to the directory where ZeroSSL is installed.
Move the key files you created earlier to this folder.

If you have the rights to add records in the DNS of your domain, you can use the DNS verification method to request the certificates. Run the following command and create the DNS record as explained in the output of this command. I ran the comment for each url:
le64.exe –key account.key –csr rds.lansingit.nl.csr –csr-key rds.lansingit.nl.key –crt rds.lansingit.nl.crt –domains “rds.lansingit.nl” –generate-missing –handle-as dns –live
le64.exe –key account.key –csr server01.lansingit.nl.csr –csr-key server01.lansingit.nl.key –crt server01.lansingit.nl.crt –domains “server01.lansingit.nl” –generate-missing –handle-as dns –live

I have tried the http verification, but it did not create the verification file, only the folders which caused the failing of the verification. Feel free to try offcourse.

Now you have the key and certificate you need to convert these to a pfx. This pfx is needed to import the certificate in your Remote Desktop Services environment.
Run the following command to convert the certifcate for each url: openssl pkcs12 -export -out rds.lansingit.nl.pfx -inkey rds.lansingit.nl.key -in rds.lansingit.nl.crt -passout pass:<password>

Now open a PowerShell prompt as an Administrator and run the following command:
> Import-Module RemoteDesktop
> set-RDCertificate -Role RDPublishing -ImportPath c:/temp/server01.lansingit.nl.pfx -Password <password> -ConnectionBroker server01.lansingit.nl -force
> set-RDCertificate -Role RDWebAccess -ImportPath c:/temp/rds.lansingit.nl.pfx -Password <password> -ConnectionBroker server01.lansingit.nl -force
> set-RDCertificate -Role RDRedirector -ImportPath c:/temp/server01.lansingit.nl.pfx -Password <password> -ConnectionBroker server01.lansingit.nl -force
> set-RDCertificate -Role RDGateway -ImportPath c:/temp/rds.lansingit.nl.pfx -Password <password> -ConnectionBroker server01.lansingit.nl -force
NOTE the use of forward slash in the path, even running on Windows(?)

Put these commando in a script to automate the renewal before the certificates expire.
For example:
$CertificatePassword = “password”
$RDCB = “server01.lansingit.nl”
$CertificateRDP = “C:/temp/server01.lansingit.nl.pfx”
$CertificateBroker = “C:/temp/server01.lansingit.nl.pfx”

# Import the RemoteDesktop module
Import-Module RemoteDesktop

# Certificate Password
$Password = ConvertTo-SecureString -String $CertificatePassword -AsPlainText -Force

# Configure RDPublishing Certificate for RDS
set-RDCertificate -Role RDPublishing -ImportPath $CertificateRDP -Password $Password -ConnectionBroker $RDCB -force

# Configure RDWebAccess Certificate for RDS
set-RDCertificate -Role RDWebAccess -ImportPath $CertificateBroker -Password $Password -ConnectionBroker $RDCB -force

# Configure RDRedirector Certificate for RDS
set-RDCertificate -Role RDRedirector -ImportPath $CertificateRDP -Password $Password -ConnectionBroker $RDCB -force

# Configure RDGateway Certificate for RDS
set-RDCertificate -Role RDGateway -ImportPath $CertificateBroker -Password $Password -ConnectionBroker $RDCB -force

For the renewal proces, run the exact same commands as a Scheduled Task. However, it is not possible to use DNS Verification, offcourse, so run the following command instead for each url. The parameter –renew 3 means you are renewing threed days or less before expiration:
le64.exe –key account.key –csr rds.lansingit.nl.csr –csr-key rds.lansingit.nl.key –crt rds.lansingit.nl.crt –domains “rds.lansingit.nl” –path /var/www/html/.well-known/acme-challenge/ –generate-missing –unlink –renew 3 –live

NOTE: Because this command is not working on my own environment, this is not tested.

Then convert the files to pfx again and import the new pfx files.