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.
will write this as a script later and integrate it with my certbot run
i believe for windows it will be a mix of python and powershell for a while as powershell has really good commandlets for doing windows related functions.
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.
@mcdado, since you are setting up a Windows Domain and Active Directory - you might want to look at using AD Group Policies to automate the distribution of the certificate to the client workstations:
And IF a single signed RDP client will work when copied to other client workstations - you can also use Active Directory to deploy that signed RDP client file to the other workstations:
A) If you are going to use letsencrypt it is definitely a good idea to have the letsencrypt intermediate certificates on all servers and workstations in the domain (so it is trusted)
B) Deploying signed RDP files is also a good idea
C) Usually for these kinds of problem I would be running and internal ca (which AD will automatically distribute certificates for) however the requirement was for letsencryt with RDP
D) From my testing RDP seems to include the Intermediate certificate (i deleted the LetsEncrypt intermediate form the intermediate store)
I briefly looked through the links you posted and it looks very interesting. If I understand this correctly, the ACMESharp is able to generate dns-01 challenges, but you’d need either to update your zone manually or using APIs from your DNS provider, is that right? (unless you’re running a public-facing DNS of course, which we’re not).
In this case, it would be interesting for me to implement the connector for my DNS provider in PowerShell, so that I could set it up on a local server in my local network to automatically perform renews based on the public facing DNS.