From f88b2d2a1b1915a10c93d4013c005ab0e3744ceb Mon Sep 17 00:00:00 2001 From: Marcel Fliegel Date: Sat, 25 Jul 2020 16:40:47 +0200 Subject: [PATCH 1/7] [hetzner-api-dyndns-2007250936] total rework --- dyndns.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 13 deletions(-) mode change 100644 => 100755 dyndns.sh diff --git a/dyndns.sh b/dyndns.sh old mode 100644 new mode 100755 index 468571f..357fb94 --- a/dyndns.sh +++ b/dyndns.sh @@ -1,30 +1,84 @@ #!/bin/bash # DynDNS Script for Hetzner API by FarrowStrange -# V0.1 +# v1.0 + +record_ttl='60' +record_type='A' + +display_help() { + cat < -z -r -n + +parameters: + -a - Auth-API-Token + -z - Zone ID + -r - Record ID + -n - Record name + +optional parameters: + -t - TTL + -T - Type + +help: + -h - Show Help + +example: + .exec: ./dyndns.sh -a 234hj23S7d9asd213 -z 98jFjsd8dh1GH7 -r AHD82h347fGAF1 -n dyn +EOF + exit 1 +} + +while getopts ":a:z:r:n:t:T:" opt; do + case "$opt" in + a ) + auth_api_token="${OPTARG}" + ;; + z ) + zone_id="${OPTARG}" + ;; + r ) + record_id="${OPTARG}" + ;; + n ) + record_name="${OPTARG}" + ;; + t ) + record_ttl="${OPTARG}" + ;; + T ) + record_type="${OPTARG}" + ;; + h|* ) + display_help + ;; + \? ) + echo "Invalid Option: -$OPTARG" + echo "use -h for help" + exit 1 + ;; + + esac +done + -api_auth_token= -api_zone= -api_record= pub_addr=`curl -s ifconfig.me` -api_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${api_record}" -H 'Auth-API-Token: '${api_auth_token} | cut -d ',' -f 4 | cut -d '"' -f 4` +api_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${record_id}" -H 'Auth-API-Token: '${auth_api_token} | cut -d ',' -f 4 | cut -d '"' -f 4` if [[ $pub_addr == $api_dyn_addr ]]; then echo "DNS record is up to date - nothing to to." - else echo "DNS record is no longer valid - updating record" - - curl -s -X "PUT" "https://dns.hetzner.com/api/v1/records/${api_record}" \ + curl -s -X "PUT" "https://dns.hetzner.com/api/v1/records/${record_id}" \ -H 'Content-Type: application/json' \ - -H 'Auth-API-Token: '${api_auth_token} \ + -H 'Auth-API-Token: '${auth_api_token} \ -d $'{ "value": "'${pub_addr}'", - "ttl": 60, - "type": "A", - "name": "gw", - "zone_id": "'${api_zone}'" + "ttl": '${record_ttl}', + "type": "'${record_type}'", + "name": "'${record_name}'", + "zone_id": "'${zone_id}'" }' if [[ $? != 0 ]]; then From c12429e4ecd005d0c15479189ee3bca098cb592a Mon Sep 17 00:00:00 2001 From: Marcel Fliegel Date: Sat, 25 Jul 2020 17:01:22 +0200 Subject: [PATCH 2/7] [hetzner-api-dyndns-2007250936] mandatory arguments --- dyndns.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dyndns.sh b/dyndns.sh index 357fb94..42704ea 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -28,7 +28,7 @@ EOF exit 1 } -while getopts ":a:z:r:n:t:T:" opt; do +while getopts ":a:z:r:n:tT" opt; do case "$opt" in a ) auth_api_token="${OPTARG}" @@ -48,15 +48,9 @@ while getopts ":a:z:r:n:t:T:" opt; do T ) record_type="${OPTARG}" ;; - h|* ) + h ) display_help ;; - \? ) - echo "Invalid Option: -$OPTARG" - echo "use -h for help" - exit 1 - ;; - esac done From 7f71a681f8564a8aa7bb60019e697704f06a59db Mon Sep 17 00:00:00 2001 From: Marcel Fliegel Date: Sun, 26 Jul 2020 11:18:31 +0200 Subject: [PATCH 3/7] [hetzner-api-dyndns-2007250936] include more case options --- dyndns.sh | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/dyndns.sh b/dyndns.sh index 42704ea..6e3ff85 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -1,66 +1,75 @@ #!/bin/bash -# DynDNS Script for Hetzner API by FarrowStrange +# DynDNS Script for Hetzner DNS API by FarrowStrange # v1.0 +auth_api_token='' record_ttl='60' record_type='A' + display_help() { cat < -z -r -n + +exec: ./dyndns.sh -z -r -n parameters: - -a - Auth-API-Token -z - Zone ID -r - Record ID -n - Record name optional parameters: - -t - TTL - -T - Type + -t - TTL (Default: 60) + -T - Record type (Default: A) help: -h - Show Help example: - .exec: ./dyndns.sh -a 234hj23S7d9asd213 -z 98jFjsd8dh1GH7 -r AHD82h347fGAF1 -n dyn + .exec: ./dyndns.sh -z 98jFjsd8dh1GH7 -r AHD82h347fGAF1 -n dyn + EOF exit 1 } -while getopts ":a:z:r:n:tT" opt; do +while getopts ":z:r:n:tTh" opt; do case "$opt" in - a ) - auth_api_token="${OPTARG}" - ;; - z ) - zone_id="${OPTARG}" - ;; - r ) - record_id="${OPTARG}" - ;; - n ) - record_name="${OPTARG}" - ;; - t ) - record_ttl="${OPTARG}" - ;; - T ) - record_type="${OPTARG}" - ;; - h ) - display_help - ;; + z ) zone_id="${OPTARG}";; + r ) record_id="${OPTARG}";; + n ) record_name="${OPTARG}";; + t ) record_ttl="${OPTARG}";; + T ) record_type="${OPTARG}";; + h ) display_help;; + \? ) echo "Invalid option: -$OPTARG" >&2; exit 1;; + : ) echo "Missing option argument for -$OPTARG" >&2; exit 1;; + * ) echo "Unimplemented option: -$OPTARG" >&2; exit 1;; esac done +if [[ "${zone_id}" = "" ]]; then + echo "Missing option for zone ID: -z " + echo "Use -h to display help." + exit 1 +elif [[ "${record_id}" = "" ]]; then + echo "Mission option for record ID: -r " + echo "Use -h to display help." + exit 1 +elif [[ "${record_name}" = "" ]]; then + echo "Mission option for record name: -n " + echo "Use -h to display help." + exit 1 +fi +if [[ "${auth_api_token}" = "" ]]; then + echo "No Auth API Token specified. Please reference at the top of the Script." + exit 1 +fi -pub_addr=`curl -s ifconfig.me` -api_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${record_id}" -H 'Auth-API-Token: '${auth_api_token} | cut -d ',' -f 4 | cut -d '"' -f 4` +cur_pub_addr=`curl -s ifconfig.me` +cur_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${record_id}" -H 'Auth-API-Token: '${auth_api_token} | cut -d ',' -f 4 | cut -d '"' -f 4` -if [[ $pub_addr == $api_dyn_addr ]]; then +if [[ $cur_pub_addr == $cur_dyn_addr ]]; then echo "DNS record is up to date - nothing to to." + exit 0 else echo "DNS record is no longer valid - updating record" @@ -68,7 +77,7 @@ else -H 'Content-Type: application/json' \ -H 'Auth-API-Token: '${auth_api_token} \ -d $'{ - "value": "'${pub_addr}'", + "value": "'${cur_pub_addr}'", "ttl": '${record_ttl}', "type": "'${record_type}'", "name": "'${record_name}'", From 206ee5d10b1693608a1008b2d2709241e13d2d01 Mon Sep 17 00:00:00 2001 From: Marcel Fliegel Date: Sun, 26 Jul 2020 11:25:55 +0200 Subject: [PATCH 4/7] [hetzner-api-dyndns-2007250936] use https to determine current pub IP --- dyndns.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dyndns.sh b/dyndns.sh index 6e3ff85..55e2059 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -6,6 +6,9 @@ auth_api_token='' record_ttl='60' record_type='A' +cur_pub_addr=`curl -s https://ifconfig.me` +cur_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${record_id}" -H 'Auth-API-Token: '${auth_api_token} | cut -d ',' -f 4 | cut -d '"' -f 4` + display_help() { cat < Date: Sun, 26 Jul 2020 11:56:21 +0200 Subject: [PATCH 5/7] [hetzner-api-dyndns-2007250936] ttl and type fix --- dyndns.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/dyndns.sh b/dyndns.sh index 55e2059..b98066b 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -6,10 +6,6 @@ auth_api_token='' record_ttl='60' record_type='A' -cur_pub_addr=`curl -s https://ifconfig.me` -cur_dyn_addr=`curl -s "https://dns.hetzner.com/api/v1/records/${record_id}" -H 'Auth-API-Token: '${auth_api_token} | cut -d ',' -f 4 | cut -d '"' -f 4` - - display_help() { cat < Date: Sun, 26 Jul 2020 12:13:55 +0200 Subject: [PATCH 6/7] [hetzner-api-dyndns-2007250936] update readme --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- dyndns.sh | 2 +- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c8c809c..6fc020d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A small script to dynamically update DNS records using the Hetzner DNS-API. Feel free to propose changes. -**Hetzner DNS API Doc** +**Hetzner DNS API Doc:** https://dns.hetzner.com/api-docs/ @@ -11,15 +11,15 @@ https://dns.hetzner.com/api-docs/ First, a new access token must be created in the DNS Console. This should be copied immediately, because for security reasons it will not be possible to display the token later. ## Get all Zones -Get all zones and copy zone ID +Get all zones and copy the desired zone ID. ``` curl "https://dns.hetzner.com/api/v1/zones" -H \ 'Auth-API-Token: ${apitoken}' ``` ## Add Record -Use the previously obtained zone id to create a dns record. -In the output you get the record ID. This is needed in the script and should therefore be noted. +Use the previously obtained zone ID to create a dns record. +In the output you get the record ID. This is needed for the script and should therefore be noted. ``` curl -X "POST" "https://dns.hetzner.com/api/v1/records" \ -H 'Content-Type: application/json' \ @@ -34,12 +34,45 @@ curl -X "POST" "https://dns.hetzner.com/api/v1/records" \ ``` # Usage -Insert the Access token and the Zone and Record ID in the script. +For security reasons, the access token is stored directly in the script. Enter your previously created token here. +``` +... +auth_api_token='' +... +``` + +As soon as the token is deposited, the script can be called with the appropriate parameters. This allows several DynDNS records to be created in different zones. Optionally, the TTL and the record type can be specified. It is advisable to keep the TTL as low as possible, so that changed records are used as soon as possible. +``` +./dyndns.sh -z -r -n [-t ] [-T ] +``` + +To keep your DynDNS Records up to date, you have to create a cronjob that calls the script periodically. -To keep your DynDNS Records up to date, you create a cronjob that calls the script periodically. -It is advisable to keep the TTL as low as possible, so that changed records are used as soon as possible. +**Example:** Check DynDNS every 5 Minutes ``` -api_auth_token=${apitoken} -api_zone=${zoneID} -api_record=${recordID} -``` \ No newline at end of file +*/5 0 * * * /usb/bin/dyndns.sh -z 98jFjsd8dh1GHasdf7a8hJG7 -r AHD82h347fGAF1 -n dyn +``` + +# Help +Type `-h` to display help page. +``` +./dyndns -h +``` +``` +exec: ./dyndns.sh -z -r -n + +parameters: + -z - Zone ID + -r - Record ID + -n - Record name + +optional parameters: + -t - TTL (Default: 60) + -T - Record type (Default: A) + +help: + -h - Show Help + +example: + .exec: ./dyndns.sh -z 98jFjsd8dh1GHasdf7a8hJG7 -r AHD82h347fGAF1 -n dyn +``` \ No newline at end of file diff --git a/dyndns.sh b/dyndns.sh index b98066b..a1617bc 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -24,7 +24,7 @@ help: -h - Show Help example: - .exec: ./dyndns.sh -z 98jFjsd8dh1GH7 -r AHD82h347fGAF1 -n dyn + .exec: ./dyndns.sh -z 98jFjsd8dh1GHasdf7a8hJG7 -r AHD82h347fGAF1 -n dyn EOF exit 1 From a90e67a812f700ef10776dd95eb716663699ec54 Mon Sep 17 00:00:00 2001 From: Marcel Fliegel Date: Sun, 26 Jul 2020 12:15:01 +0200 Subject: [PATCH 7/7] [hetzner-api-dyndns-2007250936] whitespace --- dyndns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dyndns.sh b/dyndns.sh index a1617bc..ee84308 100755 --- a/dyndns.sh +++ b/dyndns.sh @@ -89,4 +89,4 @@ else else echo "DNS record \"${record_name}\" updated successfully" fi -fi \ No newline at end of file +fi