Creating Verifiable Remote Desktop Host Certificates with spki
This guide will show you how to use
spki to generate and deploy fully verifiable x509 certificates for accessing your hosts via Windows Remote Desktop, eliminating the dreaded security warning.
Accessing remote desktops securely and without certificate warnings
By default, Windows will generate a self-signed certificate and present that when you try to connect to a remote host. This certificate is used both to verify the host’s identity and to encrypt the connection. However, this makes the connection very susceptible to man-in-the-middle attacks, as an attacker can easily generate their own self-signed certificate that appears near-identical to the one on your host. Unless you’re paying careful attention, you may not notice the change, and then the attacker can eavesdrop on your connection.
When you connect to a host that presents a self-signed certificate, Windows will show the following security warning because it is not signed by a trusted authority:
While you can just ignore the warning, it is easy and much more secure to create your own certificate authority and create a trusted, verifiable certificate that won’t generate a warning if everything is in order.
Setting up a PKI with CRL’s
The first step is creating a Public Key Infrastructure with Certificate Revocation Lists. CRL’s are used to verify that the Certificate Authority (CA) of your PKI has not revoked the certificate your host is presenting. This guide is geared towards Linux users, but as
openssl are both cross-platform, it should work for other OSes with minor modifications.
A simple CRL Distribution Point over http
The easiest way to create a CRL DP is by serving it over http. NB: this is one case where https should not be used, as the CRL of the https server would also have to be verified, and the CRL of its CA, and so on and so forth. The distribution point should be set up in advance of creating your certificates, as the URI will be permanently encoded in the certificates. If you are accessing your remote hosts over the internet, you’ll also want to make sure that your CRL Distribution Point is publicly accessible.
First we’ll set up a directory from which to server CRL’s and public certificates generated by our pki, for convenience:
sudo mkdir /var/pki sudo ln -s /root/ca/intermediate/certs/ /var/pki/certs sudo ln -s /root/ca/intermediate/crl/intermediate.crl.der /var/pki/intermediate.crl sudo ln -s /root/ca/crl/ca.crl.der /var/pki/root.crl sudo ln -s /root/ca/certs/ca.cert.pem /root/intermediate/certs/root.cert.pem
Your directory structure will end up looking something like this:
administrator@fserver:~$ ll /var/pki total 8.0K drwxr-xr-x 2 root root 4.0K Apr 4 15:16 ./ drwxr-xr-x 17 root root 4.0K Mar 29 10:15 ../ lrwxrwxrwx 1 root root 31 Apr 4 15:15 certs -> /root/ca/intermediate/certs// lrwxrwxrwx 1 root root 49 Apr 4 15:15 intermediate.crl -> /root/ca/intermediate/crl/intermediate.crl.der lrwxrwxrwx 1 root root 26 Apr 4 15:16 root.crl -> /root/ca/crl/ca.crl.der
In this example, we’ll use the Apache HTTP server, but any alternative can be used.
apache2 with your distribution’s package manager (e.g.
sudo apt-get install apache2 or
sudo yum install httpd)
If you want to use subdomain as your CRL DP (e.g.
pki.domain.com), add the following to a “site” configuration file
<VirtualHost *:80> ServerName pki.domain.com DocumentRoot /var/pki <Directory /var/pki> Allowoverride none Options FollowSymLinks Require all granted </Directory> <Directory /var/pki/certs> Options Indexes FollowSymLinks </Directory> </VirtualHost>
(Don’t forget to replace the
ServerName with your actual domain name)
Activate the site with
sudo a2ensite pki and then restart apache2 (
sudo systemctl restart apache2 or
sudo systemctl restart httpd)
If you already have domain and you’d like to add the CRL DP as a subdirectory, add the following to your existing server configuration (default location:
Alias /pki /var/pki/ <Directory /var/pki> Allowoverride none Options FollowSymLinks Require all granted </Directory> <Directory /var/pki/certs> Options Indexes FollowSymLinks </Directory>
Now restart apache2 (
sudo systemctl restart apache2 or
sudo systemctl restart httpd)
Before continuing with the PKI setup, ensure that your Distribution Point is accessible through a browser!
Setting up the PKI
spki from the Github repo and save it somewhere in your path, like
Open the script in your favorite text editor, and set the following two variables based on your previous http server setup:
spki init to go through the process of setting up the PKI. You can watch an example asciicast here.
This will create a Root CA and use it to sign an Intermediate CA. The Intermediate CA will then be used to actually sign your host certificates. The CRL’s are also automatically generated and signed.
You’ll want to make sure that the Intermediate Certificate has the correct CRL DP:
X509v3 CRL Distribution Points: Full Name: URI:http://pki.domain.com/root.crl
If the CRL is not accessible, the verification step will fail. You’ll want to correct that and re-verify the intermediate certificate before continuing:
The Root CA private key should be stored offline in a safe place. If that key is compromised, the entire PKI is compromised. If the Intermediate CA key is compromised, however, you can revoke it and generate a new one. Any attempts to verify certificates signed by your compromised intermediate key will fail upon checking the CRL.
Now we’ll actually create the certificate that will be used by your Windows host.
spki create server <windows host name> and follow the prompts. If you access the host over the internet using a domain, you can use a
subjectAltName so that the certificate is valid for both your local computer name, and also the domain name. In that case use
spki create server <windows host name> -SAN DNS:domain.com.
Again, make sure that the certificate has the correct CRL DP:
X509v3 CRL Distribution Points: Full Name: URI:http://pki.domain.com/intermediate.crl
Deploying on Windows
The easiest way to import multiple certificates in Windows is by using the pkcs12 format. Run
spki export-pkcs12 <windows host name> to generate the
.p12 file that will contain the Root CA, Intermediate CA, and your newly created keypair. You’ll have to supply an export password. Now copy that file (default:
/root/ca/intermediate/certs/<windows host name>.p12) over to your Windows host, and open the file to begin the import process. Import everything to your “Personal Store” by following the steps below.
After the import completes, open up the Certificate Management Tool (search:
manage computer certificates or Win+R,
certlm.msc, Enter). There will be three new certificates in
Personal Store\Certificates: Root CA, Intermediate CA, and the host certificate. Drag the Root CA into
Trusted Root Certification Authorities\Certificates and the Intermediate CA into
Trusted Intermediate Certification Authorities\Certificates. You can leave your host certificate in the Personal Store.
Verify the complete trust chain by double-clicking your host certificate in the Personal Store and going to Certification Path tab, you should see the entire path back to your Root CA.
Finally, you need to tell remote desktop to use the new certificate. First, find the certificate’s SHA1 Hash, or “Thumbprint” by checking its “Details” tab:
Copy that thumprint and open a command prompt with administrator privileges.
wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="THUMBPRINT", replacing THUMBPRINT with what you just copied.
You’ll have to restart the remote desktop service or host for this to take effect.
Deploying on clients
In order to trust the newly deployed certificate, your clients will also need to trust the Root CA cert and Intermediate CA cert. If you used the symbolic links above to serve certificates, you should be able to download them simply by accessing
pki.domain.com/certs/intermediate.cert.pem. Repeat the import process from above, this time on the two certificate files, and place them in the same trusted CA stores. You can also import them by changing the file extension to
.crt and simply opening the files.
Deploying on Linux
If you’re accessing your host via Linux, you’ll need to copy the Root and Intermediate CA certs into
/usr/local/share/ca-certificates and run
Last updated: 06 May 2019 by Aram Akhavan