mirror of
https://github.com/coolsnowwolf/packages
synced 2025-01-07 07:07:02 +08:00
ddns-scripts: bump version
This commit is contained in:
parent
b99b66aea3
commit
058f961c23
1096
net/ddns-scripts/Makefile
Executable file → Normal file
1096
net/ddns-scripts/Makefile
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
#
|
||||
# Please read http://wiki.openwrt.org/doc/uci/ddns
|
||||
#
|
||||
config ddns "global"
|
||||
option ddns_dateformat "%F %R"
|
||||
# option ddns_rundir "/var/run/ddns"
|
||||
# option ddns_logdir "/var/log/ddns"
|
||||
option ddns_loglines "250"
|
||||
option upd_privateip "0"
|
@ -1,201 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
g_pslfile=/usr/share/public_suffix_list.dat.gz
|
||||
[ -f "$g_pslfile" ] || g_pslfile="$(dirname $0)/public_suffix_list.dat.gz"
|
||||
|
||||
g_pslerr=0
|
||||
g_cfgfile="ddns"
|
||||
|
||||
# modify timer settings from interval and unit to dhms format
|
||||
timer2dhms() {
|
||||
# $1 Number and
|
||||
# $2 Unit of time interval
|
||||
local t=0
|
||||
case $2 in
|
||||
days) t=$(( $1 * 86400 ));;
|
||||
hours) t=$(( $1 * 3600 ));;
|
||||
minutes) t=$(( $1 * 60 ));;
|
||||
*) t=$1;;
|
||||
esac
|
||||
|
||||
local d=$(( $t / 86400 ))
|
||||
local h=$(( $t % 86400 / 3600 ))
|
||||
local m=$(( $t % 3600 / 60 ))
|
||||
local s=$(( $t % 60 ))
|
||||
if [ $d -gt 0 ]; then printf "%dd %02dh %02dm %02ds" "$d" "$h" "$m" "$s"
|
||||
elif [ $h -gt 0 ]; then printf "%dh %02dm %02ds" "$h" "$m" "$s"
|
||||
elif [ $m -gt 0 ]; then printf "%dm %02ds" "$m" "$s"
|
||||
else printf "%ds" "$s"; fi
|
||||
|
||||
unset d h m s t
|
||||
return 0
|
||||
}
|
||||
|
||||
# using function to not confuse function calls with existing ones inside /lib/functions.sh
|
||||
update_config() {
|
||||
uc_uci="$(which uci) -q" # ignore errors
|
||||
uc_cfg=""
|
||||
uc_name=""
|
||||
uc_var=""
|
||||
uc_val=""
|
||||
package() { return 0; }
|
||||
config () {
|
||||
uc_cfg="$1"
|
||||
uc_name="$2"
|
||||
|
||||
# Type = ddns Name = global
|
||||
if [ "$uc_cfg" = "$g_cfgfile" -a "$uc_name" = "global" ]; then
|
||||
option() {
|
||||
uc_var="$1"; shift
|
||||
uc_val="$*"
|
||||
case "$uc_var" in
|
||||
allow_local_ip) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_privateip";;
|
||||
date_format) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_dateformat";;
|
||||
log_lines) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_loglines";;
|
||||
log_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_logdir";;
|
||||
run_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_rundir";;
|
||||
# leave all other options currently unchanged
|
||||
*) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Type = service Name = ???
|
||||
elif [ "$uc_cfg" = "service" ]; then
|
||||
option() {
|
||||
uc_var="$1"; shift
|
||||
uc_val="$*"
|
||||
case "$uc_var" in
|
||||
# fix some option service_name values
|
||||
# and some settings for specific providers
|
||||
service_name|upd_provider)
|
||||
case "$uc_val" in
|
||||
freedns\.afraid\.org|afraid\.org)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="afraid.org-keyauth";;
|
||||
Bind-nsupdate)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="bind-nsupdate";;
|
||||
dyndns\.org|dyndns\.com)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="dyn.com";;
|
||||
free\.editdns\.net)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="editdns.net";;
|
||||
FreeDNS\.42\.pl)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="freedns.42.pl";;
|
||||
domains\.google\.com)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="google.com";;
|
||||
loopia\.com)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="loopia.se";;
|
||||
NoIP\.com|No-IP\.com)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="no-ip.com";;
|
||||
spdns\.de)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="spdyn.de";;
|
||||
strato\.de)
|
||||
$uc_uci set $g_cfgfile.$uc_name.$uc_var="strato.com";;
|
||||
*)
|
||||
# all others leave unchanged
|
||||
;;
|
||||
esac
|
||||
# rename option service_name to option upd_provider
|
||||
# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_provider"
|
||||
;;
|
||||
domain|upd_object)
|
||||
# verify if lookup_host is set
|
||||
$uc_uci get $g_cfgfile.$uc_name.lookup_host >/dev/null 2>&1 || \
|
||||
$uc_uci set $g_cfgfile.$uc_name.lookup_host="$uc_val"
|
||||
if [ -f "$g_pslfile" ]; then
|
||||
# if service_name/upd_provider cloudflare_v1 then change domain/upd_object to new syntax
|
||||
# there is no sort order inside uci data so we need multiple checks
|
||||
uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \
|
||||
uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null)
|
||||
unset uco_provider
|
||||
fi
|
||||
# rename option domain to option upd_object
|
||||
# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_object"
|
||||
;;
|
||||
# dns_server)
|
||||
# # if bind-nsupdate takeover old "dns_server" value as new "upd_nsupd_server" value
|
||||
# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \
|
||||
# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null)
|
||||
# [ "$uco_provider" = "Bind-nsupdate" -o \
|
||||
# "$uco_provider" = "bind-nsupdate" ] && \
|
||||
# $uc_uci set $g_cfgfile.$uc_name.upd_nsupd_server="$uc_val"
|
||||
# # rename option dns_server to new option global_dnssvr
|
||||
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="global_dnssvr"
|
||||
# ;;
|
||||
# bind_network)
|
||||
# $udc_uci set $g_cfgfile.$uc_name.upd_url_bindnet="$uc_val"
|
||||
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_url_bindnet"
|
||||
# ;;
|
||||
# proxy)
|
||||
# # proxy value must include protocoll
|
||||
# $udc_uci set $g_cfgfile.$uc_name.$uc_var="http://$uc_val"
|
||||
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_proxy"
|
||||
# ;;
|
||||
# use_ipv6)
|
||||
# $udc_uci set $g_cfgfile.$uc_name.$uc_var="$(( 4 + ( 2 * $uc_val ) ))"
|
||||
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_ipversion"
|
||||
# TODO update_url)
|
||||
# TODO update_script)
|
||||
# other renames
|
||||
# TODO lookup_host) -> rip_host
|
||||
# enabled) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_enabled";;
|
||||
# force_dnstcp) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_dnstcp";;
|
||||
# is_glue) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_isglue";;
|
||||
# ip_interface) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_iface";;
|
||||
# ip_network) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_net";;
|
||||
# use_https) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_secure";;
|
||||
# cacert) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_cacert";;
|
||||
# username) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_username";;
|
||||
# password) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_password";;
|
||||
# param_opt) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramopt";;
|
||||
# param_enc) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramenc";;
|
||||
|
||||
# leave all other options currently unchanged
|
||||
*) ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
|
||||
# ignore unknown
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# read config file
|
||||
uc_data=$($uc_uci -S -n export "$g_cfgfile")
|
||||
uc_ret="$?"
|
||||
# Error then create config file
|
||||
[ $uc_ret -ne 0 ] && {
|
||||
touch /etc/config/$uc_cfgfile
|
||||
chmod 644 /etc/config/$uc_cfgfile
|
||||
}
|
||||
# No error and uc_data then execute (eval)
|
||||
# this will call functions defined above
|
||||
[ $uc_ret -eq 0 -a -n "$uc_data" ] && eval "$uc_data"
|
||||
|
||||
# add config ddns "global" (ignore error if exists)
|
||||
$uc_uci set ddns.global="$g_cfgfile"
|
||||
|
||||
# write changes to config file
|
||||
$uc_uci commit "$g_cfgfile"
|
||||
|
||||
unset uc_uci uc_cfg uc_name uc_var uc_val uc_ret uc_data
|
||||
return 0
|
||||
}
|
||||
|
||||
# clear LuCI indexcache
|
||||
rm -f /tmp/luci-indexcache >/dev/null 2>&1
|
||||
|
||||
# do config update
|
||||
update_config
|
||||
|
||||
#cleanup
|
||||
[ $g_pslerr -ne 0 ] && {
|
||||
unset g_pslfile g_pslerr g_cfgfile
|
||||
return 1
|
||||
}
|
||||
|
||||
[ -f "$g_pslfile" ] && rm -f "$g_pslfile"
|
||||
unset g_pslfile g_pslerr g_cfgfile
|
||||
return 0
|
||||
|
32
net/ddns-scripts/files/etc/config/ddns
Normal file
32
net/ddns-scripts/files/etc/config/ddns
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Please read https://openwrt.org/docs/guide-user/base-system/ddns
|
||||
#
|
||||
config ddns "global"
|
||||
option ddns_dateformat "%F %R"
|
||||
# option ddns_rundir "/var/run/ddns"
|
||||
# option ddns_logdir "/var/log/ddns"
|
||||
option ddns_loglines "250"
|
||||
option upd_privateip "0"
|
||||
|
||||
|
||||
config service "myddns_ipv4"
|
||||
option service_name "dyndns.org"
|
||||
option lookup_host "yourhost.example.com"
|
||||
option domain "yourhost.example.com"
|
||||
option username "your_username"
|
||||
option password "your_password"
|
||||
option interface "wan"
|
||||
option ip_source "network"
|
||||
option ip_network "wan"
|
||||
|
||||
config service "myddns_ipv6"
|
||||
option update_url "http://[USERNAME]:[PASSWORD]@your.provider.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
option lookup_host "yourhost.example.com"
|
||||
option domain "yourhost.example.com"
|
||||
option username "your_username"
|
||||
option password "your_password"
|
||||
option use_ipv6 "1"
|
||||
option interface "wan6"
|
||||
option ip_source "network"
|
||||
option ip_network "wan6"
|
||||
|
0
net/ddns-scripts/files/ddns.hotplug → net/ddns-scripts/files/etc/hotplug.d/iface/ddns
Executable file → Normal file
0
net/ddns-scripts/files/ddns.hotplug → net/ddns-scripts/files/etc/hotplug.d/iface/ddns
Executable file → Normal file
4
net/ddns-scripts/files/ddns.init → net/ddns-scripts/files/etc/init.d/ddns
Executable file → Normal file
4
net/ddns-scripts/files/ddns.init → net/ddns-scripts/files/etc/init.d/ddns
Executable file → Normal file
@ -2,10 +2,6 @@
|
||||
START=95
|
||||
STOP=10
|
||||
|
||||
boot() {
|
||||
start "$@"
|
||||
}
|
||||
|
||||
reload() {
|
||||
/usr/lib/ddns/dynamic_dns_updater.sh -- reload
|
||||
return 0
|
@ -1,97 +0,0 @@
|
||||
#!/bin/sh
|
||||
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
#.based on Yuval Adam's route53.sh found at https://github.com/yuvadm/route53-ddns/blob/master/route53.sh
|
||||
#.2017 Max Berger <max at berger dot name>
|
||||
[ -z "$CURL_SSL" ] && write_log 14 "Amazon AWS Route53 communication require cURL with SSL support. Please install"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing key as 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing secret as 'password'"
|
||||
[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing zone id as 'domain'"
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
ENDPOINT="route53.amazonaws.com"
|
||||
RECORD_TTL=300
|
||||
RECORD_NAME="$lookup_host".
|
||||
[ $use_ipv6 -eq 0 ] && RECORD_TYPE="A"
|
||||
[ $use_ipv6 -eq 1 ] && RECORD_TYPE="AAAA"
|
||||
RECORD_VALUE="$LOCAL_IP"
|
||||
HOSTED_ZONE_ID="$domain"
|
||||
API_PATH="/2013-04-01/hostedzone/${HOSTED_ZONE_ID}/rrset/"
|
||||
|
||||
AWS_ACCESS_KEY_ID="$username"
|
||||
AWS_SECRET_ACCESS_KEY="$password"
|
||||
AWS_REGION='us-east-1'
|
||||
AWS_SERVICE='route53'
|
||||
|
||||
hash() {
|
||||
msg=$1
|
||||
echo -en "$msg" | openssl dgst -sha256 | sed 's/^.* //'
|
||||
}
|
||||
|
||||
sign_plain() {
|
||||
# Sign message using a plaintext key
|
||||
key=$1
|
||||
msg=$2
|
||||
echo -en "$msg" | openssl dgst -hex -sha256 -hmac "$key" | sed 's/^.* //'
|
||||
}
|
||||
|
||||
sign() {
|
||||
# Sign message using a hex formatted key
|
||||
key=$1
|
||||
msg=$2
|
||||
echo -en "$msg" | openssl dgst -hex -sha256 -mac HMAC -macopt "hexkey:${key}" | sed 's/^.* //'
|
||||
}
|
||||
|
||||
request_body="<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
|
||||
<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2013-04-01/\"> \
|
||||
<ChangeBatch> \
|
||||
<Changes> \
|
||||
<Change> \
|
||||
<Action>UPSERT</Action> \
|
||||
<ResourceRecordSet> \
|
||||
<Name>${RECORD_NAME}</Name> \
|
||||
<Type>${RECORD_TYPE}</Type> \
|
||||
<TTL>${RECORD_TTL}</TTL> \
|
||||
<ResourceRecords> \
|
||||
<ResourceRecord> \
|
||||
<Value>${RECORD_VALUE}</Value> \
|
||||
</ResourceRecord> \
|
||||
</ResourceRecords> \
|
||||
</ResourceRecordSet> \
|
||||
</Change> \
|
||||
</Changes> \
|
||||
</ChangeBatch> \
|
||||
</ChangeResourceRecordSetsRequest>"
|
||||
|
||||
fulldate=$(date --utc +%Y%m%dT%H%M%SZ)
|
||||
shortdate=$(date --utc +%Y%m%d)
|
||||
signed_headers="host;x-amz-date"
|
||||
request_hash=$(hash "$request_body")
|
||||
canonical_request="POST\n${API_PATH}\n\nhost:route53.amazonaws.com\nx-amz-date:${fulldate}\n\n${signed_headers}\n${request_hash}"
|
||||
|
||||
date_key=$(sign_plain "AWS4${AWS_SECRET_ACCESS_KEY}" "${shortdate}")
|
||||
region_key=$(sign "$date_key" $AWS_REGION)
|
||||
service_key=$(sign "$region_key" $AWS_SERVICE)
|
||||
signing_key=$(sign "$service_key" aws4_request)
|
||||
|
||||
credential="${shortdate}/${AWS_REGION}/${AWS_SERVICE}/aws4_request"
|
||||
sigmsg="AWS4-HMAC-SHA256\n${fulldate}\n${credential}\n$(hash "$canonical_request")"
|
||||
|
||||
signature=$(sign "$signing_key" "$sigmsg")
|
||||
|
||||
authorization="AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${credential}, SignedHeaders=${signed_headers}, Signature=${signature}"
|
||||
|
||||
ANSWER=$(curl \
|
||||
-X "POST" \
|
||||
-H "Host: route53.amazonaws.com" \
|
||||
-H "X-Amz-Date: ${fulldate}" \
|
||||
-H "Authorization: ${authorization}" \
|
||||
-H "Content-Type: text/xml" \
|
||||
-d "$request_body" \
|
||||
"https://${ENDPOINT}${API_PATH}")
|
||||
write_log 7 "${ANSWER}"
|
||||
|
||||
echo ${ANSWER} | grep Error >/dev/null && return 1
|
||||
echo ${ANSWER} | grep ChangeInfo >/dev/null && return 0
|
||||
return 2
|
172
net/ddns-scripts/files/usr/bin/ddns.sh
Normal file
172
net/ddns-scripts/files/usr/bin/ddns.sh
Normal file
@ -0,0 +1,172 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2020 TDT AG <development@tdt.de>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
DDNS_PACKAGE_DIR="/usr/share/ddns"
|
||||
URL="https://raw.githubusercontent.com/openwrt/packages/master/net/ddns-scripts/files"
|
||||
|
||||
usage() {
|
||||
local code="$1"
|
||||
local msg="$2"
|
||||
|
||||
echo "$msg"
|
||||
echo ""
|
||||
echo "Usage: $(basename "$0") <command> <action> <service>"
|
||||
echo ""
|
||||
echo "Supported ddns <command>:"
|
||||
echo " service: Command for custom ddns service providers"
|
||||
echo ""
|
||||
echo "Supported ddns 'service' command <action>:"
|
||||
echo " update: Update local custom ddns service list"
|
||||
echo " list-available: List all available custom service providers"
|
||||
echo " list-installed: List all installed custom service providers"
|
||||
echo " install <service>: Install custom service provider"
|
||||
echo " remove <service>: Remove custom service provider"
|
||||
echo " purge: Remove local custom ddns services"
|
||||
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
action_update() {
|
||||
local cacert
|
||||
|
||||
config_load ddns
|
||||
config_get url global 'url' "${URL}${DDNS_PACKAGE_DIR}"
|
||||
config_get cacert global 'cacert' "IGNORE"
|
||||
url="${url}/list"
|
||||
|
||||
mkdir -p "${DDNS_PACKAGE_DIR}"
|
||||
|
||||
if [ "$cacert" = "IGNORE" ]; then
|
||||
uclient-fetch \
|
||||
--no-check-certificate \
|
||||
"$url" \
|
||||
-O "${DDNS_PACKAGE_DIR}/list"
|
||||
elif [ -f "$cacert" ]; then
|
||||
uclient-fetch \
|
||||
--ca-certificate="${cacert}" \
|
||||
"$url" \
|
||||
-O "${DDNS_PACKAGE_DIR}/list"
|
||||
elif [ -n "$cacert" ]; then
|
||||
echo "Certification file not found ($cacert)"
|
||||
exit 5
|
||||
fi
|
||||
}
|
||||
|
||||
action_list_available() {
|
||||
if [ -f "${DDNS_PACKAGE_DIR}/list" ]; then
|
||||
cat "${DDNS_PACKAGE_DIR}/list"
|
||||
else
|
||||
echo "No custom service list file found. Please download first"
|
||||
exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
action_list_installed() {
|
||||
if [ -d "${DDNS_PACKAGE_DIR}/custom" ]; then
|
||||
ls "${DDNS_PACKAGE_DIR}/custom"
|
||||
else
|
||||
echo "No custom services installed"
|
||||
exit 4
|
||||
fi
|
||||
}
|
||||
|
||||
action_install() {
|
||||
local service="$1"
|
||||
|
||||
local url cacert
|
||||
|
||||
config_load ddns
|
||||
config_get url global 'url' "${URL}${DDNS_PACKAGE_DIR}/default"
|
||||
config_get cacert global 'cacert' "IGNORE"
|
||||
url="${url}/${service}.json"
|
||||
|
||||
if [ -z "$service" ]; then
|
||||
usage "4" "No custom service specified"
|
||||
fi
|
||||
|
||||
mkdir -p "${DDNS_PACKAGE_DIR}/custom"
|
||||
|
||||
if [ "$cacert" = "IGNORE" ]; then
|
||||
uclient-fetch \
|
||||
--no-check-certificate \
|
||||
"${url}" \
|
||||
-O "${DDNS_PACKAGE_DIR}/custom/${service}.json"
|
||||
elif [ -f "$cacert" ]; then
|
||||
uclient-fetch \
|
||||
--ca-certifcate="${cacert}" \
|
||||
"${url}" \
|
||||
-O "${DDNS_PACKAGE_DIR}/custom/${service}.json"
|
||||
elif [ -n "$cacert" ]; then
|
||||
echo "Certification file not found ($cacert)"
|
||||
exit 5
|
||||
fi
|
||||
}
|
||||
|
||||
action_remove() {
|
||||
local service="$1"
|
||||
if [ -z "$service" ]; then
|
||||
usage "4" "No custom service specified"
|
||||
fi
|
||||
|
||||
rm "${DDNS_PACKAGE_DIR}/custom/${service}.json"
|
||||
}
|
||||
|
||||
action_purge() {
|
||||
rm -rf "${DDNS_PACKAGE_DIR}/custom"
|
||||
rm -rf "${DDNS_PACKAGE_DIR}/list"
|
||||
}
|
||||
|
||||
sub_service() {
|
||||
local action="$1"
|
||||
local service="$2"
|
||||
|
||||
case "$action" in
|
||||
update)
|
||||
action_update
|
||||
;;
|
||||
list-available)
|
||||
action_list_available
|
||||
;;
|
||||
list-installed)
|
||||
action_list_installed
|
||||
;;
|
||||
purge)
|
||||
action_purge
|
||||
;;
|
||||
install)
|
||||
action_install "$service"
|
||||
;;
|
||||
remove)
|
||||
action_remove "$service"
|
||||
;;
|
||||
*)
|
||||
usage "2" "Action not supported"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
local cmd="$1"
|
||||
local action="$2"
|
||||
local service="$3"
|
||||
|
||||
[ "$#" -eq 0 ] && usage "1"
|
||||
|
||||
case "${cmd}" in
|
||||
service)
|
||||
sub_service "${action}" "${service}"
|
||||
;;
|
||||
*)
|
||||
usage "1" "Command not supported"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
312
net/ddns-scripts/files/dynamic_dns_functions.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh
Executable file → Normal file
312
net/ddns-scripts/files/dynamic_dns_functions.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh
Executable file → Normal file
@ -21,9 +21,14 @@
|
||||
. /lib/functions/network.sh
|
||||
|
||||
# GLOBAL VARIABLES #
|
||||
VERSION="2.7.8-1"
|
||||
if [ -f "/usr/share/ddns/version" ]; then
|
||||
VERSION="$(cat "/usr/share/ddns/version")"
|
||||
else
|
||||
VERSION="unknown"
|
||||
fi
|
||||
SECTION_ID="" # hold config's section name
|
||||
VERBOSE=0 # default mode is log to console, but easily changed with parameter
|
||||
DRY_RUN=0 # run without actually doing (sending) any changes
|
||||
MYPROG=$(basename $0) # my program call name
|
||||
|
||||
LOGFILE="" # logfile - all files are set in dynamic_dns_updater.sh
|
||||
@ -43,8 +48,8 @@ CURR_TIME=0 # holds the current uptime
|
||||
NEXT_TIME=0 # calculated time for next FORCED update
|
||||
EPOCH_TIME=0 # seconds since 1.1.1970 00:00:00
|
||||
|
||||
CURRENT_IP="" # holds the current IP read from the box
|
||||
REGISTERED_IP="" # holds the IP read from DNS
|
||||
LOCAL_IP="" # holds the local IP read from the box
|
||||
|
||||
URL_USER="" # url encoded $username from config file
|
||||
URL_PASS="" # url encoded $password from config file
|
||||
@ -53,7 +58,7 @@ URL_PENC="" # url encoded $param_enc from config file
|
||||
UPD_ANSWER="" # Answer given by service on success
|
||||
|
||||
ERR_LAST=0 # used to save $? return code of program and function calls
|
||||
ERR_UPDATE=0 # error counter on different local and registered ip
|
||||
RETRY_COUNT=0 # error counter on different current and registered IPs
|
||||
|
||||
PID_SLEEP=0 # ProcessID of current background "sleep"
|
||||
|
||||
@ -63,31 +68,36 @@ IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
|
||||
# IPv6 ( ( 0-9a-f 1-4char ":") min 1x) ( ( 0-9a-f 1-4char )optional) ( (":" 0-9a-f 1-4char ) min 1x)
|
||||
IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
|
||||
|
||||
# characters that are dangerous to pass to a shell command line
|
||||
SHELL_ESCAPE="[\"\'\`\$\!();><{}?|\[\]\*\\\\]"
|
||||
|
||||
# dns character set. "-" must be the last character
|
||||
DNS_CHARSET="[@a-zA-Z0-9._-]"
|
||||
|
||||
# domains can have * for wildcard. "-" must be the last character
|
||||
DNS_CHARSET_DOMAIN="[@a-zA-Z0-9._*-]"
|
||||
|
||||
# detect if called by ddns-lucihelper.sh script, disable retrys (empty variable == false)
|
||||
LUCI_HELPER=$(printf %s "$MYPROG" | grep -i "luci")
|
||||
|
||||
# Name Server Lookup Programs
|
||||
BIND_HOST=$(which host)
|
||||
KNOT_HOST=$(which khost)
|
||||
DRILL=$(which drill)
|
||||
HOSTIP=$(which hostip)
|
||||
NSLOOKUP=$(which nslookup)
|
||||
BIND_HOST=$(command -v host)
|
||||
KNOT_HOST=$(command -v khost)
|
||||
DRILL=$(command -v drill)
|
||||
HOSTIP=$(command -v hostip)
|
||||
NSLOOKUP=$(command -v nslookup)
|
||||
|
||||
# Transfer Programs
|
||||
WGET=$(which wget)
|
||||
WGET_SSL=$(which wget-ssl)
|
||||
|
||||
CURL=$(which curl)
|
||||
WGET=$(command -v wget)
|
||||
$WGET -V 2>/dev/null | grep -F -q +https && WGET_SSL=$WGET
|
||||
|
||||
CURL=$(command -v curl)
|
||||
# CURL_SSL not empty then SSL support available
|
||||
CURL_SSL=$($CURL -V 2>/dev/null | grep -F "https")
|
||||
# CURL_PROXY not empty then Proxy support available
|
||||
if [ -f /tmp/vCURL_PROXY ]; then
|
||||
CURL_PROXY=$(cat /tmp/vCURL_PROXY);
|
||||
else
|
||||
CURL_PROXY=$(find /lib /usr/lib -name libcurl.so* -exec strings {} 2>/dev/null \; | grep -im1 "all_proxy")
|
||||
echo -n $CURL_PROXY >/tmp/vCURL_PROXY
|
||||
fi
|
||||
CURL_PROXY=$(find /lib /usr/lib -name libcurl.so* -exec strings {} 2>/dev/null \; | grep -im1 "all_proxy")
|
||||
|
||||
UCLIENT_FETCH=$(which uclient-fetch)
|
||||
UCLIENT_FETCH=$(command -v uclient-fetch)
|
||||
|
||||
# Global configuration settings
|
||||
# allow NON-public IP's
|
||||
@ -280,11 +290,11 @@ write_log() {
|
||||
[ $__LEVEL -eq 7 ] && return # no syslog for debug messages
|
||||
__CMD=$(echo -e "$__CMD" | tr -d '\n' | tr '\t' ' ') # remove \n \t chars
|
||||
[ $__EXIT -eq 1 ] && {
|
||||
$__CMD # force syslog before exit
|
||||
eval '$__CMD' # force syslog before exit
|
||||
exit 1
|
||||
}
|
||||
[ $use_syslog -eq 0 ] && return
|
||||
[ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD
|
||||
[ $((use_syslog + __LEVEL)) -le 7 ] && eval '$__CMD'
|
||||
|
||||
return
|
||||
}
|
||||
@ -299,74 +309,61 @@ write_log() {
|
||||
urlencode() {
|
||||
# $1 Name of Variable to store encoded string to
|
||||
# $2 string to encode
|
||||
local __STR __LEN __CHAR __OUT
|
||||
local __ENC=""
|
||||
local __POS=1
|
||||
local __ENC
|
||||
|
||||
[ $# -ne 2 ] && write_log 12 "Error calling 'urlencode()' - wrong number of parameters"
|
||||
|
||||
__STR="$2" # read string to encode
|
||||
__LEN=${#__STR} # get string length
|
||||
|
||||
while [ $__POS -le $__LEN ]; do
|
||||
# read one chat of the string
|
||||
__CHAR=$(expr substr "$__STR" $__POS 1)
|
||||
|
||||
case "$__CHAR" in
|
||||
[-_.~a-zA-Z0-9] )
|
||||
# standard char
|
||||
__OUT="${__CHAR}"
|
||||
;;
|
||||
* )
|
||||
# special char get %hex code
|
||||
__OUT=$(printf '%%%02x' "'$__CHAR" )
|
||||
;;
|
||||
esac
|
||||
__ENC="${__ENC}${__OUT}" # append to encoded string
|
||||
__POS=$(( $__POS + 1 )) # increment position
|
||||
done
|
||||
__ENC="$(awk -v str="$2" 'BEGIN{ORS="";for(i=32;i<=127;i++)lookup[sprintf("%c",i)]=i
|
||||
for(k=1;k<=length(str);++k){enc=substr(str,k,1);if(enc!~"[-_.~a-zA-Z0-9]")enc=sprintf("%%%02x", lookup[enc]);print enc}}')"
|
||||
|
||||
eval "$1=\"$__ENC\"" # transfer back to variable
|
||||
return 0
|
||||
}
|
||||
|
||||
# extract url or script for given DDNS Provider from
|
||||
# file /etc/ddns/services for IPv4 or from
|
||||
# file /etc/ddns/services_ipv6 for IPv6
|
||||
# $1 Name of Variable to store url to
|
||||
# $2 Name of Variable to store script to
|
||||
# $3 Name of Variable to store service answer to
|
||||
# $1 Name of the provider
|
||||
# $2 Provider directory
|
||||
# $3 Name of Variable to store url to
|
||||
# $4 Name of Variable to store script to
|
||||
# $5 Name of Variable to store service answer to
|
||||
get_service_data() {
|
||||
local provider="$1"
|
||||
shift
|
||||
local dir="$1"
|
||||
shift
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
local name data url answer script
|
||||
|
||||
[ $# -ne 3 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters"
|
||||
|
||||
__FILE="/etc/ddns/services" # IPv4
|
||||
[ $use_ipv6 -ne 0 ] && __FILE="/etc/ddns/services_ipv6" # IPv6
|
||||
[ -f "${dir}/${provider}.json" ] || {
|
||||
eval "$1=\"\""
|
||||
eval "$2=\"\""
|
||||
eval "$3=\"\""
|
||||
return 1
|
||||
}
|
||||
|
||||
# workaround with variables; pipe create subshell with no give back of variable content
|
||||
mkfifo pipe_$$
|
||||
# only grep without # or whitespace at linestart | remove "
|
||||
# grep -v -E "(^#|^[[:space:]]*$)" $__FILE | sed -e s/\"//g > pipe_$$ &
|
||||
sed '/^#/d; /^[ \t]*$/d; s/\"//g' $__FILE > pipe_$$ &
|
||||
json_load_file "${dir}/${provider}.json"
|
||||
json_get_var name "name"
|
||||
if [ "$use_ipv6" -eq "1" ]; then
|
||||
json_select "ipv6"
|
||||
else
|
||||
json_select "ipv4"
|
||||
fi
|
||||
json_get_var data "url"
|
||||
json_get_var answer "answer"
|
||||
json_select ".."
|
||||
json_cleanup
|
||||
|
||||
while read __SERVICE __DATA __ANSWER; do
|
||||
if [ "$__SERVICE" = "$service_name" ]; then
|
||||
# check if URL or SCRIPT is given
|
||||
__URL=$(echo "$__DATA" | grep "^http")
|
||||
[ -z "$__URL" ] && __SCRIPT="/usr/lib/ddns/$__DATA"
|
||||
# check if URL or SCRIPT is given
|
||||
url=$(echo "$data" | grep "^http")
|
||||
[ -z "$url" ] && script="/usr/lib/ddns/${data}"
|
||||
|
||||
eval "$1=\"$__URL\""
|
||||
eval "$2=\"$__SCRIPT\""
|
||||
eval "$3=\"$__ANSWER\""
|
||||
rm pipe_$$
|
||||
return 0
|
||||
fi
|
||||
done < pipe_$$
|
||||
rm pipe_$$
|
||||
|
||||
eval "$1=\"\"" # no service match clear variables
|
||||
eval "$2=\"\""
|
||||
eval "$3=\"\""
|
||||
return 1
|
||||
eval "$1=\"$url\""
|
||||
eval "$2=\"$script\""
|
||||
eval "$3=\"$answer\""
|
||||
return 0
|
||||
}
|
||||
|
||||
# Calculate seconds from interval and unit
|
||||
@ -479,14 +476,35 @@ timeout() {
|
||||
return $status
|
||||
}
|
||||
|
||||
# sanitize a variable
|
||||
# $1 variable name
|
||||
# $2 allowed shell pattern
|
||||
# $3 disallowed shell pattern
|
||||
sanitize_variable() {
|
||||
local __VAR=$1
|
||||
eval __VALUE=\$$__VAR
|
||||
local __ALLOWED=$2
|
||||
local __REJECT=$3
|
||||
|
||||
# removing all allowed should give empty string
|
||||
if [ -n "$__ALLOWED" ]; then
|
||||
[ -z "${__VALUE//$__ALLOWED}" ] || write_log 12 "sanitize on $__VAR found characters outside allowed subset"
|
||||
fi
|
||||
|
||||
# removing rejected pattern should give the same string as the input
|
||||
if [ -n "$__REJECT" ]; then
|
||||
[ "$__VALUE" = "${__VALUE//$__REJECT}" ] || write_log 12 "sanitize on $__VAR found rejected characters"
|
||||
fi
|
||||
}
|
||||
|
||||
# verify given host and port is connectable
|
||||
# $1 Host/IP to verify
|
||||
# $2 Port to verify
|
||||
verify_host_port() {
|
||||
local __HOST=$1
|
||||
local __PORT=$2
|
||||
local __NC=$(which nc)
|
||||
local __NCEXT=$($(which nc) --help 2>&1 | grep "\-w" 2>/dev/null) # busybox nc compiled with extensions
|
||||
local __NC=$(command -v nc)
|
||||
local __NCEXT=$($(command -v nc) --help 2>&1 | grep "\-w" 2>/dev/null) # busybox nc compiled with extensions
|
||||
local __IP __IPV4 __IPV6 __RUNPROG __PROG __ERR
|
||||
# return codes
|
||||
# 1 system specific error
|
||||
@ -529,18 +547,21 @@ verify_host_port() {
|
||||
return 2
|
||||
}
|
||||
# extract IP address
|
||||
if [ -n "$BIND_HOST" -o -n "$KNOT_HOST" ]; then # use BIND host or Knot host if installed
|
||||
__IPV4=$(cat $DATFILE | awk -F "address " '/has address/ {print $2; exit}' )
|
||||
__IPV6=$(cat $DATFILE | awk -F "address " '/has IPv6/ {print $2; exit}' )
|
||||
if [ -n "$BIND_HOST" ]; then # use BIND host if installed
|
||||
__IPV4="$(awk -F "address " '/has address/ {print $2; exit}' "$DATFILE")"
|
||||
__IPV6="$(awk -F "address " '/has IPv6/ {print $2; exit}' "$DATFILE")"
|
||||
elif [ -n "$KNOT_HOST" ]; then # use Knot host if installed
|
||||
__IPV4="$(awk -F "address " '/has IPv4/ {print $2; exit}' "$DATFILE")"
|
||||
__IPV6="$(awk -F "address " '/has IPv6/ {print $2; exit}' "$DATFILE")"
|
||||
elif [ -n "$DRILL" ]; then # use drill if installed
|
||||
__IPV4=$(cat $DATFILE | awk '/^'"$lookup_host"'/ {print $5}' | grep -m 1 -o "$IPV4_REGEX")
|
||||
__IPV6=$(cat $DATFILE | awk '/^'"$lookup_host"'/ {print $5}' | grep -m 1 -o "$IPV6_REGEX")
|
||||
__IPV4="$(awk '/^'"$__HOST"'/ {print $5}' "$DATFILE" | grep -m 1 -o "$IPV4_REGEX")"
|
||||
__IPV6="$(awk '/^'"$__HOST"'/ {print $5}' "$DATFILE" | grep -m 1 -o "$IPV6_REGEX")"
|
||||
elif [ -n "$HOSTIP" ]; then # use hostip if installed
|
||||
__IPV4=$(cat $DATFILE | grep -m 1 -o "$IPV4_REGEX")
|
||||
__IPV6=$(cat $DATFILE | grep -m 1 -o "$IPV6_REGEX")
|
||||
__IPV4="$(grep -m 1 -o "$IPV4_REGEX" "$DATFILE")"
|
||||
__IPV6="$(grep -m 1 -o "$IPV6_REGEX" "$DATFILE")"
|
||||
else # use BusyBox nslookup
|
||||
__IPV4=$(cat $DATFILE | sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV4_REGEX\).*$/\\1/p }")
|
||||
__IPV6=$(cat $DATFILE | sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV6_REGEX\).*$/\\1/p }")
|
||||
__IPV4="$(sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV4_REGEX\).*$/\\1/p }" "$DATFILE")"
|
||||
__IPV6="$(sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV6_REGEX\).*$/\\1/p }" "$DATFILE")"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -610,11 +631,11 @@ verify_dns() {
|
||||
return $__ERR
|
||||
elif [ $__ERR -ne 0 ]; then
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Verify DNS server '$1' failed after $retry_count retries"
|
||||
# if error count > retry_max_count leave here
|
||||
[ $retry_max_count -gt 0 -a $__CNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Verify DNS server '$1' failed after $retry_max_count retries"
|
||||
|
||||
write_log 4 "Verify DNS server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
write_log 4 "Verify DNS server '$1' failed - retry $__CNT/$retry_max_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
@ -670,11 +691,11 @@ verify_proxy() {
|
||||
return $__ERR
|
||||
elif [ $__ERR -gt 0 ]; then
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Verify Proxy server '$1' failed after $retry_count retries"
|
||||
# if error count > retry_max_count leave here
|
||||
[ $retry_max_count -gt 0 -a $__CNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Verify Proxy server '$1' failed after $retry_max_count retries"
|
||||
|
||||
write_log 4 "Verify Proxy server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
write_log 4 "Verify Proxy server '$1' failed - retry $__CNT/$retry_max_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
@ -693,16 +714,19 @@ do_transfer() {
|
||||
|
||||
[ $# -ne 1 ] && write_log 12 "Error in 'do_transfer()' - wrong number of parameters"
|
||||
|
||||
# Use ip_network as default for bind_network if not separately specified
|
||||
[ -z "$bind_network" ] && [ "$ip_source" = "network" ] && [ "$ip_network" ] && bind_network="$ip_network"
|
||||
|
||||
# lets prefer GNU Wget because it does all for us - IPv4/IPv6/HTTPS/PROXY/force IP version
|
||||
if [ -n "$WGET_SSL" -a $USE_CURL -eq 0 ]; then # except global option use_curl is set to "1"
|
||||
__PROG="$WGET_SSL -nv -t 1 -O $DATFILE -o $ERRFILE" # non_verbose no_retry outfile errfile
|
||||
if [ -n "$WGET_SSL" ] && [ $USE_CURL -eq 0 ]; then # except global option use_curl is set to "1"
|
||||
__PROG="$WGET --hsts-file=/tmp/.wget-hsts -nv -t 1 -O $DATFILE -o $ERRFILE" # non_verbose no_retry outfile errfile
|
||||
# force network/ip to use for communication
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __BINDIP
|
||||
# set correct program to detect IP
|
||||
[ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" || __RUNPROG="network_get_ipaddr6"
|
||||
eval "$__RUNPROG __BINDIP $bind_network" || \
|
||||
write_log 13 "Can not detect local IP using '$__RUNPROG $bind_network' - Error: '$?'"
|
||||
write_log 13 "Can not detect current IP using '$__RUNPROG $bind_network' - Error: '$?'"
|
||||
write_log 7 "Force communication via IP '$__BINDIP'"
|
||||
__PROG="$__PROG --bind-address=$__BINDIP"
|
||||
fi
|
||||
@ -725,14 +749,19 @@ do_transfer() {
|
||||
# disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
|
||||
[ -z "$proxy" ] && __PROG="$__PROG --no-proxy"
|
||||
|
||||
# user agent string if provided
|
||||
if [ -n "$user_agent" ]; then
|
||||
# replace single and double quotes
|
||||
user_agent=$(echo $user_agent | sed "s/'/ /g" | sed 's/"/ /g')
|
||||
__PROG="$__PROG --user-agent='$user_agent'"
|
||||
fi
|
||||
|
||||
__RUNPROG="$__PROG '$__URL'" # build final command
|
||||
__PROG="GNU Wget" # reuse for error logging
|
||||
|
||||
# 2nd choice is cURL IPv4/IPv6/HTTPS
|
||||
# libcurl might be compiled without Proxy or HTTPS Support
|
||||
elif [ -n "$CURL" ]; then
|
||||
# CURL_SSL not empty then SSL support available
|
||||
CURL_SSL=$($(which curl) -V 2>/dev/null | grep "Protocols:" | grep -F "https")
|
||||
__PROG="$CURL -RsS -o $DATFILE --stderr $ERRFILE"
|
||||
# check HTTPS support
|
||||
[ -z "$CURL_SSL" -a $use_https -eq 1 ] && \
|
||||
@ -740,8 +769,8 @@ do_transfer() {
|
||||
# force network/interface-device to use for communication
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __DEVICE
|
||||
network_get_physdev __DEVICE $bind_network || \
|
||||
write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'"
|
||||
network_get_device __DEVICE $bind_network || \
|
||||
write_log 13 "Can not detect local device using 'network_get_device $bind_network' - Error: '$?'"
|
||||
write_log 7 "Force communication via device '$__DEVICE'"
|
||||
__PROG="$__PROG --interface $__DEVICE"
|
||||
fi
|
||||
@ -776,13 +805,7 @@ do_transfer() {
|
||||
# uclient-fetch possibly with ssl support if /lib/libustream-ssl.so installed
|
||||
elif [ -n "$UCLIENT_FETCH" ]; then
|
||||
# UCLIENT_FETCH_SSL not empty then SSL support available
|
||||
if [ -f /tmp/vUCLIENT_FETCH_SSL ]; then
|
||||
UCLIENT_FETCH_SSL=$(cat /tmp/vCURL_PROXY);
|
||||
else
|
||||
UCLIENT_FETCH_SSL=$(find /lib /usr/lib -name libustream-ssl.so* 2>/dev/null)
|
||||
echo -n $UCLIENT_FETCH_SSL >/tmp/vUCLIENT_FETCH_SSL
|
||||
fi
|
||||
|
||||
UCLIENT_FETCH_SSL=$(find /lib /usr/lib -name libustream-ssl.so* 2>/dev/null)
|
||||
__PROG="$UCLIENT_FETCH -q -O $DATFILE"
|
||||
# force network/ip not supported
|
||||
[ -n "$__BINDIP" ] && \
|
||||
@ -848,11 +871,11 @@ do_transfer() {
|
||||
}
|
||||
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Transfer failed after $retry_count retries"
|
||||
# if error count > retry_max_count leave here
|
||||
[ $retry_max_count -gt 0 -a $__CNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Transfer failed after $retry_max_count retries"
|
||||
|
||||
write_log 4 "Transfer failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
write_log 4 "Transfer failed - retry $__CNT/$retry_max_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
@ -904,26 +927,26 @@ send_update() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_local_ip () {
|
||||
# $1 Name of Variable to store local IP (LOCAL_IP)
|
||||
get_current_ip () {
|
||||
# $1 Name of Variable to store current IP
|
||||
local __CNT=0 # error counter
|
||||
local __RUNPROG __DATA __URL __ERR
|
||||
|
||||
[ $# -ne 1 ] && write_log 12 "Error calling 'get_local_ip()' - wrong number of parameters"
|
||||
write_log 7 "Detect local IP on '$ip_source'"
|
||||
[ $# -ne 1 ] && write_log 12 "Error calling 'get_current_ip()' - wrong number of parameters"
|
||||
write_log 7 "Detect current IP on '$ip_source'"
|
||||
|
||||
while : ; do
|
||||
if [ -n "$ip_network" ]; then
|
||||
if [ -n "$ip_network" -a "$ip_source" = "network" ]; then
|
||||
# set correct program
|
||||
network_flush_cache # force re-read data from ubus
|
||||
[ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
|
||||
|| __RUNPROG="network_get_ipaddr6"
|
||||
eval "$__RUNPROG __DATA $ip_network" || \
|
||||
write_log 13 "Can not detect local IP using $__RUNPROG '$ip_network' - Error: '$?'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on network '$ip_network'"
|
||||
elif [ -n "$ip_interface" ]; then
|
||||
write_log 13 "Can not detect current IP using $__RUNPROG '$ip_network' - Error: '$?'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Current IP '$__DATA' detected on network '$ip_network'"
|
||||
elif [ -n "$ip_interface" -a "$ip_source" = "interface" ]; then
|
||||
local __DATA4=""; local __DATA6=""
|
||||
if [ -n "$(which ip)" ]; then # ip program installed
|
||||
if [ -n "$(command -v ip)" ]; then # ip program installed
|
||||
write_log 7 "#> ip -o addr show dev $ip_interface scope global >$DATFILE 2>$ERRFILE"
|
||||
ip -o addr show dev $ip_interface scope global >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
@ -939,10 +962,17 @@ get_local_ip () {
|
||||
# 5: eth1 inet6 fd43:5368:6f6d:6500:a00:27ff:fed0:1032/64 scope global dynamic \ valid_lft 14352sec preferred_lft 14352sec
|
||||
# 5: eth1 inet6 2002:b0c7:f326::a00:27ff:fed0:1032/64 scope global dynamic \ valid_lft 14352sec preferred_lft 14352sec
|
||||
|
||||
# remove remove remove replace replace
|
||||
# link inet6 fxxx sec forever=>-1 / => ' ' to separate subnet from ip
|
||||
sed "/link/d; /inet6 f/d; s/sec//g; s/forever/-1/g; s/\// /g" $DATFILE | \
|
||||
awk '{ print $3" "$4" "$NF }' > $ERRFILE # temp reuse ERRFILE
|
||||
if [ $upd_privateip -eq 0 ]; then
|
||||
# remove remove remove replace replace
|
||||
# link inet6 fxxx sec forever=>-1 / => ' ' to separate subnet from ip
|
||||
sed "/link/d; /inet6 f/d; s/sec//g; s/forever/-1/g; s/\// /g" $DATFILE | \
|
||||
awk '{ print $3" "$4" "$NF }' > $ERRFILE # temp reuse ERRFILE
|
||||
else
|
||||
# remove remove replace replace
|
||||
# link sec forever=>-1 / => ' ' to separate subnet from ip
|
||||
sed "/link/d; s/sec//g; s/forever/-1/g; s/\// /g" $DATFILE | \
|
||||
awk '{ print $3" "$4" "$NF }' > $ERRFILE # temp reuse ERRFILE
|
||||
fi
|
||||
# we only need inet? IP prefered time
|
||||
|
||||
local __TIME4=0; local __TIME6=0
|
||||
@ -999,27 +1029,27 @@ get_local_ip () {
|
||||
fi
|
||||
fi
|
||||
[ $use_ipv6 -eq 0 ] && __DATA="$__DATA4" || __DATA="$__DATA6"
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on interface '$ip_interface'"
|
||||
elif [ -n "$ip_script" ]; then
|
||||
[ -n "$__DATA" ] && write_log 7 "Current IP '$__DATA' detected on interface '$ip_interface'"
|
||||
elif [ -n "$ip_script" -a "$ip_source" = "script" ]; then
|
||||
write_log 7 "#> $ip_script >$DATFILE 2>$ERRFILE"
|
||||
eval $ip_script >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
if [ $__ERR -eq 0 ]; then
|
||||
__DATA=$(cat $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected via script '$ip_script'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Current IP '$__DATA' detected via script '$ip_script'"
|
||||
else
|
||||
write_log 3 "$ip_script Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
fi
|
||||
elif [ -n "$ip_url" ]; then
|
||||
elif [ -n "$ip_url" -a "$ip_source" = "web" ]; then
|
||||
do_transfer "$ip_url"
|
||||
# use correct regular expression
|
||||
[ $use_ipv6 -eq 0 ] \
|
||||
&& __DATA=$(grep -m 1 -o "$IPV4_REGEX" $DATFILE) \
|
||||
|| __DATA=$(grep -m 1 -o "$IPV6_REGEX" $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on web at '$ip_url'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Current IP '$__DATA' detected on web at '$ip_url'"
|
||||
else
|
||||
write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
|
||||
write_log 12 "Error in 'get_current_ip()' - unhandled ip_source '$ip_source'"
|
||||
fi
|
||||
# valid data found return here
|
||||
[ -n "$__DATA" ] && {
|
||||
@ -1034,22 +1064,22 @@ get_local_ip () {
|
||||
|
||||
[ $VERBOSE -gt 1 ] && {
|
||||
# VERBOSE > 1 then NO retry
|
||||
write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
write_log 4 "Get current IP via '$ip_source' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return 1
|
||||
}
|
||||
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Get local IP via '$ip_source' failed after $retry_count retries"
|
||||
write_log 4 "Get local IP via '$ip_source' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
# if error count > retry_max_count leave here
|
||||
[ $retry_max_count -gt 0 -a $__CNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Get current IP via '$ip_source' failed after $retry_max_count retries"
|
||||
write_log 4 "Get current IP via '$ip_source' failed - retry $__CNT/$retry_max_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
PID_SLEEP=0
|
||||
done
|
||||
# we should never come here there must be a programming error
|
||||
write_log 12 "Error in 'get_local_ip()' - program coding error"
|
||||
write_log 12 "Error in 'get_current_ip()' - program coding error"
|
||||
}
|
||||
|
||||
get_registered_ip() {
|
||||
@ -1126,7 +1156,7 @@ get_registered_ip() {
|
||||
__RUNPROG="$__PROG $lookup_host >$DATFILE 2>$ERRFILE"
|
||||
__PROG="hostip"
|
||||
elif [ -n "$NSLOOKUP" ]; then # last use BusyBox nslookup
|
||||
NSLOOKUP_MUSL=$($(which nslookup) localhost 2>&1 | grep -F "(null)") # not empty busybox compiled with musl
|
||||
NSLOOKUP_MUSL=$($(command -v nslookup) localhost 2>&1 | grep -F "(null)") # not empty busybox compiled with musl
|
||||
[ $force_dnstcp -ne 0 ] && \
|
||||
write_log 14 "Busybox nslookup - no support for 'DNS over TCP'"
|
||||
[ -n "$NSLOOKUP_MUSL" -a -n "$dns_server" ] && \
|
||||
@ -1181,11 +1211,11 @@ get_registered_ip() {
|
||||
}
|
||||
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Get registered/public IP for '$lookup_host' failed after $retry_count retries"
|
||||
# if error count > retry_max_count leave here
|
||||
[ $retry_max_count -gt 0 -a $__CNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Get registered/public IP for '$lookup_host' failed after $retry_max_count retries"
|
||||
|
||||
write_log 4 "Get registered/public IP for '$lookup_host' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
write_log 4 "Get registered/public IP for '$lookup_host' failed - retry $__CNT/$retry_max_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
8
net/ddns-scripts/files/dynamic_dns_lucihelper.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh
Executable file → Normal file
8
net/ddns-scripts/files/dynamic_dns_lucihelper.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh
Executable file → Normal file
@ -137,11 +137,11 @@ case "$1" in
|
||||
if [ "$ip_source" = "web" -o "$ip_source" = "script" ]; then
|
||||
# we wait only 3 seconds for an
|
||||
# answer from "web" or "script"
|
||||
write_log 7 "-----> timeout 3 -- get_local_ip IP"
|
||||
timeout 3 -- get_local_ip IP
|
||||
write_log 7 "-----> timeout 3 -- get_current_ip IP"
|
||||
timeout 3 -- get_current_ip IP
|
||||
else
|
||||
write_log 7 "-----> get_local_ip IP"
|
||||
get_local_ip IP
|
||||
write_log 7 "-----> get_current_ip IP"
|
||||
get_current_ip IP
|
||||
fi
|
||||
__RET=$?
|
||||
;;
|
100
net/ddns-scripts/files/dynamic_dns_updater.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh
Executable file → Normal file
100
net/ddns-scripts/files/dynamic_dns_updater.sh → net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh
Executable file → Normal file
@ -37,9 +37,7 @@ Parameters:
|
||||
'1' output to console
|
||||
'2' output to console AND logfile
|
||||
+ run once WITHOUT retry on error
|
||||
'3' output to console AND logfile
|
||||
+ run once WITHOUT retry on error
|
||||
+ NOT sending update to DDNS service
|
||||
-d dry run (don't send any changes)
|
||||
|
||||
EOF
|
||||
}
|
||||
@ -50,10 +48,11 @@ usage_err() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts ":hv:n:S:V" OPT; do
|
||||
while getopts ":hv:dn:S:V" OPT; do
|
||||
case "$OPT" in
|
||||
h) usage; exit 0;;
|
||||
v) VERBOSE=$OPTARG;;
|
||||
d) DRY_RUN=1;;
|
||||
n) NETWORK=$OPTARG;;
|
||||
S) SECTION_ID=$OPTARG;;
|
||||
V) printf %s\\n "ddns-scripts $VERSION"; exit 0;;
|
||||
@ -90,7 +89,7 @@ case "$1" in
|
||||
exit 1
|
||||
;;
|
||||
reload)
|
||||
killall -1 dynamic_dns_updater.sh 2>/dev/null
|
||||
killall dynamic_dns_updater.sh 2>/dev/null
|
||||
exit $?
|
||||
;;
|
||||
*) usage_err "unknown command - $1";;
|
||||
@ -108,6 +107,8 @@ LOGFILE="$ddns_logdir/$SECTION_ID.log" # log file
|
||||
# only with this data of this run for easier diagnostic
|
||||
# new one created by write_log function
|
||||
[ $VERBOSE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE
|
||||
# Previously -v 3 could we used for dry run
|
||||
[ $VERBOSE -ge 3 ] && DRY_RUN=1
|
||||
|
||||
# TRAP handler
|
||||
trap "trap_handler 0 \$?" 0 # handle script exit with exit status
|
||||
@ -145,10 +146,10 @@ trap "trap_handler 15" 15 # SIGTERM Termination
|
||||
#
|
||||
# use_syslog log activity to syslog
|
||||
#
|
||||
# ip_source source to detect current local IP ('network' or 'web' or 'script' or 'interface')
|
||||
# ip_source source to detect current IP ('network' or 'web' or 'script' or 'interface')
|
||||
# ip_network local defined network to read IP from i.e. 'wan' or 'wan6'
|
||||
# ip_url URL to read local address from i.e. http://checkip.dyndns.com/ or http://checkipv6.dyndns.com/
|
||||
# ip_script full path and name of your script to detect local IP
|
||||
# ip_url URL to read current IP from i.e. http://checkip.dyndns.com/ or http://checkipv6.dyndns.com/
|
||||
# ip_script full path and name of your script to detect current IP
|
||||
# ip_interface physical interface to use for detecting
|
||||
#
|
||||
# check_interval check for changes every !!! checks below 10 minutes make no sense because the Internet
|
||||
@ -159,13 +160,13 @@ trap "trap_handler 15" 15 # SIGTERM Termination
|
||||
#
|
||||
# retry_interval if error was detected retry in
|
||||
# retry_unit 'days' 'hours' 'minutes' 'seconds'
|
||||
# retry_count number of retries before scripts stops
|
||||
# retry_max_count number of retries before scripts stops
|
||||
#
|
||||
# use_ipv6 detecting/sending IPv6 address
|
||||
# force_ipversion force usage of IPv4 or IPv6 for the whole detection and update communication
|
||||
# dns_server using a non default dns server to get Registered IP from Internet
|
||||
# force_dnstcp force communication with DNS server via TCP instead of default UDP
|
||||
# proxy using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!!
|
||||
# proxy using a proxy for communication !!! ALSO used to detect current IP via web => return proxy's IP !!!
|
||||
# use_logfile self-explanatory "/var/log/ddns/$SECTION_ID.log"
|
||||
# is_glue the record that should be updated is a glue record
|
||||
#
|
||||
@ -180,7 +181,7 @@ ERR_LAST=$? # save return code - equal 0 if SECTION_ID found
|
||||
|
||||
# set defaults if not defined
|
||||
[ -z "$enabled" ] && enabled=0
|
||||
[ -z "$retry_count" ] && retry_count=0 # endless retry
|
||||
[ -z "$retry_max_count" ] && retry_max_count=0 # endless retry
|
||||
[ -z "$use_syslog" ] && use_syslog=2 # syslog "Notice"
|
||||
[ -z "$use_https" ] && use_https=0 # not use https
|
||||
[ -z "$use_logfile" ] && use_logfile=1 # use logfile by default
|
||||
@ -222,9 +223,9 @@ case $VERBOSE in
|
||||
0) write_log 7 "verbose mode : 0 - run normal, NO console output";;
|
||||
1) write_log 7 "verbose mode : 1 - run normal, console mode";;
|
||||
2) write_log 7 "verbose mode : 2 - run once, NO retry on error";;
|
||||
3) write_log 7 "verbose mode : 3 - run once, NO retry on error, NOT sending update";;
|
||||
*) write_log 14 "error detecting VERBOSE '$VERBOSE'";;
|
||||
esac
|
||||
[ $DRY_RUN -ge 1 ] && write_log 7 "Dry Run: NOT sending update"
|
||||
|
||||
# check enabled state otherwise we don't need to continue
|
||||
[ $enabled -eq 0 ] && write_log 14 "Service section disabled!"
|
||||
@ -232,7 +233,14 @@ esac
|
||||
# determine what update url we're using if a service_name is supplied
|
||||
# otherwise update_url is set inside configuration (custom update url)
|
||||
# or update_script is set inside configuration (custom update script)
|
||||
[ -n "$service_name" ] && get_service_data update_url update_script UPD_ANSWER
|
||||
[ -n "$service_name" ] && {
|
||||
# Check first if we have a custom service provider with this name
|
||||
get_service_data "$service_name" "/usr/share/ddns/custom" update_url update_script UPD_ANSWER
|
||||
if [ "$?" != "0" ]; then
|
||||
get_service_data "$service_name" "/usr/share/ddns/default" update_url update_script UPD_ANSWER
|
||||
fi
|
||||
}
|
||||
|
||||
[ -z "$update_url" -a -z "$update_script" ] && write_log 14 "No update_url found/defined or no update_script found/defined!"
|
||||
[ -n "$update_script" -a ! -f "$update_script" ] && write_log 14 "Custom update_script not found!"
|
||||
|
||||
@ -247,6 +255,15 @@ esac
|
||||
# without lookup host and possibly other required options we can do nothing for you
|
||||
[ -z "$lookup_host" ] && write_log 14 "Service section not configured correctly! Missing 'lookup_host'"
|
||||
|
||||
# verify validity of variables
|
||||
[ -n "$lookup_host" ] && sanitize_variable lookup_host "$DNS_CHARSET" ""
|
||||
[ -n "$dns_server" ] && sanitize_variable dns_server "$DNS_CHARSET" ""
|
||||
[ -n "$domain" ] && sanitize_variable domain "$DNS_CHARSET_DOMAIN" ""
|
||||
|
||||
# Filter shell escape characters, if these are required in the URL, they
|
||||
# can still be passed url encoded
|
||||
[ -n "$param_opt" ] && sanitize_variable param_opt "" "$SHELL_ESCAPE"
|
||||
|
||||
[ -n "$update_url" ] && {
|
||||
# only check if update_url is given, update_scripts have to check themselves
|
||||
[ -z "$domain" ] && $(echo "$update_url" | grep "\[DOMAIN\]" >/dev/null 2>&1) && \
|
||||
@ -264,8 +281,8 @@ esac
|
||||
# verify ip_source 'script' if script is configured and executable
|
||||
if [ "$ip_source" = "script" ]; then
|
||||
set -- $ip_script #handling script with parameters, we need a trick
|
||||
[ -z "$1" ] && write_log 14 "No script defined to detect local IP!"
|
||||
[ -x "$1" ] || write_log 14 "Script to detect local IP not executable!"
|
||||
[ -z "$1" ] && write_log 14 "No script defined to detect current IP!"
|
||||
[ -x "$1" ] || write_log 14 "Script to detect current IP not executable!"
|
||||
fi
|
||||
|
||||
# compute update interval in seconds
|
||||
@ -277,7 +294,7 @@ get_seconds RETRY_SECONDS ${retry_interval:-60} ${retry_unit:-"seconds"} # defau
|
||||
write_log 7 "check interval: $CHECK_SECONDS seconds"
|
||||
write_log 7 "force interval: $FORCE_SECONDS seconds"
|
||||
write_log 7 "retry interval: $RETRY_SECONDS seconds"
|
||||
write_log 7 "retry counter : $retry_count times"
|
||||
write_log 7 "retry max count : $retry_max_count times"
|
||||
|
||||
# kill old process if it exists & set new pid file
|
||||
stop_section_processes "$SECTION_ID"
|
||||
@ -305,9 +322,6 @@ else
|
||||
write_log 7 "last update: $(eval $EPOCH_TIME)"
|
||||
fi
|
||||
|
||||
# verify DNS server
|
||||
[ -n "$dns_server" ] && verify_dns "$dns_server"
|
||||
|
||||
# verify Proxy server and set environment
|
||||
[ -n "$proxy" ] && {
|
||||
verify_proxy "$proxy" && {
|
||||
@ -331,8 +345,8 @@ ERR_LAST=$?
|
||||
write_log 6 "Starting main loop at $(eval $DATE_PROG)"
|
||||
while : ; do
|
||||
|
||||
get_local_ip LOCAL_IP # read local IP
|
||||
[ $use_ipv6 -eq 1 ] && expand_ipv6 "$LOCAL_IP" LOCAL_IP # on IPv6 we use expanded version
|
||||
get_current_ip CURRENT_IP # read current IP
|
||||
[ $use_ipv6 -eq 1 ] && expand_ipv6 "$CURRENT_IP" CURRENT_IP # on IPv6 we use expanded version
|
||||
|
||||
# prepare update
|
||||
# never updated or forced immediate then NEXT_TIME = 0
|
||||
@ -342,24 +356,23 @@ while : ; do
|
||||
|
||||
get_uptime CURR_TIME # get current uptime
|
||||
|
||||
# send update when current time > next time or local ip different from registered ip
|
||||
if [ $CURR_TIME -ge $NEXT_TIME -o "$LOCAL_IP" != "$REGISTERED_IP" ]; then
|
||||
if [ $VERBOSE -gt 2 ]; then
|
||||
write_log 7 "Verbose Mode: $VERBOSE - NO UPDATE send"
|
||||
elif [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
|
||||
write_log 7 "Update needed - L: '$LOCAL_IP' <> R: '$REGISTERED_IP'"
|
||||
# send update when current time > next time or current ip different from registered ip
|
||||
if [ $CURR_TIME -ge $NEXT_TIME -o "$CURRENT_IP" != "$REGISTERED_IP" ]; then
|
||||
if [ $DRY_RUN -ge 1 ]; then
|
||||
write_log 7 "Dry Run: NO UPDATE send"
|
||||
elif [ "$CURRENT_IP" != "$REGISTERED_IP" ]; then
|
||||
write_log 7 "Update needed - L: '$CURRENT_IP' <> R: '$REGISTERED_IP'"
|
||||
else
|
||||
write_log 7 "Forced Update - L: '$LOCAL_IP' == R: '$REGISTERED_IP'"
|
||||
write_log 7 "Forced Update - L: '$CURRENT_IP' == R: '$REGISTERED_IP'"
|
||||
fi
|
||||
|
||||
ERR_LAST=0
|
||||
[ $VERBOSE -lt 3 ] && {
|
||||
# only send if VERBOSE < 3
|
||||
send_update "$LOCAL_IP"
|
||||
[ $DRY_RUN -eq 0 ] && {
|
||||
send_update "$CURRENT_IP"
|
||||
ERR_LAST=$? # save return value
|
||||
}
|
||||
|
||||
# error sending local IP to provider
|
||||
# error sending current IP to provider
|
||||
# we have no communication error (handled inside send_update/do_transfer)
|
||||
# but update was not recognized
|
||||
# do NOT retry after RETRY_SECONDS, do retry after CHECK_SECONDS
|
||||
@ -368,9 +381,9 @@ while : ; do
|
||||
if [ $ERR_LAST -eq 0 ]; then
|
||||
get_uptime LAST_TIME # we send update, so
|
||||
echo $LAST_TIME > $UPDFILE # save LASTTIME to file
|
||||
[ "$LOCAL_IP" != "$REGISTERED_IP" ] \
|
||||
&& write_log 6 "Update successful - IP '$LOCAL_IP' send" \
|
||||
|| write_log 6 "Forced update successful - IP: '$LOCAL_IP' send"
|
||||
[ "$CURRENT_IP" != "$REGISTERED_IP" ] \
|
||||
&& write_log 6 "Update successful - IP '$CURRENT_IP' send" \
|
||||
|| write_log 6 "Forced update successful - IP: '$CURRENT_IP' send"
|
||||
elif [ $ERR_LAST -eq 127 ]; then
|
||||
write_log 3 "No update send to DDNS Provider"
|
||||
else
|
||||
@ -379,26 +392,25 @@ while : ; do
|
||||
fi
|
||||
|
||||
# now we wait for check interval before testing if update was recognized
|
||||
# only sleep if VERBOSE <= 2 because otherwise nothing was send
|
||||
[ $VERBOSE -le 2 ] && {
|
||||
[ $DRY_RUN -eq 0 ] && {
|
||||
write_log 7 "Waiting $CHECK_SECONDS seconds (Check Interval)"
|
||||
sleep $CHECK_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
PID_SLEEP=0
|
||||
} || write_log 7 "Verbose Mode: $VERBOSE - NO Check Interval waiting"
|
||||
} || write_log 7 "Dry Run: NO Check Interval waiting"
|
||||
|
||||
REGISTERED_IP="" # clear variable
|
||||
get_registered_ip REGISTERED_IP # get registered/public IP
|
||||
[ $use_ipv6 -eq 1 ] && expand_ipv6 "$REGISTERED_IP" REGISTERED_IP # on IPv6 we use expanded version
|
||||
|
||||
# IP's are still different
|
||||
if [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
|
||||
if [ "$CURRENT_IP" != "$REGISTERED_IP" ]; then
|
||||
if [ $VERBOSE -le 1 ]; then # VERBOSE <=1 then retry
|
||||
ERR_UPDATE=$(( $ERR_UPDATE + 1 ))
|
||||
[ $retry_count -gt 0 -a $ERR_UPDATE -gt $retry_count ] && \
|
||||
write_log 14 "Updating IP at DDNS provider failed after $retry_count retries"
|
||||
write_log 4 "Updating IP at DDNS provider failed - starting retry $ERR_UPDATE/$retry_count"
|
||||
RETRY_COUNT=$(( $RETRY_COUNT + 1 ))
|
||||
[ $retry_max_count -gt 0 -a $RETRY_COUNT -gt $retry_max_count ] && \
|
||||
write_log 14 "Updating IP at DDNS provider failed after $retry_max_count retries"
|
||||
write_log 4 "Updating IP at DDNS provider failed - starting retry $RETRY_COUNT/$retry_max_count"
|
||||
continue # loop to beginning
|
||||
else
|
||||
write_log 4 "Updating IP at DDNS provider failed"
|
||||
@ -406,7 +418,7 @@ while : ; do
|
||||
fi
|
||||
else
|
||||
# we checked successful the last update
|
||||
ERR_UPDATE=0 # reset error counter
|
||||
RETRY_COUNT=0 # reset error counter
|
||||
fi
|
||||
|
||||
# force_update=0 or VERBOSE > 1 - leave here
|
58
net/ddns-scripts/files/update_cloudflare_com_v4.sh → net/ddns-scripts/files/usr/lib/ddns/update_cloudflare_com_v4.sh
Executable file → Normal file
58
net/ddns-scripts/files/update_cloudflare_com_v4.sh → net/ddns-scripts/files/usr/lib/ddns/update_cloudflare_com_v4.sh
Executable file → Normal file
@ -15,7 +15,7 @@
|
||||
# option password - cloudflare api key, you can get it from cloudflare.com/my-account/
|
||||
# option domain - "hostname@yourdomain.TLD" # syntax changed to remove split_FQDN() function and tld_names.dat.gz
|
||||
#
|
||||
# The proxy status would not be changed by this script. Please change it in Cloudflare dashboard manually.
|
||||
# The proxy status would not be changed by this script. Please change it in Cloudflare dashboard manually.
|
||||
#
|
||||
# variable __IP already defined with the ip-address to use for update
|
||||
#
|
||||
@ -27,21 +27,26 @@
|
||||
[ $use_https -eq 0 ] && use_https=1 # force HTTPS
|
||||
|
||||
# used variables
|
||||
local __HOST __DOMAIN __FULLDOMAIN __TYPE __URLBASE __PRGBASE __RUNPROG __DATA __IPV6 __ZONEID __RECID __PROXIED
|
||||
local __HOST __DOMAIN __TYPE __URLBASE __PRGBASE __RUNPROG __DATA __IPV6 __ZONEID __RECID __PROXIED
|
||||
local __URLBASE="https://api.cloudflare.com/client/v4"
|
||||
local __TTL=120
|
||||
|
||||
# split __HOST __DOMAIN from $domain
|
||||
[ "${domain:0:2}" == "@." ] && domain="${domain/./}"
|
||||
[ "$domain" == "${domain/@/}" ] && domain="${domain/./@}"
|
||||
__HOST="${domain%%@*}"
|
||||
__DOMAIN="${domain#*@}"
|
||||
[ -z "$__HOST" -o "$__HOST" == "$__DOMAIN" ] && __HOST="@"
|
||||
if [ "$__HOST" = "@" ]; then
|
||||
__FULLDOMAIN="${__DOMAIN}"
|
||||
else
|
||||
__FULLDOMAIN="${__HOST}.${__DOMAIN}"
|
||||
fi
|
||||
# given data:
|
||||
# @example.com for "domain record"
|
||||
# host.sub@example.com for a "host record"
|
||||
__HOST=$(printf %s "$domain" | cut -d@ -f1)
|
||||
__DOMAIN=$(printf %s "$domain" | cut -d@ -f2)
|
||||
|
||||
# Cloudflare v4 needs:
|
||||
# __DOMAIN = the base domain i.e. example.com
|
||||
# __HOST = the FQDN of record to modify
|
||||
# i.e. example.com for the "domain record" or host.sub.example.com for "host record"
|
||||
|
||||
# handling domain record then set __HOST = __DOMAIN
|
||||
[ -z "$__HOST" ] && __HOST=$__DOMAIN
|
||||
# handling host record then rebuild fqdn host@domain.tld => host.domain.tld
|
||||
[ "$__HOST" != "$__DOMAIN" ] && __HOST="${__HOST}.${__DOMAIN}"
|
||||
|
||||
# set record type
|
||||
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
|
||||
@ -129,23 +134,27 @@ else
|
||||
fi
|
||||
__PRGBASE="$__PRGBASE --header 'Content-Type: application/json' "
|
||||
|
||||
# read zone id for registered domain.TLD
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones?name=$__DOMAIN'"
|
||||
cloudflare_transfer || return 1
|
||||
# extract zone id
|
||||
__ZONEID=$(grep -o '"id":\s*"[^"]*' $DATFILE | grep -o '[^"]*$' | head -1)
|
||||
[ -z "$__ZONEID" ] && {
|
||||
write_log 4 "Could not detect 'zone id' for domain.tld: '$__DOMAIN'"
|
||||
return 127
|
||||
}
|
||||
if [ -n "$zone_id" ]; then
|
||||
__ZONEID="$zone_id"
|
||||
else
|
||||
# read zone id for registered domain.TLD
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones?name=$__DOMAIN'"
|
||||
cloudflare_transfer || return 1
|
||||
# extract zone id
|
||||
__ZONEID=$(grep -o '"id":\s*"[^"]*' $DATFILE | grep -o '[^"]*$' | head -1)
|
||||
[ -z "$__ZONEID" ] && {
|
||||
write_log 4 "Could not detect 'zone id' for domain.tld: '$__DOMAIN'"
|
||||
return 127
|
||||
}
|
||||
fi
|
||||
|
||||
# read record id for A or AAAA record of host.domain.TLD
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones/$__ZONEID/dns_records?name=${__FULLDOMAIN}&type=$__TYPE'"
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones/$__ZONEID/dns_records?name=$__HOST&type=$__TYPE'"
|
||||
cloudflare_transfer || return 1
|
||||
# extract record id
|
||||
__RECID=$(grep -o '"id":\s*"[^"]*' $DATFILE | grep -o '[^"]*$' | head -1)
|
||||
[ -z "$__RECID" ] && {
|
||||
write_log 4 "Could not detect 'record id' for host.domain.tld: '${__FULLDOMAIN}'"
|
||||
write_log 4 "Could not detect 'record id' for host.domain.tld: '$__HOST'"
|
||||
return 127
|
||||
}
|
||||
|
||||
@ -182,7 +191,7 @@ __PROXIED=$(grep -o '"proxied":\s*[^",]*' $DATFILE | grep -o '[^:]*$')
|
||||
|
||||
# use file to work around " needed for json
|
||||
cat > $DATFILE << EOF
|
||||
{"id":"$__ZONEID","type":"$__TYPE","name":"${__FULLDOMAIN}","content":"$__IP","ttl":$__TTL,"proxied":$__PROXIED}
|
||||
{"id":"$__ZONEID","type":"$__TYPE","name":"$__HOST","content":"$__IP","ttl":$__TTL,"proxied":$__PROXIED}
|
||||
EOF
|
||||
|
||||
# let's complete transfer command
|
||||
@ -190,3 +199,4 @@ __RUNPROG="$__PRGBASE --request PUT --data @$DATFILE '$__URLBASE/zones/$__ZONEID
|
||||
cloudflare_transfer || return 1
|
||||
|
||||
return 0
|
||||
|
86
net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh
Normal file
86
net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh
Normal file
@ -0,0 +1,86 @@
|
||||
# inside url we need domain, username and password
|
||||
[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing 'domain'"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
|
||||
|
||||
local urlCp='http://cp.cnkuai.cn/'
|
||||
local urlLogin='http://cp.cnkuai.cn/userlogin.asp'
|
||||
local urlCaptcha='http://cp.cnkuai.cn/inc/image.asp'
|
||||
local urlDnsA='http://cp.cnkuai.cn/dns_a.asp'
|
||||
local urlDnsAAAA='http://cp.cnkuai.cn/dns_ipv6.asp'
|
||||
local urlDnsSave='http://cp.cnkuai.cn/dns_save.asp'
|
||||
|
||||
getPixel(){
|
||||
local filename=$1
|
||||
local x=$(($2*3))
|
||||
local y=$(($3*3))
|
||||
local width=48
|
||||
|
||||
hexdump -s "$((x+width*y))" -n 3 -e '3/1 "%02X"' "$filename"
|
||||
}
|
||||
|
||||
captchaChar(){
|
||||
local filename=$1
|
||||
local xoffset=$2
|
||||
|
||||
if [ "$(getPixel "$filename" $((xoffset+2)) 5)" = '000000' ]; then
|
||||
echo '1'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+5)) 7)" = '000000' ]; then
|
||||
echo '2'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+4)) 3)" = '000000' ]; then
|
||||
echo '4'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+6)) 4)" = '000000' ]; then
|
||||
echo '7'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+5)) 8)" = '000000' ]; then
|
||||
echo '8'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+6)) 8)" = '000000' ]; then
|
||||
echo '9'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+5)) 6)" = '000000' ]; then
|
||||
echo '3'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+0)) 4)" = '000000' ]; then
|
||||
echo '5'
|
||||
elif [ "$(getPixel "$filename" $((xoffset+1)) 5)" = '000000' ]; then
|
||||
echo '6'
|
||||
else
|
||||
echo '0'
|
||||
fi
|
||||
}
|
||||
|
||||
captcha(){
|
||||
local str
|
||||
str=$(captchaChar "$1" 9)
|
||||
str=$str$(captchaChar "$1" 18)
|
||||
str=$str$(captchaChar "$1" 26)
|
||||
str=$str$(captchaChar "$1" 35)
|
||||
echo "$str"
|
||||
}
|
||||
|
||||
#clean
|
||||
rm /tmp/cnkuai.*
|
||||
#login to cnkuai dns cp
|
||||
curl -c '/tmp/cnkuai.cookiejar' "$urlCaptcha" | gif2rgb > /tmp/cnkuai.rgb || return 1
|
||||
yzm=$(captcha "/tmp/cnkuai.rgb")
|
||||
curl -b '/tmp/cnkuai.cookiejar' -c '/tmp/cnkuai.cookiejar' -H "Content-Type: application/x-www-form-urlencoded" -H "Referer: $urlCp" -d "userid=$URL_USER&password=$URL_PASS&yzm=$yzm&B1=%C8%B7%C8%CF%B5%C7%C2%BD&lx=0&userlx=3" -X POST "$urlLogin" > /dev/null || return 1
|
||||
|
||||
if [ "$use_ipv6" -eq 0 ]; then
|
||||
curl -b '/tmp/cnkuai.cookiejar' -c '/tmp/cnkuai.cookiejar' "$urlDnsA" > /tmp/cnkuai.html || return 1
|
||||
else
|
||||
curl -b '/tmp/cnkuai.cookiejar' -c '/tmp/cnkuai.cookiejar' "$urlDnsAAAA" > /tmp/cnkuai.html || return 1
|
||||
fi
|
||||
local domainline
|
||||
domainline=$(awk "/<td>$domain<\/td>/{ print NR; exit }" /tmp/cnkuai.html)
|
||||
local domainid
|
||||
domainid=$(awk "NR==$((domainline+3))" /tmp/cnkuai.html | sed 's/^.*name=\x27domainid\x27 value="//g' | sed 's/".*$//g')
|
||||
local dnslistid
|
||||
dnslistid=$(awk "NR==$((domainline+3))" /tmp/cnkuai.html | sed 's/^.*name=\x27dnslistid\x27 value="//g' | sed 's/".*$//g')
|
||||
|
||||
local data
|
||||
|
||||
if [ "$use_ipv6" -eq 0 ]; then
|
||||
data="T2=$__IP&T3=120&act=dns_a_edit&domainid=$domainid&dnslistid=$dnslistid&B1=%D0%DE%B8%C4"
|
||||
else
|
||||
data="T2=$__IP&T3=120&act=dns_ipv6_edit&domainid=$domainid&dnslistid=$dnslistid&B1=%D0%DE%B8%C4"
|
||||
fi
|
||||
curl -b '/tmp/cnkuai.cookiejar' -c '/tmp/cnkuai.cookiejar' -H "Content-Type: application/x-www-form-urlencoded" -H "Referer: $urlDnsA" -d "$data" -X POST "$urlDnsSave" > /dev/null || return 1
|
||||
|
||||
return 0
|
@ -0,0 +1,40 @@
|
||||
# Script for sending user defined updates using the DigitalOcean API
|
||||
# 2015 Artem Yakimenko <code at temik dot me>
|
||||
# 2021 George Giannou <giannoug at gmail dot com>
|
||||
|
||||
# Options passed from /etc/config/ddns:
|
||||
# Domain - the domain name managed by DigitalOcean (e.g. example.com)
|
||||
# Username - the hostname of the domain (e.g. myrouter)
|
||||
# Password - DigitalOcean personal access token (API key)
|
||||
# Optional Parameter - the API domain record ID of the hostname (e.g. 21694203)
|
||||
|
||||
# Use the following command to find your API domain record ID (replace TOKEN and DOMAIN with your own):
|
||||
# curl -X GET -H 'Content-Type: application/json' \
|
||||
# -H "Authorization: Bearer TOKEN" \
|
||||
# "https://api.digitalocean.com/v2/domains/DOMAIN/records"
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing domain name as 'Domain'"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing hostname as 'Username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing personal access token as 'Password'"
|
||||
[ -z "$param_opt" ] && write_log 14 "Service section not configured correctly! Missing API domain record ID as 'Optional Parameter'"
|
||||
|
||||
# Construct JSON payload
|
||||
json_init
|
||||
json_add_string name "$username"
|
||||
json_add_string data "$__IP"
|
||||
|
||||
__STATUS=$(curl -Ss -X PUT "https://api.digitalocean.com/v2/domains/${domain}/records/${param_opt}" \
|
||||
-H "Authorization: Bearer ${password}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(json_dump)" \
|
||||
-w "%{http_code}\n" -o $DATFILE 2>$ERRFILE)
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat $ERRFILE)"
|
||||
return 1
|
||||
elif [ -z $__STATUS ] || [ $__STATUS != 200 ]; then
|
||||
write_log 14 "Curl failed: $__STATUS \ndigitalocean.com answered: $(cat $DATFILE)"
|
||||
return 1
|
||||
fi
|
137
net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh
Executable file
137
net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh
Executable file
@ -0,0 +1,137 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check inputs
|
||||
[ -z "$username" ] && write_log 14 "Configuration error! [User name] cannot be empty"
|
||||
[ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty"
|
||||
|
||||
# Check external tools
|
||||
[ -n "$CURL_SSL" ] || write_log 13 "Dnspod communication require cURL with SSL support. Please install"
|
||||
[ -n "$CURL_PROXY" ] || write_log 13 "cURL: libcurl compiled without Proxy support"
|
||||
|
||||
# Declare variables
|
||||
#local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __TTL
|
||||
__URLBASE="https://dnsapi.cn"
|
||||
|
||||
# Get host and domain from $domain
|
||||
[ "${domain:0:2}" = "@." ] && domain="${domain/./}" # host
|
||||
[ "$domain" = "${domain/@/}" ] && domain="${domain/./@}" # host with no sperator
|
||||
__HOST="${domain%%@*}"
|
||||
__DOMAIN="${domain#*@}"
|
||||
[ -z "$__HOST" -o "$__HOST" = "$__DOMAIN" ] && __HOST=@
|
||||
|
||||
# Set record type
|
||||
[ $use_ipv6 = 0 ] && __TYPE=A || __TYPE=AAAA
|
||||
|
||||
# Build base command
|
||||
build_command() {
|
||||
__CMDBASE="$CURL -Ss"
|
||||
# bind host/IP
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __DEVICE
|
||||
network_get_physdev __DEVICE $bind_network || write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'"
|
||||
write_log 7 "Force communication via device '$__DEVICE'"
|
||||
__CMDBASE="$__CMDBASE --interface $__DEVICE"
|
||||
fi
|
||||
# Force IP version
|
||||
if [ $force_ipversion = 1 ]; then
|
||||
[ $use_ipv6 = 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
|
||||
fi
|
||||
# Set CA
|
||||
if [ $use_https = 1 ]; then
|
||||
if [ "$cacert" = IGNORE ]; then
|
||||
__CMDBASE="$__CMDBASE --insecure"
|
||||
elif [ -f "$cacert" ]; then
|
||||
__CMDBASE="$__CMDBASE --cacert $cacert"
|
||||
elif [ -d "$cacert" ]; then
|
||||
__CMDBASE="$__CMDBASE --capath $cacert"
|
||||
elif [ -n "$cacert" ]; then
|
||||
write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
|
||||
fi
|
||||
fi
|
||||
# Set if no proxy (might be an error with .wgetrc or env)
|
||||
[ -z "$proxy" ] && __CMDBASE="$__CMDBASE --noproxy '*'"
|
||||
__CMDBASE="$__CMDBASE -d"
|
||||
}
|
||||
|
||||
# Dnspod API
|
||||
dnspod_transfer() {
|
||||
__CNT=0
|
||||
case "$1" in
|
||||
0) __A="$__CMDBASE '$__POST' $__URLBASE/Record.List" ;;
|
||||
1) __A="$__CMDBASE '$__POST1' $__URLBASE/Record.Create" ;;
|
||||
2) __A="$__CMDBASE '$__POST1&record_id=$__RECID&ttl=$__TTL' $__URLBASE/Record.Modify" ;;
|
||||
esac
|
||||
|
||||
write_log 7 "#> $__A"
|
||||
while ! __TMP=$(eval $__A 2>&1); do
|
||||
write_log 3 "[$__TMP]"
|
||||
if [ $VERBOSE -gt 1 ]; then
|
||||
write_log 4 "Transfer failed - detailed mode: $VERBOSE - Do not try again after an error"
|
||||
return 1
|
||||
fi
|
||||
__CNT=$(($__CNT + 1))
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && write_log 14 "Transfer failed after $retry_count retries"
|
||||
write_log 4 "Transfer failed - $__CNT Try again in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP
|
||||
PID_SLEEP=0
|
||||
done
|
||||
__ERR=$(jsonfilter -s "$__TMP" -e "@.status.code")
|
||||
[ $__ERR = 1 ] && return 0
|
||||
[ $__ERR = 10 ] && [ $1 = 0 ] && return 0
|
||||
__TMP=$(jsonfilter -s "$__TMP" -e "@.status.message")
|
||||
local A="$(date +%H%M%S) ERROR : [$__TMP] - Terminate process"
|
||||
logger -p user.err -t ddns-scripts[$$] $SECTION_ID: ${A:15}
|
||||
printf "%s\n" " $A" >>$LOGFILE
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Add record
|
||||
add_domain() {
|
||||
dnspod_transfer 1
|
||||
printf "%s\n" " $(date +%H%M%S) : Record add successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP]" >>$LOGFILE
|
||||
return 0
|
||||
}
|
||||
|
||||
# Modify record
|
||||
update_domain() {
|
||||
dnspod_transfer 2
|
||||
printf "%s\n" " $(date +%H%M%S) : Record modified successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP],[TTL:$__TTL]" >>$LOGFILE
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get DNS record
|
||||
describe_domain() {
|
||||
ret=0
|
||||
__POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST"
|
||||
__POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0"
|
||||
dnspod_transfer 0
|
||||
__TMP=$(jsonfilter -s "$__TMP" -e "@.records[@.type='$__TYPE' && @.line_id='0']")
|
||||
if [ -z "$__TMP" ]; then
|
||||
printf "%s\n" " $(date +%H%M%S) : Record not exist: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN]" >>$LOGFILE
|
||||
ret=1
|
||||
else
|
||||
__RECIP=$(jsonfilter -s "$__TMP" -e "@.value")
|
||||
if [ "$__RECIP" != "$__IP" ]; then
|
||||
__RECID=$(jsonfilter -s "$__TMP" -e "@.id")
|
||||
__TTL=$(jsonfilter -s "$__TMP" -e "@.ttl")
|
||||
printf "%s\n" " $(date +%H%M%S) : Record needs to be updated: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
|
||||
ret=2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
build_command
|
||||
describe_domain
|
||||
if [ $ret = 1 ]; then
|
||||
sleep 3
|
||||
add_domain
|
||||
elif [ $ret = 2 ]; then
|
||||
sleep 3
|
||||
update_domain
|
||||
else
|
||||
printf "%s\n" " $(date +%H%M%S) : Record needs not update: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
|
||||
fi
|
||||
|
||||
return 0
|
2
net/ddns-scripts/files/update_freedns_42_pl.sh → net/ddns-scripts/files/usr/lib/ddns/update_freedns_42_pl.sh
Executable file → Normal file
2
net/ddns-scripts/files/update_freedns_42_pl.sh → net/ddns-scripts/files/usr/lib/ddns/update_freedns_42_pl.sh
Executable file → Normal file
@ -5,7 +5,7 @@ local __URL="https://freedns.42.pl/xmlrpc.php"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
|
||||
[ $ip_dynamic -eq 1 ] && __IP='\<dynamic\>'
|
||||
PROG="$(which curl) -sk"
|
||||
PROG="$(command -v curl) -sk"
|
||||
write_log 7 "sending update to freedns.42.pl with ip $__IP"
|
||||
XMLDATA="<?xml version='1.0'?><methodCall><methodName>xname.updateArecord</methodName><params><param><value><struct><member><name>name</name><value><string>[RECORDNAME]</string></value></member><member><name>zone</name><value><string>[ZONENAME]</string></value></member><member><name>oldaddress</name><value><string>*</string></value></member><member><name>updatereverse</name><value><string>0</string></value></member><member><name>user</name><value><string>[USERNAME]</string></value></member><member><name>ttl</name><value><string>600</string></value></member><member><name>newaddress</name><value><string>[IP]</string></value></member><member><name>password</name><value><string>[PASSWORD]</string></value></member></struct></value></param></params></methodCall>"
|
||||
XMLDATA=$(echo $XMLDATA | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
|
48
net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh
Normal file
48
net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh
Normal file
@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
# Thanks goes to Alex Griffin who provided this script.
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
local __TTL=600
|
||||
local __RRTYPE
|
||||
local __ENDPOINT="https://api.gandi.net/v5/livedns"
|
||||
local __STATUS
|
||||
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing subdomain as 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing API Key as 'password'"
|
||||
|
||||
[ $use_ipv6 -ne 0 ] && __RRTYPE="AAAA" || __RRTYPE="A"
|
||||
|
||||
# Construct JSON payload
|
||||
json_init
|
||||
json_add_int rrset_ttl "$__TTL"
|
||||
json_add_array rrset_values
|
||||
json_add_string "" "$__IP"
|
||||
json_close_array
|
||||
|
||||
# Log the curl command
|
||||
write_log 7 "curl -s -X PUT \"$__ENDPOINT/domains/$domain/records/$username/$__RRTYPE\" \
|
||||
-H \"Authorization: Apikey $password\" \
|
||||
-H \"Content-Type: application/json\" \
|
||||
-d \"$(json_dump)\" \
|
||||
--connect-timeout 30"
|
||||
|
||||
__STATUS=$(curl -s -X PUT "$__ENDPOINT/domains/$domain/records/$username/$__RRTYPE" \
|
||||
-H "Authorization: Apikey $password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(json_dump)" \
|
||||
--connect-timeout 30 \
|
||||
-w "%{http_code}\n" -o $DATFILE 2>$ERRFILE)
|
||||
|
||||
local __ERRNO=$?
|
||||
if [ $__ERRNO -ne 0 ]; then
|
||||
write_log 14 "Curl failed with $__ERRNO: $(cat $ERRFILE)"
|
||||
return 1
|
||||
elif [ -z $__STATUS ] || [ $__STATUS != 201 ]; then
|
||||
write_log 14 "LiveDNS failed: $__STATUS \ngandi.net answered: $(cat $DATFILE)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
write_log 7 "gandi.net answered: $(cat $DATFILE)"
|
||||
|
||||
return 0
|
272
net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh
Executable file
272
net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh
Executable file
@ -0,0 +1,272 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
#.2022 Chris Barrick <chrisbarrick@google.com>
|
||||
#
|
||||
# This script sends DDNS updates using the Google Cloud DNS REST API.
|
||||
# See: https://cloud.google.com/dns/docs/reference/v1
|
||||
#
|
||||
# This script uses a GCP service account. The user is responsible for creating
|
||||
# the service account, ensuring it has permission to update DNS records, and
|
||||
# for generating a service account key to be used by this script. The records
|
||||
# to be updated must already exist.
|
||||
#
|
||||
# Arguments:
|
||||
#
|
||||
# - $username: The service account name.
|
||||
# Example: ddns-service-account@my-dns-project.iam.gserviceaccount.com
|
||||
#
|
||||
# - $password: The service account key. You can paste the key directly into the
|
||||
# "password" field or upload the key file to the router and set the field
|
||||
# equal to the file path. This script supports JSON keys or the raw private
|
||||
# key as a PEM file. P12 keys are not supported. File names must end with
|
||||
# `*.json` or `*.pem`.
|
||||
#
|
||||
# - $domain: The domain to update.
|
||||
#
|
||||
# - $param_enc: The additional required arguments, as form-urlencoded data,
|
||||
# i.e. `key1=value1&key2=value2&...`. The required arguments are:
|
||||
# - project: The name of the GCP project that owns the DNS records.
|
||||
# - zone: The DNS zone in the GCP API.
|
||||
# - Example: `project=my-dns-project&zone=my-dns-zone`
|
||||
#
|
||||
# - $param_opt: Optional TTL for the records, in seconds. Defaults to 3600 (1h).
|
||||
#
|
||||
# Dependencies:
|
||||
# - ddns-scripts (for the base functionality)
|
||||
# - openssl-util (for the authentication flow)
|
||||
# - curl (for the GCP REST API)
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
|
||||
# Authentication
|
||||
# ---------------------------------------------------------------------------
|
||||
# The authentication flow works like this:
|
||||
#
|
||||
# 1. Construct a JWT claim for access to the DNS readwrite scope.
|
||||
# 2. Sign the JWT with the service accout key, proving we have access.
|
||||
# 3. Exchange the JWT for an access token, valid for 5m.
|
||||
# 4. Use the access token for API calls.
|
||||
#
|
||||
# See https://developers.google.com/identity/protocols/oauth2/service-account
|
||||
|
||||
# A URL-safe variant of base64 encoding, used by JWTs.
|
||||
base64_urlencode() {
|
||||
openssl base64 | tr '/+' '_-' | tr -d '=\n'
|
||||
}
|
||||
|
||||
# Prints the service account private key in PEM format.
|
||||
get_service_account_key() {
|
||||
# The "password" field provides us with the service account key.
|
||||
# We allow the user to provide it to us in a few different formats.
|
||||
#
|
||||
# 1. If $password is a string ending in `*.json`, it is a file path,
|
||||
# pointing to a JSON service account key as downloaded from GCP.
|
||||
#
|
||||
# 2. If $password is a string ending with `*.pem`, it is a PEM private
|
||||
# key, extracted from the JSON service account key.
|
||||
#
|
||||
# 3. If $password starts with `{`, then the JSON service account key
|
||||
# was pasted directly into the password field.
|
||||
#
|
||||
# 4. If $password starts with `---`, then the PEM private key was pasted
|
||||
# directly into the password field.
|
||||
#
|
||||
# We do not support P12 service account keys.
|
||||
case "${password}" in
|
||||
(*".json")
|
||||
jsonfilter -i "${password}" -e @.private_key
|
||||
;;
|
||||
(*".pem")
|
||||
cat "${password}"
|
||||
;;
|
||||
("{"*)
|
||||
jsonfilter -s "${password}" -e @.private_key
|
||||
;;
|
||||
("---"*)
|
||||
printf "%s" "${password}"
|
||||
;;
|
||||
(*)
|
||||
write_log 14 "Could not parse the service account key."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Sign stdin using the service account key. Prints the signature.
|
||||
# The input is the JWT header-payload. Used to construct a signed JWT.
|
||||
sign() {
|
||||
# Dump the private key to a tmp file so openssl can get to it.
|
||||
local tmp_keyfile="$(mktemp -t gcp_dns_sak.pem.XXXXXX)"
|
||||
chmod 600 ${tmp_keyfile}
|
||||
get_service_account_key > ${tmp_keyfile}
|
||||
openssl dgst -binary -sha256 -sign ${tmp_keyfile}
|
||||
rm ${tmp_keyfile}
|
||||
}
|
||||
|
||||
# Print the JWT header in JSON format.
|
||||
# Currently, Google only supports RS256.
|
||||
jwt_header() {
|
||||
json_init
|
||||
json_add_string "alg" "RS256"
|
||||
json_add_string "typ" "JWT"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Prints the JWT claim-set in JSON format.
|
||||
# The claim is for 5m of readwrite access to the Cloud DNS API.
|
||||
jwt_claim_set() {
|
||||
local iat=$(date -u +%s) # Current UNIX time, UTC.
|
||||
local exp=$(( iat + 300 )) # Expiration is 5m in the future.
|
||||
|
||||
json_init
|
||||
json_add_string "iss" "${username}"
|
||||
json_add_string "scope" "https://www.googleapis.com/auth/ndev.clouddns.readwrite"
|
||||
json_add_string "aud" "https://oauth2.googleapis.com/token"
|
||||
json_add_string "iat" "${iat}"
|
||||
json_add_string "exp" "${exp}"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Generate a JWT signed by the service account key, which can be exchanged for
|
||||
# a Google Cloud access token, authorized for Cloud DNS.
|
||||
get_jwt() {
|
||||
local header=$(jwt_header | base64_urlencode)
|
||||
local payload=$(jwt_claim_set | base64_urlencode)
|
||||
local header_payload="${header}.${payload}"
|
||||
local signature=$(printf "%s" ${header_payload} | sign | base64_urlencode)
|
||||
echo "${header_payload}.${signature}"
|
||||
}
|
||||
|
||||
# Request an access token for the Google Cloud service account.
|
||||
get_access_token_raw() {
|
||||
local grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer"
|
||||
local assertion=$(get_jwt)
|
||||
|
||||
${CURL} -v https://oauth2.googleapis.com/token \
|
||||
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
|
||||
--data-urlencode "assertion=${assertion}" \
|
||||
| jsonfilter -e @.access_token
|
||||
}
|
||||
|
||||
# Get the access token, stripping the trailing dots.
|
||||
get_access_token() {
|
||||
# Since tokens may contain internal dots, we only trim the suffix if it
|
||||
# starts with at least 8 dots. (The access token has *many* trailing dots.)
|
||||
local access_token="$(get_access_token_raw)"
|
||||
echo "${access_token%%........*}"
|
||||
}
|
||||
|
||||
|
||||
# Google Cloud DNS API
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cloud DNS offers a straight forward RESTful API.
|
||||
#
|
||||
# - The main class is a ResourceRecordSet. It's a collection of DNS records
|
||||
# that share the same domain, type, TTL, etc. Within a record set, the only
|
||||
# difference between the records are their values.
|
||||
#
|
||||
# - The record sets live under a ManagedZone, which in turn lives under a
|
||||
# Project. All we need to know about these are their names.
|
||||
#
|
||||
# - This implementation only makes PATCH requests to update existing record
|
||||
# sets. The user must have already created at least one A or AAAA record for
|
||||
# the domain they are updating. It's fine to start with a dummy, like 0.0.0.0.
|
||||
#
|
||||
# - The API requires SSL, and this implementation uses curl.
|
||||
|
||||
# Prints a ResourceRecordSet in JSON format.
|
||||
format_record_set() {
|
||||
local domain="$1"
|
||||
local record_type="$2"
|
||||
local ttl="$3"
|
||||
shift 3 # The remaining arguments are the IP addresses for this record set.
|
||||
|
||||
json_init
|
||||
json_add_string "kind" "dns#resourceRecordSet"
|
||||
json_add_string "name" "${domain}." # trailing dot on the domain
|
||||
json_add_string "type" "${record_type}"
|
||||
json_add_string "ttl" "${ttl}"
|
||||
json_add_array "rrdatas"
|
||||
for value in $@; do
|
||||
json_add_string "" "${value}"
|
||||
done
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Makes an HTTP PATCH request to the Cloud DNS API.
|
||||
patch_record_set() {
|
||||
local access_token="$1"
|
||||
local project="$2"
|
||||
local zone="$3"
|
||||
local domain="$4"
|
||||
local record_type="$5"
|
||||
local ttl="$6"
|
||||
shift 6 # The remaining arguments are the IP addresses for this record set.
|
||||
|
||||
# Note the trailing dot after the domain name. It's fully qualified.
|
||||
local url="https://dns.googleapis.com/dns/v1/projects/${project}/managedZones/${zone}/rrsets/${domain}./${record_type}"
|
||||
local record_set=$(format_record_set ${domain} ${record_type} ${ttl} $@)
|
||||
|
||||
${CURL} -v ${url} \
|
||||
-X PATCH \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${access_token}" \
|
||||
-d "${record_set}"
|
||||
}
|
||||
|
||||
|
||||
# Main entrypoint
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Parse the $param_enc into project and zone variables.
|
||||
# The arguments are the names for those variables.
|
||||
parse_project_zone() {
|
||||
local project_var=$1
|
||||
local zone_var=$2
|
||||
|
||||
IFS='&'
|
||||
for entry in $param_enc
|
||||
do
|
||||
case "${entry}" in
|
||||
('project='*)
|
||||
local project_val=$(echo "${entry}" | cut -d'=' -f2)
|
||||
eval "${project_var}=${project_val}"
|
||||
;;
|
||||
('zone='*)
|
||||
local zone_val=$(echo "${entry}" | cut -d'=' -f2)
|
||||
eval "${zone_var}=${zone_val}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
unset IFS
|
||||
}
|
||||
|
||||
main() {
|
||||
local access_token project zone ttl record_type
|
||||
|
||||
# Dependency checking
|
||||
[ -z "${CURL_SSL}" ] && write_log 14 "Google Cloud DNS requires cURL with SSL support"
|
||||
[ -z "$(openssl version)" ] && write_log 14 "Google Cloud DNS update requires openssl-utils"
|
||||
|
||||
# Argument parsing
|
||||
[ -z ${param_opt} ] && ttl=3600 || ttl="${param_opt}"
|
||||
[ $use_ipv6 -ne 0 ] && record_type="AAAA" || record_type="A"
|
||||
parse_project_zone project zone
|
||||
|
||||
# Sanity checks
|
||||
[ -z "${username}" ] && write_log 14 "Config is missing 'username' (service account name)"
|
||||
[ -z "${password}" ] && write_log 14 "Config is missing 'password' (service account key)"
|
||||
[ -z "${domain}" ] && write_log 14 "Config is missing 'domain'"
|
||||
[ -z "${project}" ] && write_log 14 "Could not parse project name from 'param_enc'"
|
||||
[ -z "${zone}" ] && write_log 14 "Could not parse zone name from 'param_enc'"
|
||||
[ -z "${ttl}" ] && write_log 14 "Could not parse TTL from 'param_opt'"
|
||||
[ -z "${record_type}" ] && write_log 14 "Could not determine the record type"
|
||||
|
||||
# Push the record!
|
||||
access_token="$(get_access_token)"
|
||||
patch_record_set "${access_token}" "${project}" "${zone}" "${domain}" "${record_type}" "${ttl}" "${__IP}"
|
||||
}
|
||||
|
||||
main $@
|
0
net/ddns-scripts/files/update_godaddy_com_v1.sh → net/ddns-scripts/files/usr/lib/ddns/update_godaddy_com_v1.sh
Executable file → Normal file
0
net/ddns-scripts/files/update_godaddy_com_v1.sh → net/ddns-scripts/files/usr/lib/ddns/update_godaddy_com_v1.sh
Executable file → Normal file
152
net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh
Normal file
152
net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh
Normal file
@ -0,0 +1,152 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# script for sending updates to huaweicloud.com
|
||||
# 2023-2024 sxlehua <sxlehua at qq dot com>
|
||||
# API documentation at https://support.huaweicloud.com/api-dns/dns_api_62003.html
|
||||
# API signature documentation at https://support.huaweicloud.com/api-dns/dns_api_30003.html
|
||||
#
|
||||
# This script is parsed by dynamic_dns_functions.sh inside send_update() function
|
||||
#
|
||||
# useage:
|
||||
# using following options from /etc/config/ddns
|
||||
# option username - huaweicloud Access Key Id
|
||||
# option password - huaweicloud Secret Access Key,AK、SK documentation from https://support.huaweicloud.com/devg-apisign/api-sign-provide-aksk.html
|
||||
# option domain - "hostname@yourdomain.TLD" # syntax changed to remove split_FQDN() function and tld_names.dat.gz
|
||||
#
|
||||
|
||||
# Check inputs
|
||||
[ -z "$username" ] && write_log 14 "Configuration error! [username] cannot be empty"
|
||||
[ -z "$password" ] && write_log 14 "Configuration error! [password] cannot be empty"
|
||||
|
||||
[ -z "$CURL" ] && [ -z "$CURL_SSL" ] && write_log 14 "huaweicloud API require cURL with SSL support. Please install"
|
||||
command -v openssl >/dev/null 2>&1 || write_log 14 "huaweicloud API require openssl-util support. Please install"
|
||||
|
||||
# public variable
|
||||
local __HOST __DOMAIN __TYPE __ZONE_ID __RECORD_ID
|
||||
local __ENDPOINT="dns.cn-north-1.myhuaweicloud.com"
|
||||
local __TTL=120
|
||||
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
|
||||
|
||||
# Get host and domain from $domain
|
||||
[ "${domain:0:2}" == "@." ] && domain="${domain/./}" # host
|
||||
[ "$domain" == "${domain/@/}" ] && domain="${domain/./@}" # host with no sperator
|
||||
__HOST="${domain%%@*}"
|
||||
__DOMAIN="${domain#*@}"
|
||||
[ -z "$__HOST" -o "$__HOST" == "$__DOMAIN" ] && __HOST="@"
|
||||
|
||||
hcloud_transfer() {
|
||||
local method=$1
|
||||
local path=$2
|
||||
local query=$3
|
||||
local body=$4
|
||||
|
||||
local timestamp=$(date -u +'%Y%m%dT%H%M%SZ')
|
||||
local contentType=""
|
||||
if [ ! "$method" = "GET" ]; then
|
||||
contentType="application/json"
|
||||
fi
|
||||
local _H_Content_Type=""
|
||||
|
||||
local canonicalUri="${path}"
|
||||
# add / if need
|
||||
echo $canonicalUri | grep -qE "/$" || canonicalUri="$canonicalUri/"
|
||||
local canonicalQuery="$query" # for extend
|
||||
|
||||
local canonicalHeaders="host:$__ENDPOINT\nx-sdk-date:$timestamp\n"
|
||||
local signedHeaders="host;x-sdk-date"
|
||||
|
||||
if [ ! "$contentType" = "" ]; then
|
||||
canonicalHeaders="content-type:$contentType\n${canonicalHeaders}"
|
||||
signedHeaders="content-type;$signedHeaders"
|
||||
_H_Content_Type="Content-Type: ${contentType}"
|
||||
fi
|
||||
|
||||
local hexencode=$(printf "%s" "$body" | openssl dgst -sha256 -hex 2>/dev/null | sed 's/^.* //')
|
||||
local canonicalRequest="$method\n$canonicalUri\n$canonicalQuery\n$canonicalHeaders\n$signedHeaders\n$hexencode"
|
||||
canonicalRequest="$(printf "$canonicalRequest%s")"
|
||||
|
||||
local stringToSign="SDK-HMAC-SHA256\n$timestamp\n$(printf "%s" "$canonicalRequest" | openssl dgst -sha256 -hex 2>/dev/null | sed 's/^.* //')"
|
||||
stringToSign="$(printf "$stringToSign%s")"
|
||||
|
||||
local signature=$(printf "%s" "$stringToSign" | openssl dgst -sha256 -hmac "$password" 2>/dev/null | sed 's/^.* //')
|
||||
authorization="SDK-HMAC-SHA256 Access=$username, SignedHeaders=$signedHeaders, Signature=$signature"
|
||||
|
||||
reqUrl="$__ENDPOINT$path"
|
||||
if [ ! -z "$query" ]; then
|
||||
reqUrl="$reqUrl""?$query"
|
||||
fi
|
||||
|
||||
curl -s -X "${method}" \
|
||||
-H "Host: $__ENDPOINT" \
|
||||
-H "$_H_Content_Type" \
|
||||
-H "Authorization: $authorization" \
|
||||
-H "X-Sdk-Date: $timestamp" \
|
||||
-d "${body}" \
|
||||
"https://$reqUrl"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "rest api error"
|
||||
fi
|
||||
}
|
||||
|
||||
get_zone() {
|
||||
local resp=`hcloud_transfer GET /v2/zones "name=$__DOMAIN.&search_mode=equal" ""`
|
||||
__ZONE_ID=`printf "%s" $resp | grep -Eo '"id":"[a-z0-9]+"' | cut -d':' -f2 | tr -d '"'`
|
||||
if [ "$__ZONE_ID" = "" ]; then
|
||||
write_log 14 "error, no zone"
|
||||
fi
|
||||
}
|
||||
|
||||
upd_record() {
|
||||
local body="{\"name\":\"$__HOST.$__DOMAIN.\",\"type\":\"$__TYPE\",\"records\":[\"$__IP\"],\"ttl\":$__TTL}"
|
||||
local resp=`hcloud_transfer PUT /v2/zones/"$__ZONE_ID"/recordsets/$__RECORD_ID "" "$body"`
|
||||
local recordId=`printf "%s" $resp | grep -Eo '"id":"[a-z0-9]+"' | cut -d':' -f2 | tr -d '"'`
|
||||
if [ ! "$recordId" = "" ]; then
|
||||
write_log 7 "upd [$recordId] success [$__TYPE] [$__IP]"
|
||||
else
|
||||
write_log 14 "upd ecord error [$resp]"
|
||||
fi
|
||||
}
|
||||
|
||||
add_record() {
|
||||
local body="{\"name\":\"$__HOST.$__DOMAIN.\",\"type\":\"$__TYPE\",\"records\":[\"$__IP\"],\"ttl\":$__TTL}"
|
||||
local resp=`hcloud_transfer POST /v2/zones/"$__ZONE_ID"/recordsets "" "$body"`
|
||||
local recordId=`printf "%s" $resp | grep -Eo '"id":"[a-z0-9]+"' | cut -d':' -f2 | tr -d '"'`
|
||||
if [ ! "$recordId" = "" ]; then
|
||||
write_log 7 "add [$recordId] success [$__TYPE] [$__IP]"
|
||||
else
|
||||
write_log 14 "add record error [$resp]"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get DNS record
|
||||
get_record() {
|
||||
local ret=0
|
||||
local resp=`hcloud_transfer GET /v2/zones/$__ZONE_ID/recordsets "name=$__HOST.$__DOMAIN.&search_mode=equal" ""`
|
||||
__RECORD_ID=`printf "%s" $resp | grep -Eo '"id":"[a-z0-9]+"' | cut -d':' -f2 | tr -d '"' | head -1`
|
||||
if [ "$__RECORD_ID" = "" ]; then
|
||||
# Record needs to be add
|
||||
ret=1
|
||||
else
|
||||
local remoteIp=`printf "%s" $resp | grep -Eo '"records":\[[^]]+]' | cut -d ':' -f 2-10 | tr -d '[' | tr -d ']' | tr -d '"' | head -1`
|
||||
if [ ! "$remoteIp" = "$__IP" ]; then
|
||||
# Record needs to be updated
|
||||
ret=2
|
||||
fi
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
get_zone
|
||||
get_record
|
||||
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ]; then
|
||||
write_log 7 "nochg [$__IP]"
|
||||
fi
|
||||
if [ $ret -eq 1 ]; then
|
||||
add_record
|
||||
fi
|
||||
if [ $ret -eq 2 ]; then
|
||||
upd_record
|
||||
fi
|
191
net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh
Normal file
191
net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh
Normal file
@ -0,0 +1,191 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
#.2023 Jihoon Han <rapid_renard@renard.ga>
|
||||
#
|
||||
#.based on Christian Schoenebeck's update_cloudflare_com_v4.sh
|
||||
#.and on Neilpang's acme.sh found at https://github.com/acmesh-official/acme.sh
|
||||
#
|
||||
# Script for sending DDNS updates using the LuaDNS API
|
||||
# See: https://luadns.com/api
|
||||
#
|
||||
# using following options from /etc/config/ddns
|
||||
# option username - "Emaii" as registered on LuaDNS
|
||||
# option password - "API Key" as generated at https://api.luadns.com/api_keys
|
||||
# option domain - The domain to update (e.g. my.example.com)
|
||||
#
|
||||
|
||||
# check parameters
|
||||
[ -z "$CURL" ] && [ -z "$CURL_SSL" ] && write_log 14 "LuaDNS API require cURL with SSL support. Please install"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing e-mail as 'Username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing personal API key as 'Password'"
|
||||
[ $use_https -eq 0 ] && use_https=1 # force HTTPS
|
||||
|
||||
# used variables
|
||||
local __HOST __DOMAIN __TYPE __URLBASE __PRGBASE __RUNPROG __DATA __IPV6 __ZONEID __RECID
|
||||
local __URLBASE="https://api.luadns.com/v1"
|
||||
local __TTL=300
|
||||
|
||||
# set record type
|
||||
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
|
||||
|
||||
# transfer function to use for LuaDNS
|
||||
# all needed variables are set global here
|
||||
# so we can use them directly
|
||||
luadns_transfer() {
|
||||
local __CNT=0
|
||||
local __STATUS __ERR
|
||||
while : ; do
|
||||
write_log 7 "#> $__RUNPROG"
|
||||
__STATUS=$(eval "$__RUNPROG")
|
||||
__ERR=$? # save communication error
|
||||
[ $__ERR -eq 0 ] && break # no error break while
|
||||
|
||||
write_log 3 "cURL Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
|
||||
[ $VERBOSE_MODE -gt 1 ] && {
|
||||
# VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Transfer failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
break
|
||||
}
|
||||
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Transfer failed after $retry_count retries"
|
||||
|
||||
write_log 4 "Transfer failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
PID_SLEEP=0
|
||||
done
|
||||
|
||||
# handle HTTP error
|
||||
[ $__STATUS -ne 200 ] && {
|
||||
write_log 4 "LuaDNS reported an error:"
|
||||
write_log 7 "$(cat $DATFILE)"
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Build base command to use
|
||||
__PRGBASE="$CURL -RsS -w '%{http_code}' -o $DATFILE --stderr $ERRFILE"
|
||||
# force network/interface-device to use for communication
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __DEVICE
|
||||
network_get_physdev __DEVICE $bind_network || \
|
||||
write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'"
|
||||
write_log 7 "Force communication via device '$__DEVICE'"
|
||||
__PRGBASE="$__PRGBASE --interface $__DEVICE"
|
||||
fi
|
||||
# force ip version to use
|
||||
if [ $force_ipversion -eq 1 ]; then
|
||||
[ $use_ipv6 -eq 0 ] && __PRGBASE="$__PRGBASE -4" || __PRGBASE="$__PRGBASE -6" # force IPv4/IPv6
|
||||
fi
|
||||
# set certificate parameters
|
||||
if [ "$cacert" = "IGNORE" ]; then # idea from Ticket #15327 to ignore server cert
|
||||
__PRGBASE="$__PRGBASE --insecure" # but not empty better to use "IGNORE"
|
||||
elif [ -f "$cacert" ]; then
|
||||
__PRGBASE="$__PRGBASE --cacert $cacert"
|
||||
elif [ -d "$cacert" ]; then
|
||||
__PRGBASE="$__PRGBASE --capath $cacert"
|
||||
elif [ -n "$cacert" ]; then # it's not a file and not a directory but given
|
||||
write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
|
||||
fi
|
||||
# disable proxy if not set (there might be .wgetrc or .curlrc or wrong environment set)
|
||||
# or check if libcurl compiled with proxy support
|
||||
if [ -z "$proxy" ]; then
|
||||
__PRGBASE="$__PRGBASE --noproxy '*'"
|
||||
elif [ -z "$CURL_PROXY" ]; then
|
||||
# if libcurl has no proxy support and proxy should be used then force ERROR
|
||||
write_log 13 "cURL: libcurl compiled without Proxy support"
|
||||
fi
|
||||
# set headers
|
||||
__PRGBASE="$__PRGBASE --user '$username:$password' "
|
||||
__PRGBASE="$__PRGBASE --header 'Accept: application/json' "
|
||||
|
||||
if [ -n "$zone_id" ]; then
|
||||
__ZONEID="$zone_id"
|
||||
else
|
||||
# read zone id for registered domain.TLD
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones'"
|
||||
luadns_transfer || return 1
|
||||
# extract zone id
|
||||
i=1
|
||||
while : ; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100 -s)
|
||||
[ -z "$h" ] && {
|
||||
write_log 4 "Could not detect 'Zone ID' for the domain provided: '$domain'"
|
||||
return 127
|
||||
}
|
||||
|
||||
__ZONEID=$(grep -o -e "\"id\":[^,]*,\"name\":\"$h\"" $DATFILE | cut -d : -f 2 | cut -d , -f 1)
|
||||
[ -n "$__ZONEID" ] && {
|
||||
# LuaDNS API needs:
|
||||
# __DOMAIN = the base domain i.e. example.com
|
||||
# __HOST = the FQDN of record to modify
|
||||
# i.e. example.com for the "domain record" or host.sub.example.com for "host record"
|
||||
__HOST="$domain"
|
||||
__DOMAIN="$h"
|
||||
write_log 7 "Domain : '$__DOMAIN'"
|
||||
write_log 7 "Zone ID : '$__ZONEID'"
|
||||
write_log 7 "Host : '$__HOST'"
|
||||
break
|
||||
}
|
||||
i=$(expr "$i" + 1)
|
||||
done
|
||||
fi
|
||||
|
||||
# read record id for A or AAAA record of host.domain.TLD
|
||||
__RUNPROG="$__PRGBASE --request GET '$__URLBASE/zones/$__ZONEID/records'"
|
||||
luadns_transfer || return 1
|
||||
# extract record id
|
||||
__RECID=$(grep -o -e "\"id\":[^,]*,\"name\":\"$__HOST.\",\"type\":\"$__TYPE\"" $DATFILE | head -n 1 | cut -d : -f 2 | cut -d , -f 1)
|
||||
[ -z "$__RECID" ] && {
|
||||
write_log 4 "Could not detect 'Record ID' for the domain provided: '$__HOST'"
|
||||
return 127
|
||||
}
|
||||
write_log 7 "Record ID : '$__RECID'"
|
||||
|
||||
# extract current stored IP
|
||||
__DATA=$(grep -o -e "\"id\":$__RECID,\"name\":\"$__HOST.\",\"type\":\"$__TYPE\",\"content\":[^,]*" $DATFILE | grep -o '[^"]*' | tail -n 1)
|
||||
|
||||
# check data
|
||||
[ $use_ipv6 -eq 0 ] \
|
||||
&& __DATA=$(printf "%s" "$__DATA" | grep -m 1 -o "$IPV4_REGEX") \
|
||||
|| __DATA=$(printf "%s" "$__DATA" | grep -m 1 -o "$IPV6_REGEX")
|
||||
|
||||
# we got data so verify
|
||||
[ -n "$__DATA" ] && {
|
||||
# expand IPv6 for compare
|
||||
if [ $use_ipv6 -eq 1 ]; then
|
||||
expand_ipv6 $__IP __IPV6
|
||||
expand_ipv6 $__DATA __DATA
|
||||
[ "$__DATA" = "$__IPV6" ] && { # IPv6 no update needed
|
||||
write_log 7 "IPv6 at LuaDNS already up to date"
|
||||
return 0
|
||||
}
|
||||
else
|
||||
[ "$__DATA" = "$__IP" ] && { # IPv4 no update needed
|
||||
write_log 7 "IPv4 at LuaDNS already up to date"
|
||||
return 0
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
# update is needed
|
||||
# let's build data to send
|
||||
|
||||
# use file to work around " needed for json
|
||||
cat > $DATFILE << EOF
|
||||
{"name":"$__HOST.","type":"$__TYPE","content":"$__IP","ttl":$__TTL}
|
||||
EOF
|
||||
|
||||
# let's complete transfer command
|
||||
__RUNPROG="$__PRGBASE --request PUT --data @$DATFILE '$__URLBASE/zones/$__ZONEID/records/$__RECID'"
|
||||
luadns_transfer || return 1
|
||||
|
||||
return 0
|
4
net/ddns-scripts/files/update_no-ip_com.sh → net/ddns-scripts/files/usr/lib/ddns/update_no-ip_com.sh
Executable file → Normal file
4
net/ddns-scripts/files/update_no-ip_com.sh → net/ddns-scripts/files/usr/lib/ddns/update_no-ip_com.sh
Executable file → Normal file
@ -10,13 +10,15 @@
|
||||
# so we send a dummy (localhost) and a seconds later we send the correct IP addr
|
||||
#
|
||||
local __DUMMY
|
||||
local __UPDURL="http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
local __UPDURL6="http://[USERNAME]:[PASSWORD]@dynupdate6.noip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
local __UPDURL="http://[USERNAME]:[PASSWORD]@dynupdate.noip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
# inside url we need username and password
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
|
||||
|
||||
# set IP version dependend dummy (localhost)
|
||||
[ $use_ipv6 -eq 0 ] && __DUMMY="127.0.0.1" || __DUMMY="::1"
|
||||
[ $use_ipv6 -eq 0 ] && __UPDURL=$__UPDURL || __UPDURL=$__UPDURL6
|
||||
|
||||
# lets do DUMMY transfer
|
||||
write_log 7 "sending dummy IP to 'no-ip.com'"
|
77
net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh
Normal file
77
net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh
Normal file
@ -0,0 +1,77 @@
|
||||
#!/bin/sh
|
||||
# Derived from update_gandi_net.sh
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
local __ENDPOINT="https://api.nsone.net/v1"
|
||||
local __TTL=600
|
||||
local __RRTYPE
|
||||
local __URL
|
||||
local __STATUS
|
||||
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing zone as 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing API Key as 'password'"
|
||||
|
||||
[ $use_ipv6 -ne 0 ] && __RRTYPE="AAAA" || __RRTYPE="A"
|
||||
|
||||
# Construct JSON payload
|
||||
json_init
|
||||
# {"answers":[{"answer":["1.1.1.1"]}]}
|
||||
json_add_array answers
|
||||
json_add_object
|
||||
json_add_array answer
|
||||
json_add_string "" "$__IP"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_array
|
||||
|
||||
__URL="$__ENDPOINT/zones/$username/$domain/$__RRTYPE"
|
||||
|
||||
__STATUS=$(curl -s -X POST "$__URL" \
|
||||
-H "X-NSONE-Key: $password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(json_dump)" \
|
||||
-w "%{http_code}\n" -o $DATFILE 2>$ERRFILE)
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat $ERRFILE)"
|
||||
return 1
|
||||
elif [ -z $__STATUS ] || [ $__STATUS != 200 ]; then
|
||||
write_log 4 "Request failed: $__STATUS, NS1 answered: $(cat $DATFILE)"
|
||||
if [ $__STATUS = 404 ]; then
|
||||
write_log 4 "Status is 404, trying to create a DNS record"
|
||||
|
||||
json_init
|
||||
json_add_string "zone" "$username"
|
||||
json_add_string "domain" "$domain"
|
||||
json_add_string "type" "$__RRTYPE"
|
||||
json_add_string "ttl" "$__TTL"
|
||||
json_add_array answers
|
||||
json_add_object
|
||||
json_add_array answer
|
||||
json_add_string "" "$__IP"
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_array
|
||||
|
||||
__STATUS=$(curl -s -X PUT "$__URL" \
|
||||
-H "X-NSONE-Key: $password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(json_dump)" \
|
||||
-w "%{http_code}\n" -o $DATFILE 2>$ERRFILE)
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat $ERRFILE)"
|
||||
return 1
|
||||
elif [ -z $__STATUS ] || [ $__STATUS != 200 ]; then
|
||||
write_log 14 "Request failed: $__STATUS, NS1 answered: $(cat $DATFILE)"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
write_log 7 "NS1 answered: $(cat $DATFILE)"
|
||||
|
||||
return 0
|
4
net/ddns-scripts/files/update_nsupdate.sh → net/ddns-scripts/files/usr/lib/ddns/update_nsupdate.sh
Executable file → Normal file
4
net/ddns-scripts/files/update_nsupdate.sh → net/ddns-scripts/files/usr/lib/ddns/update_nsupdate.sh
Executable file → Normal file
@ -17,8 +17,8 @@
|
||||
#
|
||||
local __TTL=600 #.preset DNS TTL (in seconds)
|
||||
local __RRTYPE __PW __TCP
|
||||
local __PROG=$(which nsupdate) # BIND nsupdate ?
|
||||
[ -z "$__PROG" ] && __PROG=$(which knsupdate) # Knot nsupdate ?
|
||||
local __PROG=$(command -v nsupdate) # BIND nsupdate ?
|
||||
[ -z "$__PROG" ] && __PROG=$(command -v knsupdate) # Knot nsupdate ?
|
||||
|
||||
[ -z "$__PROG" ] && write_log 14 "'nsupdate' or 'knsupdate' not installed !"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
142
net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh
Normal file
142
net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh
Normal file
@ -0,0 +1,142 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ONE.COM DDNS SCRIPT
|
||||
# REQUIRES CURL
|
||||
# $ opkg install curl
|
||||
|
||||
# SCRIPT BY LUGICO
|
||||
# CONTACT: main@lugico.de
|
||||
|
||||
[ -z "$CURL" ] && [ -z "$CURL_SSL" ] && write_log 14 "one.com communication require cURL with SSL support. Please install"
|
||||
[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing 'domain'"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
write_log 0 "one.com ddns script started"
|
||||
|
||||
local __SUBDOMAIN __MAINDOMAIN __LOGINURL __RECORDID
|
||||
local __TTL=3600
|
||||
|
||||
COOKIEJAR=$(mktemp /tmp/one_com_cookiejar.XXXXXX) || exit 1
|
||||
|
||||
__SUBDOMAIN=$(echo $domain | sed -e 's/[^\.]*\.[^\.]*$//' -e 's/\.$//' )
|
||||
__MAINDOMAIN=$(echo $domain | sed -e "s/${__SUBDOMAIN}\.//" )
|
||||
|
||||
|
||||
# LOGGING IN
|
||||
# GET LOGIN POST URL FROM FORM
|
||||
__LOGINURL=$( $CURL \
|
||||
-RsSL \
|
||||
--stderr $ERRFILE \
|
||||
-c $COOKIEJAR \
|
||||
"https://www.one.com/admin/" \
|
||||
| grep 'Login-form login autofill' \
|
||||
| sed -e 's/.*action="//' -e 's/".*//' -e 's/\&/\&/g' \
|
||||
)
|
||||
|
||||
# POST LOGIN DATA
|
||||
$CURL \
|
||||
-RsSL \
|
||||
--stderr $ERRFILE \
|
||||
-c $COOKIEJAR \
|
||||
-b $COOKIEJAR \
|
||||
"${__LOGINURL}" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-X POST \
|
||||
-d "username=${username}&password=${password}&credentialId=" \
|
||||
| grep "Invalid username or password." > $DATFILE
|
||||
|
||||
if [ "$?" == "0" ] ; then
|
||||
write_log 14 "Invalid credentials"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# SETTING DOMAIN
|
||||
$CURL -RsSL \
|
||||
--stderr $ERRFILE \
|
||||
-c $COOKIEJAR \
|
||||
-b $COOKIEJAR \
|
||||
"https://www.one.com/admin/select-admin-domain.do?domain=${__MAINDOMAIN}" \
|
||||
| grep "<meta name=\"one.com:active-domain\" content=\"${__MAINDOMAIN}\"/>" > $DATFILE
|
||||
|
||||
if [ "$?" != "0" ] ; then
|
||||
write_log 14 "Failed to select domain '${__MAINDOMAIN}'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# GETTING RECORD ID
|
||||
records=$( $CURL \
|
||||
-RsSL \
|
||||
--stderr $ERRFILE \
|
||||
-c $COOKIEJAR \
|
||||
-b $COOKIEJAR \
|
||||
"https://www.one.com/admin/api/domains/${__MAINDOMAIN}/dns/custom_records"
|
||||
)
|
||||
|
||||
json_load "$records"
|
||||
|
||||
if json_is_a "result" "object" && \
|
||||
json_select "result" && \
|
||||
json_is_a "data" "array"
|
||||
then
|
||||
json_select "data"
|
||||
i=1
|
||||
while json_is_a ${i} "object" ; do
|
||||
json_select "${i}"
|
||||
json_select "attributes"
|
||||
json_get_var "prefix" "prefix"
|
||||
json_close_object
|
||||
if [ "$prefix" == "$__SUBDOMAIN" ] ; then
|
||||
json_get_var "__RECORDID" "id"
|
||||
write_log 0 "Found record id : ${__RECORDID}"
|
||||
break
|
||||
fi
|
||||
json_close_object
|
||||
i=$(($i + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
if [ "${__RECORDID}" == "" ] ; then
|
||||
write_log 14 "domain record not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# CREATING PATCH DATA
|
||||
json_init
|
||||
json_add_string "type" "dns_service_records"
|
||||
json_add_string "id" "${__RECORDID}"
|
||||
json_add_object "attributes"
|
||||
json_add_string "type" "A"
|
||||
json_add_string "prefix" "${__SUBDOMAIN}"
|
||||
json_add_string "content" "${__IP}"
|
||||
json_add_int "ttl" ${__TTL}
|
||||
patchdata=$(json_dump)
|
||||
|
||||
|
||||
# SENDING PATCH
|
||||
$CURL \
|
||||
-RsSL \
|
||||
--stderr $ERRFILE \
|
||||
-c $COOKIEJAR \
|
||||
-b $COOKIEJAR \
|
||||
-X PATCH \
|
||||
-d "$patchdata" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://www.one.com/admin/api/domains/${__MAINDOMAIN}/dns/custom_records/${__RECORDID}" \
|
||||
| grep "priority" > $DATFILE
|
||||
|
||||
if [ "$?" != "0" ] ; then
|
||||
write_log 14 "one.com gave an unexpected response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm $COOKIEJAR
|
||||
write_log 0 "one.com ddns script finished without errors"
|
||||
|
||||
return 0
|
63
net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh
Executable file
63
net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh
Executable file
@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
# Derived from update_gandi_net.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
local __TTL=600
|
||||
local __RRTYPE
|
||||
local __STATUS
|
||||
local __RNAME
|
||||
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing subdomain as 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing API Key as 'password'"
|
||||
[ -z "$param_opt" ] && write_log 14 "Service section not configured correctly! Missing PowerDNS URL as 'Optional Parameter'(param_opt)"
|
||||
|
||||
# Create endpoint from $param_opt
|
||||
# e.g. param_opt=http://127.0.0.1:8081
|
||||
local __ENDPOINT="$param_opt/api/v1/servers/localhost/zones"
|
||||
|
||||
[ $use_ipv6 -ne 0 ] && __RRTYPE="AAAA" || __RRTYPE="A"
|
||||
|
||||
# Make sure domain is period terminated
|
||||
if [ ${domain: -1} != '.' ]; then
|
||||
domain="${domain}."
|
||||
fi
|
||||
if [ $username == '@' ]; then
|
||||
__RNAME="$domain"
|
||||
else
|
||||
__RNAME="$username.$domain"
|
||||
fi
|
||||
|
||||
# Build JSON payload
|
||||
json_init
|
||||
json_add_array rrsets
|
||||
json_add_object
|
||||
json_add_string name "$__RNAME"
|
||||
json_add_string type "$__RRTYPE"
|
||||
json_add_int ttl $__TTL
|
||||
json_add_string changetype "REPLACE"
|
||||
json_add_array records
|
||||
json_add_object
|
||||
json_add_string content "$__IP"
|
||||
json_add_boolean disabled 0
|
||||
json_close_object
|
||||
json_close_array
|
||||
json_close_object
|
||||
json_close_array
|
||||
|
||||
__STATUS=$(curl -Ss -X PATCH "$__ENDPOINT/$domain" \
|
||||
-H "X-Api-Key: $password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(json_dump)" \
|
||||
-w "%{http_code}\n" \
|
||||
-o $DATFILE 2>$ERRFILE)
|
||||
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat $ERRFILE)"
|
||||
return 1
|
||||
elif [ -z $__STATUS ] || [ $__STATUS != 204 ]; then
|
||||
write_log 14 "PowerDNS request failed: $__STATUS \n$(cat $DATFILE)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
162
net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh
Normal file
162
net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh
Normal file
@ -0,0 +1,162 @@
|
||||
#
|
||||
# Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
# 2024 Ansel Horn <dev@cahorn.net>
|
||||
#
|
||||
# Script for DDNS support via Porkbun's v3 API for the OpenWRT ddns-scripts package.
|
||||
#
|
||||
# Will attempt to create a new or edit an existing A or AAAA record for the
|
||||
# given domain and subdomain. Existing CNAME and ALIAS records WILL NOT BE
|
||||
# EDITED OR DELETED! "username" and "password" configurations should be set to
|
||||
# Porkbun API key and secret key, respectively.
|
||||
#
|
||||
# Porkbun API documentation:
|
||||
# https://porkbun.com/api/json/v3/documentation#DNS%20Create%20Record
|
||||
#
|
||||
|
||||
# Source JSON parser
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
# Set API base URL
|
||||
# Porkbun has warned it may change API hostname in the future:
|
||||
# https://porkbun.com/api/json/v3/documentation#apiHost
|
||||
__API="https://api.porkbun.com/api/json/v3"
|
||||
|
||||
# Check availability of cURL with SSL
|
||||
[ -z "$CURL" ] && [ -z "$CURL_SSL" ] && write_log 14 "cURL with SSL support required! Please install"
|
||||
|
||||
# Validate configuration
|
||||
[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing 'domain'"
|
||||
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
|
||||
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
|
||||
|
||||
# Split FQDN into domain and subdomain(s)
|
||||
__DOMAIN_REGEX='^\(\(.*\)\.\)\?\([^.]\+\.[^.]\+\)$'
|
||||
echo $domain | grep "$__DOMAIN_REGEX" > /dev/null || write_log 14 "Invalid domain! Check 'domain' config"
|
||||
__DOMAIN=$(echo $domain | sed -e "s/$__DOMAIN_REGEX/\3/")
|
||||
__SUBDOMAIN=$(echo $domain | sed -e "s/$__DOMAIN_REGEX/\2/")
|
||||
|
||||
# Determine IPv4 or IPv6 address and record type
|
||||
if [ "$use_ipv6" -eq 1 ]; then
|
||||
expand_ipv6 "$__IP" __ADDR
|
||||
__TYPE="AAAA"
|
||||
else
|
||||
__ADDR="$__IP"
|
||||
__TYPE="A"
|
||||
fi
|
||||
|
||||
|
||||
# Inject authentication into API request JSON payload
|
||||
function json_authenticate() {
|
||||
json_add_string "apikey" "$username"
|
||||
json_add_string "secretapikey" "$password"
|
||||
}
|
||||
|
||||
# Make Porkbun API call
|
||||
# $1 - Porkbun API endpoint
|
||||
# $2 - request JSON payload
|
||||
function api_call() {
|
||||
local response url
|
||||
url="$__API/$1"
|
||||
write_log 7 "API endpoint URL: $url"
|
||||
write_log 7 "API request JSON payload: $2"
|
||||
response=$($CURL --data "$2" "$url")
|
||||
write_log 7 "API response JSON payload: $response"
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
# Check Porkbun API response status
|
||||
function json_check_status() {
|
||||
local status
|
||||
json_get_var status "status"
|
||||
[ "$status" == "SUCCESS" ] || write_log 14 "API request failed!"
|
||||
}
|
||||
|
||||
# Review DNS record and, if it is the record we're looking for, get its id
|
||||
function callback_review_record() {
|
||||
local id name type
|
||||
json_select "$2"
|
||||
json_get_var id "id"
|
||||
json_get_var name "name"
|
||||
json_get_var type "type"
|
||||
[ "$name" == "$domain" -a "$type" == "$__TYPE" ] && echo "$id"
|
||||
json_select ..
|
||||
}
|
||||
|
||||
# Retrieve all DNS records, find the first appropriate A/AAAA record, and get its id
|
||||
function find_existing_record_id() {
|
||||
local request response
|
||||
json_init
|
||||
json_authenticate
|
||||
request=$(json_dump)
|
||||
response=$(api_call "/dns/retrieve/$__DOMAIN" "$request")
|
||||
json_load "$response"
|
||||
json_check_status
|
||||
json_for_each_item callback_review_record "records"
|
||||
}
|
||||
|
||||
# Create a new A/AAAA record
|
||||
function create_record() {
|
||||
local request response
|
||||
json_init
|
||||
json_authenticate
|
||||
json_add_string "name" "$__SUBDOMAIN"
|
||||
json_add_string "type" "$__TYPE"
|
||||
json_add_string "content" "$__ADDR"
|
||||
request=$(json_dump)
|
||||
response=$(api_call "/dns/create/$__DOMAIN" "$request")
|
||||
json_load "$response"
|
||||
json_check_status
|
||||
}
|
||||
|
||||
# Retrieve an existing record and get its content
|
||||
# $1 - record id to retrieve
|
||||
function retrieve_record_content() {
|
||||
local content request response
|
||||
json_init
|
||||
json_authenticate
|
||||
request=$(json_dump)
|
||||
response=$(api_call "/dns/retrieve/$__DOMAIN/$1" "$request")
|
||||
json_load "$response"
|
||||
json_check_status
|
||||
json_select "records"
|
||||
json_select 1
|
||||
json_get_var content "content"
|
||||
echo "$content"
|
||||
}
|
||||
|
||||
# Edit an existing A/AAAA record
|
||||
# $1 - record id to edit
|
||||
function edit_record() {
|
||||
local request response
|
||||
json_init
|
||||
json_authenticate
|
||||
json_add_string "type" "$__TYPE"
|
||||
json_add_string "content" "$__ADDR"
|
||||
request=$(json_dump)
|
||||
response=$(api_call "/dns/edit/$__DOMAIN/$1" "$request")
|
||||
json_load "$response"
|
||||
json_check_status
|
||||
}
|
||||
|
||||
|
||||
# Try to identify an appropriate existing DNS record to update
|
||||
if [ -z $rec_id]; then
|
||||
write_log 7 "Retrieving DNS $__TYPE record"
|
||||
__ID=$(find_existing_record_id)
|
||||
else
|
||||
write_log 7 "Using user-supplied DNS record id: $rec_id"
|
||||
__ID=$rec_id
|
||||
fi
|
||||
|
||||
# Create or update DNS record with current IP address
|
||||
if [ -z "$__ID" ]; then
|
||||
write_log 7 "Creating new DNS $__TYPE record"
|
||||
create_record
|
||||
else
|
||||
write_log 7 "Updating existing DNS $__TYPE record"
|
||||
if [ "$(retrieve_record_content $__ID)" == "$__ADDR" ]; then
|
||||
write_log 7 "Skipping Porkbun-unsupported forced noop update"
|
||||
else
|
||||
edit_record "$__ID"
|
||||
fi
|
||||
fi
|
96
net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh
Normal file
96
net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh
Normal file
@ -0,0 +1,96 @@
|
||||
#!/bin/sh
|
||||
# Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
# based on Yuval Adam's route53.sh found at https://github.com/yuvadm/route53-ddns/blob/master/route53.sh
|
||||
# 2017 Max Berger <max at berger dot name>
|
||||
|
||||
[ -z "${CURL_SSL}" ] && write_log 14 "Amazon AWS Route53 communication require cURL with SSL support. Please install"
|
||||
[ -z "${username}" ] && write_log 14 "Service section not configured correctly! Missing key as 'username'"
|
||||
[ -z "${password}" ] && write_log 14 "Service section not configured correctly! Missing secret as 'password'"
|
||||
[ -z "${domain}" ] && write_log 14 "Service section not configured correctly! Missing zone id as 'domain'"
|
||||
|
||||
ENDPOINT="route53.amazonaws.com"
|
||||
RECORD_TTL=300
|
||||
RECORD_NAME="${lookup_host}."
|
||||
RECORD_VALUE="${__IP}"
|
||||
[ ${use_ipv6} -eq 0 ] && RECORD_TYPE="A"
|
||||
[ ${use_ipv6} -eq 1 ] && RECORD_TYPE="AAAA"
|
||||
|
||||
HOSTED_ZONE_ID="${domain}"
|
||||
API_PATH="/2013-04-01/hostedzone/${HOSTED_ZONE_ID}/rrset/"
|
||||
|
||||
AWS_ACCESS_KEY_ID="${username}"
|
||||
AWS_SECRET_ACCESS_KEY="${password}"
|
||||
AWS_REGION='us-east-1'
|
||||
AWS_SERVICE='route53'
|
||||
|
||||
hash() {
|
||||
msg="$1"
|
||||
echo -en "${msg}" | openssl dgst -sha256 | sed 's/^.* //'
|
||||
}
|
||||
|
||||
sign_plain() {
|
||||
# Sign message using a plaintext key
|
||||
key="$1"
|
||||
msg="$2"
|
||||
echo -en "${msg}" | openssl dgst -hex -sha256 -hmac "${key}" | sed 's/^.* //'
|
||||
}
|
||||
|
||||
sign() {
|
||||
# Sign message using a hex formatted key
|
||||
key="$1"
|
||||
msg="$2"
|
||||
echo -en "${msg}" | openssl dgst -hex -sha256 -mac HMAC -macopt "hexkey:${key}" | sed 's/^.* //'
|
||||
}
|
||||
|
||||
request_body="<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
|
||||
<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2013-04-01/\"> \
|
||||
<ChangeBatch> \
|
||||
<Changes> \
|
||||
<Change> \
|
||||
<Action>UPSERT</Action> \
|
||||
<ResourceRecordSet> \
|
||||
<Name>${RECORD_NAME}</Name> \
|
||||
<Type>${RECORD_TYPE}</Type> \
|
||||
<TTL>${RECORD_TTL}</TTL> \
|
||||
<ResourceRecords> \
|
||||
<ResourceRecord> \
|
||||
<Value>${RECORD_VALUE}</Value> \
|
||||
</ResourceRecord> \
|
||||
</ResourceRecords> \
|
||||
</ResourceRecordSet> \
|
||||
</Change> \
|
||||
</Changes> \
|
||||
</ChangeBatch> \
|
||||
</ChangeResourceRecordSetsRequest>"
|
||||
|
||||
fulldate="$(date --utc +%Y%m%dT%H%M%SZ)"
|
||||
shortdate="$(date --utc +%Y%m%d)"
|
||||
signed_headers="host;x-amz-date"
|
||||
request_hash="$(hash "${request_body}")"
|
||||
canonical_request="POST\n${API_PATH}\n\nhost:route53.amazonaws.com\nx-amz-date:${fulldate}\n\n${signed_headers}\n${request_hash}"
|
||||
|
||||
date_key="$(sign_plain "AWS4${AWS_SECRET_ACCESS_KEY}" "${shortdate}")"
|
||||
region_key="$(sign "${date_key}" ${AWS_REGION})"
|
||||
service_key="$(sign "${region_key}" ${AWS_SERVICE})"
|
||||
signing_key="$(sign "${service_key}" aws4_request)"
|
||||
|
||||
credential="${shortdate}/${AWS_REGION}/${AWS_SERVICE}/aws4_request"
|
||||
sigmsg="AWS4-HMAC-SHA256\n${fulldate}\n${credential}\n$(hash "${canonical_request}")"
|
||||
|
||||
signature="$(sign "${signing_key}" "${sigmsg}")"
|
||||
|
||||
authorization="AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${credential}, SignedHeaders=${signed_headers}, Signature=${signature}"
|
||||
|
||||
ANSWER="$(flock /tmp/$(basename -s .sh "$0").lock curl \
|
||||
-X "POST" \
|
||||
-H "Host: route53.amazonaws.com" \
|
||||
-H "X-Amz-Date: ${fulldate}" \
|
||||
-H "Authorization: ${authorization}" \
|
||||
-H "Content-Type: text/xml" \
|
||||
-d "$request_body" \
|
||||
"https://${ENDPOINT}${API_PATH}")"
|
||||
write_log 7 "${ANSWER}"
|
||||
|
||||
echo "${ANSWER}" | grep -F "Error" >/dev/null && return 1
|
||||
echo "${ANSWER}" | grep -F "ChangeInfo" >/dev/null && return 0
|
||||
return 2
|
134
net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh
Normal file
134
net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh
Normal file
@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 2021 Martijn Atema <martijn@atema.one>
|
||||
#
|
||||
# This script sends ddns updates using the TransIP API (see https://api.transip.nl/)
|
||||
# and is parsed by dynamic_dns_functions.sh inside send_update().
|
||||
#
|
||||
# The following options provided by ddns are used:
|
||||
# username - Username of account used for logging in to TransIP
|
||||
# password - Private key generated at https://www.transip.nl/cp/account/api/
|
||||
# (make sure to accept non-whitelisted IP addresses)
|
||||
# domain - Base domain name registered at TransIP
|
||||
# ('domain.tld' when updating 'hostname.domain.tld')
|
||||
# param_enc - Name of DNS record to update
|
||||
# ('hostname' when updating 'hostname.domain.tld')
|
||||
# param_opt - TTL of the DNS record to update (in seconds)
|
||||
#
|
||||
# Note: Make sure that there is exactly one record of type A (for IPv4) or
|
||||
# AAAA (for IPv6) with the specified name and TTL. That record will be
|
||||
# updated by this script.
|
||||
#
|
||||
# The script requires cURL with SSL and the openssl binary
|
||||
|
||||
|
||||
[ -z "${username}" ] && write_log 14 "Service config is missing 'username'"
|
||||
[ -z "${password}" ] && write_log 14 "Service config is missing 'password' (private key)"
|
||||
[ -z "${domain}" ] && write_log 14 "Service config is missing 'domain' (base domain name)"
|
||||
[ -z "${param_enc}" ] && write_log 14 "Service config is missing 'param_enc' (DNS record name)"
|
||||
[ -z "${param_opt}" ] && write_log 14 "Service config is missing 'param_opt' (DNS record TTL)"
|
||||
|
||||
[ -z "${CURL_SSL}" ] && write_log 14 "TransIP update requires cURL with SSL"
|
||||
[ -z "$(openssl version)" ] && write_log 14 "TransIP update requires openssl binary"
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
|
||||
# Re-format the private key and write to a temporary file
|
||||
|
||||
__tmp_keyfile="$(mktemp -t ddns-transip.XXXXXX)"
|
||||
|
||||
echo "${password}" | \
|
||||
sed -e "s/-----BEGIN PRIVATE KEY-----\s*/&\n/" \
|
||||
-e "s/-----END PRIVATE KEY-----/\n&/" \
|
||||
-e "s/\S\{64\}\s*/&\n/g" \
|
||||
> "${__tmp_keyfile}"
|
||||
|
||||
|
||||
# Create authentication request
|
||||
|
||||
json_init
|
||||
json_add_string "login" "${username}"
|
||||
json_add_string "label" "DDNS-script ($(openssl rand -hex 4))"
|
||||
json_add_string "nonce" $(openssl rand -hex 16)
|
||||
json_add_boolean "read_only" 0
|
||||
json_add_boolean "global_key" 1
|
||||
__auth_body="$(json_dump)"
|
||||
|
||||
|
||||
# Sign body using the private key and encode with base64
|
||||
|
||||
__auth_signature=$(echo -n "${__auth_body}" | \
|
||||
openssl dgst -sha512 -sign "${__tmp_keyfile}" | \
|
||||
openssl base64 | \
|
||||
tr -d " \t\n\r")
|
||||
|
||||
rm "${__tmp_keyfile}"
|
||||
|
||||
|
||||
# Send and parse request for a temporary authentication token
|
||||
|
||||
__auth_status=$(curl -s -X POST "https://api.transip.nl/v6/auth" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Signature: ${__auth_signature}" \
|
||||
-d "${__auth_body}" \
|
||||
-w "%{http_code}\n" \
|
||||
-o "${DATFILE}" 2>"${ERRFILE}")
|
||||
|
||||
|
||||
# Logging for error and debug
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat "${ERRFILE}")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z ${__auth_status} ] || [ ${__auth_status} -ne 201 ]; then
|
||||
write_log 14 "TransIP authentication (status ${__auth_status}) failed: $(cat ${DATFILE})"
|
||||
return 1
|
||||
fi
|
||||
|
||||
write_log 7 "TransIP authentication successful"
|
||||
|
||||
|
||||
## Extract token from the response
|
||||
|
||||
__auth_token=$(cat ${DATFILE} | sed 's/^.*"token" *: *"\([^"]*\)".*$/\1/')
|
||||
|
||||
|
||||
# Create request body for update
|
||||
|
||||
json_init
|
||||
json_add_object "dnsEntry"
|
||||
json_add_string "name" "${param_enc}"
|
||||
json_add_string "type" "$([ $use_ipv6 -ne 0 ] && echo -n AAAA || echo -n A)"
|
||||
json_add_int "expire" "${param_opt}"
|
||||
json_add_string "content" "${__IP}"
|
||||
json_close_object
|
||||
__update_body="$(json_dump)"
|
||||
|
||||
|
||||
# Send update request
|
||||
|
||||
__update_status=$(curl -s -X PATCH "https://api.transip.nl/v6/domains/${domain}/dns" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${__auth_token}" \
|
||||
-d "${__update_body}" \
|
||||
-w "%{http_code}\n" \
|
||||
-o "${DATFILE}" 2>"${ERRFILE}")
|
||||
|
||||
|
||||
# Logging for error and debug
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
write_log 14 "Curl failed: $(cat "${ERRFILE}")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z ${__update_status} ] || [ ${__update_status} -ne 204 ]; then
|
||||
write_log 14 "TransIP DNS update (status ${__update_status}) failed: $(cat ${DATFILE})"
|
||||
return 1
|
||||
fi
|
||||
|
||||
write_log 7 "TransIP DNS update successful"
|
||||
return 0
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "3322.org",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@members.3322.org/dyndns/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "afraid.org-basicauth",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@freedns.afraid.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@freedns.afraid.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "afraid.org-keyauth",
|
||||
"ipv4": {
|
||||
"url": "https://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "afraid.org-v2-basic",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@sync.afraid.org/u/?h=[DOMAIN]&ip=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@v6.sync.afraid.org/u/?h=[DOMAIN]&ip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "afraid.org-v2-token",
|
||||
"ipv4": {
|
||||
"url": "https://sync.afraid.org/u/[PASSWORD]/?address=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://v6.sync.afraid.org/u/[PASSWORD]/?address=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "all-inkl.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.kasserver.com/?myip=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.kasserver.com/?myip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "bind-nsupdate",
|
||||
"ipv4": {
|
||||
"url": "update_nsupdate.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_nsupdate.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "changeip.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@nic.changeip.com/nic/update?u=[USERNAME]&p=[PASSWORD]&cmd=update&hostname=[DOMAIN]&ip=[IP]",
|
||||
"answer": "Successful"
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "cloud.google.com-v1",
|
||||
"ipv4": {
|
||||
"url": "update_gcp_v1.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_gcp_v1.sh"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "cloudflare.com-v4",
|
||||
"ipv4": {
|
||||
"url": "update_cloudflare_com_v4.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_cloudflare_com_v4.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "cnkuai.cn",
|
||||
"ipv4": {
|
||||
"url": "update_cnkuai_cn.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_cnkuai_cn.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "core-networks.de",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.core-networks.de/?hostname=[DOMAIN]&myip=[IP]&keepipv6=1",
|
||||
"answer": "good"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.core-networks.de/?hostname=[DOMAIN]&myip=[IP]&keepipv4=1",
|
||||
"answer": "good"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "ddnss.de",
|
||||
"ipv4": {
|
||||
"url": "http://ip4.ddnss.de/upd.php?user=[USERNAME]&pwd=[PASSWORD]&host=[DOMAIN]&ip=[IP]",
|
||||
"answer": "Updated|No change"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "ddo.jp",
|
||||
"ipv4": {
|
||||
"url": "http://free.ddo.jp/dnsupdate.php?dn=[DOMAIN]&pw=[PASSWORD]&ip=[IP]"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/desec.io.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/desec.io.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "desec.io",
|
||||
"ipv4": {
|
||||
"url": "https://update.dedyn.io/update?username=[USERNAME]&password=[PASSWORD]&hostname=[DOMAIN]&myipv4=[IP]&myipv6=preserve",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://update.dedyn.io/update?username=[USERNAME]&password=[PASSWORD]&hostname=[DOMAIN]&myipv6=[IP]&myipv4=preserve",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "dhis.org",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@is.dhis.org/"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@is.dhis.org/"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "digitalocean.com-v2",
|
||||
"ipv4": {
|
||||
"url": "update_digitalocean_com_v2.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_digitalocean_com_v2.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dnsdynamic.org",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@www.dnsdynamic.org/api/?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "dnsever.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyna.dnsever.com/update.php?host[[DOMAIN]]"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "dnsexit.com",
|
||||
"ipv4": {
|
||||
"url": "http://update.dnsexit.com/RemoteUpdate.sv?login=[USERNAME]&password=[PASSWORD]&host=[DOMAIN]&myip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "dnshome.de",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@www.dnshome.de/dyndns.php?hostname=[DOMAIN]&ip=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@www.dnshome.de/dyndns.php?hostname=[DOMAIN]&ip6=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dnsmadeeasy.com",
|
||||
"ipv4": {
|
||||
"url": "http://cp.dnsmadeeasy.com/servlet/updateip?username=[USERNAME]&password=[PASSWORD]&id=[DOMAIN]&ip=[IP]",
|
||||
"answer": "success|ip-same"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "dnsmax.com",
|
||||
"ipv4": {
|
||||
"url": "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=1&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dnsomatic.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dnspark.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@control.dnspark.com/api/dynamic/update.php?hostname=[DOMAIN]&ip=[IP]",
|
||||
"answer": "ok|nochange"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "dnspod.cn",
|
||||
"ipv4": {
|
||||
"url": "update_dnspod_cn.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_dnspod_cn.sh"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/do.de.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/do.de.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "do.de",
|
||||
"ipv4": {
|
||||
"url": "http://ddns.do.de/?myip=[IP]&hostname=[DOMAIN]&username=[USERNAME]&password=[PASSWORD]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://ddns.do.de/?myip=[IP]&hostname=[DOMAIN]&username=[USERNAME]&password=[PASSWORD]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "domopoli.de",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@http://dyndns.domopoli.de/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "duckdns.org",
|
||||
"ipv4": {
|
||||
"url": "http://www.duckdns.org/update?domains=[DOMAIN]&token=[PASSWORD]&ip=[IP]",
|
||||
"answer": "OK"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://www.duckdns.org/update?domains=[DOMAIN]&token=[PASSWORD]&ipv6=[IP]",
|
||||
"answer": "OK"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "duiadns.net",
|
||||
"ipv4": {
|
||||
"url": "http://ip.duiadns.net/dynamic.duia?host=[DOMAIN]&password=[PASSWORD]&ip4=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://ip.duiadns.net/dynamic.duia?host=[DOMAIN]&password=[PASSWORD]&ip6=[IP]"
|
||||
}
|
||||
}
|
7
net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json
Normal file
7
net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dy.fi",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@www.dy.fi/nic/update?hostname=[DOMAIN]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "dyn.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@members.dyndns.org/v3/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@members.dyndns.org/v3/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "dyndns.it",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@update.dyndns.it/nic/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "dyndns.org",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@members.dyndns.org/v3/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@members.dyndns.org/v3/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "dynu.com",
|
||||
"ipv4": {
|
||||
"url": "http://api.dynu.com/nic/update?hostname=[DOMAIN]&myip=[IP]&username=[USERNAME]&password=[PASSWORD]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://api.dynu.com/nic/update?hostname=[DOMAIN]&myipv6=[IP]&username=[USERNAME]&password=[PASSWORD]"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "dynv6.com",
|
||||
"ipv4": {
|
||||
"url": "http://dynv6.com/api/update?hostname=[DOMAIN]&token=[PASSWORD]&ipv4=[IP]",
|
||||
"answer": "updated|unchanged"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://dynv6.com/api/update?hostname=[DOMAIN]&token=[PASSWORD]&ipv6=[IP]",
|
||||
"answer": "updated|unchanged"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "easydns.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@api.cp.easydns.com/dyn/generic.php?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "OK|NOERROR"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@api.cp.easydns.com/dyn/generic.php?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "OK|NOERROR"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "freedns.42.pl",
|
||||
"ipv4": {
|
||||
"url": "update_freedns_42_pl.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "gandi.net",
|
||||
"ipv4": {
|
||||
"url": "update_gandi_net.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_gandi_net.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "godaddy.com-v1",
|
||||
"ipv4": {
|
||||
"url": "update_godaddy_com_v1.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_godaddy_com_v1.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "goip.de",
|
||||
"ipv4": {
|
||||
"url": "http://www.goip.de/setip?username=[USERNAME]&password=[PASSWORD]&subdomain=[DOMAIN]&ip=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://www.goip.de/setip?username=[USERNAME]&password=[PASSWORD]&subdomain=[DOMAIN]&ip6=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "google.com",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@domains.google.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@domains.google.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/he.net.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/he.net.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "he.net",
|
||||
"ipv4": {
|
||||
"url": "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "hosting.de",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@ddns.hosting.de/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@ddns.hosting.de/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "huaweicloud.com",
|
||||
"ipv4": {
|
||||
"url": "update_huaweicloud_com.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_huaweicloud_com.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "infomaniak.com",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@infomaniak.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@infomaniak.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "inwx.de",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.inwx.com/nic/update?myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dyndns.inwx.com/nic/update?myipv6=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "ipnodns.ru",
|
||||
"ipv4": {
|
||||
"url": "https://ipnodns.ru/cgi-bin/dyndns.cgi?login=[USERNAME]&secret=[PASSWORD]",
|
||||
"answer": "ok"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "joker.com",
|
||||
"ipv4": {
|
||||
"url": "http://svc.joker.com/nic/update?username=[USERNAME]&password=[PASSWORD]&myip=[IP]&hostname=[DOMAIN]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "loopia.se",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "luadns.com-v1",
|
||||
"ipv4": {
|
||||
"url": "update_luadns_v1.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_luadns_v1.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "moniker.com",
|
||||
"ipv4": {
|
||||
"url": "https://dynamicdns.key-systems.net/update.php?hostname=[DOMAIN]&password=[PASSWORD]&ip=[IP]",
|
||||
"answer": "success"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "mydns.jp",
|
||||
"ipv4": {
|
||||
"url": "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV4ADDR=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV6ADDR=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "myonlineportal.net",
|
||||
"ipv4": {
|
||||
"url": "http://myonlineportal.net/updateddns?hostname=[DOMAIN]&ip=[IP]&username=[USERNAME]&password=[PASSWORD]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://myonlineportal.net/updateddns?hostname=[DOMAIN]&ip6=[IP]&username=[USERNAME]&password=[PASSWORD]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "mythic-beasts.com (API v2)",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@ipv4.api.mythic-beasts.com/dns/v2/dynamic/[DOMAIN]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@ipv6.api.mythic-beasts.com/dns/v2/dynamic/[DOMAIN]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "mythic-beasts.com",
|
||||
"ipv4": {
|
||||
"url": "http://dnsapi4.mythic-beasts.com/?domain=[USERNAME]&password=[PASSWORD]&command=REPLACE%20[DOMAIN]%2060%20A%20DYNAMIC_IP&origin=."
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://dnsapi6.mythic-beasts.com/?domain=[USERNAME]&password=[PASSWORD]&command=REPLACE%20[DOMAIN]%2060%20AAAA%20DYNAMIC_IP&origin=."
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "namecheap.com",
|
||||
"ipv4": {
|
||||
"url": "http://dynamicdns.park-your-domain.com/update?host=[USERNAME]&domain=[DOMAIN]&password=[PASSWORD]&ip=[IP]"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "njal.la",
|
||||
"ipv4": {
|
||||
"url": "https://njal.la/update/?h=[DOMAIN]&k=[PASSWORD]&a=[IP]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://njal.la/update/?h=[DOMAIN]&k=[PASSWORD]&aaaa=[IP]"
|
||||
}
|
||||
}
|
10
net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json
Normal file
10
net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "no-ip.com",
|
||||
"ipv4": {
|
||||
"url": "update_no-ip_com.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_no-ip_com.sh"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "no-ip.pl",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "now-dns.com",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@now-dns.com/update?hostname=[DOMAIN]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@now-dns.com/update?hostname=[DOMAIN]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "ns1.com",
|
||||
"ipv4": {
|
||||
"url": "update_ns1_com.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_ns1_com.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "nsupdate.info",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@ipv4.nsupdate.info/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@ipv6.nsupdate.info/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "one.com",
|
||||
"ipv4": {
|
||||
"url": "update_one_com.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name":"opendns.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@updates.opendns.com/nic/update?hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "oray.com",
|
||||
"ipv4": {
|
||||
"url": "http://[USERNAME]:[PASSWORD]@ddns.oray.com/ph/update?hostname=[DOMAIN]&myip=[IP]"
|
||||
}
|
||||
}
|
11
net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json
Normal file
11
net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "ovh.com",
|
||||
"ipv4": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@dns.eu.ovhapis.com/nic/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "https://[USERNAME]:[PASSWORD]@dns.eu.ovhapis.com/nic/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]",
|
||||
"answer": "good|nochg"
|
||||
}
|
||||
}
|
9
net/ddns-scripts/files/usr/share/ddns/default/pdns.json
Normal file
9
net/ddns-scripts/files/usr/share/ddns/default/pdns.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "PowerDNS",
|
||||
"ipv4": {
|
||||
"url": "update_pdns.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_pdns.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "porkbun.com-v3",
|
||||
"ipv4": {
|
||||
"url": "update_porkbun_v3.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_porkbun_v3.sh"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "regfish.de",
|
||||
"ipv4": {
|
||||
"url": "http://dyndns.regfish.de/?fqdn=[DOMAIN]&forcehost=1&authtype=secure&token=[PASSWORD]&ipv4=[IP]",
|
||||
"answer": "success|100|101"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "http://dyndns.regfish.de/?fqdn=[DOMAIN]&forcehost=1&authtype=secure&token=[PASSWORD]&ipv6=[IP]",
|
||||
"answer": "success|100|101"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "route53-v1",
|
||||
"ipv4": {
|
||||
"url": "update_route53_v1.sh"
|
||||
},
|
||||
"ipv6": {
|
||||
"url": "update_route53_v1.sh"
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user