Mit einer Azure Subscription und einer gekauften Domäne kann man seinen eigenen DynDNS Dienst anbieten.
Das zum Schluss verwendete Updatescript wurde von verschiedenen Seiten zusammenkopiert und auf eine FritzBox abgestimmt. Ehre gebührt den IT´lern aus den Quell Links die das ganze überhaupt möglich gemacht haben.
if ($PSVersionTable.PSVersion.Major -lt 3)
function md5([string]string){
[System.BitConverter]::ToString([System.Security.Cryptography.MD5]::Create().ComputeHash((new-object System.Text.UTF8Encoding).GetBytes(string))).replace('-','').toLower()
}
function Execute-SOAPRequest {
param(
[Xml]soapactionheader,
[String]$URL
)
try{
URL)
soapactionheader)
$wr.ContentType = 'text/xml; charset="UTF-8"'
$wr.Accept = 'text/xml'
$wr.Method = 'POST'
$requestStream = $wr.GetRequestStream()
$SOAPRequest.Save($requestStream)
$requestStream.Close()
[System.Net.HttpWebResponse]$wresp = $wr.GetResponse()
$responseStream = $wresp.GetResponseStream()
$responseXML = [Xml]([System.IO.StreamReader]($responseStream)).ReadToEnd()
$responseStream.Close()
return $responseXML
}catch {
if ($_.Exception.InnerException.Response){
throw ([System.IO.StreamReader]($_.Exception.InnerException.Response.GetResponseStream())).ReadToEnd()
}else{
throw $_.Exception.InnerException
}
}
}
[xml](ns = new-Object System.Xml.XmlNamespaceManager ns.AddNamespace("ns",$serviceinfo.DocumentElement.NamespaceURI)
[xml]$script:request = @"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Header>
<h:ClientAuth xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
</h:ClientAuth>
</s:Header>
<s:Body>
</s:Body>
</s:Envelope>
"@
function SetAuthInfo([xml]data){
# Benötigte Daten für die Authentifierung aus der Response auslesen und in den neuen Request schreiben
if (data.Envelope.Header.NextChallenge.Nonce){
$NONCE = $data.Envelope.Header.NextChallenge.Nonce
$REALM = $data.Envelope.Header.NextChallenge.Realm
}else{
$NONCE = $data.Envelope.Header.Challenge.Nonce
$REALM = $data.Envelope.Header.Challenge.Realm
}
$script:request.Envelope.Header.ClientAuth.Nonce = $NONCE
$script:request.Envelope.Header.ClientAuth.Realm = $REALM
$script:request.Envelope.Header.ClientAuth.UserID = $username
(md5 "username):REALM):password)"):NONCE)"
}
function Invoke-FBReboot(){
$URN = 'urn:dslforum-org:service:DeviceConfig:1'
$action = 'Reboot'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.Body.InnerText
}
function Get-FBInfo(){
$URN = 'urn:dslforum-org:service:DeviceInfo:1'
$action = 'GetInfo'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.Body.GetInfoResponse
}
<# Anruferliste abrufen
function Get-FBCallList(){
param(
[int]days = 999
)
$URN = 'urn:dslforum-org:service:X_AVM-DE_OnTel:1'
$action = 'GetCallList'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
[xml]$list = irm -uri "$($resp.Envelope.Body.GetCallListResponse.NewCallListURL)&max=$maxentries&days=$days" -Method Get
return $list.root.call
}#>
function Get-FBWANPPPInfo(){
$URN = 'urn:dslforum-org:service:WANPPPConnection:1'
$action = 'GetInfo'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.Body.GetInfoResponse
}
<# Aktuelle DSL-Verbindungsdaten auslesen
function Get-FBWANDSLInterfaceConfig(){
$URN = 'urn:dslforum-org:service:WANDSLInterfaceConfig:1'
$action = 'GetInfo'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.body.GetInfoResponse
}#>
<# DSL Leitungsstatistik abfragen
function Get-FBWANDSLInterfaceStatistics(){
$URN = 'urn:dslforum-org:service:WANDSLInterfaceConfig:1'
$action = 'GetStatisticsTotal'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType)) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.body.GetStatisticsTotalResponse
}#>
<# Portfreigaben abrufen
function Get-FBPortMappings(){
$URN = 'urn:dslforum-org:service:WANPPPConnection:1'
$action = 'GetGenericPortMappingEntry'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$actiontag = $script:request.CreateElement('u',$action,$service.serviceType)
$parametertag = $script:request.CreateElement('u','NewPortMappingIndex',$service.serviceType)
$actiontag.AppendChild($parametertag) | out-null
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($actiontag) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
$cnt = 0
while($true){
# Parameter Index für die Portregel im XML setzen
$parametertag.InnerText = $cnt
# Authentifizierungsdaten setzen
SetAuthInfo $resp
try{
# Request senden
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Mapping ausgeben
$resp.Envelope.body.GetGenericPortMappingEntryResponse
$cnt++
}catch{
break
}
}
}#>
<# DSL-Verbindung trennen
function Invoke-DSLDisconnect(){
$URN = 'urn:dslforum-org:service:WANPPPConnection:1'
$action = 'ForceTermination'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$actiontag = $script:request.GetElementsByTagName('s:Body')[0].AppendChild($script:request.CreateElement('u',$action,$service.serviceType))
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.body
}#>
<# Portweiterleitungen anlegen / verändern
function Add-FBPortMapping(){
param(
[string]ExternalPort,
[ValidateSet('TCP','UDP')][string]InternalClient,
[ValidateRange(1,65535)][uint16]Enabled = Description,
[string]$LeaseDuration = "0"
)
$URN = 'urn:dslforum-org:service:WANPPPConnection:1'
$action = 'AddPortMapping'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$actiontag = $script:request.CreateElement('u',$action,$service.serviceType)
$parameter_NewRemoteHost = $script:request.CreateElement('NewRemoteHost')
$parameter_NewExternalPort = $script:request.CreateElement('NewExternalPort')
$parameter_NewProtocol = $script:request.CreateElement('NewProtocol')
$parameter_NewInternalPort = $script:request.CreateElement('NewInternalPort')
$parameter_NewInternalClient = $script:request.CreateElement('NewInternalClient')
$parameter_NewEnabled = $script:request.CreateElement('NewEnabled')
$parameter_NewPortMappingDescription = $script:request.CreateElement('NewPortMappingDescription')
$parameter_NewLeaseDuration = $script:request.CreateElement('NewLeaseDuration')
$parameter_NewRemoteHost.InnerText = $RemoteHost
$parameter_NewExternalPort.innerText = [string]$ExternalPort
$parameter_NewProtocol.innerText = $Protocol
$parameter_NewInternalPort.innerText = [string]$InternalPort
$parameter_NewInternalClient.innerText = $InternalClient
$parameter_NewEnabled.innerText = @{$true=1;$false=0}[$Enabled]
$parameter_NewPortMappingDescription.innerText = $Description
$parameter_NewLeaseDuration.innerText = $LeaseDuration
$actiontag.AppendChild($parameter_NewRemoteHost) | out-null
$actiontag.AppendChild($parameter_NewExternalPort) | out-null
$actiontag.AppendChild($parameter_NewProtocol) | out-null
$actiontag.AppendChild($parameter_NewInternalPort) | out-null
$actiontag.AppendChild($parameter_NewInternalClient) | out-null
$actiontag.AppendChild($parameter_NewEnabled) | out-null
$actiontag.AppendChild($parameter_NewPortMappingDescription) | out-null
$actiontag.AppendChild($parameter_NewLeaseDuration) | out-null
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($actiontag) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
#$script:request.OuterXml
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.envelope.body
}#>
<# Bestimmte Portweiterleitung löschen
function Delete-FBPortMapping(){
param(
[ValidateRange(1,65535)][uint16]Protocol
)
$URN = 'urn:dslforum-org:service:WANPPPConnection:1'
$action = 'DeletePortMapping'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$actiontag = $script:request.CreateElement('u',$action,$service.serviceType)
$parameter_NewRemoteHost = $script:request.CreateElement('NewRemoteHost')
$parameter_NewExternalPort = $script:request.CreateElement('NewExternalPort')
$parameter_NewProtocol = $script:request.CreateElement('NewProtocol')
$parameter_NewRemoteHost.InnerText = '0.0.0.0'
$parameter_NewExternalPort.innerText = [string]$ExternalPort
$parameter_NewProtocol.innerText = $Protocol
$actiontag.AppendChild($parameter_NewRemoteHost) | out-null
$actiontag.AppendChild($parameter_NewExternalPort) | out-null
$actiontag.AppendChild($parameter_NewProtocol) | out-null
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($actiontag) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.envelope.body
}#>
<# Rufnummer mit der Wählhilfe wählen
function Dial-FBNumber {
param(
[Parameter(Mandatory=number
)
$URN = 'urn:dslforum-org:service:X_VoIP:1'
$action = 'X_AVM-DE_DialNumber'
# Service auslesen
$service = $serviceinfo.SelectNodes('//ns:service',$ns) | ?{$_.ServiceType -eq $URN}
# passenden Body Request-Tag ins XML einfügen
$actiontag = $script:request.CreateElement('u',$action,$service.serviceType)
# Tag für die Telefonnummer erzeugen
$parameter_number = $script:request.CreateElement('NewX_AVM-DE_PhoneNumber')
$parameter_number.InnerText = $number
$actiontag.AppendChild($parameter_number) | out-null
# Actiontag zum Request hinzufügen
$script:request.GetElementsByTagName('s:Body')[0].AppendChild($actiontag) | out-null
# Initialer Request
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
# Authentifizierungsdaten setzen
SetAuthInfo $resp
# Request mit Authentifizierung abschicken
$resp = Execute-SOAPRequest $script:request "$($service.serviceType)#$($action)" "$($FB_URL):49000$($service.controlURL)"
return $resp.Envelope.Body
}#>
<#Function Get-DDWRTExternalIP {
$Page = Invoke-WebRequest -UseBasicParsing -Uri "http://192.168.0.2/Status_Internet.live.asp" -Credential (Import-Clixml $ScriptPath"\DDWRTCreds.xml")
$WANregex='(?<Address>{wan_ipaddr::(\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b)})'
$IPregex='(?<Address>(\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b))'
If ($Page.Content -match $WANregex) {$WANAddress = $Matches.Address}
Else {Return $false}
If ($WANAddress -match $IPregex) {Return $Matches.Address}
Else {Return $false}
}#>
$ScriptPath = Split-Path $Script:MyInvocation.MyCommand.Path
HostAddress) | Select-Object -ExpandProperty IPAddressToString
$IP = Get-FBWANPPPInfo | select -ExpandProperty NewExternalIPAddress #Original: Get-DDWRTExternalIP
If ($IP -ne $EI) {
# Login to Azure
#$Creds = Import-Clixml -Path $ScriptPath"\AzureRMCreds.xml"
#Login-AzureRmAccount -Credential $Creds
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
#Login-AzureRmAccount -C -Credential $psCred
Add-AzureRmAccount -Credential $psCred -TenantId $TenantID -ServicePrincipal
Get-AzureRmLog -StartTime (Get-Date).AddMinutes(-10)
# Update the apex record
$RecordSet = New-AzureRmDnsRecordSet -Name $HostARecord -RecordType A -ZoneName $ZoneName -ResourceGroupName $ResourceGroupName -Ttl 60 -Overwrite -Confirm:$false
Add-AzureRmDnsRecordConfig -RecordSet $RecordSet -Ipv4Address $IP
Set-AzureRmDnsRecordSet -RecordSet $RecordSet
}
Else {
Write-Output "Dynamic address (EI) match."
}
# <span class="mw-headline" id="bkmrk-nachfolgearbeiten%3A-1">Nachfolgearbeiten:</span>
Das Passwort des Azure Serviceaccounts (App Service) läuft nach einer Zeit ab und muss erneuert werden. Im Script als **$azurePassword** angegeben
Am einfachsten geht das über die GUI von Azure.
<div class="vector-body" id="bkmrk-azure-active-directo"><div class="mw-body-content mw-content-ltr" dir="ltr" lang="de"><div class="mw-parser-output">1. Azure Active Directory > App-Registrierungen > Service Benutzer auswählen <dl><dd>[](https://wiki.eidolf.de/index.php/Datei:Azure-DynDNS-001.png)</dd></dl>
2. Unter Zertifikate & Geheimnisse > einen neuen geheimen Clientschlüssel erstellen <dl><dd>[](https://wiki.eidolf.de/index.php/Datei:Azure-DynDNS-002.png)</dd></dl>
3. Das neue Passwort ist der erstellte Wert, der nur nach der Erstellung vollständig angezeigt wird. Deshalb wegkopieren oder am besten sofort in das verwendete Script einfügen. Danach wird der Wert nur noch teilweise angezeigt, siehe Screenshot.
4. Im Screenshot nicht ersichtlich, aber eigentlich nötig. Den alten obsoleten Schlüssel löschen.
</div></div></div># <span class="mw-headline" id="bkmrk-quelle%3A-1">Quelle:</span>
Idee dazu aus folgendem Link
http://www.lewisroberts.com/2016/05/28/using-azure-dns-dynamic-dns/
Fritzbox Abfrage in folgendem Link
Service Benutzer für Azure Dienste
https://cmatskas.com/automate-login-for-azure-powershell-scripts/
https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal