[2020-12-24 Edit-start]
Two things here -
1. Cloudflare now allows for access tokens which you can lock down to specific areas and actions.. like dns zones and read\edit. So its better to now use these than the global api key that was only available when I wrote this article. You will need to create the access token in cloudflare and then change the $header variable to something like this.
1. Cloudflare now allows for access tokens which you can lock down to specific areas and actions.. like dns zones and read\edit. So its better to now use these than the global api key that was only available when I wrote this article. You will need to create the access token in cloudflare and then change the $header variable to something like this.
$headers = @{
"Authorization" = 'Bearer <access token>';
"Content-Type" = 'application/json'
}
2. Also now with the demise of internet explorer I have found that to use the Invoke-WebRequest
you have to add -UseBasicParsing to the command. So it will read like this.
$request = Invoke-WebRequest -Uri "${cloudFlareApiBaseUrl}/zones/?name=${Zone}"
-Method 'GET' -Headers $headers -UseBasicParsing
[2020-12-24 Edit-end]
We had a connection that ran our company VPN. The VPN was available on a couple of URLs. This connection also had a backup connection, so if the primary link failed it would swap to the backup. However this would change the IP address.
I wanted to make it so that the when the connection failed over the VPN URLs were updated.
The script below achieves that by updating the DNS records in cloudflare with the new public IP of the connection.
It looks at the public IP and then compares it to the record in dns, if the same do nothing. If different then update and send SMS
The SMS api maybe different for you depending on the company you use.
function Get-ScriptDirectory{ #Determine the folder in which the script lives. $Invocation = (Get-Variable MyInvocation -Scope 1).Value Split-Path $Invocation.MyCommand.Path}#[string]$CRLF#needed to find the location of the script.$scriptPath = Get-ScriptDirectory
[String]$scriptCurrentDateTime = Get-Date -format "yyyyMMddHHmmss"
$headers = @{ 'X-Auth-Key' = '<auth-key>'; 'X-Auth-Email' = '<email>'; 'Content-Type' = 'application/json' }
[string]$urlRequest = 'https://api.smscompanyurl.com/api-adv.php?';[string]$smsUsername = '<username>';[string]$smsPassword = '<password>';[string]$smsNumbers = '<phonenumber1>,<phonenumber2>,<phonenumber3>';[string]$smsFrom = '<Company Name>';[string]$smsMessage = [uri]::EscapeDataString('Office IP Address has changed. Attempting auto update.');
$ZoneRecords = @('temp.contoso.com','tempytemp.contoso.com')
[string]$Zone = 'contoso.com';[string]$cloudFlareApiBaseUrl = 'https://api.cloudflare.com/client/v4';[string]$public_IP='';[string]$public_IP='';
# Get Zone ID from cloudflare try { $request = Invoke-WebRequest -Uri "${cloudFlareApiBaseUrl}/zones/?name=${Zone}" -Method 'GET' -Headers $headers } catch { $MyError = $_ Throw $MyError } $zoneId = $(ConvertFrom-Json $request.Content).result[0].id
#Lookup external ip try { $public_IP = (Invoke-RestMethod https://api.ipify.org?format=json).ip.trim() } catch { $MyError = $_ Throw $MyError }
Foreach ($Element IN $ZoneRecords) {
#GET record info from cloudflare #$RecordVPNweb = Invoke-WebRequest -Uri "${cloudFlareApiBaseUrl}/zones/${ZoneId}/dns_records/?name=${Element}" -Method 'GET' -Headers $headers try { $RecordVPN = Invoke-RestMethod -Uri "${cloudFlareApiBaseUrl}/zones/${ZoneId}/dns_records/?name=${Element}" -Method 'GET' -Headers $headers -ContentType 'application/json' } catch { $MyError = $_ Throw $MyError } #When using webrequest need to convert from jason #$RecordVPN_ID = $(ConvertFrom-Json $RecordVPN.Content).result[0].id #$RecordVPN_IP = $(ConvertFrom-Json $RecordVPN.Content).result[0].content $RecordVPN_ID = $RecordVPN.result[0].id $RecordVPN_IP = $RecordVPN.result[0].content if ($RecordVPN_IP -ne $public_IP) {
$smsMessage = $smsMessage + [uri]::EscapeDataString("Changing from $RecordVPN_IP to new $public_IP"); $queryString = "username=$smsUsername&password=${smsPassword}&to=${smsNumbers}&from=${smsFrom}&message=${smsMessage}"; ${urlRequest}+${queryString} [string]$textfileName = "$scriptPath\IPChanged$scriptCurrentDateTime.txt" try { #send sms [String]$scriptIPChangeDateTime = Get-Date -format "yyyy-MM-dd HHmmss" [string]$textfileContent = "IP Change attempted at $scriptIPChangeDateTime : ${urlRequest}+${queryString}" out-file -filepath $textfileName -inputobject $textfileContent -encoding ASCII Invoke-RestMethod -Uri "${urlRequest}+${queryString}" -Method 'GET'; } catch { $MyError = $_ Throw $MyError }
$Data = @{ 'id' = "${RecordVPN_ID}"; 'type' = 'A'; 'name' = "${Element}"; 'content' = "${public_IP}"; } # If it exists, UPDATE (PUT), if not, CREATE (POST) [string]$method = 'PUT'; if ($RecordVPN.result.Count -eq 0) { $method = 'POST'; $Data.Remove('id'); }
$DataJson = ConvertTo-Json $Data
try { $JSONResponse = Invoke-RestMethod -Uri "${cloudFlareApiBaseUrl}/zones/${ZoneId}/dns_records/${RecordVPN_ID}/" -Headers $Headers -Body $DataJson -Method "${method}" -ContentType 'application/json' -ErrorAction Stop } catch { $MyError = $_ Throw $MyError } }}
No comments:
Post a Comment