Create Trusted Remote Desktop Services (RDP) SSL Certificate

For Windows Server 2016/2019 and Windows 10, see my new post: Trusted Remote Desktop Services SSL Certs for Win10/2019

For Windows environments that want extra security, one of the features that has been around for ages is requiring TLS 1.0 for Windows RDP (Remote Desktop) connections. This functionality requires a certificate on the server, since TLS is based on the usage of X.509 certificates. Installing a RDP SSL certificate is easy.

By default Windows will create a self-signed certificate automatically for use with RDP. But as we all know, self-signed certificates are nearly worthless, and could easily be intercepted for man-in-the-middle attacks. So one should reconfigure Windows to use a trusted certificate. Thankfully this is fairly easy, and once configured, pushed down to all servers via GPO for automated deployment.

I’ve validated that this procedure works both on Windows Server 2008 R2 and Windows Server 2012. It may work on Windows Server 2008.It requires the use of a Microsoft enterprise online certificate authority. Again, I’ve used both Windows Server 2008 R2 and Windows Server 2012 CAs with success. Not surprising, since certificates are industry standard. For the purposes of this article I’ll use Windows Server 2008 R2 CA, and Windows Server 2012 “target” server.

The general process is first creating a new Certificate Authority certificate template that has an extended key usage to limit its use to only Remote Desktop TLS sessions. Second, we configure a GPO setting to automatically configure servers to request a certificate via this template, and use it for RDP TLS. Refresh GPO on the target server, and finally we attempt to connect via a stand-alone computer to verify it sees the certificate that we deployed.

Installing a RDP SSL Certificate

1. On your Microsoft certificate authority server open the Certificate Templates console.

2. Duplicate the Computer template and use the Windows Server 2003 Enterprise format (Server 2008 v3 templates will NOT work).

3. Change the template display name to RemoteDesktopComputer (no spaces). Verify the Template Name is exactly the same (no spaces). You can use a different name if you want, but both fields must match exactly.

4. Now we need to create an application policy to limit the usage to RDS authentication, then remove the other application uses for the certificate. On the extensions tab click on Application Policies then click on Edit.

5. Click on Add, then click on New.  Set the value of Name to Remote Desktop Authentication. Change the object identifier to 1.3.6.1.4.1.311.54.1.2.

6. From the Application Policies list, select Remote Desktop Authentication.
7. Back on the certificate template properties, remove all other entries. Only Remote Desktop Authentication should be present.
8. If you wish, you can modify the validity period of the certificate, making it say two years instead of the default of one.
9. You probably want to secure your domain controllers as well, so for that we need to modify the security setting on the template. Open the Security tab and add the group Domain Controllers and give the group Read and Enroll (not Autoenroll).
10. Open the MMC snap-in for managing your Certificate Authority and locate the Certificate Templates node. Right click, select New, then Certificate Template to Issue. Choose the RemoteDesktopComputer template.
11. Next up is configuring the GPO to utilize the new template. You can modify any GPO you wish, or create a new one. Obviously the scope of the GPO should cover any servers that you want to secure with TLS. This could be a server baseline GPO, domain GPO, or whatever you want.
12. In the GPO editor locate the node Computer Configuration\Policies\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session HostSecurity. Modify the Server Authentication Certificate Template setting. Enable the policy and enter the certificate template name that exactly matches what you created in your CA.

13. In the same GPO node, configure the Require use of specific security layer for remote (RDP) connections to use SSL (TLS 1.0).

14. Wait for the GPO to replicate, then refresh the GPO on a test server. Wait a minute, then open the Certificates MMC snap-in for the computer account. Look in the PersonalCertificates store for a certificate that has the Intended Purposes of Remote Desktop Authentication. If it’s not there, wait a minute, and refresh. If it never appears, something is wrong. Look at the gpresult to make sure your GPO is being applied to the server.

15. Once the certificate appears, double click on the certificate to open it. On the Details tab look at the first few characters of the thumbprint value and remember them.

16. To make sure the RDP service is aware of the new certificate, I restart the Remote Desktop Services service.

17. Open an elevated PowerShell prompt and run this command:

Get-WmiObject -class “Win32_TSGeneralSetting” -Namespace root\cimv2\terminalservices -Filter “TerminalName=’RDP-tcp'”

Validate that the Security Layer value is 2 and that the thumbprint matches the certificate. If both of those settings are correct, then you are good to go!

As a quick test I attempted to connect to this server from a non-domain joined computer that did not have the root certificate for my CA. I configured the RDP client to warn on any security issues. As expected, the client threw errors about the CRL not being available, and that it didn’t trust the chain. I also viewed the certificate and verified it was the correct one.

It seems Windows 8 has much more stringent certificate checking than Windows 7. The screenshots below are from Windows 7, in case you didn’t recognize the chrome. When using a Windows 7 non-domain joined computer to access the same TLS protected server, I got NO certificate warnings. That was even with the RDP 8 add-on hotfix. I’m glad to see Win8 does thorough certificate validation.

Connecting to the same server from a domain-joined computer that trusted the root CA resulted in no security warnings and a successful connection. If you look at a Wireshark capture you can also validate that CRL information is being exchanged between the computers, which means TLS is being used.

For Windows Server 2016/2019 and Windows 10, see my new post: Trusted Remote Desktop Services SSL Certs for Win10/2019
Print Friendly, PDF & Email

Related Posts

Subscribe
Notify of
22 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Angel Castillo
May 18, 2013 3:00 pm

Hi Derek, this is what I needed, thank you so much! Now that you talk about the CRL, I can see that you are using LDAP CDP Publishing, now could you post an OCSP AIA Publishing, I am preparing for my 70-646 Exam and I've read two books already, several TechNet and other Blogs in how to work with OCSP in a proper way that truly work but, nothing seems to be working… inside the PKIView.msc the OCSP AIA Location #1 is Unable to Download, please uploaded a step by step guide on that, thank you very very much!

Raul
July 24, 2013 6:25 pm

The powershell command failed on windows 8. I had to remove the -filter and then it worked. Thanks for the write up!

mtol20mtol20
August 18, 2013 3:45 am

Hi, I'm trying to get my RDS certificate problem solved but after several hours of troubleshooting i'm reaching out for help. I have four 2012 servers with RDS roles. SRV1 is RDS Session Host SRV2 is RDS Session Host SRV3 Is Connection Broker SRV4 with roles: RDGateway and RDWEB internal.domain.local extrenal.domain.nl Wildcard certificate on all rds roles for external domain.nl Internal ca with certificate based on Remote Desktop Authentication (1.3.6.1.4.1.311.54.1.2) I can get to https://rdweb.external.domain.nl and see all rds rdweb apps without certificate warnings. When I start the app I get: name mismatch, request remote computer:srv1.internal.domain.nl, name in certificate from… Read more »

mtol20mtol20
August 18, 2013 3:53 am
Reply to  mtol20mtol20

tried: wmic /namespace:\\root\CIMV2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="222779121ab46b5e5a1188c9f75e4fb4381f454"}
Comes back with: Updating property(s) of '\\SRV1\root\CIMV2\TerminalServices:Win32_TSGeneralSetting.TerminalName="RDP-Tcp"'
ERROR:Description = Invalid parameter

Can Someone help me with this.

Logic
December 10, 2013 2:33 pm

I like it how you say it's easy and it comes with a convoluted 4 page guide

rick
December 30, 2013 5:35 pm

Followed the post using a test OU with a test server.
Upon GP refresh the server is issued two certificates and it is being issued two new certs every time the server refreshes policy.
None of them prevent the security warning from displaying when connecting to the server via RDP session from a Win7 client.

John
January 8, 2014 1:51 pm

Hello, first of all thanks for great guidance! I tried it as you described (except deployment via GPO – I did it manually via mmc), but it did not work:( I have 2 servers (Windows Server 2012). One is DC, where is CA stored. I created certificate template as you advised. Then I connected to second WS2012 (terminal server), run MMC and requested certificate based on template created in previous step. So far so good. Certificate has been added to Personal store on WS2012 (terminal server). But when I tried to connect to server (from non-domain machine) I got pop… Read more »

Mark
April 23, 2014 1:55 am

Hello

i have followed the guide above
only at certificates/remote desktop/certificates there is alway's a self signed certificate (it will recover when i delete it)
when running Get-WmiObject -class “Win32_TSGeneralSetting” -Namespace rootcimv2terminalservices it show the self signed certificate

Jerrod
October 8, 2014 12:02 pm

Will this work if you connect to the server by IP instead of by name?

Tito
October 14, 2014 11:54 am

I attempted to follow these steps but when adding the application policy extension "Remote Desktop Authentication" and adding in the correct Object Identifier, the "Intended Purpose" is listed as the Object Identifier and not Remote Desktop Authentication, on top of this it remains editable if I were to go back into the "Edit Application Policies Extension" property box for the template. Why is it doing this? I tested on another system and it worked just fine…

Tommy
November 25, 2014 1:37 pm

Great post. I followed the directions verbatim and RDP connects with SSL to 2008 servers. I can see the enterprise ca issue the cert, and the target server automatically puts in in the Personal Store. However, all of our Windows Server 2003 R2 servers pickup the certificate in their personal stores, but the cert does not show up under the TS configuration settings. Also, IIS does not see a cert either that it can use. Any ideas?

Martin
December 17, 2014 6:50 am

When I right-click on "Certificate Template, New, Certificate template to issue", the new RemoteDesktopComputer certificate is missing

Fresco
March 15, 2015 11:35 pm
Reply to  Martin

I've got same situation 🙁

May 1, 2017 2:12 pm

Hi Derek,

Thanks for this great post. I'll be implementing this on my servers asap.

I'm a bit surprised here though: Does this mean that by default RDP connections are *not* encrypted at all ?

All of a sudden I'm feeling unwell, thinking of all the business critical work I do through (unencrypted ?) RDP…

Arun
July 7, 2017 5:39 am

What will happen when the certificate expires. Will it get automatically renewed.

Peter
October 11, 2017 5:23 pm

Fantastic guide – thanks Derek!

Lyn Williams
December 6, 2018 9:54 am

Hi Derek,
Thank you for the excellent ” Create Trusted Remote Desktop Services (RDP) SSL Certificate”. It cleared up many questions for me.

Have you done any revisions or a new article for Windows 10 and Server 2012r2?

Kevin
June 12, 2019 9:09 am

Hello Derek, I have followed these steps on my CA and created the GPO. I am applying it to a test server and seeing the below results in the test server certificate console:

The cert is not being auto-enrolled, and after manually enrolling the certificate, it is being placed in the “Certificate Enrollment Requests” store. Shows Issued To: [not available] and Issued By: [not available]

Is there a step I missed somewhere?

Anderson Lacruz
August 5, 2019 1:18 pm

Good article, just a little typos and case sensitive with the powershell execution, specifically the filter “RDP-tcp”. Here the execution with the correction:
Get-WmiObject -class “Win32_TSGeneralSetting” -Namespace root\cimv2\terminalservices -Filter “TerminalName=’RDP-Tcp’”

Virgil
July 22, 2020 5:35 pm

This steps saved me again. Thanks Derek.