From 3c56196bf8824c1e34df6f4886c18485c76f8c8d Mon Sep 17 00:00:00 2001 From: jsgaard <66730840+jsgaard@users.noreply.github.com> Date: Tue, 11 Aug 2020 09:26:04 +0200 Subject: [PATCH] Add support for DynECT provider --- Posh-ACME/DnsPlugins/DynECT-Readme.md | 22 +++ Posh-ACME/DnsPlugins/DynECT.ps1 | 237 ++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 Posh-ACME/DnsPlugins/DynECT-Readme.md create mode 100644 Posh-ACME/DnsPlugins/DynECT.ps1 diff --git a/Posh-ACME/DnsPlugins/DynECT-Readme.md b/Posh-ACME/DnsPlugins/DynECT-Readme.md new file mode 100644 index 00000000..fcf32147 --- /dev/null +++ b/Posh-ACME/DnsPlugins/DynECT-Readme.md @@ -0,0 +1,22 @@ +# How To Use the DynECT DNS Plugin + +This plugin works against DynECT DNS provider. +It requires PoshDynDnsApi powershell module to be installed in order to work correctly. - However, if this module is missing, it will be installed on first run (You will be prompted if you want to install or not.) + +## Setup + +In addition to your username and password, you will also need a "customer" name, in order to make a successful connection. +Customer name can be found on the home dashboard when logged into the dyn ECT portal. + +### Any OS + +```powershell +$pass = Read-Host -Prompt "Password" -AsSecureString +$params = @{ + user='myusername' + pass=$pass + customer='examplecustomer' + zone='example.com' +} +New-PACertificate *.test.example.com -DnsPlugin DynECT -PluginArgs $params +``` diff --git a/Posh-ACME/DnsPlugins/DynECT.ps1 b/Posh-ACME/DnsPlugins/DynECT.ps1 new file mode 100644 index 00000000..ed36952e --- /dev/null +++ b/Posh-ACME/DnsPlugins/DynECT.ps1 @@ -0,0 +1,237 @@ +function Add-DnsTxtDynECT { + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)] + [string]$RecordName, + [Parameter(Mandatory,Position=1)] + [string]$TxtValue, + [Parameter(Mandatory,Position=2)] + [string]$zone, + [Parameter(Mandatory,Position=3)] + [string]$user, + [Parameter(Mandatory,Position=4)] + [securestring]$pass, + [Parameter(Mandatory,Position=5)] + [string]$customer + ) + + Add-DynModule + + If ($user -and $customer -and $pass) { + Write-Verbose "All arguments for authentication has been set" + Write-Verbose "Trying to establish connection to DynECT" + Connect-DynDnsSession -User $user -Customer $customer -Password $pass + + If (Test-DynDnsSession) { + Write-Verbose "Successfully generated auth token to DynECT" + } Else { + Write-Warning "Token could not be generated, connection to DynECT has failed" + Return + } + + If ($zone -and $RecordName -and $TxtValue) { + Write-Verbose "All arguments for updating DNS has been set" + Write-Verbose "Trying to add DNS record to DynECT" + Add-DynDnsRecord -Zone $zone -Node $RecordName -DynDnsRecord (New-DynDnsRecord -Text $TxtValue) -Confirm:$false + + If (Get-DynDnsZoneChanges -Zone $zone) { + Write-Verbose "DNS Zone has new changes" + } Else { + Write-Warning "DNS Zone do not have any new changes to publish" + } + } Else { + Write-Warning "Missing arguments for updating DNS zone" + Write-Warning "Following arguments are needed: `nzone `nRecordName `nTxtValue" + Return + } + + } Else { + Write-Warning "Missing arguments for authentication" + Write-Warning "Following arguments are needed: `nuser `ncustomer `npass" + Return + } + +<# + .SYNOPSIS + Add a DNS TXT record to a DynECT hosted zone. + + .DESCRIPTION + This plugin require PoShDynDnsApi powershell module. + + .PARAMETER RecordName + The fully qualified name of the TXT record. + + .PARAMETER TxtValue + The value of the TXT record. + + .PARAMETER Zone + The zone is the root domain e.g. example.com + + .PARAMETER user + The user is the username that has permissions to DynECT API + + .PARAMETER pass + The pass is the password of the user that has permissions to DynECT API + + .PARAMETER customer + The customer is the DynECT customer registered name, this is needed to generate authentication token + + .EXAMPLE + Add-DnsTxtDynECT '_acme-challenge.example.com' 'asdfqwer12345678' -Zone 'example.com' -user 'username' -pass (ConvertTo-SecureString -AsPlainText 'password' -Force) -customer 'customername' + + .EXAMPLE + $seckey = Read-Host -Prompt 'Secret Key:' -AsSecureString + Add-DnsTxtDynECT '_acme-challenge.example.com' 'asdfqwer12345678' -Zone 'example.com' -user 'username' -pass $seckey -customer 'customername + + Add a TXT record using an explicit Access Key and Secret key from Windows. +#> + +} + +function Remove-DnsTxtDynECT { + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)] + [string]$RecordName, + [Parameter(Mandatory,Position=1)] + [string]$TxtValue, + [Parameter(Mandatory,Position=2)] + [string]$zone, + [Parameter(Mandatory,Position=3)] + [string]$user, + [Parameter(Mandatory,Position=4)] + [securestring]$pass, + [Parameter(Mandatory,Position=5)] + [string]$customer + ) + + If ($user -and $customer -and $pass) { + Write-Verbose "All arguments for authentication has been set" + Write-Verbose "Trying to establish connection to DynECT" + Connect-DynDnsSession -User $user -Customer $customer -Password $pass + + If (Test-DynDnsSession) { + Write-Verbose "DynECT session is alive" + + If ($zone -and $RecordName) { + Write-Verbose "Trying to remove DNS record" + $txtToRemove = Get-DynDnsRecord -Zone $zone -RecordType TXT -Node $RecordName + + If ($txtToRemove) { + Write-Verbose "Record found, removing record: $txtToRemove" + Remove-DynDnsRecord -DynDnsRecord $txtToRemove -Confirm:$false + + If (Get-DynDnsZoneChanges -Zone $zone) { + Write-Verbose "DNS Zone has new changes" + } Else { + Write-Warning "DNS Zone do not have any new changes to publish" + } + } Else { + Write-Warning "No records to remove was found. Skipping removal" + } + } Else { + Write-Warning "Missing arguments for removal of DNS Zone." + Write-Warning "Make sure both 'zone' and 'RecordName' is set" + Return + } + } Else { + Write-Warning "DynECT session has been terminated. unable to remove record" + } + } Else { + Write-Warning "Missing arguments for authentication" + Write-Warning "Following arguments are needed: `nuser `ncustomer `npass" + Return + } + +<# + .SYNOPSIS + Removes DNS record from DynECT hosted zone. + + .DESCRIPTION + + + .PARAMETER RecordName + The fully qualified name of the TXT record. + + .PARAMETER Zone + The zone is the root domain e.g. example.com + + .EXAMPLE + Remove-DnsTxtDynECT '_acme-challenge.example.com' -Zone 'example.com' +#> +} + +function Save-DnsTxtDynECT { + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)] + [string]$zone, + [Parameter(Mandatory,Position=1)] + [string]$user, + [Parameter(Mandatory,Position=2)] + [securestring]$pass, + [Parameter(Mandatory,Position=3)] + [string]$customer + ) + + If ($zone) { + Write-Verbose "All arguments has been set for publishing zone: $zone" + Publish-DynDnsZoneChanges -Zone $zone -Force -Confirm:$false + + If (!(Get-DynDnsZoneChanges -Zone $zone)) { + Write-Verbose "Zone: $zone has been published. no missing changes" + } Else { + Write-Warning "Zone: $zone still has missing changes to publish" + } + + Write-Verbose "Disconnecting session to DynECT" + Disconnect-DynDnsSession + + If (Test-DynDnsSession) { + Write-Warning "Unable to disconnect session to DynECT" + } Else { + Write-Verbose "Successfully disconnected to DynECT" + } + } +<# + .SYNOPSIS + Publish DNS changes to DynECT hosted zone. + + .DESCRIPTION + + .PARAMETER Zone + The zone is the root domain e.g. example.com + + .EXAMPLE + Save-DnsTxtDynECT -Zone 'example.com' +#> + +} + +Function Add-DynModule { + $Module = Get-Module -ListAvailable -name "PoShDynDnsApi" + + If ($Module.Count -ge 1) { + Write-Verbose "PoShDynDnsApi powershell module is present" + Import-Module -Name PoShDynDnsApi + } Else { + Try { + Write-Verbose "PoShDynDnsApi powershell module is missing, installing" + Install-Module -Name PoShDynDnsApi -Scope CurrentUser + Write-Verbose "Successfully installed PoShDynDnsApi module" + Import-Module -Name "PoShDynDnsApi" + } Catch { + Write-Warning "Module was unable to be installed" + Return + } + } +} + +############################ +# Helper Functions +############################ + +# Add additional functions here if necessary. +# Make sure they're uniquely named and try to follow +# verb-noun naming guidelines. +# https://msdn.microsoft.com/en-us/library/ms714428