Ich betreibe z.Z. eine Linux-Maschine als Reverse-Proxy. NGINX habe ich dabei als Applikation verwendet weil ich es in dieser Hinsicht einfacher zum konfigurieren empfinde.
Per CRON-Job wird zyklisch geprüft, ob das Zertifikat abgelaufen ist. letzencrypt-Zertifikate haben eine Gültigkeit von 90 Tagen. Somit ist Automatisierung hier Pflicht.
Hier das Script, welche unter /ets/cron.weekly liegt:
#!/bin/bash certbot certonly -n -d mail.powershell.pub -d autodiscover.powershell.pub -d fs.powershell.pub -d mfa.powershell.pub -d vpn.powershell.pub --webroot -w /var/www/html/ --renew-hook "service nginx restart" --renew-hook "openssl pkcs12 -export -out /var/www/html/letsencrypt/mail.powershell.pub.pfx -inkey /etc/letsencrypt/live/mail.powershell.pub/privkey.pem -in /etc/letsencrypt/live/mail.powershell.pub/cert.pem -certfile /etc/letsencrypt/live/mail.powershell.pub/fullchain.pem -passout pass:<PFX-Passwort>"
Durch –renew-hook, welches öfters angegeben werden kann, starte ich nicht nur NGINX neu, sondern erstelle ein PFX in einem Ordner der wiederum per NGINX als Webseite freigegeben ist. Der Zugriff auf dieses Verzeichnis ist natürlich auf interne Server begrenzt. Das Passwort, komplex und lang, sorgt nur dafür, im Falle des Falles die Sicherheit aufrechtzuerhalten 😉
Auf den Exchange-Server wird ebenfalls ein Script per Task-Scheduler ausgeführt. Wöchentlich ist genug und natürlich ist es ein PowerShell-Script
param ( [string]$Url = "http://le.powershell.pub/letsencrypt/mail.powershell.pub.pfx", [string]$Output = "C:\Script\download.pfx", [string]$ActualCert = "C:\Script\mail.pfx", [string]$PFXPassword, [switch]$DonteDeleteOldCert, [switch]$ForceUpdate, [switch]$Whatif, [switch]$Debug ) $Error.clear() . $(Join-Path -Path $PSScriptRoot -ChildPath "functions.ps1") if ( -not $PFXPassword ) { . $(Join-Path -Path $PSScriptRoot -ChildPath "password.ps1") } if ( $Error ) { write-error "Import Failed" exit } write-log "Cert-Renew.ps1 Starts" if ( test-path $Output ) { remove-item $Output } write-log "Download File $Url" (New-Object System.Net.WebClient).DownloadFile($Url, $Output) if ( -not ( test-path $Output )) { write-log "Cant download File! Exit." ende } if ( test-path $ActualCert ) { $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider $DownloadHash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($Output))) $ActualHash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($ActualCert))) if ( $DownloadHash -eq $ActualHash -and -not $ForceUpdate) { Write-Log "Source and Destination is equal. Nothing to do..." remove-item $Output ende } else { Write-Log "New Cert loaded!" remove-item $ActualCert } } Move-Item $Output $ActualCert if ( $Error ) { write-log "Cant move PFX-File!. Exit." -err ende } $a = (Get-PSSnapin | where {$_.Name -ilike "Microsoft.Exchange.Management.*"} | measure).Count if ( $a -eq 0 ) { write-log "Import Exchange-PS1-Modules..." Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 } if ( $Error ) { write-log "Import of Exchange-PS1-Modules Failed" -err ende } write-log "Get Old Cert-Infos" $OldCert = Get-ExchangeCertificate | where { $_.Services -match "IIS" } if ( $OldCert.Count -ne 1 ) { write-log "Problems when reding actual certificate. Returnd $($OldCert.Count) certifivates! Exit." ende } $FrendlyName = "Exchange-$(Get-Date -UFormat "%y%m%d-%H%M")" write-log "Import new Cert $FrendlyName" $NewCert = Import-ExchangeCertificate -FileName $ActualCert -Password (ConvertTo-SecureString -String $PFXPassword -AsPlainText -Force) -PrivateKeyExportable $true -FriendlyName $FrendlyName -Whatif:$Whatif write-log "Enable New Cert for Services $($OldCert.Services)" Import-Module WebAdministration if ( $Error ) { write-log "Import of WebAdministration-Module failed. Exit" -err ende } Get-WebBinding -Protocol "https" | foreach { $_.AddSslCertificate( $NewCert.Thumbprint, "my") } #Get-Item "cert:\LocalMachine\MY\$($NewCert.Thumbprint)" | Set-Item IIS:\SslBindings\0.0.0.0!444 #Get-Item "cert:\LocalMachine\MY\$($NewCert.Thumbprint)" | Set-Item IIS:\SslBindings\0.0.0.0!443 #Get-Item "cert:\LocalMachine\MY\$($NewCert.Thumbprint)" | Set-Item IIS:\SslBindings\127.0.0.1!443 Enable-ExchangeCertificate -Thumbprint $NewCert.Thumbprint -Services $OldCert.Services -NetworkServiceAllowed -Force -Confirm:$false -Whatif:$Whatif if ( $Error ) { write-log "Import or Enable of the new Certificate Failed" -err ende } if ( -not $DonteDeleteOldCert ) { write-log "Delete old Cert: $($OldCert.Thumbprint)" Remove-ExchangeCertificate -Thumbprint $OldCert.Thumbprint -Confirm:$false -Whatif:$Whatif Enable-ExchangeCertificate -Thumbprint $NewCert.Thumbprint -Services $OldCert.Services -NetworkServiceAllowed -Force -Confirm:$false -Whatif:$Whatif } #write-log "Reset IIS" #iisreset ende
Die Funktionen „ende“ und „write-log“ wurden im File functions.ps1 definiert…