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

16 Commits

Author SHA1 Message Date
2352d655a3 refactor(extract method): read_config_file 2022-06-30 14:28:08 +02:00
341d535f21 minor: 📝 update CHANGELOG 2022-06-30 13:57:27 +02:00
fc2c499daa minor: increase version 2022-06-30 13:52:48 +02:00
39d5143108 minor: lint tables in README 2022-06-30 13:51:01 +02:00
e58d87cf94 doc: 📝 update providers in README 2022-06-30 13:20:49 +02:00
9d41354695 feat: add support for ddnss.de as DynDNS2 provider 2022-06-30 09:46:40 +02:00
d8a298f58a minor: change .gitignore 2022-06-30 09:30:24 +02:00
3e89610e22 minor: response output as debug message 2022-06-30 09:30:24 +02:00
faa9c371c1 refactor: extract methods 2022-06-30 09:30:09 +02:00
11fccf2f0e minor: fix typo 2022-06-12 18:41:27 +02:00
75715cb0a8 minor: 📝 update CHANGELOG 2022-06-07 10:00:10 +02:00
6313ee4347 minor: set version 0.3.3 2022-06-07 09:58:10 +02:00
f37230401f fix: wrong parameter name for DuckDNS
Co-authored-by: Qrrbrbirlbel <Qrrbrbirlbel@users.noreply.github.com>
2022-06-06 22:26:40 +02:00
d6c98c04ad doc: 📝 add comments to docker-compose.yml example 2022-05-28 15:20:16 +02:00
64a5a76b6d minor: 📝 update CHANGELOG 2022-05-26 16:15:12 +02:00
05120c25e4 feat: add tzdata to Dockerfile for timezone config
You can now set your timezone with the environment variable
`TZ="Europe/Berlin"`
2022-05-26 16:10:47 +02:00
5 changed files with 155 additions and 66 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.env* .env*
docker-compose* docker-compose*
.vscode

View File

@@ -1,6 +1,48 @@
# Changelog # Changelog
## 0.3.4 (2022-06-30)
### Features
* ✨ add support for ddnss.de as DynDNS2 provider. [Eduard Veit]
### Documentation
* 📝 update providers in README. [Eduard Veit]
## 0.3.3 (2022-06-07)
### Fix
* Wrong parameter name for DuckDNS. [Eduard Veit]
### Documentation
* 📝 add comments to docker-compose.yml example. [Eduard Veit]
## 0.3.2 (2022-05-26)
### Features
* ✨ add tzdata to Dockerfile for timezone config. [Eduard Veit]
You can now set your timezone with the environment variable
`TZ="Europe/Berlin"`
## 0.3.1 (2022-05-26)
### Fix
* 🐛 curl/libcurl doesn't support dns-server option. [Eduard Veit]
the latest alpine we are using for the docker image
does also drops the support for that option like debian/ubuntu/etc
## 0.3.0 (2022-05-26) ## 0.3.0 (2022-05-26)
### Features ### Features

View File

@@ -7,7 +7,8 @@ apk add \
bash \ bash \
curl \ curl \
jq \ jq \
bind-tools bind-tools \
tzdata
WORKDIR /usr/src/app WORKDIR /usr/src/app

View File

@@ -7,8 +7,6 @@ IPv4 (A) and IPv6 (AAAA) record updates are supported.
<!-- TOC --> <!-- TOC -->
- [✨ Update Methods](#-update-methods) - [✨ Update Methods](#-update-methods)
- [APIs](#apis)
- [DynDNS2](#dyndns2)
- [📦 Requirements](#-requirements) - [📦 Requirements](#-requirements)
- [🚀 Installation](#-installation) - [🚀 Installation](#-installation)
- [⚙ Configuration](#-configuration) - [⚙ Configuration](#-configuration)
@@ -25,18 +23,14 @@ IPv4 (A) and IPv6 (AAAA) record updates are supported.
The following update methods are currently implemented: The following update methods are currently implemented:
### APIs | Provider | API | TTL in seconds | Credentials | own domain via NS record | free (sub-) domain |
|---------------------|-----------------------|----------------|----------------------------------------------------------------------------------------------|--------------------------|------------------------------------------------|
- INWX.com Domrobot JSON-RPC-API\ | 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 |
Limitations: | INWX.com | DynDNS2 | 60 | specific dyndns `username` & `password` | ✔️ | ⛔ choose one of your owned domains per account |
- minimum TTL is 300 (5 minutes) | deSEC.io (dedyn.io) | DynDNS2 | 60 | `token` | ✔️ | ✔️ |
| DuckDNS.org | DynDNS2 | 60 | `token` | ⛔ | ✔️ |
### DynDNS2 | dynv6.com | DynDNS2 | 60 | `token` | ✔️ | ✔️ |
| ddnss.de | DynDNS2 | 10 | update key as `token` | ⛔ | ✔️ |
- INWX.com
- deSEC.io (dedyn.io)
- DuckDNS.org
- dynv6.com
## 📦 Requirements ## 📦 Requirements
@@ -57,7 +51,7 @@ or simply clone this repo
git clone https://github.com/EV21/dynb.git git clone https://github.com/EV21/dynb.git
``` ```
If you want to add the script to you PATH, run :point_down: If you want to add the script to you PATH, run 👇
```shell ```shell
bash dynb.sh --link bash dynb.sh --link
@@ -79,7 +73,7 @@ DYNB_SERVICE_PROVIDER=inwx
## update method options: domrobot, dyndns ## update method options: domrobot, dyndns
DYNB_UPDATE_METHOD=domrobot DYNB_UPDATE_METHOD=domrobot
## ip mode could be either: 4, 6 or dual for dualstack ## ip mode could be either: 4, 6 or 64 for dualstack
DYNB_IP_MODE=64 DYNB_IP_MODE=64
## If you are using the DomRobot RPC-API enter your credentials for the web interface login here ## If you are using the DomRobot RPC-API enter your credentials for the web interface login here
@@ -92,14 +86,14 @@ DYNB_TOKEN=
## 🏃 Run ## 🏃 Run
If you have a config file just run :point_down: If you have a config file just run 👇
```bash ```bash
dynb dynb
``` ```
Alternatively you can use parameters if your system meets the relevant requirements. This example shows the long form parameter, there are also short ones.\ Alternatively you can use parameters if your system meets the relevant requirements. This example shows the long form parameter, there are also short ones.\
Call the help function :point_down: Call the help function 👇
```bash ```bash
dynb --help dynb --help
@@ -123,13 +117,13 @@ Just use the parameter `--interval 60` or the environment variable `DYNB_INTERVA
### crontab ### crontab
execute :point_down: execute 👇
```bash ```bash
crontab -e crontab -e
``` ```
then enter :point_down: to run dynb every five minutes. then add the following line 👇 to run dynb every five minutes.
```bash ```bash
*/5 * * * * $HOME/.local/bin/dynb >> $HOME/.local/share/dynb/dynb-cron.log */5 * * * * $HOME/.local/bin/dynb >> $HOME/.local/share/dynb/dynb-cron.log
@@ -155,25 +149,33 @@ services:
image: ev21/dynb image: ev21/dynb
container_name: dynb container_name: dynb
network_mode: host network_mode: host
build: stdin_open: true
context: . tty: true
dockerfile: ./Dockerfile
environment: environment:
- DYNB_DYN_DOMAIN=dyndns.example.com - DYNB_DYN_DOMAIN=dyndns.example.com
- DYNB_SERVICE_PROVIDER=inwx # Providers: deSec, duckDNS, dynv6, inwx
- DYNB_SERVICE_PROVIDER=desec
# Possible update methods are: dyndns, domrobot
- DYNB_UPDATE_METHOD=dyndns - DYNB_UPDATE_METHOD=dyndns
# IP modes: 4 (IPv4 only), 6 (IPv6 only), 64 both
- DYNB_IP_MODE=64 - DYNB_IP_MODE=64
# If your provider uses tokens use DYNB_TOKEN instead of DYNB_USERNAME and DYNB_PASSWORD
- DYNB_USERNAME=User42 - DYNB_USERNAME=User42
- DYNB_PASSWORD=SuperSecretPassword - DYNB_PASSWORD=SuperSecretPassword
- DYNB_INTERVAL=60 # The interval in seconds is the time the script waits before executing it again
- DYNB_INTERVAL=300
# TZ: Timezone setting for correct log time
- TZ=Europe/Berlin
# TERM: For colorful console output (attached mode)
- TERM=xterm-256color
``` ```
## 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` | | DYNB_SERVICE_PROVIDER | undefined | required; `deSEC`, `duckdns`, `dynv6`, `inwx`, `ddnss` |
| DYNB_UPDATE_METHOD | undefined | required; `dyndns` or `domrobot` (with inwx) | | DYNB_UPDATE_METHOD | undefined | required; `dyndns` or `domrobot` (with inwx) |
| DYNB_IP_MODE | undefined | required; `4`, `6` or `64` for both | | DYNB_IP_MODE | undefined | required; `4`, `6` or `64` for both |
| DYNB_USERNAME | undefined | the requirement depends on your provider and the update method | | DYNB_USERNAME | undefined | the requirement depends on your provider and the update method |

119
dynb.sh
View File

@@ -66,7 +66,7 @@ _response=
_statusHostname= _statusHostname=
_statusUsername= _statusUsername=
_statusPassword= _statusPassword=
_version=0.3.1 _version=0.3.4
_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
@@ -258,8 +258,7 @@ function updateRecord
fi fi
} }
# using DynDNS2 protocol function select_update_base_url
function dynupdate
{ {
# default parameter values # default parameter values
myip_str=myip myip_str=myip
@@ -269,6 +268,7 @@ function dynupdate
DESEC_DYNDNS_UPDATE_URL="https://update.dedyn.io/?" DESEC_DYNDNS_UPDATE_URL="https://update.dedyn.io/?"
DUCKDNS_DYNDNS_UPDATE_URL="https://www.duckdns.org/update?domains=$DYNB_DYN_DOMAIN&token=$DYNB_TOKEN&" DUCKDNS_DYNDNS_UPDATE_URL="https://www.duckdns.org/update?domains=$DYNB_DYN_DOMAIN&token=$DYNB_TOKEN&"
DYNV6_DYNDNS_UPDATE_URL="https://dynv6.com/api/update?zone=$DYNB_DYN_DOMAIN&token=$DYNB_TOKEN&" DYNV6_DYNDNS_UPDATE_URL="https://dynv6.com/api/update?zone=$DYNB_DYN_DOMAIN&token=$DYNB_TOKEN&"
DDNSS_DYNDNS_UPDATE_URL="https://ddnss.de/upd.php?key=$DYNB_TOKEN&host=$DYNB_DYN_DOMAIN&"
case $DYNB_SERVICE_PROVIDER in case $DYNB_SERVICE_PROVIDER in
inwx* | INWX*) inwx* | INWX*)
@@ -284,34 +284,32 @@ function dynupdate
;; ;;
DuckDNS* | duckdns*) DuckDNS* | duckdns*)
dyndns_update_url="${DUCKDNS_DYNDNS_UPDATE_URL}" dyndns_update_url="${DUCKDNS_DYNDNS_UPDATE_URL}"
myip_str=ipv4 myip_str=ip
myipv6_str=ipv6 myipv6_str=ipv6
;; ;;
ddnss*)
dyndns_update_url="${DDNSS_DYNDNS_UPDATE_URL}"
## we are currently not using the syntax with ip auto detection
myip_str=ip
myipv6_str=ip6
;;
*) *)
errorMessage "$DYNB_SERVICE_PROVIDER is not supported" errorMessage "$DYNB_SERVICE_PROVIDER is not supported"
exit 1 exit 1
;; ;;
esac esac
}
# pre encode ip parameters function send_request
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]]; then {
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}&${myipv6_str}=${_new_IPv6}" case $DYNB_SERVICE_PROVIDER in
fi
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == false ]]; then
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}"
fi
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]]; then
dyndns_update_url="${dyndns_update_url}${myipv6_str}=${_new_IPv6}"
fi
debugMessage "Update URL was: $dyndns_update_url"
## request ##
case $DYNB_SERVICE_PROVIDER in
inwx* | INWX*) inwx* | INWX*)
_response=$(curl --silent "$_interface_str" \ _response=$(curl --silent "$_interface_str" \
--user-agent "$_userAgent" \ --user-agent "$_userAgent" \
--user "$DYNB_USERNAME":"$DYNB_PASSWORD" \ --user "$DYNB_USERNAME":"$DYNB_PASSWORD" \
"${dyndns_update_url}") "${dyndns_update_url}")
analyse_response
return $?
;; ;;
deSEC* | desec* | dedyn*) deSEC* | desec* | dedyn*)
_response=$(curl --silent "$_interface_str" \ _response=$(curl --silent "$_interface_str" \
@@ -319,41 +317,52 @@ function dynupdate
--header "Authorization: Token $DYNB_TOKEN" \ --header "Authorization: Token $DYNB_TOKEN" \
--get --data-urlencode "hostname=$DYNB_DYN_DOMAIN" \ --get --data-urlencode "hostname=$DYNB_DYN_DOMAIN" \
"${dyndns_update_url}") "${dyndns_update_url}")
analyse_response
return $?
;; ;;
dynv6* | duckDNS* | duckdns*) dynv6* | duckDNS* | duckdns* | ddnss*)
_response=$( _response=$(
curl --silent "$_interface_str" \ curl --silent "$_interface_str" \
--user-agent "$_userAgent" \ --user-agent "$_userAgent" \
"${dyndns_update_url}" "${dyndns_update_url}")
) analyse_response
return $?
;; ;;
esac esac
}
case $_response in function analyse_response
good* | OK* | "addresses updated") {
case $_response in
good* | OK* | "addresses updated" | *Updated*hostname*)
if [[ $_response == "good 127.0.0.1" ]]; then if [[ $_response == "good 127.0.0.1" ]]; then
errorMessage "$_response: Request ignored." errorMessage "$_response: Request ignored."
return 1 return 1
else else
infoMessage "$_response: The DynDNS update has been executed." infoMessage "The DynDNS update has been executed."
debugMessage "Response: $_response"
_errorCounter=0 _errorCounter=0
return 0 return 0
fi fi
;; ;;
nochg*) nochg*)
infoMessage "$_response: Nothing has changed, IP addresses are still up to date." infoMessage "Nothing has changed, IP addresses are still up to date."
debugMessage "Response: $_response"
return 1 return 1
;; ;;
abuse) abuse)
errorMessage "$_response: Username is blocked due to abuse." errorMessage "Username is blocked due to abuse."
debugMessage "Response: $_response"
return 1 return 1
;; ;;
badauth | 401) *badauth* | 401)
errorMessage "$_response: Invalid username password combination." errorMessage "Invalid token or username password combination."
debugMessage "Response: $_response"
return 1 return 1
;; ;;
badagent) badagent)
errorMessage "$_response: Client disabled. Something is very wrong!" errorMessage "Client disabled. Something is very wrong!"
debugMessage "Response: $_response"
return 1 return 1
;; ;;
!donator) !donator)
@@ -368,8 +377,9 @@ function dynupdate
errorMessage "$_response: Hostname $DYNB_DYN_DOMAIN is invalid" errorMessage "$_response: Hostname $DYNB_DYN_DOMAIN is invalid"
return 1 return 1
;; ;;
nohost) *nohost*)
errorMessage "$_response: 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."
debugMessage "Response: $_response"
return 1 return 1
;; ;;
numhost) numhost)
@@ -386,7 +396,7 @@ function dynupdate
;; ;;
*) *)
if [[ "$_response" == "$_status" ]]; then if [[ "$_response" == "$_status" ]]; 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
errorMessage "unknown respnse code: $_response" errorMessage "unknown respnse code: $_response"
@@ -396,6 +406,32 @@ function dynupdate
esac esac
} }
# using DynDNS2 protocol
function dynupdate
{
select_update_base_url
# pre encode ip parameters
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]]
then
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}&${myipv6_str}=${_new_IPv6}"
send_request
fi
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == false ]]
then
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}"
send_request
fi
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]]
then
dyndns_update_url="${dyndns_update_url}${myipv6_str}=${_new_IPv6}"
send_request
fi
request_status=$?
debugMessage "Update URL was: $dyndns_update_url"
return $request_status
}
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
@@ -408,7 +444,7 @@ function checkStatus
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 an 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
fi fi
;; ;;
@@ -523,7 +559,7 @@ function ipHasChanged
dns_ip=$(echo "$dig_response" | head -n 1) 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 "IPv6 from remote IP check server: $_new_IPv6, IPv6 from DNS: $dns_ip"
;; ;;
*) ;; *) ;;
esac esac
@@ -777,11 +813,8 @@ function check_internet_connection
fi fi
} }
function main function read_config_file
{ {
# shellcheck disable=SC1091,SC1090
source "$(dirname "$(realpath "$0")")/dynb-parsing.sh"
# shellcheck source=.env # shellcheck source=.env
if test -f "$_configFile" if test -f "$_configFile"
then then
@@ -795,6 +828,15 @@ function main
source "$alternativeConfig" source "$alternativeConfig"
fi fi
fi fi
}
function main
{
# shellcheck disable=SC1091,SC1090
source "$(dirname "$(realpath "$0")")/dynb-parsing.sh"
read_config_file
if test -f "$_statusFile" if test -f "$_statusFile"
then then
debugMessage "read previous status file" debugMessage "read previous status file"
@@ -812,6 +854,7 @@ function main
while : while :
do do
doUpdates doUpdates
debugMessage "wait $DYNB_INTERVAL seconds until next check"
sleep $DYNB_INTERVAL sleep $DYNB_INTERVAL
done done
else doUpdates else doUpdates