Since we’re setting up our local network with a domain, I’d like to properly secure our connections to Remote Desktop sessions. One might argue that using self-signed certificated is valid in the context of the local network, but I don’t like the idea of collecting self-signed certificates in my keychain, plus it would also stop people from the company to dismiss security warnings about certificates.
I did some googling about this, but many informations are outdated or not specific to this issue. The main assumption is that I’d like to automate the whole process of renewal. The second assumption is that a DNS challenge becomes the necessary way of obtaining the certificate, since servers/workstations are not accessible directly from outside our network via public-facing DNS.
In our case, our domain and public DNS are hosted on OVH, which as far as I can tell has an API to manage the DNS zone programmatically. Many other DNS providers offer APIs to make such changes. Can you confirm that this would allow me to pass the DNS challenge, if properly configured?
The next step would be the setup of Remote Desktop services to use the certificate. The way to configure it and reloading it is outside the scope of this community site (even though if you found a killer guide/blogpost, I would be very grateful!), but I would like to know if a certificate from Let’s Encrypt is compatible with such a use case. Maybe it just need extra processing/packaging in a different format?
In summary, has anyone tried to automate this use case? Any tips?
In terms of using Let’s Encrypt certificate in Windows Remote Desktop, we’ve had a handful of questions about that and it doesn’t look like anyone ever reported back afterward about how well it worked (or didn’t work).
Thanks for all these details, @ahaw021! They should be super-useful and I’ll try to remember this thread in case people ask about this in the future.
For removing the spaces from the fingerprint, do you have an equivalent of tr in the Windows command line, maybe with Powershell? In Unix you could use tr -d ' ' to remove spaces from a string, without having to do it by hand in a text editor.
Andrei, your posts are awesome! I’m glad you shared your knowledge here.
Also, I didn’t know about https://zerossl.com, it’s a great starting point for experimentation!
I bookmarked this conversation so that I can try to accomplish the same on my own, later on when I’ll set this up.
As far I understand it, this should be completely automatable through PowerShell and Python, right?
For example, at renewal you would run certbot, with a hook for DNS validation, and once we have the certificate then obtain the thumbprint and store it in a PowerShell variable (with space removal), convert the certificate to PFX and import it. This last step is still not clear to me: in your screenshot you used the key store GUI, can you use PowerShell to import the certificate, or update it on renewal? On Windows does it work and makes sense to use something such as symlinks like on Unix OSes?
this is where i am currently having challenges with windows
i am trying to figure out how to put the RSA key in to the store. There is no point having a cert without a key.
PFX allows us to do this.
There is the certutil.exe utility which will generate a CSR and create a key in the right store (you then fulfill the challenge and import the cert only)
Windows IIS cannot make use of certs on file stores they have to be in the cert store
I am working my way through the powershell side also going to log a request with the boulder team to make PFX an option as being able to download a PFX file from letsencrypt will simplify things for windows users
I’ll give you the manual steps that I take. I only have a couple of client stations that it is needed on, so I have not taken the time to automate the process. Besides, this is the best way to see what is actually happening.
Even though we have a valid LetsEncrypt certificate in the server’s certificate store [Remote Desktop]-[Certificates], RDP clients still see a “The identity of the remote computer cannot be verified” message when trying to connect.
We need to digitally sign the RDP files on the client machines with an SSL certificate to get rid of the message.
First - Copy the Let’s Encrypt certificate that you want to use from [Personal]-[Certificates] and Paste it into the certificate store under [Remote Desktop]-[Certificates].
Export that LetsEncrypt certificate on the server from the server’s certificate store under [Remote Desktop]-[Certificates].
You MUST choose to include the cert’s Private Key when exporting.
Copy the exported PFX file from the server to the client machines that have RDP files.
On the client machine, import the server’s PFX format certificate into the client’s Personal certificate store.
Now, we can use rdpsign.exe to sign the client’s RDP file that connects to the server.
Go into the client’s certificate store to [Personal]-[Certificates].
Open the imported cert and go the [Details] tab of the [Certificate Information] dialog.
Choose [All Fields] from the first dropdown list.
Find the value of the [Signature Hash Algorithm] … (probably SHA256, or maybe SHA1 on older certs).
Find the value of the [Thumbprint] field. This will be a series of two byte characters that are separated by spaces.
Copy the Thumbprint value and edit all of the white-space out of it, so that it is a solid string of characters. There may be an odd character at the front of the string - if so, that will need to be deleted. You might not be able to see this character, so it is best to place the cursor at the front of the string and just hit delete until the first real character of the thumbprint string is deleted - and then retype that character at the beginning of the string.
Launch a Command Prompt (with admin privileges).
Run this command with YOUR OWN values:
rdpsign.exe /sha256 f428629df8fdaefc701ee0335e956edc9844b0aa “C:\Users\bubba\Desktop\MyServerConnection.rdp”
If rdpsign completes successfully, you will see the message “All rdp file(s) have been succesfully signed.”
Now, when that signed client is used to connect to its server the first time; the user will see the server name, etc.; and they will have to click on [Ok] the first time.
After that, future RDP connections will connect with no messages.
Yes. Since you will have a new Let’s Encrypt certificate when it is set to renew, you will need to copy the new cert to the RDP cert location in the server’s certificate store - and then perform the export and the rest of the steps each time.
Hmmm @mcdado… I never thought about it before, but you may be able to perform the RDP client script signing on a single client workstation - import the new cert on the rest of your client workstations - and copy the signed RDP script to those other client workstations. Not sure, but if it works it could save a tedious step.
I bet a PowerShell expert can automate most of this process. I understand that Microsoft has exposed a significant amount of Windows configuration to PowerShell in one way or another. So I expect there could be a script made that takes care of most of these steps for you.
This limitation throws me off somehow… for me automating the server is one thing, automating n clients is another. Plus is not a situation where you enter the host and credentials on the fly and you can access securely, you’d need to have a signed .rdp file that expires whenever there’s a renew.
Also, I’d need to figure out how to sign macOS clients.
Thanks so much for the feedback @CBruce , soon I’ll be able to experiment myself when I get the local domain and DNS going.