Jak na Windows Serveru s IIS použít certifikát z Azure Key Vault
Tento návod vám pomůže nasadit certifikáty ze služby Azure Key Vault do vašeho IIS webserveru na Windows Serveru.
Azure Key Vault může být propojen přímo s DigiCertem a automatizován.
Návod je vytvořen pro dvě varianty - pro virtuální stroje v Azure a pro ty on-premise Windows Servery, které máte ve firmě.
Tento návod předpokládá, že budeme mít certifikát v Azure Key Vaultu. Jak ho tam dostat pomocí přímého napojení na CA DigiCert najdete v návodu Propojení Azure Key Vault s CA DigiCert.
Pak máte dvě možnosti nasazení TLS certifikátu na server:
- nasadit certifikát na server (VM) v Azure
- nebo na lokální on-premise Windows server (ve vaší firmě)
Tento návod pokrývá oba scénáře, přičemž první je bezpečnější (certifikát se neexportuje z Azure Key Vaultu a neukládá lokálně).
Varianta nasazení na VM v Azure
Pokud máte virtuální Windows server (VM) přímo v Azure, využijte tuto možnost. Nainstalujte si Azure PowerShell a Az PowerShell module.
V návodu je použit Windows Server 2022 s IIS 10 (poslední verzi 2025 není možné pro tento účet použít) a použil jsem rozšíření KeyVaultForWindows ve verzi 3.3.
Automatická synchronizace certifikátu z Azure Key Vault do Azure VM
Povolte Managed Identity na Azure VM
V Azure Portal otevřete VM > Identity > System assigned a zapněte ji. Přejděte do Azure Key Vault > Access Policies a přidejte oprávnění pro VM.
Pro nejlepší praxi Microsoft doporučuje pro VM rozšíření využít Azure RBAC model. V tomto případě se pro Managed Identity očekává přiřazená role Key Vault Secrets User na úrovni vaultu prostřednictvím Azure RBAC.
Pokud se rozhodnete pro Access Policies, udělte v sekci `Secrets` oprávnění `Get` a `List`. Oprávnění v sekci `Certificates` nejsou obvykle potřeba, pokud používáte `secretsManagementSettings`, jelikož rozšíření stahuje PFX soubor z `/secrets/` endpointu, a proto využívá oprávnění pro Secrets. Oprávnění na `Certificate` by byla relevantní pouze při použití `certificateManagementSettings`.
Instalace Azure Key Vault VM Extension
Vytvořte v prvním kroku konfigurační soubor, který bude uložen lokálně na serveru. V něm uveďte cestu k "Secrets" ve Vaultu, nikoliv jen k certifikátu (taková cesta vede pouze na veřejný klíč).
{
"secretsManagementSettings": {
"pollingIntervalInS": "60",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine",
"observedCertificates": [
{
"url": "https://xxxxx-test.vault.azure.net/secrets/zoner-test-azure",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine"
}
]
}
}
Pokud používáte user-assigned managed identity, musí v JSON bloku `authenticationSettings` být specifikován `msiEndpoint` a `msiClientId` vaší user-assigned identity. Příklad:
{
"secretsManagementSettings": {
"pollingIntervalInS": "3600",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine",
"observedCertificates": [
{ "url": "https://.vault.azure.net/secrets/",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine"
}
]
},
"authenticationSettings": {
"msiEndpoint": "http://169.254.169.254/metadata/identity/oauth2/token",
"msiClientId": ""
}
}
Pak nainstalujte a spusťte VM extension (PowerShell). Nastavení načtěte z lokálně uloženého JSON souboru. Název VM a Resource Group si můžete uložit i jako proměnné a použít je, nebo konkrétní názvy.
az vm extension set --resource-group "RG-name" --vm-name "vmname" --name "KeyVaultForWindows" --publisher "Microsoft.Azure.KeyVault" --version 3.3 --settings ".\settings.json"
Po spuštění tohoto příkazu bude program v PS chvíli pracovat a při úspěchu dostanete dlouhý JSON report o stavu VM extension. Následně se certifikát objeví ve Windows certificate store v Local Computer -> Personal -> Certificates. Tím, že je v Local Computer, na něj vidí všechny aplikace včetně IIS. Synchronizace může trvat, záleží na intervalu "pollingIntervalInS" a kolik jste v něm uvedli sekund.
Ověření synchronizace certifikátu
Po instalaci zkontrolujte, zda se certifikát stáhl do Windows Certificate Store:
PowerShell
certlm.msc
Certifikát by měl být v sekci Personal > Certificates.
ACL Oprávnění pro privátní klíče: Po importu certifikátu v konzoli v MMC (Local Computer → Certificates → vaše certifikáty) klikněte na certifikát → All Tasks → Manage Private Keys. Zde přidejte účet IIS (`IIS_IUSRS` nebo `Network Service`) s právem `Read`. Absence těchto oprávnění může způsobit chybu "logon session does not exist" v IIS.
Automatické přiřazení certifikátu k IIS
Prvně si vypište certifikáty dostupné v Local Machine Storu:
Get-ChildItem -Path Cert:\LocalMachine\My
Pak vybereme správný certifikát podle otisku a uložíme ho do proměnné `$cert`:
$certThumbprint = "THUMBPRINT_VYBRANEHO_CERTIFIKATU"
$cert = Get-ChildItem -Path Cert:\LocalMachine\My |
Where-Object { $_.Thumbprint -eq $certThumbprint }
Pro zajištění, že se nedeploynul špatný certifikát, doporučujeme přidat validaci certifikátu k doméně. Můžete přidat kontrolu `Subject` certifikátu:
$expectedDomain = "zoner-test-azure.eu" # Nahraďte očekávanou doménou
if ($cert.Subject -notmatch "CN=$expectedDomain") {
throw "Certificate subject mismatch. Expected CN to contain '$expectedDomain'."
}
Nyní přiřadíme vybraný certifikát k Bindingu. Verze 3.0 VM Extension obsahuje podporu "IIS Certificate Rebind", kterou lze využít pro automatickou změnu vazby v IIS při aktualizaci certifikátu.
Doporučený postup pro vazbu certifikátu:
Nejprve vytvořte vazbu (s `SslFlags 1` pro SNI, pokud je třeba):
New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -HostHeader "zoner-test-azure.eu" -SslFlags 1
Poté certifikát přiřaďte pomocí metody `.AddSslCertificate()`:
(Get-WebBinding -Name "Default Web Site" -Protocol https).AddSslCertificate($certThumbprint, 'My')
Alternativně, můžete použít `netsh` pro přímé přidání SSL certifikátu k HTTP.sys. Thumbprint certifikátu ve storu už známe, budete ještě potřebovat appid, které zjistíte pomocí
[guid]::NewGuid()
$certThumbprint = "THUMBPRINT_VYBRANEHO_CERTIFIKATU"
$port = 443
$appid = "{00112233-4455-6677-8899-AABBCCDDEEFF}" # Nahraďte svým GUID aplikace
$certStoreName = "MY" # 'MY' = 'Personal' ve Windows cert store
$cert = Get-ChildItem -Path Cert:\LocalMachine\My |
Where-Object { $_.Thumbprint -replace '\s','' -ieq $certThumbprint }
if (-not $cert) {
Write-Host "❌ Certifikát s otiskem $certThumbprint nebyl nalezen v LocalMachine\My." `
-ForegroundColor Red
return
}
if (-not $cert.HasPrivateKey) {
Write-Host "❌ Certifikát neobsahuje privátní klíč, nelze jej použít pro SSL." `
-ForegroundColor Red
return
}
# === Odebrání případného existujícího bindingu ===
Write-Host "? Odstraňuji starý SSL binding na 0.0.0.0:$port (pokud existuje)..."
netsh http delete sslcert ipport=0.0.0.0:$port | Out-Null
# === Přidání nového bindingu pomocí netsh ===
Write-Host "? Přidávám nový SSL certifikát pro 0.0.0.0:$port..."
netsh http add sslcert `
ipport=0.0.0.0:$port `
certhash=$($cert.Thumbprint) `
appid=$appid `
certstorename=$certStoreName | Out-Null
Write-Host "✅ Certifikát byl úspěšně přiřazen ke 0.0.0.0:$port pomocí netsh." `
-ForegroundColor Green
Nakonec proveďte reload IIS:
iisreset
Že se certifikát přiřadil ke správnému bindingu zkontrolovat manuálně v IIS, nebo pomocí tohoto skriptu:
$bindings = Get-WebBinding |
Where-Object {$_.protocol -eq "https"}
foreach ($binding in $bindings) {
$bindingDetails = $binding |
Select-Object -Property protocol, bindingInformation
$parts = $bindingDetails.bindingInformation.Split(":")
$ip = $parts[0]
$port = $parts[1]
if ($ip -eq "*") {
$ip = "0.0.0.0"
}
try {
$sslCertOutput = netsh http show sslcert ipport=${ip}:${port}
# Vytáhni potřebné řádky
$certHash = ($sslCertOutput | Select-String "Certificate Hash").Line.Split(":")[1].Trim()
$storeName = ($sslCertOutput | Select-String
"Certificate Store Name").Line.Split(":")[1].Trim()
Write-Host "`n? SSL Binding: ${ip}:${port}" -ForegroundColor Cyan
Write-Host " Certificate Hash : $certHash"
Write-Host " Store : $storeName"
# Vyhledání certifikátu v LocalMachine\
$cert = Get-ChildItem -Path "Cert:\LocalMachine\$storeName" |
Where-Object {
$_.Thumbprint -replace '\s','' -ieq $certHash
}
if ($cert) {
Write-Host " CN (Subject) : $($cert.Subject)"
Write-Host " Platnost : $($cert.NotBefore.ToShortDateString()) – $($cert.NotAfter.ToShortDateString())"
} else {
Write-Host " ⚠️ Certifikát s tímto otiskem nebyl nalezen ve Windows certifikátovém úložišti."
}
} catch {
Write-Host "❌ Nelze načíst certifikát pro ${ip}:${port} – $($_.Exception.Message)"
}
Write-Host "`n---`n"
}
Doporučuji zkonfigurovat a zkontrolovat, ať tam nemáte nějaké Bindings navíc.
Automatická obnova
Azure Key Vault VM Extension zajistí, že se certifikát při změně v Key Vaultu automaticky aktualizuje. IIS se při změně certifikátu restartuje a vždy použije nejnovější verzi.
Varianta nasazení na on-premise server
Pokud máte Windows server na vlastním virtuálu či vlastním železe, není možné využít Azure Key Vault VM Extension a je potřeba import udělat jinak.
Automatická synchronizace certifikátu z Azure Key Vault do on-premise IIS
Vytvoření Azure AD aplikace pro přístup k Key Vault
V Azure Portal přejděte do Azure Active Directory > App registrations a vytvořte novou aplikaci. Po registraci aplikace zkopírujte Application (client) ID a Directory (tenant) ID.
V sekci Certificates & secrets vygenerujte nový client secret a uložte ho.
Přiřazení oprávnění aplikaci v Azure Key Vault
- Otevřete Azure Key Vault > Access Policies.
- Přidejte oprávnění pro aplikaci:
- Get, List pro Secret permissions
- Get, List pro Certificate permissions
Aplikaci je následně potřeba vytvořit a přidělit Client Secret.
Stáhnutí certifikátu z Azure Key Vault na on-premise server
PowerShell
$tenantId = "TENANT_ID"
$clientId = "CLIENT_ID"
$clientSecret = "CLIENT_SECRET"
$vaultName = "MOJE-KEYVAULT-JMENO"
$certName = "MOJE-CERTIFIKAT-JMENO"
$outputPath = "C:\certscert.pfx"
# Přihlášení k Azure AD
$body = @{grant_type="client_credentials";
client_id=$clientId; client_secret=$clientSecret; resource="https://vault.azure.net" }
$tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/token" -Body $body
$token = $tokenResponse.access_token
# Získání certifikátu
$headers = @{ Authorization = "Bearer $token" }
$apiVersion = "7.5"
$secret = Invoke-RestMethod -Uri "https://$vaultName.vault.azure.net/secrets/${certName}?api-version=$apiVersion" -Headers $headers
$pfxBytes = [Convert]::FromBase64String($secret.value)
[System.IO.File]::WriteAllBytes($outputPath, $pfxBytes)
Import certifikátu do Windows Certificate Store
PowerShell
$password = ConvertTo-SecureString -String "MOJE-HESLO" -Force -AsPlainText
Import-PfxCertificate -FilePath $outputPath -CertStoreLocation Cert:LocalMachineMy -Password $password
ACL Oprávnění pro privátní klíče: Po importu certifikátu v konzoli v MMC (Local Computer → Certificates → vaše certifikáty) klikněte na certifikát → All Tasks → Manage Private Keys. Zde přidejte účet IIS (`IIS_IUSRS` nebo `Network Service`) s právem `Read`. Absence těchto oprávnění může způsobit chybu "logon session does not exist" v IIS.
Přiřazení certifikátu k IIS
Nejprve zjistíme otisk certifikátu, který je v certificate storu.
PowerShell
$cert = Get-ChildItem -Path Cert:LocalMachineMy |
Sort-Object NotAfter -Descending | Select-Object -First 1
$thumbprint = $cert.Thumbprint
Pak vytvoříme Binding a přiřadíme ho. `New-WebBinding` vytvoří vazbu a certifikát k ní musíte přiřadit pomocí metody `.AddSslCertificate(Thumbprint, 'My')`.
Nejprve vytvořte vazbu (s `SslFlags` pro SNI, pokud je třeba):
New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -HostHeader "zoner-test-azure.eu" -SslFlags 1
Poté certifikát přiřaďte:
(Get-WebBinding -Name "Default Web Site" -Protocol https).AddSslCertificate($certThumbprint, 'My')
Alternativně můžete použít netsh pro přímé přidání SSL certifikátu k HTTP.sys:
netsh http add sslcert ipport=0.0.0.0:443 `
certhash= `
appid={} `
certstorename=My
Pro načtení nové konfigurace použijte iisreset.
Doporučuje se přidat validaci certifikátu k doméně, aby se nedeploynul špatný certifikát. Můžete přidat kontrolu "Subject" certifikátu:
$expectedDomain = "zoner-test-azure.eu" # Nahraďte očekávanou doménou
if ($cert.Subject -notmatch "CN=$expectedDomain") {
throw "Certificate subject mismatch. Expected CN to contain '$expectedDomain'."
}
Automatická obnova
Naplánujte tento skript jako Scheduled Task (například denně) v Task Scheduleru, aby se certifikát automaticky aktualizoval při změně v Azure Key Vault.
Povolení automatického přesměrování HTTP → HTTPS v IIS
Použijte následující PowerShell skript pro automatické přesměrování všech HTTP požadavků na HTTPS.
PowerShell
Import-Module WebAdministration
# Povolit přesměrování v IIS
Set-WebConfigurationProperty -Filter "/system.webServer/httpRedirect" -Name "enabled" -Value "True" -PSPath "IIS:SitesDefault Web Site"
Set-WebConfigurationProperty -Filter "/system.webServer/httpRedirect"
-Name "destination" -Value "https://localhost" -PSPath "IIS:SitesDefault Web Site"
Set-WebConfigurationProperty -Filter "/system.webServer/httpRedirect" -Name "exactDestination" -Value "True" -PSPath "IIS:SitesDefault Web Site"
Set-WebConfigurationProperty -Filter "/system.webServer/httpRedirect" -Name "httpResponseStatus" -Value "Permanent" -PSPath "IIS:SitesDefault Web Site"
# Restart IIS
iisreset
Automatizace celého procesu
Pokud budete používat Azure Key Vault VM Extension a Key Vault bude napojen na DigiCert, bude se certifikát automaticky prodlužovat a synchronizovat do úložiště certifikátů systému Windows Certificate Store. Je však potřeba dořešit nabindování certifikátu v IIS, protože to se samo nestane. Je potřeba udělat několik dalších kroků, aby byl certifikát při změně automaticky přiřazen do IIS.
Níže je uveden skript, který automaticky detekuje změnu certifikátu a provádí potřebné úpravy v IIS. Zajistí automatickou aktualizaci certifikátu ve webovém serveru IIS. Certifikáty budou v úložišti Certificate Store automaticky aktualizované z Azure Key Vault. Skript bude pravidelně kontrolovat, zda byl nový certifikát importován do LocalMachine\My store a zda je třeba tento certifikát přiřadit k bindingu v IIS.
Jak nastavit automatizaci pomocí Scheduled Task a PowerShell skriptů
Nejprve si připravíme PowerShell skript, který provede potřebné akce, jako je získání certifikátu a aktualizace IIS bindingu. PowerShell skript pro automatické připojení certifikátu k IIS bindingu:
Import-Module WebAdministration
# Získání certifikátů, které byly vydány dnes
$certificates = Get-ChildItem -Path Cert:\LocalMachine\My
$today = (Get-Date).Date
$todayCerts = $certificates |
Where-Object { $_.NotBefore.Date -eq $today }
$appid = "{fbb8250d-a9d7-4d41-b7bc-e75b77578802}"
if ($todayCerts.Count -gt 0) {
# Seřadíme certifikáty podle data vytvoření (nejnovější certifikát bude první)
$latestCert = $todayCerts |
Sort-Object NotBefore -Descending | Select-Object -First 1
# Získání thumbprintu z nejnovějšího certifikátu
$certThumbprint = $latestCert.Thumbprint
Write-Output "Nový certifikát (dnes vydaný): $certThumbprint"
# Port pro HTTPS
$bindingPort = 443
$hostHeader = "zoner-test-azure.eu"
# Validace certifikátu k doméně
$expectedDomain = "zoner-test-azure.eu" # Nahraďte očekávanou doménou
if ($latestCert.Subject -notmatch "CN=$expectedDomain") {
Write-Output "❌ Certifikát s otiskem $certThumbprint má nesprávný Subject. Očekáváno: CN=$expectedDomain" -ForegroundColor Red
return
}
# Získání certifikátu podle thumbprintu
$cert = Get-ChildItem -Path Cert:\LocalMachine\My |
Where-Object { $_.Thumbprint -eq $certThumbprint }
if ($cert -and $cert.HasPrivateKey) {
# Získání bindingu z IIS pro daný port a host header
$binding = Get-WebBinding |
Where-Object { $_.bindingInformation -like "*:$($bindingPort):$hostHeader" }
# Pokud binding existuje, odstraníme starý binding
if ($binding) {
# Pro odstranění bindingu použijeme Remove-WebBinding
Remove-WebBinding -Name "Default Web Site" -BindingInformation "*:$($bindingPort):$hostHeader" -Protocol "https"
Write-Output "Starý binding pro $hostHeader byl odstraněn."
} else {
Write-Output "Binding pro $hostHeader na portu $bindingPort neexistuje."
}
# Přidání nového bindingu
# Použijeme New-WebBinding k připojení certifikátu k portu s HostHeader a SslFlags 1 pro SNI
New-WebBinding -Name "Default Web Site" -Protocol "https" -Port $bindingPort -HostHeader $hostHeader -SslFlags 1
# Získání nového bindingu
$binding = Get-WebBinding |
Where-Object { $_.bindingInformation -like "*:$($bindingPort):$hostHeader" }
# Pokud binding ještě neexistuje, přidáme nový certifikát
if ($binding) {
# Použijeme metodu AddSslCertificate pro přiřazení certifikátu k bindingu
$binding.AddSslCertificate($cert.Thumbprint, "My")
Write-Output "IIS binding pro $hostHeader byl aktualizován s novým
certifikátem."
} else {
Write-Host "❌ Nepodařilo se přidat nový binding pro $hostHeader."
-ForegroundColor Red
}
} else {
Write-Host "❌ Certifikát s otiskem $certThumbprint neobsahuje privátní klíč, nelze jej použít pro SSL."
-ForegroundColor Red
}
} else {
Write-Output "Dnes nebyl vydán žádný nový certifikát."
}
Co tento skript dělá:
- Kontrola nového certifikátu: Skript zjistí, jestli byl dnes vydán nový certifikát.
- Získání thumbprintu: Pokud certifikát existuje, získá jeho thumbprint.
- Validace certifikátu k doméně: Zkontroluje, zda `Subject` certifikátu odpovídá očekávané doméně.
- Aktualizace IIS bindingu: Pokud certifikát obsahuje private key (což je nutné pro SSL), skript odstraní starý binding na portu 443 a přidá nový s aktualizovaným certifikátem pomocí metody `.AddSslCertificate()`.
Aby tento skript běžel pravidelně a kontroloval změny certifikátu, je třeba nastavit Scheduled Task na serveru, který bude tento skript spouštět například každou hodinu nebo denně. Nastavte tedy v Task Scheduler spouštění tohoto PS skriptu.
Kde najít logy
V případě potíží je užitečné podívat se do logu, co se vlastně děje.
Ty najdete zde:
Event Log: Microsoft-Windows-CertificateServicesClient-Lifecycle-System/Operational
Podrobný log soubor: %windrive%\WindowsAzure\Logs\Plugins\Microsoft.Azure.KeyVault.KeyVaultForWindows\
Závěr
Tento návod by vám měl napovědět jak zautomatizovat vydávání a následné nasazování TLS certifikátů pro IIS na platformě Windows Server. Pro získání certifikátů jsme použili Azure Key Vault a přímou integraci s CA DigiCert.
Pak certifikát synchronizujeme buď na jiný Azure VM, nebo na on-premise Windows server a pomocí Powershellu přiřazujeme na vytvořený binding v IIS. Je samozřejmě možné použít i jiný postup, než zde uvedený.
Při nastavení opakovaných úloh bude jak získání certifikátu, tak i deploy fungovat plně automaticky a bezstarostně.
Oficiální dokumentace
- Azure Key Vault VM Extension for Windows
- IIS SSL Certificate Binding
- Default MachineKeys folders Windows Server
- Azure Key Vault PowerShell Reference
- Managed Identity for Azure Resources
- IIS PowerShell Cmdlets
Mrzí nás, že jste zde nenašli potřebné.
Pomůžete nám článek vylepšit? Napiště nám, co jste zde očekávali a nedozvěděli se.