IONOS DNS API Plugin für Win-ACME Client


PowerShell Script zum bearbeiten der IONOS DNS API
PowerShell Script zum bearbeiten der IONOS DNS API

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:

„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

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.