Set-IISCertificate issue with multiple sites, Server Name Identification (SNI)
snblackout opened this issue · 4 comments
Hello again. I finally was able to get Posh-ACME and Posh-ACME.Deploy installed on my Windows Server 2016 VM to do some testing. This was after Let's Encrypt emailed me that I need to re-issue renewals for all my certificates, well before their expiration and with only a 2 days notice before they revoke them themselves. Thankfully I'm not on vacation off the grid... makes me wonder how to tackle this automatically in the future. If anyone has ideas.
So, I was able to reproduce an issue I've been having on my production server, but running in LE_STAGE for Posh-ACME. Here below are the steps to re-create.
Note: I'm starting from complete scratch here, so someone can try this on their own VM easily.
Note 2: Using PowerShell 5.1
I was getting errors installing modules, so found solution to enable TLS 1.2 and set the default repository with the two below commands:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Register-PSRepository -Default
- Install Posh-ACME:
Install-Module -Name Posh-ACME
- Install Posh-ACME.Deploy:
Install-Module -Name Posh-ACME.Deploy
- Set POSH-ACME to Staging so we can renew as frequent as we need:
Set-PAServer LE_STAGE
- Using Route53 here, so setup that information for the new certificate creation:
$awsSecret=ConvertTo-SecureString "your_aws_secret_string" –asplaintext –force
$r53Params = @{R53AccessKey='your_aws_access_key';R53SecretKey=$awsSecret}
- This issue is found with multiple sites, so create all your new certificates:
New-PACertificate stagetest1.example.com -Contact webmaster@example.com -DnsPlugin Route53 -PluginArgs $r53Params -AcceptTOS -Verbose
New-PACertificate stagetest2.example.com -Contact webmaster@example.com -DnsPlugin Route53 -PluginArgs $r53Params -AcceptTOS -Verbose
New-PACertificate stagetest3.example.com -Contact webmaster@example.com -DnsPlugin Route53 -PluginArgs $r53Params -AcceptTOS -Verbose
- In IIS, import your new certificates to the server
- In IIS, create 3 separate sites, all using HTTPS binding and each site using its respective certificate
- While creating each site, make sure to check
Require Server Name Indentification
and fill in the hostname, ex:stagetest1.example.com
To review: At this point, you should have Posh-ACME running in LE_STAGE, 3 new certificates created and imported into IIS, and 3 new IIS sites created, configured for HTTPS and each site bound to their respective certificate, and finally, SNI enabled with correct hostname filled.
At this point, this should run fine for providing SSL/HTTPS to your clients.
Now, the inevitable renewal issue.
- Create 3 new PowerShell scripts somewhere like
C:\Temp
namedrenew-set-iis-stagetest1.ps1
with the below. Make sure to create the other 2 as well for those renewals and change theMainDomain
,SiteName
andHostHeader
.
if ($cert = Submit-Renewal -MainDomain "stagetest1.example.com" -Verbose -Force) {
$cert | Set-IISCertificate -SiteName "stagetest1.example.com" -HostHeader "stagetest1.example.com" -RemoveOldCert -Verbose
}
- Let's issue a renewal via the script that will then set IIS certificate on success (goal is to have this script run on a scheduled task)
- In PowerShell CD to the directory where the scripts are saved and run the stagetest1 script:
.\renew-set-iis-stagetest1.ps1
- Let the script renew and then attempt to set the certificate for that particular site
Once finished, goto IIS management console and go-to the HTTPS binding for stagetest1.example.com
. You will see that the certificate for that binding has been updated to use the new certificate, but SNI has been un-checked.
- Now, run the 2nd script:
.\renew-set-iis-stagetest2.ps1
Refresh your view in IIS management, go-to the HTTPS binding for stagetest1.example.com
, You will see that site is now using the new certificate for stagetest2.example.com
. Because SNI was un-checked from the previous script. stagetest2.example.com
site HTTPS binding is using the new certificate as well, but SNI is now un-checked for that site.
- Now, run the 3rd script:
.\renew-set-iis-stagetest3.ps1
Refresh your view in IIS again, go-to each site HTTPS binding, every site is now using stagetest3.example.com
certificate, every site also has SNI disabled.
I've also noticed that sometimes the old certificate is not removed as well. Most of the time it isn't removed, but noticed one time the old cert was removed from IIS. Separate issue, but related. Maybe because IIS is still using the other certificates because of this issue.
Welcome back, @snblackout. This should be an easy one. There's a -RequireSNI
switch on that Set-IISCertificate
function that you need to use when you want to check that SNI required check box. So for example:
$cert | Set-IISCertificate -SiteName "stagetest1.example.com" -HostHeader "stagetest1.example.com" -RequireSNI -RemoveOldCert -Verbose
Technically, you can use that same command when getting the first certificate instead of setting up the binding manually as well.
Thanks for the quick reply @rmbolger! I had no idea about that switch! I know you can run Get-Command -Module Posh-ACME.Deploy
to get the functions, but seem to not find anything for support switches that are obvious in the README or Wiki. Might help others coming in to use this fresh. I will try that switch shortly and report back. Thanks.
There's a lot of help built into the functions that you can access using PowerShell's Get-Help
command. So for example:
Get-Help Set-IISCertificate
In PS 5.1, this shows the syntax and some other descriptive data about the function. But you can add -Detailed
or -Examples
to show parameter details and examples. In PS 7, it will show everything by default.
P.S. I've definitely thought about trying to add better web-based help to the main Posh-ACME docs site for Posh-ACME.Deploy. I just haven't come up with a great way to deal with the fact that the git repos are different.
Thanks for your help. I was able to use that switch and now can reliably renew certificates automatically.