1
0
mirror of https://github.com/EV21/dynb.git synced 2025-12-26 16:39:32 +01:00

9 Commits

3 changed files with 252 additions and 104 deletions

View File

@@ -1,6 +1,30 @@
# Changelog # Changelog
## 0.5.1 (2022-11-21)
### Features
* Use provider checkip API. [Eduard Veit]
### Fix
* Handle some curl exit codes. [Eduard Veit]
## 0.5.0 (2022-11-10)
### Features
* Use provider DNS servers. [Eduard Veit]
* Temporarily disable an ip version if the connectivity/routing does not work. [Eduard Veit]
### Documentation
* 📝 update default values in table. [Eduard Veit]
## 0.4.0 (2022-11-07) ## 0.4.0 (2022-11-07)
### Features ### Features

View File

@@ -24,15 +24,15 @@ IPv4 (A) and IPv6 (AAAA) record updates are supported.
The following update methods are currently implemented: The following update methods are currently implemented:
| Provider | API | TTL in seconds | Credentials | own domain via NS record | free (sub-) domain | | Provider | API | TTL in seconds | Credentials | own domain via NS record | free (sub-) domain |
|---------------------|-----------------------|----------------|----------------------------------------------------------------------------------------------|--------------------------|------------------------------------------------| |---------------------|-----------------------|----------------|----------------------------------------------------------------------------------------------|------------------------------------------|--------------------------------------|
| INWX.com | Domrobot JSON-RPC-API | 300 | customer login `username` & `password`. Mobile TAN (OTP) is currently not supported by DynB. | ✔️ | ⛔ choose one of your owned domains | | INWX.com | Domrobot JSON-RPC-API | 300 | customer login `username` & `password`. Mobile TAN (OTP) is currently not supported by DynB. | ✔️ 🆓 for your registered domains @ inwx | ⛔ for your registered domains @ inwx |
| INWX.com | DynDNS2 | 60 | specific dyndns `username` & `password` | ✔️ | ⛔ choose one of your owned domains per account | | INWX.com | DynDNS2 | 60 | specific dyndns `username` & `password` | ✔️ 🆓 for your registered domains @ inwx | ⛔ for your registered domains @ inwx |
| deSEC.io (dedyn.io) | DynDNS2 | 60 | `token` | ✔️ | ✔️ | | deSEC.io (dedyn.io) | DynDNS2 | 60 | `token` | ✔️ 🆓 | ✔️ |
| DuckDNS.org | DynDNS2 | 60 | `token` | ⛔ | ✔️ | | DuckDNS.org | DynDNS2 | 60 | `token` | ⛔ | ✔️ |
| dynv6.com | DynDNS2 | 60 | `token` | ✔️ | ✔️ | | dynv6.com | DynDNS2 | 60 | `token` | ✔️ 🆓 | ✔️ |
| ddnss.de | DynDNS2 | 10 | `update key` as `token` | ⛔ | ✔️ | | ddnss.de | DynDNS2 | 10 | `update key` as `token` | ⛔ | ✔️ |
| IPv64.net | DynDNS2 | 60 | `DynDNS Updatehash` as `token` | | ✔️ | | IPv64.net | DynDNS2 | 60 | `DynDNS Updatehash` as `token` | ✔️ 💲 | ✔️ |
| dynu.com | DynDNS2 | 30 | `username` & `password` | ✔️ | ✔️ | | dynu.com | DynDNS2 | 30 | `username` & `password` | ✔️ 🆓 | ✔️ |
## 📦 Requirements ## 📦 Requirements
@@ -175,7 +175,7 @@ services:
## environment variables ## environment variables
| variable | default value | description | | variable | default value | description |
|-----------------------|-----------------|----------------------------------------------------------------------------------------------------------------| |-----------------------|--------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
| DYNB_DYN_DOMAIN | undefined | required; `dyndns.example.com` | | DYNB_DYN_DOMAIN | undefined | required; `dyndns.example.com` |
| DYNB_SERVICE_PROVIDER | undefined | required; `deSEC`, `duckdns`, `dynv6`, `inwx`, `ddnss`, `ipv64` | | DYNB_SERVICE_PROVIDER | undefined | required; `deSEC`, `duckdns`, `dynv6`, `inwx`, `ddnss`, `ipv64` |
| DYNB_UPDATE_METHOD | undefined | required; `dyndns` or `domrobot` (with inwx) | | DYNB_UPDATE_METHOD | undefined | required; `dyndns` or `domrobot` (with inwx) |
@@ -185,6 +185,6 @@ services:
| DYNB_TOKEN | undefined | the requirement depends on your provider and the update method | | DYNB_TOKEN | undefined | the requirement depends on your provider and the update method |
| DYNB_INTERVAL | undefined | without this setting the script/docker container will run one time and exits | | DYNB_INTERVAL | undefined | without this setting the script/docker container will run one time and exits |
| DYNB_DEBUG | undefined | more console outputs | | DYNB_DEBUG | undefined | more console outputs |
| DYNB_IPv4_CHECK_SITE | api64.ipify.org | You need a website or Web-API that outputs your remote IP | | DYNB_IPv4_CHECK_SITE | tries in this order `ip64.ev21.de` (anonymous logging for 7 days), `api64.ipify.org`, `api.my-ip.io/ip`, `ip.anysrc.net/plain` | You need a website or Web-API that outputs your remote IP |
| DYNB_IPv6_CHECK_SITE | api64.ipify.org | You need a website or Web-API that outputs your remote IP | | DYNB_IPv6_CHECK_SITE | tries in this order `ip64.ev21.de` (anonymous logging for 7 days), `api64.ipify.org`, `api.my-ip.io/ip`, `ip.anysrc.net/plain` | You need a website or Web-API that outputs your remote IP |
| DYNB_DNS_CHECK_SERVER | undefined | If you are using a local DNS Resolver/Server make sure it answers with the public answer or set another server | | DYNB_DNS_CHECK_SERVER | using the DynDNS2 providers DNS servers | If you are using a local DNS Resolver/Server make sure it answers with the public answer or set another server |

266
dynb.sh
View File

@@ -53,30 +53,35 @@ _network_interface=
_INWX_JSON_API_URL=https://api.domrobot.com/jsonrpc/ _INWX_JSON_API_URL=https://api.domrobot.com/jsonrpc/
_internet_connectivity_test_server=https://www.google.de _internet_connectivity_test_server=https://www.google.de
_default_check_ip_servers=("ip64.ev21.de" "api64.ipify.org" "api.my-ip.io/ip" "ip.anysrc.net/plain")
_ipv4_checker= _ipv4_checker=
_ipv6_checker= _ipv6_checker=
_DNS_checkServer= _DNS_checkServer=
_new_IPv4= _remote_IPv4=
_new_IPv6= _remote_IPv6=
_dns_records= _dns_records=
_main_domain= _main_domain=
_is_IPv4_enabled=false _is_IPv4_enabled=false
_is_IPv6_enabled=false _is_IPv6_enabled=false
_interface_str= _interface_str=
_status=
_eventTime=0 _eventTime=0
_errorCounter=0 _errorCounter=0
_response= _response=
_statusHostname= _statusHostname=
_statusUsername= _statusUsername=
_statusPassword= _statusPassword=
_version=0.4.0 _version=0.5.1
_userAgent="DynB/$_version github.com/EV21/dynb" _userAgent="DynB/$_version github.com/EV21/dynb"
_configFile=$HOME/.local/share/dynb/.env _configFile=$HOME/.local/share/dynb/.env
_statusFile=/tmp/dynb.status _statusFile=/tmp/dynb.status
_debug=false _debug=false
_minimum_looptime=60 _minimum_looptime=60
_loopMode=false _loopMode=false
_remote_ip=
_dns_ip=
_has_remote_ip_error=
_has_remote_ip4=false
_has_remote_ip6=false
# Ansi color code variables # Ansi color code variables
yellow_color="\e[0;33m" yellow_color="\e[0;33m"
@@ -220,24 +225,22 @@ function getRecordID
jq "select(.type == \"${1}\") | .id" jq "select(.type == \"${1}\") | .id"
} }
## getDNSIP A ## do_dig_request A B
# requires parameter A or AAAA # sets variable: _dns_ip
# result to stdout #
function getDNSIP() { # requires parameter
local record_type=$1 # 1. param: dns server address
if [[ $DYNB_UPDATE_METHOD == domrobot ]] # 2. param: A or AAAA
then function do_dig_request
echo "$_dns_records" | {
jq --raw-output "select(.type == \"${record_type}\") | .content" local dns_server=$1
else local record_type=$2
if [[ -n $_DNS_checkServer ]] dig_response=$(dig @"$dns_server" in "$record_type" +short "$DYNB_DYN_DOMAIN")
then dig_response=$(dig @"${_DNS_checkServer}" in "$record_type" +short "$DYNB_DYN_DOMAIN")
else dig_response=$(dig in "$record_type" +short "$DYNB_DYN_DOMAIN")
fi
dig_exitcode=$? dig_exitcode=$?
if [[ $dig_exitcode -gt 0 ]] if [[ $dig_exitcode -gt 0 ]]
then then
errorMessage "DNS request failed with exit code: $dig_exitcode $dig_response" errorMessage "DNS request failed with exit code: $dig_exitcode $dig_response"
unset _dns_ip
return 1 return 1
else else
case $record_type in case $record_type in
@@ -247,56 +250,86 @@ function getDNSIP() {
;; ;;
esac esac
if test $? -gt 0 if test $? -gt 0
then return 1 then
test -n "$dig_response" || debugMessage "dig response: $dig_response"
unset _dns_ip
return 1
fi fi
fi fi
# If the dns resolver lists multiple records in the answer section we filter the first line # If the dns resolver lists multiple records in the answer section we filter the first line
# using short option "-n" and not "--lines" because of alpines limited BusyBox head command # using short option "-n" and not "--lines" because of alpines limited BusyBox head command
echo "$dig_response" | head -n 1 _dns_ip=$(echo "$dig_response" | head -n 1)
return 0
}
## getDNSIP A
# sets variable: _dns_ip
#
# requires parameter
# 1. param: A or AAAA
function getDNSIP() {
local record_type=$1
if [[ $DYNB_UPDATE_METHOD == domrobot ]]
then
echo "$_dns_records" |
jq --raw-output "select(.type == \"${record_type}\") | .content"
else
for current_dns_server in "${provider_dns_servers[@]}"
do
debugMessage "try dig DNS request with record type $record_type @$current_dns_server"
if do_dig_request "$current_dns_server" "$record_type"
then break
fi
done
fi fi
} }
_has_remote_ip_error=false ## getRemoteIP A
# sets variable: _remote_ip,
#
# requires parameter # requires parameter
# 1. param: 4 or 6 for ip version # 1. param: 4 or 6 for ip version
#
# result to stdout # result to stdout
function getRemoteIP function getRemoteIP
{ {
local ip_version=$1 local ip_version=$1
default_ip_check_servers=("ip64.ev21.de" "api64.ipify.org" "api.my-ip.io/ip" "ip.anysrc.net/plain") if test -n "$_provider_check_ip"
then ip_check_servers=("$_provider_check_ip" "${_default_check_ip_servers[@]}")
fi
case $ip_version in case $ip_version in
4) 4)
if test -n "$_ipv4_checker" if test -n "$_ipv4_checker"
then ip_check_servers=("$_ipv4_checker" "${default_ip_check_servers[@]}") then ip_check_servers=("$_ipv4_checker" "${_default_check_ip_servers[@]}")
else ip_check_servers=("${default_ip_check_servers[@]}") else ip_check_servers=("${_default_check_ip_servers[@]}")
fi fi
;; ;;
6) 6)
if test -n "$_ipv6_checker" if test -n "$_ipv6_checker"
then ip_check_servers=("$_ipv6_checker" "${default_ip_check_servers[@]}") then ip_check_servers=("$_ipv6_checker" "${_default_check_ip_servers[@]}")
else ip_check_servers=("${default_ip_check_servers[@]}") else ip_check_servers=("${_default_check_ip_servers[@]}")
fi fi
;; ;;
esac esac
for current_check_server in "${ip_check_servers[@]}" for current_check_server in "${ip_check_servers[@]}"
do do
debugMessage "try getting remote IPv$ip_version via $current_check_server"
response=$(curl --silent "$_interface_str" --user-agent "$_userAgent" \ response=$(curl --silent "$_interface_str" --user-agent "$_userAgent" \
--ipv"${ip_version}" --location "${current_check_server}") --ipv"${ip_version}" --location "${current_check_server}")
curls_status_code=$? curls_status_code=$?
# shellcheck disable=2181 # shellcheck disable=2181
if [[ $curls_status_code -gt 0 ]] if [[ $curls_status_code -gt 0 ]]
then then
errorMessage "Remote IPv$ip_version request failed with ${current_check_server}" errorMessage "Remote IPv$ip_version request failed with ${current_check_server} curl status code: $curls_status_code"
_has_remote_ip_error=true _has_remote_ip_error=true
return_value=1 return_value=1
else else
if is_ip_address "$ip_version" "$response" if is_ip_address "$ip_version" "$response"
then then
_has_remote_ip_error=false _has_remote_ip_error=false
echo "$response" _remote_ip="$response"
return_value=0 return_value=0
break break
else else
@@ -307,6 +340,20 @@ function getRemoteIP
fi fi
done done
case $ip_version in
4)
if [[ $_has_remote_ip_error == true ]]
then _has_remote_ip4=false
else _has_remote_ip4=true
fi
;;
6)
if [[ $_has_remote_ip_error == true ]]
then export _has_remote_ip6=false
else export _has_remote_ip6=true
fi
;;
esac
return $return_value return $return_value
} }
@@ -318,12 +365,12 @@ function updateRecord
if [[ ${ip_version} == 4 ]] if [[ ${ip_version} == 4 ]]
then then
ID=$(getRecordID A) ID=$(getRecordID A)
IP=$_new_IPv4 IP=$_remote_IPv4
fi fi
if [[ ${ip_version} == 6 ]] if [[ ${ip_version} == 6 ]]
then then
ID=$(getRecordID AAAA) ID=$(getRecordID AAAA)
IP=$_new_IPv6 IP=$_remote_IPv6
fi fi
if [[ $IP != "" ]] if [[ $IP != "" ]]
then then
@@ -364,11 +411,13 @@ function prepare_request_parameters
curl_parameters+=("--user" "$DYNB_USERNAME:$DYNB_PASSWORD") curl_parameters+=("--user" "$DYNB_USERNAME:$DYNB_PASSWORD")
curl_parameters+=("--get") # inwx will ignore the ipv6 parameter if you don't put it into the url curl_parameters+=("--get") # inwx will ignore the ipv6 parameter if you don't put it into the url
dyndns_update_url="https://dyndns.inwx.com/nic/update" dyndns_update_url="https://dyndns.inwx.com/nic/update"
provider_dns_servers=("ns.inwx.de" "ns2.inwx.de" "ns3.inwx.eu")
;; ;;
[Dd][Yy][Nn][Uu]*) [Dd][Yy][Nn][Uu]*)
curl_parameters+=("--user" "$DYNB_USERNAME:$DYNB_PASSWORD") curl_parameters+=("--user" "$DYNB_USERNAME:$DYNB_PASSWORD")
curl_parameters+=("--get") curl_parameters+=("--get")
dyndns_update_url="https://api.dynu.com/nic/update" dyndns_update_url="https://api.dynu.com/nic/update"
provider_dns_servers=("NS11.dynu.com" "NS10.dynu.com" "NS12.dynu.com")
;; ;;
[Dd][Ee][Ss][Ee][Cc]* | [Dd][Ee][Dd][Yy][Nn]* ) [Dd][Ee][Ss][Ee][Cc]* | [Dd][Ee][Dd][Yy][Nn]* )
# deSEC.de / dedyn.io # deSEC.de / dedyn.io
@@ -376,6 +425,8 @@ function prepare_request_parameters
curl_parameters+=("--get") curl_parameters+=("--get")
curl_parameters+=("--data-urlencode" "hostname=$DYNB_DYN_DOMAIN") curl_parameters+=("--data-urlencode" "hostname=$DYNB_DYN_DOMAIN")
dyndns_update_url="https://update.dedyn.io" dyndns_update_url="https://update.dedyn.io"
provider_dns_servers=("ns1.desec.io" "ns2.desec.org")
_provider_check_ip="https://checkip.dedyn.io" # checkipv4 and checkipv6 is also available
;; ;;
[Dd][Yy][Nn][Vv]6*) [Dd][Yy][Nn][Vv]6*)
# dynv6.com # dynv6.com
@@ -385,6 +436,7 @@ function prepare_request_parameters
curl_parameters+=("--data-urlencode" "zone=$DYNB_DYN_DOMAIN") curl_parameters+=("--data-urlencode" "zone=$DYNB_DYN_DOMAIN")
curl_parameters+=("--data-urlencode" "token=$DYNB_TOKEN") curl_parameters+=("--data-urlencode" "token=$DYNB_TOKEN")
dyndns_update_url="https://dynv6.com/api/update" dyndns_update_url="https://dynv6.com/api/update"
provider_dns_servers=("ns1.dynv6.com" "ns2.dynv6.com" "ns3.dynv6.com")
;; ;;
[Dd][Uu][Cc][Kk][Dd][Nn][Ss]*) [Dd][Uu][Cc][Kk][Dd][Nn][Ss]*)
# DuckDNS.org # DuckDNS.org
@@ -394,6 +446,7 @@ function prepare_request_parameters
curl_parameters+=("--data-urlencode" "domains=$DYNB_DYN_DOMAIN") curl_parameters+=("--data-urlencode" "domains=$DYNB_DYN_DOMAIN")
curl_parameters+=("--data-urlencode" "token=$DYNB_TOKEN") curl_parameters+=("--data-urlencode" "token=$DYNB_TOKEN")
dyndns_update_url="https://www.duckdns.org/update" dyndns_update_url="https://www.duckdns.org/update"
provider_dns_servers=("ns1.duckdns.org" "ns2.duckdns.org")
;; ;;
[Dd][Dd][Nn][Ss][Ss]*) [Dd][Dd][Nn][Ss][Ss]*)
# ddnss.de # ddnss.de
@@ -403,6 +456,7 @@ function prepare_request_parameters
curl_parameters+=("--data-urlencode" "host=$DYNB_DYN_DOMAIN") curl_parameters+=("--data-urlencode" "host=$DYNB_DYN_DOMAIN")
curl_parameters+=("--data-urlencode" "key=$DYNB_TOKEN") curl_parameters+=("--data-urlencode" "key=$DYNB_TOKEN")
dyndns_update_url="https://ddnss.de/upd.php" dyndns_update_url="https://ddnss.de/upd.php"
provider_dns_servers=("ns1.ddnss.de" "ns2.ddnss.de" "ns3.ddnss.de")
;; ;;
[Ii][Pp][Vv]64*) [Ii][Pp][Vv]64*)
# IPv64.net # IPv64.net
@@ -412,30 +466,32 @@ function prepare_request_parameters
curl_parameters+=("--header" "Authorization: Bearer $DYNB_TOKEN") curl_parameters+=("--header" "Authorization: Bearer $DYNB_TOKEN")
curl_parameters+=("--data-urlencode" "domain=$DYNB_DYN_DOMAIN") curl_parameters+=("--data-urlencode" "domain=$DYNB_DYN_DOMAIN")
dyndns_update_url="https://ipv64.net/nic/update" dyndns_update_url="https://ipv64.net/nic/update"
provider_dns_servers=("ns1.IPv64.net" "ns2.IPv64.net")
;; ;;
*) *)
errorMessage "$DYNB_SERVICE_PROVIDER is not supported" errorMessage "$DYNB_SERVICE_PROVIDER is not supported"
exit 1 exit 1
;; ;;
esac esac
if test -n "$_DNS_checkServer"
prepare_ip_flag_parameters then provider_dns_servers=("$_DNS_checkServer" "${provider_dns_servers[@]}")
curl_parameters+=("${ip_flag_parameters[@]}") fi
} }
function prepare_ip_flag_parameters function prepare_ip_flag_parameters
{ {
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] debugMessage "IPv4 enabled: $_is_IPv4_enabled; IPv6 enabled: $_is_IPv6_enabled; has remote IPv4: $_has_remote_ip4; has remote IPv6: $_has_remote_ip6"
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] && [[ $_has_remote_ip4 == true ]] && [[ $_has_remote_ip6 == true ]]
then then
ip_flag_parameters=("--data-urlencode" "${ipv4_parameter_name}=${_new_IPv4}" "--data-urlencode" "${ipv6_parameter_name}=${_new_IPv6}") ip_flag_parameters=("--data-urlencode" "${ipv4_parameter_name}=${_remote_IPv4}" "--data-urlencode" "${ipv6_parameter_name}=${_remote_IPv6}")
fi fi
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == false ]] if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == false ]] || [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] && [[ $_has_remote_ip4 == true ]] && [[ $_has_remote_ip6 == false ]]
then then
ip_flag_parameters=("--data-urlencode" "${ipv4_parameter_name}=${_new_IPv4}") ip_flag_parameters=("--data-urlencode" "${ipv4_parameter_name}=${_remote_IPv4}")
fi fi
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]] if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]] || [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] && [[ $_has_remote_ip4 == false ]] && [[ $_has_remote_ip6 == true ]]
then then
ip_flag_parameters=("--data-urlencode" "${ipv6_parameter_name}=${_new_IPv6}") ip_flag_parameters=("--data-urlencode" "${ipv6_parameter_name}=${_remote_IPv6}")
fi fi
} }
@@ -447,6 +503,7 @@ function send_request
curl --silent "$_interface_str" \ curl --silent "$_interface_str" \
"${curl_parameters[@]}" \ "${curl_parameters[@]}" \
"${dyndns_update_url}") "${dyndns_update_url}")
_curl_exit_code=$?
analyse_response analyse_response
status_code=$? status_code=$?
return $status_code return $status_code
@@ -525,7 +582,11 @@ function analyse_response
return 1 return 1
;; ;;
*) *)
if [[ "$_response" == "$_status" ]]; then if test $_curl_exit_code -gt 0
then
analyse_curl_exit_code $_curl_exit_code
return $?
elif test -n "$_response" && [[ "$_response" == "$_previous_response_was" ]]; then
errorMessage "An unknown response code has been received: $_response" errorMessage "An unknown response code has been received: $_response"
return 1 return 1
else else
@@ -536,10 +597,31 @@ function analyse_response
esac esac
} }
function analyse_curl_exit_code
{
local current_curl_exit_code=$1
case $current_curl_exit_code in
6)
errorMessage "curl exit code: $_curl_exit_code; Couldn't resolve host: $dyndns_update_url"
;;
7)
errorMessage "curl exit code: $_curl_exit_code; Failed to connect to host: $dyndns_update_url"
;;
22)
errorMessage "curl exit code: $_curl_exit_code HTTP error code being 400 or above"
;;
*)
errorMessage "curl exit code: $_curl_exit_code"
;;
esac
return "$current_curl_exit_code"
}
# using DynDNS2 protocol # using DynDNS2 protocol
function dynupdate function dynupdate
{ {
prepare_request_parameters prepare_ip_flag_parameters
curl_parameters+=("${ip_flag_parameters[@]}")
send_request send_request
request_status=$? request_status=$?
return $request_status return $request_status
@@ -547,15 +629,25 @@ function dynupdate
function setStatus function setStatus
{ {
echo "_status=$1; _eventTime=$2; _errorCounter=$3; _statusHostname=$4; _statusUsername=$5; _statusPassword=$6" >/tmp/dynb.status echo "_curl_exit_code_was=$1; _previous_response_was=$2 _eventTime=$3; _errorCounter=$4; _statusHostname=$5; _statusUsername=$6; _statusPassword=$7" >/tmp/dynb.status
} }
declare _previous_response_was
declare _curl_exit_code_was
# handle errors from past update requests # handle errors from past update requests
function checkStatus function checkStatus
{ {
case $_status in local check_string
if [[ -z "${_previous_response_was}" ]]
then check_string=$_curl_exit_code_was
else check_string=$_previous_response_was
fi
case $check_string in
*nochg*) *nochg*)
if [[ _errorCounter -gt 1 ]]; then if [[ _errorCounter -gt 1 ]]
then
errorMessage "The update client was spamming unnecessary update requests, something might be wrong with your IP-Check site." errorMessage "The update client was spamming unnecessary update requests, something might be wrong with your IP-Check site."
errorMessage "Fix your config and then delete $_statusFile or restart your docker container" errorMessage "Fix your config and then delete $_statusFile or restart your docker container"
return 1 return 1
@@ -565,7 +657,7 @@ function checkStatus
if [[ "$_statusHostname" == "$DYNB_DYN_DOMAIN" && ("$_statusUsername" == "$DYNB_USERNAME" || $_statusUsername == "$DYNB_TOKEN") ]]; then if [[ "$_statusHostname" == "$DYNB_DYN_DOMAIN" && ("$_statusUsername" == "$DYNB_USERNAME" || $_statusUsername == "$DYNB_TOKEN") ]]; then
errorMessage "Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request." errorMessage "Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
return 1 return 1
else rm "$_statusFile" else delete_status_file
fi fi
return 0 return 0
;; ;;
@@ -573,7 +665,7 @@ function checkStatus
if [[ "$_statusUsername" == "$DYNB_USERNAME" && ("$_statusPassword" == "$DYNB_PASSWORD" || $_statusPassword == "$DYNB_TOKEN") ]]; then if [[ "$_statusUsername" == "$DYNB_USERNAME" && ("$_statusPassword" == "$DYNB_PASSWORD" || $_statusPassword == "$DYNB_TOKEN") ]]; then
errorMessage "Invalid username password combination." errorMessage "Invalid username password combination."
return 1 return 1
else rm "$_statusFile" else delete_status_file
fi fi
return 0 return 0
;; ;;
@@ -595,63 +687,87 @@ function checkStatus
return 1 return 1
;; ;;
servererror | 911 | 5* | *'Too Many Requests'*) servererror | 911 | 5* | *'Too Many Requests'*)
delta=$(($(date +%s) - _eventTime)) if check_delay 30
if [[ $delta -lt 1800 ]]
then then
errorMessage "$_status: The provider currently has an fatal error. DynB will wait for next update until 30 minutes have passed since last request, $(date --date=@$delta -u +%M) minutes already passed." delete_status_file
return 1
else rm "$_statusFile"
fi
return 0 return 0
else
errorMessage "$_previous_response_was: The provider currently has a fatal error."
return 1
fi
;; ;;
*'Bad Request'*) *'Bad Request'*)
if [[ "$_statusUsername" == "$DYNB_USERNAME" && ("$_statusPassword" == "$DYNB_PASSWORD" || $_statusPassword == "$DYNB_TOKEN") ]]; then if [[ "$_statusUsername" == "$DYNB_USERNAME" && ("$_statusPassword" == "$DYNB_PASSWORD" || $_statusPassword == "$DYNB_TOKEN") ]]
then
errorMessage "Bad Request: Please check your credentials, maybe your token is invalid." errorMessage "Bad Request: Please check your credentials, maybe your token is invalid."
return 1 return 1
else rm "$_statusFile" else delete_status_file
fi fi
return 0 return 0
;; ;;
*) *)
if [[ _errorCounter -gt 1 ]] if [[ $_errorCounter -gt 1 ]] && [[ "$_curl_exit_code_was" -eq 0 ]]
then then
errorMessage "An unknown response code has repeatedly been received. $_response" errorMessage "An unknown response code has repeatedly been received. $_response"
return 1 return 1
elif [[ $_errorCounter -gt 1 ]] && [[ "$_curl_exit_code_was" -eq 7 ]]
then
if check_delay 15
then
delete_status_file
return 0
else return 1
fi
else return 0 else return 0
fi fi
;; ;;
esac esac
} }
function check_delay
{
local minutes=$1
local seconds=$(( minutes * 60 ))
delta=$(($(date +%s) - _eventTime))
if [[ $delta -lt $seconds ]]
then
errorMessage "DynB only executes an update when $minutes minutes have passed since the last failed request, $(date --date=@$delta -u +%M) minutes have already passed."
if loopMode
then sleep $seconds
else return 1
fi
else return 0
fi
}
# requires parameter # requires parameter
# 1. param: 4 or 6 for IP version # 1. param: 4 or 6 for IP version
function ipHasChanged function ipHasChanged
{ {
local ip_version=$1 local ip_version=$1
remote_ip=$(getRemoteIP "$ip_version") getRemoteIP "$ip_version"
if test $? -gt 0 if test $? -gt 0
then return 1 then return 1
fi fi
case ${ip_version} in case ${ip_version} in
4) 4)
dns_ip=$(getDNSIP A) getDNSIP A
_new_IPv4=$remote_ip _remote_IPv4=$_remote_ip
debugMessage "IPv4 from remote IP check server: $_new_IPv4, IPv4 from DNS: $dns_ip" debugMessage "IPv4 from remote IP check server: $_remote_IPv4, IPv4 from DNS: $_dns_ip"
;; ;;
6) 6)
dns_ip=$(getDNSIP AAAA) getDNSIP AAAA
_new_IPv6=$remote_ip _remote_IPv6=$_remote_ip
debugMessage "IPv6 from remote IP check server: $_new_IPv6, IPv6 from DNS: $dns_ip" debugMessage "IPv6 from remote IP check server: $_remote_IPv6, IPv6 from DNS: $_dns_ip"
;; ;;
*) ;;
esac esac
if [[ "$remote_ip" == "$dns_ip" ]] if [[ "$_remote_ip" == "$_dns_ip" ]]
then return 1 then return 1
else else
case ${ip_version} in case ${ip_version} in
4) infoMessage "New IPv4: $_new_IPv4 old was: $dns_ip";; 4) infoMessage "Remote IPv4: $_remote_IPv4 DNS IPv4: $_dns_ip";;
6) infoMessage "New IPv6: $_new_IPv6 old was: $dns_ip";; 6) infoMessage "Remote IPv6: $_remote_IPv6 DNS IPv6: $_dns_ip";;
esac esac
return 0 return 0
fi fi
@@ -781,8 +897,8 @@ function doUnsets
unset _is_IPv4_enabled unset _is_IPv4_enabled
unset _is_IPv6_enabled unset _is_IPv6_enabled
unset _main_domain unset _main_domain
unset _new_IPv4 unset _remote_IPv4
unset _new_IPv6 unset _remote_IPv6
unset _version unset _version
unset DYNB_DYN_DOMAIN unset DYNB_DYN_DOMAIN
unset DYNB_USERNAME unset DYNB_USERNAME
@@ -823,11 +939,19 @@ function delete_status_file
then then
debugMessage "Delete status file with previous errors" debugMessage "Delete status file with previous errors"
rm "$_statusFile" rm "$_statusFile"
unset _curl_exit_code_was
unset _previous_response_was
unset _eventTime
unset _errorCounter
unset _statusHostname
unset _statusUsername
unset _statusPassword
fi fi
} }
function doDynDNS2Updates function doDynDNS2Updates
{ {
prepare_request_parameters
changed=0 changed=0
if [[ $_is_IPv4_enabled == true ]] && ipHasChanged 4 if [[ $_is_IPv4_enabled == true ]] && ipHasChanged 4
then ((changed += 1)) then ((changed += 1))
@@ -835,7 +959,7 @@ function doDynDNS2Updates
if [[ $_is_IPv6_enabled == true ]] && ipHasChanged 6 if [[ $_is_IPv6_enabled == true ]] && ipHasChanged 6
then ((changed += 1)) then ((changed += 1))
fi fi
if [[ $changed -gt 0 ]] && [[ $_has_remote_ip_error == false ]] if [[ $changed -gt 0 ]]
then then
if checkStatus if checkStatus
then then
@@ -846,7 +970,7 @@ function doDynDNS2Updates
delete_status_file delete_status_file
else else
debugMessage "Save new status after dynupdate has failed" debugMessage "Save new status after dynupdate has failed"
setStatus "$_response" "$(date +%s)" $((_errorCounter += 1)) "$DYNB_DYN_DOMAIN" "${DYNB_USERNAME}" "${DYNB_PASSWORD}${DYNB_TOKEN}" setStatus "$_curl_exit_code" "$_response" "$(date +%s)" $((_errorCounter += 1)) "$DYNB_DYN_DOMAIN" "${DYNB_USERNAME}" "${DYNB_PASSWORD}${DYNB_TOKEN}"
fi fi
else debugMessage "Skip DynDNS2 update, checkStatus fetched previous error." else debugMessage "Skip DynDNS2 update, checkStatus fetched previous error."
fi fi