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

45 Commits

Author SHA1 Message Date
4e82eab9f4 doc: 📝 add labels to Dockerfile 2021-11-01 17:36:49 +01:00
ca2a5a0d62 feat: 🎨 colorful info, debug and error messages 2021-10-31 19:48:37 +01:00
06de559607 refactor: remove unused argbash fragment 2021-10-31 18:27:01 +01:00
c5cadfe544 📝 update CHANGELOG.md 2021-09-24 14:32:56 +02:00
c130ef6ac3 🔧 remove md-toc from pre-commit 2021-09-24 14:03:19 +02:00
31818ffec1 📝 document docker parameters 2021-09-24 14:00:45 +02:00
200c5b5d1a enable parameter extensions for docker run --interactive 2021-09-24 12:22:25 +02:00
4925be5405 add pre-commit hooks for markdown 2021-09-13 20:38:09 +02:00
f8df351fe9 🎨 lint README.md 2021-09-13 20:28:28 +02:00
fcdddde456 📝 change default dns server setting 2021-09-13 16:06:06 +02:00
e2ddda5ba7 🎨 add shfmt params to pre-commit check 2021-09-13 15:58:31 +02:00
24aa20be3b 🎨 fix shell style 2021-09-13 15:58:29 +02:00
d92cdb2652 🔧 handle dns server selection 2021-09-13 15:58:29 +02:00
4643331534 ♻️ seperate parsing logic 2021-09-13 15:58:29 +02:00
fa15700e5d change git hooks and add shfmt 2021-09-13 15:58:29 +02:00
43b09d7145 📝 update CHANGELOG 2021-09-13 15:58:29 +02:00
3b543754b3 ♻️ normalizing pre-commit configuration to a top-level map 2021-09-13 15:58:28 +02:00
040aec7472 ♻️ refactorings 2021-09-13 15:58:28 +02:00
eda5a69da2 add pre-commit git hook for shellcheck 2021-09-13 15:58:21 +02:00
01eaa30523 refactor: ♻️ remove unused help message 2021-09-12 22:00:46 +02:00
30c5373705 📝 update README.md 2021-04-23 22:16:59 +02:00
4e26ff135d 📝 document environment variables 2021-04-23 18:08:44 +02:00
be2f4f3862 ♻️ refactor: method extractions and other beautifications 2021-04-23 18:02:16 +02:00
93c1ed18d0 🐛 fix loop and error handling in case of connection issues 2021-04-23 12:00:35 +02:00
2c23b1de6e 📝 document example of an docker-compose.yml file 2021-04-22 22:30:08 +02:00
f9507929da add Dockerfile 2021-04-22 22:17:49 +02:00
30e77c9722 📝 document loop mode and dig as requirement 2021-04-22 22:10:11 +02:00
bb1d514b50 add loop mode 2021-04-22 21:55:25 +02:00
c02dc68f17 📝 update example of .env in README.md 2021-04-21 13:45:45 +02:00
dcf9f1e7a2 ♻️ refactor: rename environment variables 2021-04-21 13:04:59 +02:00
4d28f55ce9 add support for Duck DNS as DynDNS2 provider 2021-04-04 16:31:42 +02:00
b8565eb38f add support for deSEC as DynDNS2 provider 2021-04-04 11:24:13 +02:00
ab330e9731 add completion
 add man page
2021-04-03 17:35:26 +02:00
262f7c3709 replace getopt with argbash 2021-04-03 14:06:03 +02:00
5210c35400 ♻️ refactor, fix and debug error handling 2021-01-27 17:52:15 +01:00
522a0f99bb ♻️ refactor main code 2021-01-26 22:23:03 +01:00
3bf6b69ae8 add interpretaton of status codes and act accordingly 2021-01-26 21:43:07 +01:00
d139022295 make network interface configurable 2021-01-26 21:43:07 +01:00
8997835903 🐛 fix sourcing of config file
♻️ do some shellcheck fixes
2021-01-26 21:43:07 +01:00
d6dc223794 add DynDNS2 support for dynv6.com 2021-01-26 21:43:07 +01:00
dc12f71d00 📝 add CHANGELOG.md 2021-01-26 21:43:07 +01:00
5ba730cff1 add .gitchangelog.rc 2021-01-26 21:43:07 +01:00
1104cf8505 📝 add example.env 2021-01-26 21:43:07 +01:00
99a446f4c7 📝 write README.md 2021-01-26 21:42:21 +01:00
f056e96e25 add dynb.sh 2021-01-26 21:24:33 +01:00
3 changed files with 196 additions and 314 deletions

View File

@@ -82,34 +82,24 @@ ignore_regexps = [
## whenever you are tweaking this variable. ## whenever you are tweaking this variable.
## ##
section_regexps = [ section_regexps = [
('Features', [ ('New', [
r'^[fF]eat\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', r'^:sparkles\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]), ]),
('Added', [ ('Changes', [
r'^[aA]dd\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', r'^:wrench\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Changed', [
r'^[cC]hange\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Deprecated', [
r'^[dD]epricated\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Removed', [
r'^[rR]emove\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]), ]),
('Fix', [ ('Fix', [
r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', r'^:bug\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Security', [
r'^[sS]ec\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]), ]),
('Documentation', [ ('Documentation', [
r'^[dD]oc\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$', r'^:memo\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]), ]),
('Remove', [
r'^:fire\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Other', None ## Match all lines
#('Other', None ## Match all lines ),
# ),
] ]
@@ -158,7 +148,7 @@ body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip
## ##
## Available constructs are those listed in ``body_process`` doc. ## Available constructs are those listed in ``body_process`` doc.
subject_process = (strip | subject_process = (strip |
ReSub(r'^([cC]hg|[fF]ix|[nN]ew|[dD]oc|[fF]eat|[aA]dd|[cC]hange)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') | ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') |
SetIfEmpty("No commit message.") | ucfirst | final_dot) SetIfEmpty("No commit message.") | ucfirst | final_dot)

View File

@@ -1,16 +0,0 @@
name: Run shellcheck with reviewdog
on: [pull_request]
jobs:
shellcheck:
name: runner / shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: shellcheck
uses: reviewdog/action-shellcheck@v1.9.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
path: "."
pattern: "*.sh"
exclude: "./.git/*"

458
dynb.sh
View File

@@ -51,7 +51,6 @@ _network_interface=
###################################################### ######################################################
## You don't need to change the following variables ## ## You don't need to change the following variables ##
_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
_new_IPv4= _new_IPv4=
_new_IPv6= _new_IPv6=
_dns_records= _dns_records=
@@ -66,7 +65,7 @@ _response=
_statusHostname= _statusHostname=
_statusUsername= _statusUsername=
_statusPassword= _statusPassword=
_version=0.3.0 _version=0.1.2
_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
@@ -82,69 +81,43 @@ red_color_bg="\e[0;101m${expand_bg}"
bold="\e[1m" bold="\e[1m"
reset_color_modification="\e[0m" reset_color_modification="\e[0m"
REGEX_IPv4="^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$" function loopMode() {
REGEX_IPv6="^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$" if [[ $_loopMode -eq 1 ]]; then
return 0
function is_IPv4_address else
{ return 1
local ip=$1
if [[ $ip =~ $REGEX_IPv4 ]]
then return 0
else return 1
fi fi
} }
function is_IPv6_address function debugMode() {
{ if [[ $_debug -eq 1 ]]; then
local ip=$1 return 0
if [[ $ip =~ $REGEX_IPv6 ]] else
then return 0 return 1
else return 1
fi fi
} }
function loopMode function infoMessage() {
{
if [[ $_loopMode -eq 1 ]]
then return 0
else return 1
fi
}
function debugMode
{
if [[ $_debug -eq 1 ]]
then return 0
else return 1
fi
}
function infoMessage
{
echo -e "${green_color}$(logtime) INFO: $*${reset_color_modification}" echo -e "${green_color}$(logtime) INFO: $*${reset_color_modification}"
} }
function debugMessage function debugMessage() {
{ if debugMode; then
if debugMode echo -e "${yellow_color}$(logtime) DEBUG: ${*}${reset_color_modification}"
then echo -e "${yellow_color}$(logtime) DEBUG: ${*}${reset_color_modification}"
fi fi
} }
function errorMessage function errorMessage() {
{
echo -e "${red_color_bg}${bold}$(logtime) ERROR: $*${reset_color_modification}" >&2 echo -e "${red_color_bg}${bold}$(logtime) ERROR: $*${reset_color_modification}" >&2
} }
function logtime function logtime() {
{
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$LOGTIME]" echo "[$LOGTIME]"
} }
# 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=$( request=$(
echo "{}" | echo "{}" |
jq '(.method="nameserver.list")' | jq '(.method="nameserver.list")' |
@@ -163,8 +136,7 @@ function getMainDomain
_main_domain=$(echo "$_response" | jq --raw-output '.domain') _main_domain=$(echo "$_response" | jq --raw-output '.domain')
} }
function fetchDNSRecords function fetchDNSRecords() {
{
request=$( request=$(
echo "{}" | echo "{}" |
jq '(.method="'nameserver.info'")' | jq '(.method="'nameserver.info'")' |
@@ -188,34 +160,27 @@ function fetchDNSRecords
# requires parameter A or AAAA # requires parameter A or AAAA
# result to stdout # result to stdout
function getRecordID function getRecordID() {
{ echo "$_dns_records" | jq "select(.type == \"${1}\") | .id"
echo "$_dns_records" |
jq "select(.type == \"${1}\") | .id"
} }
# requires parameter A or AAAA # requires parameter A or AAAA
# result to stdout # result to stdout
function getDNSIP() { function getDNSIP() {
echo "$_dns_records" | echo "$_dns_records" | jq --raw-output "select(.type == \"${1}\") | .content"
jq --raw-output "select(.type == \"${1}\") | .content"
} }
# requires parameter # requires parameter
# 1. param: 4 or 6 for ip version # 1. param: 4 or 6 for ip version
# 2. param: IP check server address # 2. param: IP check server address
# result to stdout # result to stdout
function getRemoteIP function getRemoteIP() {
{ if [[ -n $_DNS_checkServer ]]; then
local ip_version=$1
local ip_check_server=$2
if [[ -n $_DNS_checkServer ]]
then
curl --silent "$_interface_str" --user-agent "$_userAgent" \ curl --silent "$_interface_str" --user-agent "$_userAgent" \
--ipv"${ip_version}" --dns-servers "$_DNS_checkServer" --location "${ip_check_server}" --ipv"${1}" --dns-servers "$_DNS_checkServer" --location "${2}"
else else
curl --silent "$_interface_str" --user-agent "$_userAgent" \ curl --silent "$_interface_str" --user-agent "$_userAgent" \
--ipv"${ip_version}" --location "${ip_check_server}" --ipv"${1}" --location "${2}"
fi fi
# shellcheck disable=2181 # shellcheck disable=2181
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
@@ -226,21 +191,16 @@ function getRemoteIP
# requires parameter # requires parameter
# 1. param: 4 or 6 as ip version # 1. param: 4 or 6 as ip version
function updateRecord function updateRecord() {
{ if [[ ${1} == 4 ]]; then
local ip_version=$1
if [[ ${ip_version} == 4 ]]
then
ID=$(getRecordID A) ID=$(getRecordID A)
IP=$_new_IPv4 IP=$_new_IPv4
fi fi
if [[ ${ip_version} == 6 ]] if [[ ${1} == 6 ]]; then
then
ID=$(getRecordID AAAA) ID=$(getRecordID AAAA)
IP=$_new_IPv6 IP=$_new_IPv6
fi fi
if [[ $IP != "" ]] if [[ $IP != "" ]]; then
then
request=$( request=$(
echo "{}" | echo "{}" |
jq '(.method="nameserver.updateRecord")' | jq '(.method="nameserver.updateRecord")' |
@@ -259,13 +219,12 @@ function updateRecord
--request POST $_INWX_JSON_API_URL \ --request POST $_INWX_JSON_API_URL \
--data "$request" --data "$request"
) )
infoMessage "$(echo "$_response" | jq --raw-output '.msg')\n Domain: $DYNB_DYN_DOMAIN\n New IPv${1}: $IP" echo -e "$(echo "$_response" | jq --raw-output '.msg')\n Domain: $DYNB_DYN_DOMAIN\n new IPv${1}: $IP"
fi fi
} }
# using DynDNS2 protocol # using DynDNS2 protocol
function dynupdate function dynupdate() {
{
# default parameter values # default parameter values
myip_str=myip myip_str=myip
myipv6_str=myipv6 myipv6_str=myipv6
@@ -401,14 +360,12 @@ function dynupdate
esac esac
} }
function setStatus function setStatus() {
{
echo "_status=$1; _eventTime=$2; _errorCounter=$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
nochg*) nochg*)
if [[ _errorCounter -gt 1 ]]; then if [[ _errorCounter -gt 1 ]]; then
@@ -421,7 +378,8 @@ 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
rm "$_statusFile"
fi fi
return 0 return 0
;; ;;
@@ -429,7 +387,8 @@ function checkStatus
if [[ "$_statusUsername" == "$DYNB_USERNAME" && "$_statusPassword" == "$DYNB_PASSWORD" ]]; then if [[ "$_statusUsername" == "$DYNB_USERNAME" && "$_statusPassword" == "$DYNB_PASSWORD" ]]; then
errorMessage "Invalid username password combination." errorMessage "Invalid username password combination."
return 1 return 1
else rm "$_statusFile" else
rm "$_statusFile"
fi fi
return 0 return 0
;; ;;
@@ -453,20 +412,20 @@ function checkStatus
;; ;;
911 | 5*) 911 | 5*)
delta=$(($(date +%s) - _eventTime)) delta=$(($(date +%s) - _eventTime))
if [[ $delta -lt 1800 ]] 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." 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."
return 1 return 1
else rm "$_statusFile" else
rm "$_statusFile"
fi fi
return 0 return 0
;; ;;
*) *)
if [[ _errorCounter -gt 1 ]] if [[ _errorCounter -gt 1 ]]; 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
else return 0 else
return 0
fi fi
;; ;;
esac esac
@@ -474,192 +433,178 @@ function checkStatus
# requires parameter # requires parameter
# 1. param: 4 or 6 for IP version # 1. param: 4 or 6 for IP version
function ipHasChanged function ipHasChanged() {
{ case ${1} in
local ip_version=$1
case ${ip_version} in
4) 4)
remote_ip=$(getRemoteIP 4 $_ipv4_checker) remote_ip=$(getRemoteIP 4 $_ipv4_checker)
if ! is_IPv4_address "$remote_ip" if [[ $DYNB_UPDATE_METHOD == domrobot ]]; then
then dns_ip=$(getDNSIP A)
errorMessage "The response from the IP check server is not an IPv4 address: $remote_ip"
return 1
fi
if [[ $DYNB_UPDATE_METHOD == domrobot ]]
then dns_ip=$(getDNSIP A)
else else
if [[ -n $_DNS_checkServer ]] if [[ -n $_DNS_checkServer ]]; then
then dig_response=$(dig @"${_DNS_checkServer}" in a +short "$DYNB_DYN_DOMAIN") dig_response=$(dig @"${_DNS_checkServer}" in a +short "$DYNB_DYN_DOMAIN")
else dig_response=$(dig in a +short "$DYNB_DYN_DOMAIN") else
dig_response=$(dig in a +short "$DYNB_DYN_DOMAIN")
fi fi
if [[ $dig_response == ";; connection timed out; no servers could be reached" ]] if [[ $dig_response == ";; connection timed out; no servers could be reached" ]]; then
then
errorMessage "DNS request failed $dig_response" errorMessage "DNS request failed $dig_response"
return 1 return 0
fi fi
# If the dns resolver lists multiple records in the answer section we filter the first line dns_ip=$dig_response
# using short option "-n" and not "--lines" because of alpines limited BusyBox head command
dns_ip=$(echo "$dig_response" | head -n 1)
fi fi
_new_IPv4=$remote_ip _new_IPv4=$remote_ip
debugMessage "IPv4 from remote IP check server: $_new_IPv4, IPv4 from DNS: $dns_ip" debugMessage "New IPv4: $_new_IPv4 old was: $dns_ip"
;; ;;
6) 6)
remote_ip=$(getRemoteIP 6 $_ipv6_checker) remote_ip=$(getRemoteIP 6 $_ipv6_checker)
if ! is_IPv6_address "$remote_ip" if [[ $DYNB_UPDATE_METHOD == domrobot ]]; then
then dns_ip=$(getDNSIP AAAA)
errorMessage "The response from the IP check server is not an IPv6 address: $remote_ip"
return 1
fi
if [[ $DYNB_UPDATE_METHOD == domrobot ]]
then dns_ip=$(getDNSIP AAAA)
else else
if [[ -n $_DNS_checkServer ]] if [[ -n $_DNS_checkServer ]]; then
then dig_response=$(dig @"${_DNS_checkServer}" in aaaa +short "$DYNB_DYN_DOMAIN") dig_response=$(dig @"${_DNS_checkServer}" in aaaa +short "$DYNB_DYN_DOMAIN")
else dig_response=$(dig in aaaa +short "$DYNB_DYN_DOMAIN") else
dig_response=$(dig in aaaa +short "$DYNB_DYN_DOMAIN")
fi fi
exitcode=$? if [[ $dig_response == ";; connection timed out; no servers could be reached" ]]; then
if [[ $exitcode -gt 0 ]] errorMessage "DNS request failed $dig_response"
then return 0
errorMessage "DNS request failed with exit code: $exitcode $dig_response"
return 1
fi fi
# If the dns server lists multiple records in the answer section we filter the first line dns_ip=$dig_response
dns_ip=$(echo "$dig_response" | head -n 1)
fi fi
_new_IPv6=$remote_ip _new_IPv6=$remote_ip
debugMessage "IPv6 from remote IP check server: $_new_IPv6, IPv4 from DNS: $dns_ip" debugMessage "New IPv6: $_new_IPv6 old was: $dns_ip"
;; ;;
*) ;; *) ;;
esac esac
if [[ "$remote_ip" == "$dns_ip" ]] if [[ "$remote_ip" == "$dns_ip" ]]; then
then return 1
else
case ${ip_version} in
4) infoMessage "New IPv4: $_new_IPv4 old was: $dns_ip";;
6) infoMessage "New IPv6: $_new_IPv6 old was: $dns_ip";;
esac
return 0 return 0
else
return 1
fi fi
} }
function handleParameters ################
{ ## parameters ##
################
function handleParameters() {
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_version == "on" ]] if [[ $_arg_version == "on" ]]; then
then echo $_version; exit 0 echo $_version
exit 0
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_link == "on" ]] if [[ $_arg_link == "on" ]]; then
then ln --verbose --symbolic "$(realpath "$0")" "$HOME/.local/bin/dynb"; exit 0 ln --verbose --symbolic "$(realpath "$0")" "$HOME/.local/bin/dynb"
exit 0
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_reset == "on" ]] && test -f "$_statusFile" if [[ $_arg_reset == "on" ]]; then
then rm --verbose "$_statusFile"; exit 0 rm --verbose "$_statusFile"
exit 0
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_debug == "on" ]] if [[ $_arg_debug == "on" ]]; then
then _debug=1 _debug=1
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_update_method != "" ]] if [[ $_arg_update_method != "" ]]; then
then DYNB_UPDATE_METHOD=$_arg_update_method DYNB_UPDATE_METHOD=$_arg_update_method
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_ip_mode != "" ]] if [[ $_arg_ip_mode != "" ]]; then
then DYNB_IP_MODE=$_arg_ip_mode DYNB_IP_MODE=$_arg_ip_mode
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_domain != "" ]] if [[ $_arg_domain != "" ]]; then
then DYNB_DYN_DOMAIN=$_arg_domain DYNB_DYN_DOMAIN=$_arg_domain
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_service_provider != "" ]] if [[ $_arg_service_provider != "" ]]; then
then DYNB_SERVICE_PROVIDER=$_arg_service_provider DYNB_SERVICE_PROVIDER=$_arg_service_provider
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_username != "" ]] if [[ $_arg_username != "" ]]; then
then DYNB_USERNAME=$_arg_username DYNB_USERNAME=$_arg_username
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_password != "" ]] if [[ $_arg_password != "" ]]; then
then DYNB_PASSWORD=$_arg_password DYNB_PASSWORD=$_arg_password
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_token != "" ]] if [[ $_arg_token != "" ]]; then
then DYNB_TOKEN=$_arg_token DYNB_TOKEN=$_arg_token
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ $_arg_interval != "" ]] if [[ $_arg_interval != "" ]]; then
then DYNB_INTERVAL=$_arg_interval DYNB_INTERVAL=$_arg_interval
fi fi
if [[ -z $DYNB_INTERVAL ]] if [[ -z $DYNB_INTERVAL ]]; then
then _loopMode=0 _loopMode=0
elif [[ $DYNB_INTERVAL -lt _minimum_looptime ]] elif [[ $DYNB_INTERVAL -lt _minimum_looptime ]]; then
then
DYNB_INTERVAL=$_minimum_looptime DYNB_INTERVAL=$_minimum_looptime
_loopMode=1 _loopMode=1
else _loopMode=1 else
_loopMode=1
fi fi
if [[ $_network_interface != "" ]] if [[ $_network_interface != "" ]]; then
then _interface_str="--interface $_network_interface" _interface_str="--interface $_network_interface"
fi fi
if [[ $DYNB_IP_MODE == d* ]] if [[ $DYNB_IP_MODE == d* ]]; then
then
_is_IPv4_enabled=true _is_IPv4_enabled=true
_is_IPv6_enabled=true _is_IPv6_enabled=true
fi fi
if [[ $DYNB_IP_MODE == *4* ]] if [[ $DYNB_IP_MODE == *4* ]]; then
then _is_IPv4_enabled=true _is_IPv4_enabled=true
fi fi
if [[ $DYNB_IP_MODE == *6* ]] if [[ $DYNB_IP_MODE == *6* ]]; then
then _is_IPv6_enabled=true _is_IPv6_enabled=true
fi fi
if [[ $DYNB_DEBUG == true ]] if [[ $DYNB_DEBUG == true ]]; then
then _debug=1 _debug=1
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ -n $DYNB_IPv4_CHECK_SITE ]] if [[ -n $DYNB_IPv4_CHECK_SITE ]]; then
then _ipv4_checker=$DYNB_IPv4_CHECK_SITE _ipv4_checker=$DYNB_IPv4_CHECK_SITE
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [[ -n $DYNB_IPv6_CHECK_SITE ]] if [[ -n $DYNB_IPv6_CHECK_SITE ]]; then
then _ipv6_checker=$DYNB_IPv6_CHECK_SITE _ipv6_checker=$DYNB_IPv6_CHECK_SITE
fi fi
if [[ -n $DYNB_DNS_CHECK_SERVER ]] if [[ -n $DYNB_DNS_CHECK_SERVER ]]; then
then _DNS_checkServer=$DYNB_DNS_CHECK_SERVER _DNS_checkServer=$DYNB_DNS_CHECK_SERVER
fi fi
return 0 return 0
} }
function checkDependencies ##################
{ ## dependencies ##
##################
function checkDependencies() {
failCounter=0 failCounter=0
for i in curl dig; do for i in curl dig; do
if ! command -v $i >/dev/null 2>&1 if ! command -v $i >/dev/null 2>&1; then
then
errorMessage "could not find \"$i\", DynB depends on it. " errorMessage "could not find \"$i\", DynB depends on it. "
((failCounter++)) ((failCounter++))
fi fi
done done
[[ -x $(command -v jq 2>/dev/null) ]] || { [[ -x $(command -v jq 2>/dev/null) ]] || {
if [[ $DYNB_UPDATE_METHOD != dyndns* ]] if [[ $DYNB_UPDATE_METHOD != dyndns* ]]; then
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
((failCounter++)) ((failCounter++))
fi fi
} }
if [[ failCounter -gt 0 ]] if [[ failCounter -gt 0 ]]; then
then exit 1 exit 1
fi fi
} }
function doUnsets function doUnsets() {
{
unset _network_interface unset _network_interface
unset _DNS_checkServer unset _DNS_checkServer
unset _dns_records unset _dns_records
@@ -687,121 +632,83 @@ function doUnsets
unset DYNB_DEBUG unset DYNB_DEBUG
} }
function doDomrobotUpdates function doDomrobotUpdates() {
{
getMainDomain getMainDomain
fetchDNSRecords fetchDNSRecords
if [[ $_is_IPv4_enabled == true ]] if [[ $_is_IPv4_enabled == true ]]; then
then ipHasChanged 4
if ipHasChanged 4 if [[ $? == 1 ]]; then
then updateRecord 4 updateRecord 4
else debugMessage "Skip IPv4 record update, it is already up to date" else
debugMessage "Skip IPv4 record update, it is already up to date"
fi fi
fi fi
if [[ $_is_IPv6_enabled == true ]] if [[ $_is_IPv6_enabled == true ]]; then
then ipHasChanged 6
if ipHasChanged 6 if [[ $? == 1 ]]; then
then updateRecord 6 updateRecord 6
else debugMessage "Skip IPv6 record update, it is already up to date" else
debugMessage "Skip IPv6 record update, it is already up to date"
fi fi
fi fi
} }
function doDynDNS2Updates function doDynDNS2Updates() {
{
changed=0 changed=0
if [[ $_is_IPv4_enabled == true ]] && ipHasChanged 4 if [[ $_is_IPv4_enabled == true ]]; then
then ((changed += 1)) ipHasChanged 4
((changed += $?))
fi fi
if [[ $_is_IPv6_enabled == true ]] && ipHasChanged 6 if [[ $_is_IPv6_enabled == true ]]; then
then ((changed += 1)) ipHasChanged 6
((changed += $?))
fi fi
if [[ $changed -gt 0 ]] if [[ $changed -gt 0 ]]; then
then if checkStatus; then
if checkStatus
then
debugMessage "checkStatus has no errors, try update" debugMessage "checkStatus has no errors, try update"
if dynupdate if dynupdate; then
then debugMessage "DynDNS2 update success" debugMessage "DynDNS2 update success"
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 "$_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
else debugMessage "Skip DynDNS2 update, IPs are up to date or there is a connection problem" else
debugMessage "Skip DynDNS2 update, IPs are up to date or there is a connection problem"
fi fi
} }
function doUpdates function doUpdates() {
{ if [[ $DYNB_UPDATE_METHOD == "domrobot" ]]; then
if [[ $DYNB_UPDATE_METHOD == "domrobot" ]] doDomrobotUpdates
then doDomrobotUpdates fi
elif [[ $DYNB_UPDATE_METHOD == "dyndns" ]]
then doDynDNS2Updates if [[ $DYNB_UPDATE_METHOD == "dyndns" ]]; then
doDynDNS2Updates
fi fi
} }
function ipv6_is_not_working #################
{ ## MAIN method ##
curl --ipv6 --head --silent --max-time 5 $_internet_connectivity_test_server > /dev/null #################
status_code=$? function dynb() {
if test $status_code -gt 0
then return 0
else return 1
fi
}
function ipv4_is_not_working
{
curl --ipv4 --head --silent --max-time 5 $_internet_connectivity_test_server > /dev/null
status_code=$?
if test $status_code -gt 0
then return 0
else return 1
fi
}
function check_internet_connection
{
if [[ $_is_IPv4_enabled == true ]]
then
if ipv4_is_not_working
then
_is_IPv4_enabled="false"
errorMessage "Your IPv4 internet connection does not work."
fi
fi
if [[ $_is_IPv6_enabled == true ]]
then
if ipv6_is_not_working
then
_is_IPv6_enabled="false"
errorMessage "Your IPv6 internet connection does not work."
fi
fi
}
function main
{
# shellcheck disable=SC1091,SC1090 # shellcheck disable=SC1091,SC1090
source "$(dirname "$(realpath "$0")")/dynb-parsing.sh" source "$(dirname "$(realpath "$0")")/dynb-parsing.sh"
# shellcheck source=.env # shellcheck source=.env
if test -f "$_configFile" if test -f "$_configFile"; then
then
# shellcheck disable=SC1091 # shellcheck disable=SC1091
source "$_configFile" source "$_configFile"
else else
alternativeConfig="$(dirname "$(realpath "$0")")/.env" alternativeConfig="$(dirname "$(realpath "$0")")/.env"
if test -f "$alternativeConfig" if test -f "$alternativeConfig"; then
then
# shellcheck disable=SC1091 # shellcheck disable=SC1091
source "$alternativeConfig" source "$alternativeConfig"
fi fi
fi fi
if test -f "$_statusFile" if test -f "$_statusFile"; then
then
debugMessage "read previous status file" debugMessage "read previous status file"
# shellcheck disable=SC1090 # shellcheck disable=SC1090
source "$_statusFile" source "$_statusFile"
@@ -810,21 +717,22 @@ function main
## parameters and checks ## parameters and checks
handleParameters handleParameters
checkDependencies checkDependencies
check_internet_connection
if loopMode if loopMode; then
then while :; do
while :
do
doUpdates doUpdates
sleep $DYNB_INTERVAL sleep $DYNB_INTERVAL
done done
else doUpdates else
doUpdates
fi fi
doUnsets doUnsets
return 0 return 0
} }
######################
## END MAIN section ##
######################
main "${@}" dynb "${@}"
exit $? exit $?