Last active
May 1, 2019 00:41
-
-
Save luginbash/7c9dac4653855df1a2c1 to your computer and use it in GitHub Desktop.
Dynamic DNS endpoint IP address update script with Mikrotik router
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
function snmpGetIP | |
{ | |
local SNMP_HOST=$1 | |
local SNMP_COMM=$2 | |
local SNMP_IFID=$3 | |
snmpwalk -Os -c ${SNMP_COMM} -v 2c ${SNMP_HOST} ipAdEntIf | grep "INTEGER: ${SNMP_IFID}" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | |
} | |
function cfGetZone | |
{ | |
curl -sX "GET" "https://api.cloudflare.com/client/v4/zones/" \ | |
-H "X-Auth-Key: ${cfSecret}" \ | |
-H "Content-Type: application/json" \ | |
-H "X-Auth-Email: ${cfLogin}" -o ${TEMP_DIR}/zone.json | |
} | |
function cfGetZoneId | |
{ | |
cfDomain=$1 | |
jq -r '.result[]|select(.name=="'${cfDomain}'")|.id' \ | |
$TEMP_DIR/zone.json | |
} | |
function cfGetRecords | |
{ | |
cfZoneId=$1 | |
curl -sX GET "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records?type=A" \ | |
-H "X-Auth-Email: ${cfLogin}" \ | |
-H "X-Auth-Key: ${cfSecret}" \ | |
-H "Content-Type: application/json" \ | |
-o $TEMP_DIR/records.json | |
} | |
function cfGetRecordId | |
{ | |
local recName=$1 | |
jq -r ".result|.[]|select(.name == \"${recName}.${cfDomain}\")|.id" $TEMP_DIR/records.json | |
} | |
function cfPushRecord | |
{ | |
local cfZoneId=$1 | |
local cfRecordId=$2 | |
local recName=$3 | |
local recVal=$4 | |
t_exec=$(date -u +%s) | |
validateStr=$t_exec\ \#$(sha1sum <<< $t_exec|cut -c-8) | |
curl -sX "PUT" "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records/${cfRecordId}" \ | |
-H "X-Auth-Key: ${cfSecret}" \ | |
-H "Content-Type: application/json" \ | |
-H "X-Auth-Email: ${cfLogin}" \ | |
-d "{\"type\":\"A\",\"name\":\"$recName\",\"content\":\"$recVal\",\"proxied\":false,\"ttl\":120}" \ | |
-o $TEMP_DIR/result.json | |
echo $validateStr | |
} | |
function cfPushTxtRecord | |
{ | |
local cfZoneId=$1 | |
local cfRecordId=$2 | |
local recName=$3 | |
local recVal=$4 | |
curl -sX "PUT" "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records/${cfRecordId}" \ | |
-H "X-Auth-Key: ${cfSecret}" \ | |
-H "Content-Type: application/json" \ | |
-H "X-Auth-Email: ${cfLogin}" \ | |
-d "{\"type\":\"TXT\",\"name\":\"$recName\",\"content\":\"$recVal\",\"proxied\":false,\"ttl\":120}" \ | |
-o $TEMP_DIR/txt.json | |
} | |
function cleanUp | |
{ | |
rm -rf ${TEMP_DIR} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Dynamic DNS endpoint IP address update script with Mikrotik | |
# This script uses ssh to get IP address from Mikrotik router | |
# The hostname(subdomains) parts has to be stored as global | |
# variables FIRST. | |
# | |
# To setup on a Mikrotik: | |
# https://gist.github.com/methou/f9622e6cc15b5055096e | |
# | |
# only current user can rw intermediate files genereated by this script | |
umask 066 | |
# CloudFlare Configuration | |
# Secret | |
tkn=<api key> | |
# cloudflare login, must be an email address | |
email=<email address> | |
# domain name, naked. | |
domain=<domain name> | |
# subdomains, please remember set up on the Mikrotik router side | |
# e.g. subdomains=("a01" "a02" "a03" "a04") | |
# for a01.example.org etc. | |
subdomains=<an array of subdomains> | |
# Router Configuraion | |
mikrotikHost="192.168.88.1" | |
# SSH Port number | |
PORT=22 | |
TEMP_DIR=$(mktemp -d) # create a temp only us can rw from/to | |
# source functions | |
. ./functions.sh | |
# int main(){ ... } | |
NUM_CHG=0 | |
# compare first IP | |
for i in $(seq ${#cfRecordNames[*]}); do | |
sampleIpAddr=$(snmpGetIP ${mkHostIp} ${mkSnmpCommunity} ${mkSnmpIfId[$i-1]}) | |
recordIpAddr=$(dig @$nameServer +adflag +short ${cfRecordNames[i-1]}.$cfDomain) | |
# echo -e "${mkSnmpIfId[i-1]}:\t rec:${recordIpAddr}\tsampled:${sampleIpAddr}" | |
if [[ ${sampleIpAddr} == ${recordIpAddr} ]]; then | |
echo -e "(${cfRecordNames[i-1]}: NOCHG, no need to update)" | |
else | |
((NUM_CHG+=1)) | |
fi | |
done | |
#echo $NUM_CHG | |
if [ ${NUM_CHG} -ge 1 ] || [[ ${1:-auto} != "auto" ]] ; then | |
exit 1 | |
echo "Mismatch found, updating..." | |
cfGetZone | |
zoneId=$(cfGetZoneId ${cfDomain}) | |
cfGetRecords ${zoneId} | |
for i in $(seq ${#cfRecordNames[*]}); do | |
thisRecId=$(cfGetRecordId ${cfRecordNames[i-1]}) | |
#thisTxtRecId=$(cfGetRecordId _${cfRecordNames[i-1]}) | |
thisIpAddr=$(snmpGetIP ${mkHostIp} ${mkSnmpCommunity} ${mkSnmpIfId[i-1]}) | |
thisFqdn=${cfRecordNames[i-1]}\.${cfDomain}; | |
validateStr=$(cfPushRecord ${zoneId} ${thisRecId} ${cfRecordNames[i-1]} ${thisIpAddr}) | |
#cfPushTxtRecord ${zoneId} ${thisTxtRecId} _${cfRecordNames[i-1]} "${validateStr}" | |
done | |
cleanUp | |
else | |
exit -1 | |
echo "(All NOCHG: no need to update at all)" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
update.sh functions.sh and hostIp.func.rsc, the three seem to have no connection, how to use? There are no common global variable between them.