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

4 Commits

Author SHA1 Message Date
3d76946db5 minor: 📝 update CHANGELOG 2022-11-21 16:15:10 +01:00
0448d698ae minor: increase version 2022-11-21 16:12:08 +01:00
2ac50d326f fix: handle some curl exit codes 2022-11-21 16:09:12 +01:00
327e896754 feat: use provider checkip API 2022-11-21 10:45:16 +01:00
2 changed files with 119 additions and 38 deletions

View File

@@ -1,6 +1,17 @@
# 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) ## 0.5.0 (2022-11-10)
### Features ### Features

148
dynb.sh
View File

@@ -53,24 +53,24 @@ _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.5.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
@@ -295,25 +295,27 @@ 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 ip from $current_check_server" 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=$?
@@ -363,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
@@ -424,6 +426,7 @@ function prepare_request_parameters
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_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
@@ -480,15 +483,15 @@ function prepare_ip_flag_parameters
debugMessage "IPv4 enabled: $_is_IPv4_enabled; IPv6 enabled: $_is_IPv6_enabled; has remote IPv4: $_has_remote_ip4; has remote IPv6: $_has_remote_ip6" 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 ]] 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 ]] || [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] && [[ $_has_remote_ip4 == true ]] && [[ $_has_remote_ip6 == 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 ]] || [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]] && [[ $_has_remote_ip4 == false ]] && [[ $_has_remote_ip6 == 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
} }
@@ -500,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
@@ -578,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
@@ -589,6 +597,26 @@ 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
{ {
@@ -601,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
@@ -619,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
;; ;;
@@ -627,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
;; ;;
@@ -649,34 +687,59 @@ 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
@@ -689,13 +752,13 @@ function ipHasChanged
case ${ip_version} in case ${ip_version} in
4) 4)
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)
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
@@ -703,8 +766,8 @@ function ipHasChanged
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
@@ -834,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
@@ -876,6 +939,13 @@ 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
} }
@@ -900,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