{"copy":"Zkop\u00edrovat","expand":"Rozbalit","collapse":"Sbalit","copy_success":"Zkop\u00edrov\u00e1no!","copy_error":"Kop\u00edrov\u00e1n\u00ed selhalo!"}

Jak na Windows Serveru s IIS použít certifikát z Azure Key Vault

Logo 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:

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.

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:

  • Get, List pro Secret permissions
  • Get, List pro Certificate permissions

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 certu 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://cc-iis-test.vault.azure.net/secrets/zoner-test-azure",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine"
}
]
}
} 

Pak nainstalujte a spusťte VM extension (PowerShell). Nastavení načtěte s z lokálně uloženího souboru JSON. 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.

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 }

Je potřeba vytvořit nový Binding pro doménové jméno (místo Default Web Site můžete použít jméno, které máte v IIS). Nastavíme tedy Binding na konkrétní doménový název na portu 443 (HTTPS):

Import-Module WebAdministration
New-WebBinding -Name "Default Web Site" -IPAddress "*" -Port 443 -HostHeader "zoner-test-azure.eu" -Protocol https

Vytvoření bindingu pro SNI:

Import-Module WebAdministration
New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -HostHeader "zoner-test-azure.eu"

Nyní přiřadíme vybraný certifikát k Bindingu pomocí netsh. 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 zkonfiguraci 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žit 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

Přiřazení certifikátu k IIS

PowerShell
$cert = Get-ChildItem -Path Cert:LocalMachineMy | Sort-Object NotAfter -Descending | Select-Object -First 1
$thumbprint = $cert.Thumbprint

New-WebBinding -Name "Default Web Site" -IPAddress "*" -Port 443 -Protocol https
$cmd = "netsh http add sslcert ipport=0.0.0.0:443 certhash=$thumbprint appid='{4dc3e181-e14b-4a21-b022-59fc669b0914}'"
Invoke-Expression $cmd

iisreset

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"

    # 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
        New-WebBinding -Name "Default Web Site" -Protocol "https" -Port $bindingPort -HostHeader $hostHeader

        # 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 netsh pro přiřazení certifikátu k bindingu            
            netsh http add sslcert ipport=0.0.0.0:$bindingPort certhash=$($cert.Thumbprint) appid=$appid
            Write-Output "IIS binding pro $hostHeader byl aktualizován s novým certifikátem."
        } else {
            Write-Output "❌ Nepodařilo se přidat nový binding pro $hostHeader." -ForegroundColor Red
        }
    } else {
        Write-Output "❌ 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.
  • 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.

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.

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ě.

Byl tento článek pro vás užitečný?