We’ll set up a plain Windows Server 2022 environment with IIS and PowerShell to issue a Let’s Encrypt SSL certificate using the Posh-ACME PowerShell module. This guide will ensure that your environment is ready for certificate issuance and renewal using automated and Secure DNS validation and can be used to setup Windows 10\11 also.
Contents
- Prerequisites
- Step 1: Install PowerShell
- Step 2: Install IIS on Windows Server 2022 or 10\11
- Step 3: Install and Configure Posh-ACME
- Step 4: Configure Let’s Encrypt Staging Server
- Step 5: Generate a Staging(test) Certificate
- Step 6: Switch to Production
- Step 7: Confirm the ACME Server
- Step 8: Generate the Production(real) Certificate
- Step 9: Understand the Files
- Step 10: Install OpenSSL on Windows
- Step 11: Prepare the Certificate for IIS
- Step 12: Create the .pfx File
- Step 13: Import into IIS
- Step 14: Bind the Certificate to Your Site
- Step 15: Test Your Site
- Step 16: Enable HTTPS Redirection
- Step 17: Configure HTTPS Redirection
- Step 18: Test the Redirect
- Step 19: Enable HSTS (HTTP Strict Transport Security)
- Step 20: Disable Weak Protocols and Ciphers
- Step 21: Harden Cipher Suites, Use IIS Crypto (Optional)
- Step 22: Enable OCSP Stapling (Optional)
- Step 23: Test Your Configuration
Prerequisites
- Environment Setup:
- Windows Server 2022 or Windows 10\11 with IIS installed.
- PowerShell installed (download from PowerShell).
- OpenSSL installed (download from slproweb.com).
- URL Rewrite module:( download from IIS URL Rewrite )
- A domain you own, like <yourdomain.eu>
- DNS access to manage your domain.
- A static IP, SSL certificates are issued to domain names, not directly to IPs. However, your domain’s A record must point to a valid public IP at the time of certificate issuance and validation.
- If your local development setup involves a public IP (e.g., through DDNS), you can set up a domain name pointing to your public IP and use that for certificate issuance, but we are not going to cover this here, to keep things as simple as possible.
- Posh-ACME Module:
- We are going to use Posh-ACME to issue a Let’s Encrypt SSL, Certbot discontinued Windows support in February 2024
- Valid Contact Email Address:
- An email like <email>@yourdomain.eu that will be associated with the Let’s Encrypt ACME account for certificate expiration notifications.
Step 1: Install PowerShell
To ensure compatibility and access to the latest features, it’s important to install and verify the correct version of PowerShell. Follow these steps:
Install the Latest Version of PowerShell:
Download and install the latest PowerShell.
Download the installer suitable for your operating system (e.g., Windows, macOS, Linux).
Run the installer and follow the on-screen instructions to complete the installation.
Verify the Installed PowerShell Version:
Open PowerShell with administrative privileges, make sure that you opened the latest version 7.xx and higher that you just installed, not the one that comes installed with Windows.
Execute the following command to check the installed PowerShell version:
pwsh -v
This command will display the version number of PowerShell. Ensure it is version 7.0 or higher for optimal compatibility.
Set the Execution Policy to Allow Script Execution:
PowerShell’s execution policy determines which scripts are permitted to run on your system. To allow the execution of local scripts while maintaining security, set the execution policy to RemoteSigned
for the current user:
Open PowerShell with administrative privileges, make sure that you opened the latest version 7.xx and higher that you just installed, not the one that comes installed with Windows.
Run the following command:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
When prompted, confirm the change by typing Y
and pressing Enter.
Setting the execution policy to RemoteSigned
allows scripts created locally to run without a digital signature, while scripts downloaded from the internet require a trusted signature. This balance enhances security without hindering local script development.
Note: Adjusting the execution policy affects script execution behavior. For more details on execution policies and their implications, refer to the official Microsoft documentation: about_Execution_Policies
Step 2.1 : Install IIS on Windows Server 2022
To install Internet Information Services (IIS) on Windows Server 2022, follow these steps:
- Open Server Manager:
- Click on the Start menu.
- Type Server Manager and press Enter to launch it.
- Add Roles and Features:
- In Server Manager, click on Manage in the top-right corner.
- Select Add Roles and Features from the dropdown menu.
- Proceed Through the Wizard:
- On the Before You Begin page, click Next.
- Choose Role-based or feature-based installation and click Next.
- Select your server from the server pool and click Next.
- Select Server Roles:
- In the Select server roles section, check the box for Web Server (IIS).
- A dialog will appear to add required features; click Add Features.
- Click Next to continue.
- Select Features:
- On the Select features page, you can choose additional features if needed. For a basic IIS setup, no extra features are required. Click Next.
- Web Server Role (IIS):
- Review the information on the Web Server Role (IIS) page and click Next.
- Select Role Services:
- In the Select role services section, ensure the following are selected:
- Common HTTP Features: Static Content, HTTP Redirection.
- Application Development: WebSocket Protocol.
- Management Tools: IIS Management Console.
- Click Next to proceed.
- In the Select role services section, ensure the following are selected:
- Confirm Installation Selections:
- Review your selections and click Install.
- Complete the Installation:
- Wait for the installation to finish. Once completed, click Close.
- Verify IIS Installation:
- Open a web browser and navigate to
http://localhost
. - You should see the default IIS welcome page, indicating that IIS is installed and running.
- Open a web browser and navigate to
Step 2.2 : Install IIS on Windows 10/11
- Open Control Panel:
PressWindows Key + S
, type Control Panel, and select it. - Navigate to Programs and Features:
In Control Panel, click on Programs > Programs and Features. - Access Windows Features:
On the left side, click Turn Windows features on or off. - Enable IIS and Required Features:
- Scroll down and find Internet Information Services (IIS).
- Expand the Web Management Tools and World Wide Web Services sections.
- Select the following features:
- Web Server > Common HTTP Features: Enable Static Content and HTTP Redirect.
- Application Development Features: Enable WebSocket Protocol.
- Ensure IIS Management Console is also selected.
- Apply Changes:
Click OK and wait for the installation to complete. - Start IIS:
- Press
Windows Key + R
, typeservices.msc
, and press Enter. - Locate World Wide Web Publishing Service (W3SVC), right-click it, and select Start.
- Press
Alternative way using PowerShell:
You can streamline the installation process of IIS for every Windows version using one line of PowerShell
Open PowerShell as an Administrator.
Enable IIS and required features:
Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-WebSockets, IIS-HttpRedirect, IIS-StaticContent, IIS-ManagementConsole
Start IIS:
Start-Service W3SVC
Verify IIS is running by visiting
http://localhost
Step 3: Install and Configure Posh-ACME
Open PowerShell as an administrator and install the module:
Install-Module -Name Posh-ACME -Scope CurrentUser -Force
Verify installation:
Get-Module -ListAvailable Posh-ACME
Step 4: Configure Let’s Encrypt Staging Server
To avoid rate limits during testing, use the Staging Server of Let’s Encrypt, this way you will know that everything works well before you ask to issue the Real production SSL, you will change to production at Step 6:
Set-PAServer LE_STAGE
Step 5: Generate a Staging(test) Certificate
Create an ACME account and accept the Terms of Service:
New-PACertificate -Domain <yourdomain.eu> -AcceptTOS -Contact <email>@yourdomain.eu
Follow the instructions to create a DNS TXT record for domain validation.
PS C:\Windows\System32> New-PACertificate -Domain <yourdomain.eu> -AcceptTOS -Contact <email>@yourdomain.eu
Please create the following TXT records: ------------------------------------------
_acme-challenge.yourdomain.eu -> Q11tHfO0D8J34mD74ctTMZKUEDZpZ5svHXB_ONFtxxx
The message indicates that the ACME protocol used by Let’s Encrypt requires you to prove ownership of the domain yourdomain.eu
by creating a DNS TXT record with a specific name and value.
Instructions Provided
- TXT Record Name:
_acme-challenge.yourdomain.eu
This is the name of the TXT record you need to add to your DNS configuration. - TXT Record Value:
Q11tHfO0D8J34mD74ctTMZKUEDZpZ5svHXB_ONFtxxx
This is the value of the TXT record, it will be different each time you issue an SSL.
Why It’s Needed
This is part of the dns-01
challenge for domain validation:
- Let’s Encrypt asks you to create a TXT record in your domain’s DNS to prove that you own or control the domain.
- The ACME server (e.g., Let’s Encrypt) will query the DNS system to verify that the record exists and matches the expected value.
What to Do
- Log in to Your DNS Management Console:
Access the DNS settings for theyourdomain.eu
domain, typically provided by your domain registrar or hosting provider. - Add a TXT Record:
- Name:
_acme-challenge
(Some DNS providers automatically append.yourdomain.eu
to the name, so just_acme-challenge
may suffice.) - Type: TXT
- Value:
Q11tHfO0D8J34mD74ctTMZKUEDZpZ5svHXB_ONFtxxx
- Name:
- Wait for DNS Propagation:
Allow time for the TXT record to propagate across the DNS system. This can take a few minutes to several hours, depending on your DNS provider. - Verify the TXT Record :
- It’s important to highlight that DNS changes can take time to propagate. You should verify that the TXT record is publicly accessible before proceeding.
- Verify the TXT record with a DNS query tool, like
nslookup
that you will check in another PowerShell terminal, DO NOT INTERRUPT THE PROCESS AT THE ORIGINAL TERMINAL: - nslookup -q=txt _acme-challenge.<yourdomain.eu>
- If the value that you entered at your TXT RECORD is returned, you can proceed with the certificate generation.
- Verify the TXT record with a DNS query tool, like
- It’s important to highlight that DNS changes can take time to propagate. You should verify that the TXT record is publicly accessible before proceeding.
- Continue the Certificate Request :
After adding the TXT record, go back to PowerShell and press Enter to letNew-PACertificate
complete the process. Posh-ACME will verify the record and, if successful, generate the certificate.
After a while, in the original terminal, Let’s encrypt will create the SSL certificate and return something like:
Please remove the following TXT records:
_acme-challenge.yourdomain.eu -> Q11tHfO0D8J34mD74ctTMZKUEDZpZ5svHXB_ONFtxxx
Subject NotAfter KeyLength Thumbprint AllSANs
------- -------- --------- ---------- -------
CN=yourdomain.eu 2/15/2025 9:49:24 PM 2048 2235563AB1F2FB26A67DA6AE25F72794C364xxx {yourdomain.eu}
Congratulations! You’ve successfully generated a STAGING SSL certificate for <yourdomain.eu
> using the Posh-ACME PowerShell module and Let’s Encrypt! 🎉
Here’s a summary of what you achieved:
- Installed Posh-ACME:
- Ensured the environment is ready for ACME operations.
- Set the ACME Server to Staging:
- Used
Set-PAServer LE_STAGE
to avoid hitting production rate limits during testing.
- Used
- Issued the Certificate:
- Validated the domain by adding the required DNS TXT record.
- Generated the SSL certificate files with details:
- Subject (CN):
yourdomain.eu
- Expiration Date:
2/15/2025
- Key Length: 2048-bit
- Thumbprint:
2235563AB1F2FB26A67DA6AE25F72794C364xxx
- Subject (CN):
- Success!
Your Staging SSL files will be at:
C:\Users\<YourUser>\AppData\Local\Posh-ACME\LE_STAGE\<OrderID>\<yourdomain.eu>
Advantages of DNS-01 Challenge
The DNS-01 challenge is a highly secure and flexible way to validate domain ownership because:
- No Open Ports Required:
- Unlike the HTTP-01 challenge, which requires an accessible web server on port 80, the DNS-01 challenge only involves modifying DNS records. This means you don’t need to expose your server to the internet during validation.
- Wildcard Certificates Support:
- It’s the only ACME challenge type that supports issuing wildcard certificates (e.g.,
*.yourdomain.com
). This makes it ideal for securing subdomains without needing to validate each one individually.
- It’s the only ACME challenge type that supports issuing wildcard certificates (e.g.,
- Works Anywhere:
- It doesn’t matter where your website or application is hosted. As long as you have access to manage the DNS for your domain, you can use this method.
- Better for Multi-Server Environments:
- If you’re managing multiple servers or cloud environments, you don’t need to configure validation for each server. You just handle DNS centrally.
- Seamless Automation:
- When combined with DNS APIs (e.g., AWS Route 53, Cloudflare, etc.), the DNS-01 challenge can be fully automated, making certificate issuance and renewal a breeze.
- Enhanced Security:
- By avoiding the need for HTTP/HTTPS traffic during validation, the DNS-01 challenge reduces the attack surface for potential vulnerabilities during the certificate issuance process.
Step 6: Switch to Production
Once everything works in the staging environment, switch to the production server:
Open PowerShell as administrator.
Switch to the production ACME server:
Set-PAServer LE_PROD
This ensures all subsequent certificate requests are made to the production Let’s Encrypt server, which issues certificates trusted by browsers.
Step 7: Confirm the ACME Server
Verify that the ACME server is now set to production:
Get-PAServer
The output should indicate the production server:https://acme-v02.api.letsencrypt.org/directory
Step 8: Generate the Production(real) Certificat
Request a new certificate for your domain, ensuring that it’s valid for production:
New-PACertificate -Domain <yourdomain.eu> -AcceptTOS -Contact <email@yourdomain.eu>
This process will:
- Validate your domain ownership (using DNS-01 or other challenges).
- Generate the certificate files, including
cert.cer
,fullchain.cer
, andcert.key
.
You will have to repeat the process that you performed to get the staging SSL, to create a new TXT record at your DNS provider.
Great! You have successfully generated the certificate files using Posh-ACME, and they are stored in the directory:
C:\Users\<YourUsername>\AppData\Local\Posh-ACME\LE_PROD\<OrderID>\<yourdomain.eu>
Let’s go step-by-step to implement these certificates on IIS while ensuring everything is clear and manageable.
Step 9: Understand the Files
Here’s a breakdown of the files you have in the folder:
cert.cer
- The actual SSL certificate for your domain (
yourdomain.eu
).
- The actual SSL certificate for your domain (
cert.key
- The private key that corresponds to your certificate. This must remain secure and private.
fullchain.cer
- Combines your certificate and the intermediate CA (Certificate Authority) chain. This is typically what IIS uses.
chain.cer
/chain0.cer
- Contains the intermediate CA certificates, used to verify your certificate’s authenticity.
request.csr
- The Certificate Signing Request (CSR) file generated during the certificate request.
order.json
- Metadata related to your ACME order (for internal use by Posh-ACME).
Step 10: Install OpenSSL on Windows
- Download the Installer:
- Go to the OpenSSL for Windows page.
- Download the version that matches your system architecture:
- Win64 OpenSSL v3.4.x for 64-bit Windows.
- Win32 OpenSSL v3.4.x for 32-bit Windows (rare cases).
- Run the Installer:
- Execute the downloaded installer as an administrator.
- During installation:
- Select the default options unless you have a specific requirement.
- Choose where OpenSSL will be installed (e.g.,
C:\Program Files\OpenSSL-Win64
).
- Add OpenSSL to the System Path:
- Open System Properties:
- Press
Windows + R
, typesysdm.cpl
, and press Enter.
- Press
- Go to the Advanced tab and click Environment Variables.
- Under System Variables, locate the
Path
variable and click Edit. - Add the OpenSSL
bin
directory (e.g.,C:\Program Files\OpenSSL-Win64\bin
) to thePath
. - Click OK to save and close.
- Open System Properties:
- Verify Installation:
- Open a new Command Prompt or PowerShell window.
- Type:
openssl version
- If installed correctly, you will see the OpenSSL version number.
Step 11: Prepare the Certificate for IIS
IIS requires a .pfx
file (PKCS#12 format) that includes the certificate, private key, and chain.
Open PowerShell and navigate to the directory:
cd "C:\Users\<YourUsername>\AppData\Local\Posh-ACME\LE_PROD\<OrderID>\<yourdomain.eu>"
Combine the certificate and private key into a .pfx
file using OpenSSL:
Step 12: Create the .pfx
File
Use the fullchain.cer
file to include the intermediate certificate when creating the .pfx
:
openssl pkcs12 -export -out <yourdomain>.pfx -inkey cert.key -in fullchain.cer -password pass:YourPfxPassword
Replace YourPfxPassword
with a strong password to secure the .pfx
file, you are going to need this password later to import the SSL at the IIs Web Server.
<yourdomain>.pfx will be the name of the certificate to import, do not include the domain extension like .eu, .com etc.
Alternative way using Posh-ACME
After generating your certificate with Posh-ACME, you can directly export it as a .pfx
file. Follow these steps:
Retrieve the Certificate Object: Use the Get-PACertificate
cmdlet to obtain the certificate object:
$cert = Get-PACertificate -MainDomain <yourdomain.eu>
Export the Certificate as a .pfx File:
Utilize the Export-PfxCertificate
cmdlet to create the .pfx
$pfxPassword = ConvertTo-SecureString -String 'YourPfxPassword' -Force -AsPlainText Export-PfxCertificate -Cert $cert.Certificate -FilePath 'C:\path\to\yourdomain.pfx' -Password $pfxPassword
Replace 'YourPfxPassword'
with a strong password of your choice, and specify the desired path for the .pfx
file.
Step 13: Import into IIS
- Open IIS Manager.
- Import the production
.pfx
file:- Go to Server Certificates > Import.
- Select the <yourdomain>.pfx file and enter the password you used as (
YourPfxPassword
). - Click OK.
Step 14: Bind the Certificate to Your Site
- In IIS Manager, expand the Sites node and select your website (e.g., Default Web Site).
- Click Bindings in the right-hand panel.
- Add HTTPS binding:
- Click Add.
- Choose https as the type.
- Select the imported certificate from the dropdown.
- Click OK.
- Close the Site Bindings dialog.
Step 15: Test Your Site
Open a browser and visit
https://<yourdomain.eu>
Check the SSL status (you should see the secure padlock icon).
Verify the certificate using SSL Labs.
Step 16: Enable HTTPS Redirection
16.1 Download and Install the IIS URL Rewrite Module
The IIS URL Rewrite module allows you to create powerful rules for URL redirection and rewriting directly in IIS or the web.config
file. It’s essential for setting up conditional redirects, such as redirecting all HTTP traffic to HTTPS.
16.2 Download the Module
- Visit the official Microsoft IIS URL Rewrite module page: Download IIS URL Rewrite
- Click on the Download button to get the installer.
16.3 Install the Module
- Run the downloaded installer.
- Follow the installation wizard steps:
- Accept the license agreement.
- Click Next and complete the installation.
- Restart IIS:
iisreset
16.4 Verify Installation
- Open IIS Manager.
- Select your website.
- Look for URL Rewrite in the Features View. If it’s present, the module is installed successfully.
Step 17: Configure HTTPS Redirection
17.1 Add or Update the web.config
File
- Navigate to the root directory of your site (e.g.,
C:\inetpub\wwwroot
). - Open the
web.config
file. If it doesn’t exist, create one. - Add the following content to enable HTTPS redirection:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- Redirect HTTP to HTTPS -->
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<!-- Only redirect if the request is NOT already HTTPS -->
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Step 18: Test the Redirect
18.1 Steps to Test
- Open your browser and navigate to:
http://yourdomain.eu
→ Should redirect tohttps://yourdomain.eu
.https://yourdomain.eu
→ Should load directly without any redirection issues.
18.2 Verify the Redirect
- Use a tool like Redirect Checker to confirm the redirect.
- Alternatively, use browser developer tools (F12):
- Go to the Network tab.
- Watch the HTTP request redirect to HTTPS with a 301 Permanent Redirect.
Common Troubleshooting
Issue: Redirect Loops
- Cause: The redirect is applied to HTTPS traffic as well.
- Solution: Ensure the
<conditions>
section in theweb.config
specifies{HTTPS} pattern="off"
.
Issue: Redirection Doesn’t Work
- Cause 1: The
web.config
file is missing or not applied. - Solution: Check the site’s root directory for the
web.config
file and confirm the content matches the example. - Cause 2: URL Rewrite module is not installed.
- Solution: Install the URL Rewrite module as described in Step 1.
Step 19: Enable HSTS (HTTP Strict Transport Security)
HSTS ensures browsers only connect to your site over HTTPS, improving security.
- Configure HSTS in IIS:
- Open the HTTP Response Headers feature for your site in IIS.
- Click Add in the Actions pane.
- Add the following header:
- Name:
Strict-Transport-Security
- Value:
max-age=31536000; includeSubDomains
- Name:
- Click OK to save.
- Verify HSTS Behavior:
Step 20: Disable Weak Protocols and Ciphers
20.1. Disable TLS 1.0 and TLS 1.1
Edit the Windows Registry:
Open the Registry Editor (regedit
).
Navigate to:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
Create the following subkeys (if they do not already exist):
TLS 1.0\Client
TLS 1.0\Server
TLS 1.1\Client
TLS 1.1\Server
For each subkey, create a DWORD (32-bit)
value named Enabled
and set it to 0
(disabled).
20.2 Enable Only TLS 1.2 and TLS 1.3:
Navigate to
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2
Ensure the Client
and Server
subkeys exist.
For each subkey, create a DWORD (32-bit)
value named Enabled
and set it to 1
.
Restart the Server:
Apply the changes by restarting the computer: shutdown /r /t 0
Step 21: Harden Cipher Suites, Use IIS Crypto (Optional):
To further strengthen your security, configure Windows Server to prioritize modern and secure cipher suites.
Download and Run IIS Crypto Tool:
Download the free IIS Crypto tool.
Open the tool and:
Disable weak protocols and cipher suites.
Enable strong ones (e.g., AES-GCM, AES-CBC with 128/256-bit keys).
Apply changes and restart.
Manually Adjust Cipher Suites (Optional):
If you prefer manual configuration, adjust the cipher suite order in the registry or via PowerShell:
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002' -Name Functions -Value "TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256"
Step 22: Enable OCSP Stapling (Optional)
OCSP stapling improves performance and reduces latency for certificate status checks.
- Enable OCSP Stapling in IIS:
- In IIS Manager, select your site.
- Go to SSL Settings and ensure Require SSL is checked.
- Verify that Disable OCSP Stapling is unchecked in the Site Binding settings.
Step 23: Test Your Configuration
Verify the SSL/TLS setup for your site.
- Check HTTPS Functionality:
- Open a browser and visit
https://yourdomain.eu
. - Ensure the site loads without errors and displays a secure padlock.
- Open a browser and visit
- Run an SSL Test:
- Use SSL Labs to analyze your site. It will provide a detailed report and security grading.
Notes
Ensure DNS propagation delays are accounted for during manual validation.
- Use a secure and encrypted method to store API credentials.
- Automate renewals and deployment to minimize manual intervention.