Vor einiger Zeit wurden Zertifikate von Let’s Encrypt bei einem Kunden benötigt und dabei war die HTTP-01 Challenge leider nicht möglich. Glücklicherweise gibt es mittlerweile eine IONOS DNS API, die sich ganz gut per PowerShell in der Win-ACME Client als DNS Plugin integrieren lässt. Hier passte quasi die Faust aufs Auge, da die DNS Zone der Domain bei IONOS lag. 🙂
Damit die DNS API von IONOS genutzt werden kann, muss man sich im ersten Step für die Nutzung anmelden und die DNS API Funktionen (gratis) „kaufen“. Im Anschluss wird ein API Key zur Authentifizierung erstellt. Der Key besteht dabei aus einem öffentlichen Prefix und dem Secret. Anbei die Links zur Dokumentation der API bei IONOS:
- API Entwicklerportal | IONOS – Getting Started with the IONOS APIs
- API Entwicklerportal | IONOS – Access the DNS API documentation„
„Langer“ Rede kurzer Sinn, hier das PowerShell Script, welches als DNS Plugin vom Win-ACME für die IONOS API genutzt werden kann:
param(
[parameter(Mandatory=$true,Position=0)]
[String]
[ValidateSet("create", "delete")]
$Action,
[parameter(Mandatory=$true,Position=1)]
[String]
[ValidatePattern("[a-zA-Z0-9-_.]")]
$Identifier,
[parameter(Mandatory=$true,Position=2)]
[String]
[ValidateScript({$_ -match $("^_acme-challenge.{0}$" -f $Identifier)})]
$RecordName,
[parameter(Mandatory=$true,Position=3)]
[String]
$Token
)
$Basedomain = -join(
$Identifier.Split(".")[$Identifier.Split(".").Count-2],
".",
$Identifier.Split(".")[$Identifier.Split(".").Count-1]
)
$tmpRecordFilePath = -join($env:TEMP, "\ACME-", $Identifier, ".txt")
$publicAPI = ""
$secretAPI = ""
$XAPIKey = -join($publicAPI, ".", $secretAPI)
$APIUri = "https://api.hosting.ionos.com"
$DNSApiUri = -join($APIUri, "/dns/v1")
$DNSZonesApiUri = -join($DNSApiUri, "/zones")
$curwr = Invoke-WebRequest -UseBasicParsing `
-Method Get `
-Uri $DNSZonesApiUri `
-ContentType "application/json" `
-Headers @{
"Accept" = "application/json";
"X-API-Key" = "$XAPIKey"
}
$DNSZones = ConvertFrom-Json -InputObject $curwr.Content
$curDomain = $DNSZones |
Where-Object { $_.name -eq $Basedomain }
$DNSRecordApiUri = -join($DNSZonesApiUri, "/", $curDomain.id, "/records")
$RecordData = @"
[
{
"name": "$RecordName",
"type": "TXT",
"content": "$Token",
"ttl": "3600",
"prio": "0",
"disabled": "false"
}
]
"@
if($Action -eq "create"){
# Post new TXT record for ACME challenge
$curwr = Invoke-WebRequest -UseBasicParsing `
-Method Post `
-Uri $DNSRecordApiUri `
-ContentType "application/json" `
-Headers @{
"Accept" = "application/json";
"X-API-Key" = "$XAPIKey"
} `
-Body $RecordData
$newRecord = ConvertFrom-Json -InputObject $curwr.Content
$newRecord.id |
Out-File -FilePath $tmpRecordFilePath `
-Confirm:$false `
-Force
}
# Delete TXT record after ACME challenge
if($Action -eq "delete"){
$RecordId = Get-Content -Path $tmpRecordFilePath
$deleteRecordUri = -join($DNSZonesApiUri, "/", $curDomain.id, "/records/", $RecordId)
Invoke-WebRequest -UseBasicParsing `
-Method Delete `
-Uri $deleteRecordUri `
-Headers @{
"Accept" = "*/*";
"X-API-Key" = "$XAPIKey"
}
if(Test-Path -Path $tmpRecordFilePath -PathType Leaf){
Remove-Item -Path $tmpRecordFilePath `
-Confirm:$false `
-Force
}
}
Im Script müssen nur die beiden Variablen „$publicAPI“ und „$secretAPI“ mit den Daten des API Keys bestückt werden, damit folgendermaßen der Win-ACME Client das/die Zertifkat/e per DNS-01 Challenge anfordern kann:
# Staging:
wacs.exe --baseuri https://acme-staging-v02.api.letsencrypt.org/ --accepttos --emailaddress "<einetolle@emailadresse.de" --friendlyname "LE Exchange (Staging)" --source manual --host "outlook.jans.cloud, autodiscover.jans.cloud" --validationmode dns-01 --validation script --dnsscript Scripts\IONOSDNS.ps1 --dnscreatescriptarguments "create {Identifier} {RecordName} {Token}" --dnsdeletescriptarguments "delete {Identifier} {RecordName} {Token}" --certificatestore My --acl-fullcontrol "Netzwerkdienst,Administratoren" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP,POP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'"
# Production:
wacs.exe --baseuri https://acme-v02.api.letsencrypt.org/ --accepttos --emailaddress "<einetolle@emailadresse.de" --friendlyname "LE Exchange" --source manual --host "outlook.jans.cloud, autodiscover.jans.cloud" --validationmode dns-01 --validation script --dnsscript Scripts\IONOSDNS.ps1 --dnscreatescriptarguments "create {Identifier} {RecordName} {Token}" --dnsdeletescriptarguments "delete {Identifier} {RecordName} {Token}" --certificatestore My --acl-fullcontrol "Netzwerkdienst,Administratoren" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP,POP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'"
Unter Umständen – bzw. wenn es um Exchange Server geht – sollte im Win-ACME Ordner noch in der „settings.json“ im Bereich „Security“ noch der Wert „PrivateKeyExportable“ von false auf true gesetzt werden. Sollte es – weiterhin – um Exchange Server gehen, dann auf deutschsprachigen System noch die Parameter „–acl-fullcontrol „Netzwerkdienst,Administratoren““ bzw. auf englischsprachigen Systemen die Parameter „–acl-fullcontrol „Network Service,Administrators““ beim Aufruf der „wcas.exe“ anfügen!
Schreibe einen Kommentar