mirror of
https://github.com/EV21/dynb.git
synced 2025-12-26 16:39:32 +01:00
fix: 🐛 fix error handling
This commit is contained in:
215
dynb.sh
215
dynb.sh
@@ -40,6 +40,7 @@ TTL=300
|
|||||||
_ipv4_checker=api64.ipify.org
|
_ipv4_checker=api64.ipify.org
|
||||||
_ipv6_checker=api64.ipify.org
|
_ipv6_checker=api64.ipify.org
|
||||||
|
|
||||||
|
## An exernal DNS check server prevents wrong info from local DNS servers/resolvers
|
||||||
_DNS_checkServer=1.1.1.1
|
_DNS_checkServer=1.1.1.1
|
||||||
|
|
||||||
## if you are actively using multiple network interfaces you might want to specify this
|
## if you are actively using multiple network interfaces you might want to specify this
|
||||||
@@ -60,7 +61,8 @@ _is_IPv6_enabled=false
|
|||||||
_interface_str=
|
_interface_str=
|
||||||
_status=
|
_status=
|
||||||
_eventTime=0
|
_eventTime=0
|
||||||
_counter=0
|
_errorCounter=0
|
||||||
|
_response=
|
||||||
_statusHostname=
|
_statusHostname=
|
||||||
_statusUsername=
|
_statusUsername=
|
||||||
_statusPassword=
|
_statusPassword=
|
||||||
@@ -68,18 +70,7 @@ _version=0.0.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=1
|
||||||
function echoerr() { printf "%s\n" "$*" >&2; }
|
|
||||||
|
|
||||||
for i in curl jq date; do
|
|
||||||
if ! command -v $i >/dev/null 2>&1; then
|
|
||||||
echoerr "Error: could not find \"$i\", DynB depends on it. "
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
[[ -x $(command -v getopt 2> /dev/null) ]] || {
|
|
||||||
_has_getopt=false
|
|
||||||
}
|
|
||||||
|
|
||||||
_help_message="$(cat << 'EOF'
|
_help_message="$(cat << 'EOF'
|
||||||
dynb - dynamic DNS update script for bash
|
dynb - dynamic DNS update script for bash
|
||||||
@@ -109,6 +100,22 @@ dynb --ip-mode dual --update-method dyndns --service-provider inwx --domain dynd
|
|||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
|
|
||||||
|
function debugMode() {
|
||||||
|
if [[ $_debug -eq 1 ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugMessage() {
|
||||||
|
if debugMode; then
|
||||||
|
echo "Debug: ${1}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function echoerr() { printf "%s\n" "$*" >&2; }
|
||||||
|
|
||||||
# The main domain as an identifier for the dns zone is required for the updateRecord call
|
# The main domain as an identifier for the dns zone is required for the updateRecord call
|
||||||
function getMainDomain() {
|
function getMainDomain() {
|
||||||
request=$( echo "{}" | \
|
request=$( echo "{}" | \
|
||||||
@@ -117,14 +124,14 @@ function getMainDomain() {
|
|||||||
jq "(.params.pass=\"$_password\")"
|
jq "(.params.pass=\"$_password\")"
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl --silent \
|
_response=$(curl --silent \
|
||||||
"$_interface_str" \
|
"$_interface_str" \
|
||||||
--user-agent "$_userAgent" \
|
--user-agent "$_userAgent" \
|
||||||
--header "Content-Type: application/json" \
|
--header "Content-Type: application/json" \
|
||||||
--request POST $_INWX_JSON_API_URL \
|
--request POST $_INWX_JSON_API_URL \
|
||||||
--data "$request" | jq ".resData.domains[] | select(inside(.domain=\"$_dyn_domain\"))"
|
--data "$request" | jq ".resData.domains[] | select(inside(.domain=\"$_dyn_domain\"))"
|
||||||
)
|
)
|
||||||
_main_domain=$( echo "$response" | jq --raw-output '.domain' )
|
_main_domain=$( echo "$_response" | jq --raw-output '.domain' )
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchDNSRecords() {
|
function fetchDNSRecords() {
|
||||||
@@ -136,7 +143,7 @@ function fetchDNSRecords() {
|
|||||||
jq "(.params.name=\"$_dyn_domain\")"
|
jq "(.params.name=\"$_dyn_domain\")"
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$( curl --silent \
|
_response=$( curl --silent \
|
||||||
"$_interface_str" \
|
"$_interface_str" \
|
||||||
--user-agent "$_userAgent" \
|
--user-agent "$_userAgent" \
|
||||||
--header "Content-Type: application/json" \
|
--header "Content-Type: application/json" \
|
||||||
@@ -144,7 +151,7 @@ function fetchDNSRecords() {
|
|||||||
--data "$request"
|
--data "$request"
|
||||||
)
|
)
|
||||||
|
|
||||||
_dns_records=$( echo "$response" | jq '.resData.record[]' )
|
_dns_records=$( echo "$_response" | jq '.resData.record[]' )
|
||||||
}
|
}
|
||||||
|
|
||||||
# requires parameter A or AAAA
|
# requires parameter A or AAAA
|
||||||
@@ -189,14 +196,14 @@ function updateRecord() {
|
|||||||
jq "(.params.ttl=\"$TTL\")"
|
jq "(.params.ttl=\"$TTL\")"
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl --silent \
|
_response=$(curl --silent \
|
||||||
"$_interface_str" \
|
"$_interface_str" \
|
||||||
--user-agent "$_userAgent" \
|
--user-agent "$_userAgent" \
|
||||||
--header "Content-Type: application/json" \
|
--header "Content-Type: application/json" \
|
||||||
--request POST $_INWX_JSON_API_URL \
|
--request POST $_INWX_JSON_API_URL \
|
||||||
--data "$request"
|
--data "$request"
|
||||||
)
|
)
|
||||||
echo -e "$(echo "$response" | jq --raw-output '.msg')\n Domain: $_dyn_domain\n new IPv${1}: $IP"
|
echo -e "$(echo "$_response" | jq --raw-output '.msg')\n Domain: $_dyn_domain\n new IPv${1}: $IP"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,136 +234,155 @@ function dynupdate() {
|
|||||||
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]]; then
|
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]]; then
|
||||||
dyndns_update_url="${dyndns_update_url}${myipv6_str}=${_new_IPv6}"
|
dyndns_update_url="${dyndns_update_url}${myipv6_str}=${_new_IPv6}"
|
||||||
fi
|
fi
|
||||||
|
debugMessage "Update URL was: $dyndns_update_url"
|
||||||
## request ##
|
## request ##
|
||||||
if [[ $_serviceProvider == "dynv6" ]]; then
|
if [[ $_serviceProvider == "dynv6" ]]; then
|
||||||
response=$(curl --silent "$_interface_str" \
|
_response=$(curl --silent "$_interface_str" \
|
||||||
--user-agent "$_userAgent" \
|
--user-agent "$_userAgent" \
|
||||||
"${dyndns_update_url}"
|
"${dyndns_update_url}"
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
if [[ $_serviceProvider == "inwx" ]]; then
|
if [[ $_serviceProvider == "inwx" ]]; then
|
||||||
response=$(curl --silent "$_interface_str" \
|
_response=$(curl --silent "$_interface_str" \
|
||||||
--user-agent "$_userAgent" \
|
--user-agent "$_userAgent" \
|
||||||
--user "$_username":"$_password" \
|
--user "$_username":"$_password" \
|
||||||
"${dyndns_update_url}" )
|
"${dyndns_update_url}" )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case $response in
|
case $_response in
|
||||||
good* )
|
good* )
|
||||||
if [[ $response == "good 127.0.0.1" ]]; then
|
if [[ $_response == "good 127.0.0.1" ]]; then
|
||||||
echoerr "Error: $response: Request ignored."
|
echoerr "Error: $_response: Request ignored."
|
||||||
|
return 1
|
||||||
else
|
else
|
||||||
echo "$response: The DynDNS update has been executed."
|
echo "$_response: The DynDNS update has been executed."
|
||||||
|
_errorCounter=0
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
return
|
|
||||||
;;
|
;;
|
||||||
nochg* )
|
nochg* )
|
||||||
echo "$response: Nothing has changed, IP addresses are still up to date."
|
echo "$_response: Nothing has changed, IP addresses are still up to date."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
abuse )
|
abuse )
|
||||||
echoerr "Error: $response: Username is blocked due to abuse."
|
echoerr "Error: $_response: Username is blocked due to abuse."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
badauth )
|
badauth | 401 )
|
||||||
echoerr "Error: $response: Invalid username password combination."
|
echoerr "Error: $_response: Invalid username password combination."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
badagent )
|
badagent )
|
||||||
echoerr "Error: $response: Client disabled. Something is very wrong!"
|
echoerr "Error: $_response: Client disabled. Something is very wrong!"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
!donator )
|
!donator )
|
||||||
echoerr "Error: $response: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
echoerr "Error: $_response: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
!yours )
|
!yours )
|
||||||
echoerr "Error: $response: The domain does not belong to your user account"
|
echoerr "Error: $_response: The domain does not belong to your user account"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
notfqdn )
|
notfqdn )
|
||||||
echoerr "Error: $response: Hostname $_dyn_domain is invalid"
|
echoerr "Error: $_response: Hostname $_dyn_domain is invalid"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
nohost )
|
nohost )
|
||||||
echoerr "Error: $response: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
echoerr "Error: $_response: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
numhost )
|
numhost )
|
||||||
echoerr "Error: $response: Too many hostnames have been specified for this update"
|
echoerr "Error: $_response: Too many hostnames have been specified for this update"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
dnserr )
|
dnserr )
|
||||||
echoerr "Error: $response: There is an internal error in the dyndns update system"
|
echoerr "Error: $_response: There is an internal error in the dyndns update system. Retry update no sooner than 30 minutes."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
911 )
|
911 | 5* )
|
||||||
echoerr "Error: $response: A fatal error on provider side such as a database outage. Retry the update no sooner than 30 minutes."
|
echoerr "Error: $_response: A fatal error on provider side such as a database outage. Retry update no sooner than 30 minutes."
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
echo "$response"
|
if [[ "$_response" == "$_status" ]]; then
|
||||||
return
|
echoerr "Error: An unknown response code has been received. $_response"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echoerr "Error: unknown respnse code: $_response"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [[ $response != good ]]; then
|
|
||||||
setStatus "$response" "$(date +%s)" $(( _counter += 1 )) "$_dyn_domain" "${_username}${_token}"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus() {
|
function setStatus() {
|
||||||
echo "_status=$1; _eventTime=$2; _counter=$3; _statusHostname=$4; _statusUsername=$5; _statusPassword=$6" > /tmp/dynb.status
|
echo "_status=$1; _eventTime=$2; _errorCounter=$3; _statusHostname=$4; _statusUsername=$5; _statusPassword=$6" > /tmp/dynb.status
|
||||||
}
|
}
|
||||||
|
|
||||||
# handle errors from past update requests
|
# handle errors from past update requests
|
||||||
function checkStatus() {
|
function checkStatus() {
|
||||||
case $_status in
|
case $_status in
|
||||||
nohost )
|
nochg* )
|
||||||
|
if [[ _errorCounter -gt 1 ]]; then
|
||||||
|
echoerr "Error: The update client was spamming unnecessary update requests, something might be wrong with your IP-Check site."
|
||||||
|
echoerr "Fix your config an then delete $_statusFile"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
nohost | !yours )
|
||||||
if [[ "$_statusHostname" == "$_dyn_domain" && ( "$_statusUsername" == "$_username" || $_statusUsername == "$_token" ) ]]; then
|
if [[ "$_statusHostname" == "$_dyn_domain" && ( "$_statusUsername" == "$_username" || $_statusUsername == "$_token" ) ]]; then
|
||||||
echoerr "Error: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
echoerr "Error: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
||||||
exit 1
|
return 1
|
||||||
else
|
else
|
||||||
rm "$_statusFile"
|
rm "$_statusFile"
|
||||||
fi
|
fi
|
||||||
return
|
return 0
|
||||||
;;
|
;;
|
||||||
badauth )
|
badauth | 401 )
|
||||||
if [[ "$_statusUsername" == "$_username" && "$_statusPassword" == "$_password" ]]; then
|
if [[ "$_statusUsername" == "$_username" && "$_statusPassword" == "$_password" ]]; then
|
||||||
echoerr "Error: Invalid username password combination."
|
echoerr "Error: Invalid username password combination."
|
||||||
exit 1
|
return 1
|
||||||
else
|
else
|
||||||
rm "$_statusFile"
|
rm "$_statusFile"
|
||||||
fi
|
fi
|
||||||
return
|
return 0
|
||||||
;;
|
;;
|
||||||
badagent )
|
badagent )
|
||||||
echoerr "Error: Client is deactivated by provider."
|
echoerr "Error: Client is deactivated by provider."
|
||||||
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade."
|
||||||
exit 1
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
!donator )
|
!donator )
|
||||||
echoerr "Error: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
echoerr "Error: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
||||||
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
||||||
exit 1
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
abuse )
|
abuse )
|
||||||
echoerr "Error: Username is blocked due to abuse."
|
echoerr "Error: Username is blocked due to abuse."
|
||||||
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
||||||
exit 1
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
return
|
return 1
|
||||||
;;
|
;;
|
||||||
911 )
|
911 | 5* )
|
||||||
delta=$(( $(date +%s) - _eventTime ))
|
delta=$(( $(date +%s) - _eventTime ))
|
||||||
if [[ $delta -lt 1800 ]]; then
|
if [[ $delta -lt 1800 ]]; then
|
||||||
echoerr "$_status: The provider currently has an fatal error. DynB will wait $(date --date=@$delta -u +%M) minutes for next update until 30 minutes have passed since last request"
|
echoerr "$_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."
|
||||||
exit 1
|
return 1
|
||||||
else
|
else
|
||||||
rm "$_statusFile"
|
rm "$_statusFile"
|
||||||
fi
|
fi
|
||||||
return
|
return 0
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
if [[ _errorCounter -gt 1 ]]; then
|
||||||
|
echoerr "Error: An unknown response code has repeatedly been received. $_response"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -381,9 +407,6 @@ function ipHasChanged() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$remote_ip" == "$dns_ip" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
if [[ ${1} == 4 ]]; then
|
if [[ ${1} == 4 ]]; then
|
||||||
_new_IPv4=$remote_ip
|
_new_IPv4=$remote_ip
|
||||||
#echo "New IPv4: $_new_IPv4 old was: $dns_ip"
|
#echo "New IPv4: $_new_IPv4 old was: $dns_ip"
|
||||||
@@ -391,6 +414,10 @@ function ipHasChanged() {
|
|||||||
_new_IPv6=$remote_ip
|
_new_IPv6=$remote_ip
|
||||||
#echo "New IPv6: $_new_IPv6 old was: $dns_ip"
|
#echo "New IPv6: $_new_IPv6 old was: $dns_ip"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$remote_ip" == "$dns_ip" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -465,16 +492,20 @@ function processParameters() {
|
|||||||
##################
|
##################
|
||||||
|
|
||||||
function checkDependencies() {
|
function checkDependencies() {
|
||||||
[[ -x $(command -v curl 2> /dev/null) ]] || {
|
## If there will be more general dependencies use a loop
|
||||||
echo "This script depends on curl and it is not available." >&2
|
# for i in curl and some other stuff; do
|
||||||
exit 1
|
# if ! command -v $i >/dev/null 2>&1; then
|
||||||
}
|
# echoerr "Error: could not find \"$i\", DynB depends on it. "
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
# done
|
||||||
[[ -x $(command -v jq 2> /dev/null) ]] || {
|
[[ -x $(command -v jq 2> /dev/null) ]] || {
|
||||||
if [[ $_update_method != dyndns* ]]; then
|
if [[ $_update_method != dyndns* ]]; then
|
||||||
echo "This script depends on jq and it is not available." >&2
|
echo "This script depends on jq and it is not available." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
# maybe replace this with matejak/argbash
|
||||||
[[ -x $(command -v getopt 2> /dev/null) ]] || {
|
[[ -x $(command -v getopt 2> /dev/null) ]] || {
|
||||||
_has_getopt=false
|
_has_getopt=false
|
||||||
}
|
}
|
||||||
@@ -502,6 +533,9 @@ function doUnsets() {
|
|||||||
unset _version
|
unset _version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#################
|
||||||
|
## MAIN method ##
|
||||||
|
#################
|
||||||
function dynb() {
|
function dynb() {
|
||||||
## parameters and checks
|
## parameters and checks
|
||||||
checkDependencies
|
checkDependencies
|
||||||
@@ -518,6 +552,7 @@ function dynb() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test -f "$_statusFile"; then
|
if test -f "$_statusFile"; then
|
||||||
|
debugMessage "read previous status file"
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
source "$_statusFile"
|
source "$_statusFile"
|
||||||
fi
|
fi
|
||||||
@@ -571,15 +606,25 @@ function dynb() {
|
|||||||
(( changed += $? ))
|
(( changed += $? ))
|
||||||
fi
|
fi
|
||||||
if [[ $changed -gt 0 ]]; then
|
if [[ $changed -gt 0 ]]; then
|
||||||
dynupdate
|
if checkStatus; then
|
||||||
|
debugMessage "checkStatus has no errors"
|
||||||
|
if dynupdate; then
|
||||||
|
debugMessage "DynDNS2 update success"
|
||||||
|
else
|
||||||
|
debugMessage "Save new status after dynupdate has failed"
|
||||||
|
setStatus "$_response" "$(date +%s)" $(( _errorCounter += 1 )) "$_dyn_domain" "${_username}${_token}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debugMessage "Skip DynDNS2 update, checkStatus fetched previous error."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
doUnsets
|
doUnsets
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
##################
|
######################
|
||||||
## MAIN section ##
|
## END MAIN section ##
|
||||||
##################
|
######################
|
||||||
|
|
||||||
dynb "${@}"
|
dynb "${@}"
|
||||||
exit $?
|
exit $?
|
||||||
|
|||||||
Reference in New Issue
Block a user