ddns-scripts: update to 2.7.6-1

- tld_names.dat.gz
  - rename to public_suffix_list.dat.gz
  - (re)created during build
  - new location /usr/share
- move services files to /etc/ddns
- new services
  - CloudFlare.com-v4 using API-Version 4 without using public_suffix_list.dat
  - GoDaddy.com
  - both depending on cURL package
  - both with modified syntax for option domain ( NEW: [host[.subdom]@]domain.tld )
- new service
  - Now-DNS.com formerly Now-IP.com
- service afraid.org now supports key-auth and basic-auth
- new command line options for dynamic_dns_updater.sh and dynamic_dns_updater.sh
- adapted ddns.init and ddns.hotplug to new command line options
- renaming config options inside section global

Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
This commit is contained in:
Christian Schoenebeck 2016-12-04 16:47:09 +01:00
parent 4a07953154
commit 1c20dcb71a
16 changed files with 954 additions and 12445 deletions

View File

@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-scripts
# Version == major.minor.patch
# increase on new functionality (minor) or patches (patch)
PKG_VERSION:=2.7.5
PKG_VERSION:=2.7.6
# Release == build
# increase on changes of services files or tld_names.dat
PKG_RELEASE:=3
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
@ -43,26 +43,44 @@ define Package/$(PKG_NAME)/config
help
A highly configurable set of scripts for doing dynamic dns updates.
- IPv6 support
- force communication to IPv4 or IPv6 only
- DNS server support
- using BIND host if installed
- Glue Record support (require BIND host or KNOT host)
- DNS requests via TCP
- Proxy server support
- log file support
- support to run once
Version: $(PKG_VERSION)-$(PKG_RELEASE)
Info : http://wiki.openwrt.org/doc/howto/ddns.client
$(PKG_MAINTAINER)
endef
##### **********************************
define Package/$(PKG_NAME)_cloudflare
$(call Package/$(PKG_NAME)/Default)
TITLE:=DDNS extension for CloudFlare.com
TITLE:=CloudFlare.com API v1 (deprecated)
DEPENDS:=$(PKG_NAME)
endef
define Package/$(PKG_NAME)_cloudflare/description
Dynamic DNS Client scripts extension for CloudFlare.com
Dynamic DNS Client scripts extension for CloudFlare.com API-v1 (deprecated)
endef
##### **********************************
define Package/$(PKG_NAME)_cloudflare.com-v4
$(call Package/$(PKG_NAME)/Default)
TITLE:=CloudFlare.com API v4 (require cURL)
DEPENDS:=$(PKG_NAME) +curl
endef
define Package/$(PKG_NAME)_cloudflare.com-v4/description
Dynamic DNS Client scripts extension for CloudFlare.com API-v4 (require/install cURL)
endef
##### **********************************
define Package/$(PKG_NAME)_godaddy.com-v1
$(call Package/$(PKG_NAME)/Default)
TITLE:=GoDaddy.com (require cURL)
DEPENDS:=$(PKG_NAME) +curl
endef
define Package/$(PKG_NAME)_godaddy.com-v1/description
Dynamic DNS Client scripts extension for GoDaddy.com (require/install cURL)
endef
##### **********************************
@ -107,7 +125,13 @@ define Build/Compile
-e '/^\/\/\s/d' \
-e '/^\s*$$$$/d' $$$$FILE; \
done
gzip -f9 $(PKG_BUILD_DIR)/files/tld_names.dat
# ensure that VERSION inside dynamic_dns_functions.sh reflect PKG_VERSION of Makefile
$(SED) '/^VERSION=*/s/.*/VERSION="$(PKG_VERSION)"/' $(PKG_BUILD_DIR)/files/dynamic_dns_functions.sh
$(CP) ./tools $(PKG_BUILD_DIR)
chmod 755 $(PKG_BUILD_DIR)/tools/*
$(PKG_BUILD_DIR)/tools/public_suffix_list.sh
mv -f $(PKG_BUILD_DIR)/tools/public_suffix_list.dat.gz \
$(PKG_BUILD_DIR)/files/public_suffix_list.dat.gz
endef
define Package/$(PKG_NAME)/conffiles
@ -116,18 +140,20 @@ endef
##### **********************************
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.hotplug $(1)/etc/hotplug.d/iface/95-ddns
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.init $(1)/etc/init.d/ddns
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.hotplug $(1)/etc/hotplug.d/iface/95-ddns
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.init $(1)/etc/init.d/ddns
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) $(PKG_BUILD_DIR)/files/ddns.config $(1)/etc/config/ddns
$(INSTALL_DIR) $(1)/usr/lib/ddns
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/services* $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/dynamic_*.sh $(1)/usr/lib/ddns
$(INSTALL_DIR) $(1)/etc/ddns
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/services* $(1)/etc/ddns
$(INSTALL_DIR) $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/dynamic_dns_*.sh $(1)/usr/lib/ddns
endef
define Package/$(PKG_NAME)/prerm
#!/bin/sh
@ -146,20 +172,58 @@ endef
##### **********************************
define Package/$(PKG_NAME)_cloudflare/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_cloudflare
$(INSTALL_DIR) $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_cloudflare_com.sh $(1)/usr/lib/ddns
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/tld_names.dat.gz $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_cloudflare_com_v1.sh $(1)/usr/lib/ddns
$(INSTALL_DIR) $(1)/usr/share
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/public_suffix_list.dat.gz $(1)/usr/share
endef
define Package/$(PKG_NAME)_cloudflare/postinst
#!/bin/sh
echo -e '"cloudflare.com"\t"update_cloudflare_com.sh"' >> $${IPKG_INSTROOT}/usr/lib/ddns/services
echo -e '"cloudflare.com"\t"update_cloudflare_com.sh"' >> $${IPKG_INSTROOT}/usr/lib/ddns/services_ipv6
/bin/sed -i '/service_name/s/CloudFlare/cloudflare\.com/g' $${IPKG_INSTROOT}/etc/config/ddns
printf "%s\\t%s\\n" '"cloudflare.com-v1"' '"update_cloudflare_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t%s\\n" '"cloudflare.com-v1"' '"update_cloudflare_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
endef
define Package/$(PKG_NAME)_cloudflare/prerm
#!/bin/sh
/bin/sed -i '/update_cloudflare_com\.sh/ d' $${IPKG_INSTROOT}/usr/lib/ddns/services
/bin/sed -i '/update_cloudflare_com\.sh/ d' $${IPKG_INSTROOT}/usr/lib/ddns/services_ipv6
/bin/sed -i '/cloudflare\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/cloudflare\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
endef
##### **********************************
define Package/$(PKG_NAME)_cloudflare.com-v4/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_cloudflare.com-v4
$(INSTALL_DIR) $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_cloudflare_com_v4.sh $(1)/usr/lib/ddns
endef
define Package/$(PKG_NAME)_cloudflare.com-v4/postinst
#!/bin/sh
printf "%s\\t%s\\n" '"cloudflare.com-v4"' '"update_cloudflare_com_v4.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t%s\\n" '"cloudflare.com-v4"' '"update_cloudflare_com_v4.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
endef
define Package/$(PKG_NAME)_cloudflare.com-v4/prerm
#!/bin/sh
/bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
endef
##### **********************************
define Package/$(PKG_NAME)_godaddy.com-v1/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_godaddy.com-v1
$(INSTALL_DIR) $(1)/usr/lib/ddns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_godaddy_com_v1.sh $(1)/usr/lib/ddns
endef
define Package/$(PKG_NAME)_godaddy.com-v1/postinst
#!/bin/sh
printf "%s\\t%s\\n" '"godaddy.com-v1"' '"update_godaddy_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t%s\\n" '"godaddy.com-v1"' '"update_godaddy_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
endef
define Package/$(PKG_NAME)_godaddy.com-v1/prerm
#!/bin/sh
/bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
endef
##### **********************************
@ -169,13 +233,11 @@ define Package/$(PKG_NAME)_no-ip_com/install
endef
define Package/$(PKG_NAME)_no-ip_com/postinst
#!/bin/sh
echo -e '"no-ip.com"\t"update_no-ip_com.sh"' >> $${IPKG_INSTROOT}/usr/lib/ddns/services
/bin/sed -i '/service_name/s/NoIP\.com/no-ip\.com/g' $${IPKG_INSTROOT}/etc/config/ddns
/bin/sed -i '/service_name/s/No-IP\.com/no-ip\.com/g' $${IPKG_INSTROOT}/etc/config/ddns
printf "%s\\t%s\\n" '"no-ip.com"' '"update_no-ip_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
endef
define Package/$(PKG_NAME)_no-ip_com/prerm
#!/bin/sh
/bin/sed -i '/update_no-ip_com\.sh/ d' $${IPKG_INSTROOT}/usr/lib/ddns/services
/bin/sed -i '/no-ip\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
endef
##### **********************************
@ -185,18 +247,19 @@ define Package/$(PKG_NAME)_nsupdate/install
endef
define Package/$(PKG_NAME)_nsupdate/postinst
#!/bin/sh
echo -e '"bind-nsupdate"\t"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/usr/lib/ddns/services
echo -e '"bind-nsupdate"\t"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/usr/lib/ddns/services_ipv6
/bin/sed -i '/service_name/s/Bind-nsupdate/bind-nsupdate/g' $${IPKG_INSTROOT}/etc/config/ddns
printf "%s\\t%s\\n" '"bind-nsupdate"' '"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services
printf "%s\\t%s\\n" '"bind-nsupdate"' '"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6
endef
define Package/$(PKG_NAME)_nsupdate/prerm
#!/bin/sh
/bin/sed -i '/update_nsupdate\.sh/ d' $${IPKG_INSTROOT}/usr/lib/ddns/services
/bin/sed -i '/update_nsupdate\.sh/ d' $${IPKG_INSTROOT}/usr/lib/ddns/services_ipv6
/bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1
/bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1
endef
##### **********************************
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,$(PKG_NAME)_cloudflare))
$(eval $(call BuildPackage,$(PKG_NAME)_cloudflare.com-v4))
$(eval $(call BuildPackage,$(PKG_NAME)_godaddy.com-v1))
$(eval $(call BuildPackage,$(PKG_NAME)_no-ip_com))
$(eval $(call BuildPackage,$(PKG_NAME)_nsupdate))

View File

@ -1,25 +1,99 @@
#!/bin/sh
# add new section "ddns" "global" if not exists
/sbin/uci -q get ddns.global > /dev/null || /sbin/uci -q set ddns.global='ddns'
/sbin/uci -q get ddns.global.date_format > /dev/null || /sbin/uci -q set ddns.global.date_format='%F %R'
/sbin/uci -q get ddns.global.log_lines > /dev/null || /sbin/uci -q set ddns.global.log_lines='250'
/sbin/uci -q get ddns.global.allow_local_ip > /dev/null || /sbin/uci -q set ddns.global.allow_local_ip='0'
/sbin/uci -q commit ddns
# using function to not confuse function calls with existing ones inside /lib/functions.sh
update_ddns_config() {
udc_uci="$(which uci) -q" # ignore errors
udc_pkg="ddns"
udc_cfg=""
udc_name=""
udc_var=""
udc_val=""
package() { return 0; }
config () {
udc_cfg="$1"
udc_name="$2"
# fix some service_name entries to new once
/bin/sed -i \
-e '/service_name/s/CloudFlare/cloudflare\.com/g' \
-e '/service_name/s/NoIP\.com/no-ip\.com/g' \
-e '/service_name/s/No-IP\.com/no-ip\.com/g' \
-e '/service_name/s/freedns.afraid.org/afraid.org/g' \
-e '/service_name/s/free.editdns.net/editdns.net/g' \
-e '/service_name/s/domains.google.com/google.com/g' \
-e '/service_name/s/spdns.de/spdyn.de/g' \
-e '/service_name/s/strato.de/strato.com/g' \
/etc/config/ddns
# Type = ddns Name = global
if [ "$udc_cfg" = "$udc_pkg" -a "$udc_name" = "global" ]; then
option() { return 0; }
# rename options
$udc_uci rename $udc_pkg.$udc_name.allow_local_ip="upd_privateip"
$udc_uci rename $udc_pkg.$udc_name.date_format="ddns_dateformat"
$udc_uci rename $udc_pkg.$udc_name.log_dir="ddns_logdir"
$udc_uci rename $udc_pkg.$udc_name.log_lines="ddns_loglines"
$udc_uci rename $udc_pkg.$udc_name.run_dir="ddns_rundir"
# clear LuCI indexcache
# Type = service Name = ???
elif [ "$udc_cfg" = "service" ]; then
option() {
udc_var="$1"; shift
udc_val="$*"
# fix some option service_name values
case "$udc_var" in
service_name)
case "$udc_val" in
freedns\.afraid\.org|afraid\.org)
$udc_uci set $udc_pkg.$udc_name.$udc_var="afraid.org-keyauth";;
Bind-nsupdate)
$udc_uci set $udc_pkg.$udc_name.$udc_var="bind-nsupdate";;
CloudFlare|cloudflare\.com)
$udc_uci set $udc_pkg.$udc_name.$udc_var="cloudflare.com-v1";;
dyndns\.org|dyndns\.com)
$udc_uci set $udc_pkg.$udc_name.$udc_var="dyn.com";;
free\.editdns\.net)
$udc_uci set $udc_pkg.$udc_name.$udc_var="editdns.net";;
domains\.google\.com)
$udc_uci set $udc_pkg.$udc_name.$udc_var="google.com";;
loopia\.com)
$udc_uci set $udc_pkg.$udc_name.$udc_var="loopia.se";;
NoIP\.com|No-IP\.com)
$udc_uci set $udc_pkg.$udc_name.$udc_var="no-ip.com";;
spdns\.de)
$udc_uci set $udc_pkg.$udc_name.$udc_var="spdyn.de";;
strato\.de)
$udc_uci set $udc_pkg.$udc_name.$udc_var="strato.com";;
*)
# all others leave unchanged
;;
esac
# rename option service_name to option upd_provider
# $udc_uci rename $udc_pkg.$udc_name.$udc_var="upd_provider"
;;
*)
# leave all other options currently unchanged
;;
esac
return 0
}
return 0
# ignore unknown
else
return 0
fi
}
# read package config file
udc_data=$($udc_uci -S -n export "$udc_pkg")
udc_ret="$?"
# No error and udc_data then execute (eval)
# this will call functions defined above
[ "$udc_ret" -eq 0 -a -n "$udc_data" ] && eval "$udc_data"
# add config ddns "global" (ignore error if exists)
$udc_uci set ddns.global="$udc_pkg"
# write changes to config file
$udc_uci commit "$udc_pkg"
unset udc_uci udc_pkg udc_cfg udc_name udc_var udc_val udc_ret udc_data
return 0
}
# do existing config update
update_ddns_config
# clear Ludc_uci indexcache
rm -f /tmp/luci-indexcache >/dev/null 2>&1
exit 0
return 0

9
net/ddns-scripts/files/ddns.hotplug Normal file → Executable file
View File

@ -1,14 +1,11 @@
#!/bin/sh
# there are other ACTIONs like ifupdate we don't need
# so parse dynamic_dns_functions.sh only when needed
case "$ACTION" in
ifup)
. /usr/lib/ddns/dynamic_dns_functions.sh
/etc/init.d/ddns enabled && start_daemon_for_all_ddns_sections "$INTERFACE"
ifup) # OpenWrt is giving a network not phys. Interface
/etc/init.d/ddns enabled && /usr/lib/ddns/dynamic_dns_updater.sh -n "$INTERFACE" -- start
;;
ifdown)
. /usr/lib/ddns/dynamic_dns_functions.sh
stop_daemon_for_all_ddns_sections "$INTERFACE"
/usr/lib/ddns/dynamic_dns_updater.sh -n "$INTERFACE" -- stop
;;
esac

13
net/ddns-scripts/files/ddns.init Normal file → Executable file
View File

@ -7,22 +7,21 @@ boot() {
}
reload() {
killall -1 dynamic_dns_updater.sh 2>/dev/null # send SIGHUP
/usr/lib/ddns/dynamic_dns_updater.sh -- reload
return 0
}
restart() {
stop
/usr/lib/ddns/dynamic_dns_updater.sh -- stop
sleep 1 # give time to shutdown
start
/usr/lib/ddns/dynamic_dns_updater.sh -- start
}
start() {
. /usr/lib/ddns/dynamic_dns_functions.sh
start_daemon_for_all_ddns_sections
/usr/lib/ddns/dynamic_dns_updater.sh -- start
}
stop() {
killall dynamic_dns_updater.sh 2>/dev/null
return 0 # if killall fails, ignore
/usr/lib/ddns/dynamic_dns_updater.sh -- stop
return 0
}

View File

@ -21,16 +21,17 @@
. /lib/functions/network.sh
# GLOBAL VARIABLES #
VERSION="2.7.5"
VERSION="2.7.6"
SECTION_ID="" # hold config's section name
VERBOSE_MODE=1 # default mode is log to console, but easily changed with parameter
VERBOSE=1 # default mode is log to console, but easily changed with parameter
MYPROG=$(basename $0) # my program call name
LOGFILE="" # logfile - all files are set in dynamic_dns_updater.sh
PIDFILE="" # pid file
UPDFILE="" # store UPTIME of last update
DATFILE="" # save stdout data of WGet and other external programs called
ERRFILE="" # save stderr output of WGet and other external programs called
TLDFILE=/usr/lib/ddns/tld_names.dat.gz # TLD file used by split_FQDN
TLDFILE=/usr/share/public_suffix_list.dat.gz # TLD file used by split_FQDN
CHECK_SECONDS=0 # calculated seconds out of given
FORCE_SECONDS=0 # interval and unit
@ -48,7 +49,7 @@ URL_USER="" # url encoded $username from config file
URL_PASS="" # url encoded $password from config file
URL_PENC="" # url encoded $param_enc from config file
SRV_ANSWER="" # Answer given by service on success
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
@ -61,8 +62,8 @@ 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,\}\)"
# detect if called by dynamic_dns_lucihelper.sh script, disable retrys (empty variable == false)
[ "$(basename $0)" = "dynamic_dns_lucihelper.sh" ] && LUCI_HELPER="TRUE" || LUCI_HELPER=""
# detect if called by ddns-lucihelper.sh script, disable retrys (empty variable == false)
[ "$MYPROG" = "ddns-lucihelper.sh" ] && LUCI_HELPER="TRUE" || LUCI_HELPER=""
# Name Server Lookup Programs
BIND_HOST=$(which host)
@ -88,23 +89,23 @@ UCLIENT_FETCH_SSL=$(find /lib /usr/lib -name libustream-ssl.so* 2>/dev/null)
# Global configuration settings
# allow NON-public IP's
ALLOW_LOCAL_IP=$(uci -q get ddns.global.allow_local_ip) || ALLOW_LOCAL_IP=0
upd_privateip=$(uci -q get ddns.global.allow_local_ip) || upd_privateip=0
# directory to store run information to.
RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns"
[ -d $RUNDIR ] || mkdir -p -m755 $RUNDIR
ddns_rundir=$(uci -q get ddns.global.run_dir) || ddns_rundir="/var/run/ddns"
[ -d $ddns_rundir ] || mkdir -p -m755 $ddns_rundir
# directory to store log files
LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns"
[ -d $LOGDIR ] || mkdir -p -m755 $LOGDIR
ddns_logdir=$(uci -q get ddns.global.log_dir) || ddns_logdir="/var/log/ddns"
[ -d $ddns_logdir ] || mkdir -p -m755 $ddns_logdir
# number of lines to before rotate logfile
LOGLINES=$(uci -q get ddns.global.log_lines) || LOGLINES=250
LOGLINES=$((LOGLINES + 1)) # correct sed handling
ddns_loglines=$(uci -q get ddns.global.log_lines) || ddns_loglines=250
ddns_loglines=$((ddns_loglines + 1)) # correct sed handling
# format to show date information in log and luci-app-ddns default ISO 8601 format
DATE_FORMAT=$(uci -q get ddns.global.date_format) || DATE_FORMAT="%F %R"
DATE_PROG="date +'$DATE_FORMAT'"
ddns_dateformat=$(uci -q get ddns.global.date_format) || ddns_dateformat="%F %R"
DATE_PROG="date +'$ddns_dateformat'"
# USE_CURL if GNU Wget and cURL installed normally Wget is used by do_transfer()
# to change this use global option use_curl '1'
@ -180,7 +181,7 @@ start_daemon_for_all_ddns_sections()
for __SECTIONID in $__SECTIONS; do
config_get __IFACE "$__SECTIONID" interface "wan"
[ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue
/usr/lib/ddns/dynamic_dns_updater.sh $__SECTIONID 0 >/dev/null 2>&1 &
/usr/lib/ddns/dynamic_dns_updater.sh -v "0" -S "$__SECTIONID" -- start
done
}
@ -188,7 +189,7 @@ start_daemon_for_all_ddns_sections()
# $1 = section
stop_section_processes() {
local __PID=0
local __PIDFILE="$RUNDIR/$1.pid"
local __PIDFILE="$ddns_rundir/$1.pid"
[ $# -ne 1 ] && write_log 12 "Error calling 'stop_section_processes()' - wrong number of parameters"
[ -e "$__PIDFILE" ] && {
@ -253,14 +254,14 @@ write_log() {
esac
# verbose echo
[ $VERBOSE_MODE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG"
[ $VERBOSE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG"
# write to logfile
if [ ${use_logfile:-1} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then
if [ ${use_logfile:-1} -eq 1 -o $VERBOSE -gt 1 ]; then
echo -e "$__MSG" >> $LOGFILE
# VERBOSE_MODE > 1 then NO loop so NO truncate log to $LOGLINES lines
[ $VERBOSE_MODE -gt 1 ] || sed -i -e :a -e '$q;N;'$LOGLINES',$D;ba' $LOGFILE
# VERBOSE > 1 then NO loop so NO truncate log to $ddns_loglines lines
[ $VERBOSE -gt 1 ] || sed -i -e :a -e '$q;N;'$ddns_loglines',$D;ba' $LOGFILE
fi
[ $LUCI_HELPER ] && return # nothing else todo when running LuCI helper script
[ -n "$LUCI_HELPER" ] && return # nothing else todo when running LuCI helper script
[ $__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 ] && {
@ -269,6 +270,7 @@ write_log() {
}
[ $use_syslog -eq 0 ] && return
[ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD
return
}
@ -314,22 +316,22 @@ urlencode() {
}
# extract url or script for given DDNS Provider from
# file /usr/lib/ddns/services for IPv4 or from
# file /usr/lib/ddns/services_ipv6 for IPv6
# 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
get_service_data() {
[ $# -ne 3 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters"
__FILE="/usr/lib/ddns/services" # IPv4
[ $use_ipv6 -ne 0 ] && __FILE="/usr/lib/ddns/services_ipv6" # IPv6
__FILE="/etc/ddns/services" # IPv4
[ $use_ipv6 -ne 0 ] && __FILE="/etc/ddns/services_ipv6" # IPv6
# 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]*$/ds/\"//g' $__FILE > pipe_$$ &
sed '/^#/d; /^[ \t]*$/d; s/\"//g' $__FILE > pipe_$$ &
while read __SERVICE __DATA __ANSWER; do
if [ "$__SERVICE" = "$service_name" ]; then
@ -533,7 +535,7 @@ verify_host_port() {
[ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && __ERR=4
[ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && __ERR=6
[ $__ERR -gt 0 ] && {
[ $LUCI_HELPER ] && return 4
[ -n "$LUCI_HELPER" ] && return 4
write_log 14 "Verify host Error '4' - Forced IP Version IPv$__ERR don't match"
}
fi
@ -586,10 +588,10 @@ verify_dns() {
# DNS uses port 53
verify_host_port "$1" "53"
__ERR=$?
if [ $LUCI_HELPER ]; then # no retry if called by LuCI helper script
if [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script
return $__ERR
elif [ $__ERR -ne 0 -a $VERBOSE_MODE -gt 1 ]; then # VERBOSE_MODE > 1 then NO retry
write_log 4 "Verify DNS server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
elif [ $__ERR -ne 0 -a $VERBOSE -gt 1 ]; then # VERBOSE > 1 then NO retry
write_log 4 "Verify DNS server '$1' failed - Verbose Mode: $VERBOSE - NO retry on error"
return $__ERR
elif [ $__ERR -ne 0 ]; then
__CNT=$(( $__CNT + 1 )) # increment error counter
@ -639,17 +641,17 @@ verify_proxy() {
fi
# No Port detected - EXITING
[ -z "$__PORT" ] && {
[ $LUCI_HELPER ] && return 5
[ -n "$LUCI_HELPER" ] && return 5
write_log 14 "Invalid Proxy server Error '5' - proxy port missing"
}
while [ $__ERR -gt 0 ]; do
verify_host_port "$__HOST" "$__PORT"
__ERR=$?
if [ $LUCI_HELPER ]; then # no retry if called by LuCI helper script
if [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script
return $__ERR
elif [ $__ERR -gt 0 -a $VERBOSE_MODE -gt 1 ]; then # VERBOSE_MODE > 1 then NO retry
write_log 4 "Verify Proxy server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
elif [ $__ERR -gt 0 -a $VERBOSE -gt 1 ]; then # VERBOSE > 1 then NO retry
write_log 4 "Verify Proxy server '$1' failed - Verbose Mode: $VERBOSE - NO retry on error"
return $__ERR
elif [ $__ERR -gt 0 ]; then
__CNT=$(( $__CNT + 1 )) # increment error counter
@ -809,14 +811,14 @@ do_transfer() {
eval $__RUNPROG # DO transfer
__ERR=$? # save error code
[ $__ERR -eq 0 ] && return 0 # no error leave
[ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script
[ -n "$LUCI_HELPER" ] && return 1 # no retry if called by LuCI helper script
write_log 3 "$__PROG 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"
[ $VERBOSE -gt 1 ] && {
# VERBOSE > 1 then NO retry
write_log 4 "Transfer failed - Verbose Mode: $VERBOSE - NO retry on error"
return 1
}
@ -841,7 +843,7 @@ send_update() {
[ $# -ne 1 ] && write_log 12 "Error calling 'send_update()' - wrong number of parameters"
if [ $ALLOW_LOCAL_IP -eq 0 ]; then
if [ $upd_privateip -eq 0 ]; then
# verify given IP / no private IPv4's / no IPv6 addr starting with fxxx of with ":"
[ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10\.|^100\.6[4-9]\.|^100\.[7-9][0-9]\.|^100\.1[0-1][0-9]\.|^100\.12[0-7]\.|^127|^169\.254|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168)")
[ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")
@ -870,9 +872,9 @@ send_update() {
write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)"
[ -z "$SRV_ANSWER" ] && return 0 # not set then ignore
[ -z "$UPD_ANSWER" ] && return 0 # not set then ignore
grep -i -E "$SRV_ANSWER" $DATFILE >/dev/null 2>&1
grep -i -E "$UPD_ANSWER" $DATFILE >/dev/null 2>&1
return $? # "0" if found
fi
}
@ -886,91 +888,123 @@ get_local_ip () {
write_log 7 "Detect local IP on '$ip_source'"
while : ; do
case $ip_source in
network)
# set correct program
[ $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'"
;;
interface)
if [ -n "$ip_network" ]; then
# set correct program
[ $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
local __DATA4=""; local __DATA6=""
if [ -n "$(which 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=$?
if [ $__ERR -eq 0 ]; then
# DATFILE (sample)
# 5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000\ link/ether 08:00:27:d0:10:32 brd ff:ff:ff:ff:ff:ff
# 5: eth1 inet 172.27.10.128/24 brd 172.27.10.255 scope global eth1\ valid_lft forever preferred_lft forever
# 5: eth1 inet 172.55.55.155/24 brd 172.27.10.255 scope global eth1\ valid_lft 12345sec preferred_lft 12345sec
# 5: eth1 inet6 2002:b0c7:f326::806b:c629:b8b9:433/128 scope global dynamic \ valid_lft 8026sec preferred_lft 8026sec
# 5: eth1 inet6 fd43:5368:6f6d:6500:806b:c629:b8b9:433/128 scope global dynamic \ valid_lft 8026sec preferred_lft 8026sec
# 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 remove remove
# BROADCAST inet6 fxxx sec forever=>-1 between / and pref.. linestart to inet
sed -i "/BROADCAST/d; /inet6 f/d; s/sec//g; s/forever/-1/g; s/\/.*preferred_lft//g; s/^.*$ip_interface *//g" $DATFILE
local __TIME4=0; local __TIME6=0
local __TYP __ADR __TIME
while read __TYP __ADR __TIME; do
__TIME=${__TIME:-0} # supress shell errors on last (empty) line of DATFILE
# IPversion no "-1" record stored - now "-1" record or new time > oldtime
[ "$__TYP" = "inet6" -a $__TIME6 -ge 0 -a \( $__TIME -lt 0 -o $__TIME -gt $__TIME6 \) ] && {
__DATA6="$__ADR"
__TIME6="$__TIME"
}
[ "$__TYP" = "inet" -a $__TIME4 -ge 0 -a \( $__TIME -lt 0 -o $__TIME -gt $__TIME4 \) ] && {
__DATA4="$__ADR"
__TIME4="$__TIME"
}
done < $DATFILE
else
write_log 3 "ip Error: '$__ERR'"
write_log 7 "$(cat $ERRFILE)" # report error
fi
else # use deprecated ifconfig
write_log 7 "#> ifconfig $ip_interface >$DATFILE 2>$ERRFILE"
ifconfig $ip_interface >$DATFILE 2>$ERRFILE
__ERR=$?
if [ $__ERR -eq 0 ]; then
if [ $use_ipv6 -eq 0 ]; then
__DATA=$(awk '
/inet addr:/ { # Filter IPv4
# inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
$1=""; # remove inet
$3=""; # remove Bcast: ...
$4=""; # remove Mask: ...
FS=":"; # separator ":"
$0=$0; # reread to activate separator
$1=""; # remove addr
FS=" "; # set back separator to default " "
$0=$0; # reread to activate separator (remove whitespaces)
print $1; # print IPv4 addr
}' $DATFILE
)
else
__DATA=$(awk '
/inet6/ && /: [0-9a-eA-E]/ { # Filter IPv6 exclude fxxx
# inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
FS="/"; # separator "/"
$0=$0; # reread to activate separator
$2=""; # remove everything behind "/"
FS=" "; # set back separator to default " "
$0=$0; # reread to activate separator
print $3; # print IPv6 addr
}' $DATFILE
)
fi
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on interface '$ip_interface'"
__DATA4=$(awk '
/inet addr:/ { # Filter IPv4
# inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
$1=""; # remove inet
$3=""; # remove Bcast: ...
$4=""; # remove Mask: ...
FS=":"; # separator ":"
$0=$0; # reread to activate separator
$1=""; # remove addr
FS=" "; # set back separator to default " "
$0=$0; # reread to activate separator (remove whitespaces)
print $1; # print IPv4 addr
}' $DATFILE
)
__DATA6=$(awk '
/inet6/ && /: [0-9a-eA-E]/ { # Filter IPv6 exclude fxxx
# inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
FS="/"; # separator "/"
$0=$0; # reread to activate separator
$2=""; # remove everything behind "/"
FS=" "; # set back separator to default " "
$0=$0; # reread to activate separator
print $3; # print IPv6 addr
}' $DATFILE
)
else
write_log 3 "ifconfig Error: '$__ERR'"
write_log 7 "$(cat $ERRFILE)" # report error
fi
;;
script)
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'"
else
write_log 3 "$ip_script Error: '$__ERR'"
write_log 7 "$(cat $ERRFILE)" # report error
fi
;;
web)
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'"
;;
*)
write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
;;
esac
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
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'"
else
write_log 3 "$ip_script Error: '$__ERR'"
write_log 7 "$(cat $ERRFILE)" # report error
fi
elif [ -n "$ip_url" ]; 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'"
else
write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
fi
# valid data found return here
[ -n "$__DATA" ] && {
eval "$1=\"$__DATA\""
return 0
}
[ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script
[ -n "$LUCI_HELPER" ] && return 1 # no retry if called by LuCI helper script
write_log 7 "Data detected:\n$(cat $DATFILE)"
write_log 7 "Data detected:"
write_log 7 "$(cat $DATFILE)"
[ $VERBOSE_MODE -gt 1 ] && {
# VERBOSE_MODE > 1 then NO retry
write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
[ $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"
return 1
}
@ -1107,11 +1141,11 @@ get_registered_ip() {
__ERR=127
fi
[ $LUCI_HELPER ] && return $__ERR # no retry if called by LuCI helper script
[ -n "$LUCI_HELPER" ] && return $__ERR # no retry if called by LuCI helper script
[ -n "$2" ] && return $__ERR # $2 is given -> no retry
[ $VERBOSE_MODE -gt 1 ] && {
# VERBOSE_MODE > 1 then NO retry
write_log 4 "Get registered/public IP for '$lookup_host' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
[ $VERBOSE -gt 1 ] && {
# VERBOSE > 1 then NO retry
write_log 4 "Get registered/public IP for '$lookup_host' failed - Verbose Mode: $VERBOSE - NO retry on error"
return $__ERR
}
@ -1156,7 +1190,7 @@ trap_handler() {
fi ;;
1) write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)"
# reload config via starting the script again
eval "/usr/lib/ddns/dynamic_dns_updater.sh $SECTION_ID $VERBOSE_MODE &"
/usr/lib/ddns/dynamic_dns_updater.sh -v "0" -S "$__SECTIONID" -- start || true
exit 0 ;; # and leave this one
2) write_log 5 "PID '$$' terminated by 'SIGINT' at $(eval $DATE_PROG)\n";;
3) write_log 5 "PID '$$' terminated by 'SIGQUIT' at $(eval $DATE_PROG)\n";;

View File

@ -1,5 +1,5 @@
#!/bin/sh
# /usr/lib/ddns/luci_dns_helper.sh
# /usr/lib/ddns/dynamic_dns_lucihelper.sh
#
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
#.2014-2016 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
@ -10,63 +10,120 @@
# variables in big chars beginning with "__" are local defined inside functions only
# set -vx #script debugger
[ $# -lt 2 ] && exit 1
. /usr/lib/ddns/dynamic_dns_functions.sh # global vars are also defined here
# preset some variables, wrong or not set in dynamic_dns_functions.sh
usage() {
cat << EOF
Usage:
$MYPROG [options] -- command
Commands:
get_local_ip using given INTERFACE or NETWORK or SCRIPT or URL
get_registered_ip for given FQDN
verify_dns given DNS-SERVER
verify_proxy given PROXY
start start given SECTION
reload force running ddns processes to reload changed configuration
restart restart all ddns processes
Parameters:
-6 => use_ipv6=1 (default 0)
-d DNS-SERVER => dns_server=SERVER[:PORT]
-f => force_ipversion=1 (default 0)
-g => is_glue=1 (default 0)
-i INTERFACE => ip_interface=INTERFACE; ip_source="interface"
-l FQDN => lookup_host=FQDN
-n NETWORK => ip_network=NETWORK; ip_source="network"
-p PROXY => proxy=[USER:PASS@]PROXY:PORT
-s SCRIPT => ip_script=SCRIPT; ip_source="script"
-t => force_dnstcp=1 (default 0)
-u URL => ip_url=URL; ip_source="web"
-S SECTION SECTION to start
-h => show this help and exit
-L => use_logfile=1 (default 0)
-v LEVEL => VERBOSE=LEVEL (default 0)
-V => show version and exit
EOF
}
usage_err() {
printf %s\\n "$MYPROG: $@" >&2
usage >&2
exit 255
}
# preset some variables, wrong or not set in ddns-functions.sh
SECTION_ID="lucihelper"
LOGFILE="$LOGDIR/$SECTION_ID.log"
DATFILE="$RUNDIR/$SECTION_ID.$$.dat" # save stdout data of WGet and other extern programs called
ERRFILE="$RUNDIR/$SECTION_ID.$$.err" # save stderr output of WGet and other extern programs called
VERBOSE_MODE=0 # no console logging
LOGFILE="$ddns_logdir/$SECTION_ID.log"
DATFILE="$ddns_rundir/$SECTION_ID.$$.dat" # save stdout data of WGet and other extern programs called
ERRFILE="$ddns_rundir/$SECTION_ID.$$.err" # save stderr output of WGet and other extern programs called
DDNSPRG="/usr/lib/ddns/dynamic_dns_updater.sh"
VERBOSE=0 # no console logging
# global variables normally set by reading DDNS UCI configuration
use_syslog=0 # no syslog
use_logfile=0 # by default no logfile, can be changed here
use_logfile=0 # no logfile
use_ipv6=0 # Use IPv6 - default IPv4
force_ipversion=0 # Force IP Version - default 0 - No
force_dnstcp=0 # Force TCP on DNS - default 0 - No
is_glue=0 # Is glue record - default 0 - No
use_https=0 # not needed but must be set
while getopts ":6d:fghi:l:n:p:s:S:tu:Lv:V" OPT; do
case "$OPT" in
6) use_ipv6=1;;
d) dns_server="$OPTARG";;
f) force_ipversion=1;;
g) is_glue=1;;
i) ip_interface="$OPTARG"; ip_source="interface";;
l) lookup_host="$OPTARG";;
n) ip_network="$OPTARG"; ip_source="network";;
p) proxy="$OPTARG";;
s) ip_script="$OPTARG"; ip_source="script";;
t) force_dnstcp=1;;
u) ip_url="$OPTARG"; ip_source="web";;
h) usage; exit 255;;
L) use_logfile=1;;
v) VERBOSE=$OPTARG;;
S) SECTION=$OPTARG;;
V) printf %s\\n "ddns-scripts $VERSION"; exit 255;;
:) usage_err "option -$OPTARG missing argument";;
\?) usage_err "invalid option -$OPTARG";;
*) usage_err "unhandled option -$OPT $OPTARG";;
esac
done
shift $((OPTIND - 1 )) # OPTIND is 1 based
[ $# -eq 0 ] && usage_err "missing command"
__RET=0
case "$1" in
get_registered_ip)
lookup_host=$2 # FQDN of host registered at DDNS
use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
force_dnstcp=${5:-"0"} # Force TCP on DNS - default 0 - No
is_glue=${6:-"0"} # Is glue record - default 0 - No
dns_server=${7:-""} # DNS server - default No DNS
[ -z "$lookup_host" ] && usage_err "command 'get_registered_ip': 'lookup_host' not set"
write_log 7 "-----> get_registered_ip IP"
IP=""
get_registered_ip IP
__RET=$?
[ $__RET -ne 0 ] && IP=""
echo -n "$IP" # suppress LF
printf "%s" "$IP"
;;
verify_dns)
# $2 : dns-server to verify # no need for force_dnstcp because
# verify with nc (netcat) uses tcp anyway
use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
write_log 7 "-----> verify_dns '$2'"
verify_dns "$2"
[ -z "$dns_server" ] && usage_err "command 'verify_dns': 'dns_server' not set"
write_log 7 "-----> verify_dns '$dns_server'"
verify_dns "$dns_server"
__RET=$?
;;
verify_proxy)
# $2 : proxy string to verify
use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
write_log 7 "-----> verify_proxy '$2'"
verify_proxy "$2"
[ -z "$proxy" ] && usage_err "command 'verify_proxy': 'proxy' not set"
write_log 7 "-----> verify_proxy '$proxy'"
verify_proxy "$proxy"
__RET=$?
;;
get_local_ip)
use_ipv6="$2" # Use IPv6
ip_source="$3" # IP source
ip_network="$4" # set if source = "network" otherwise "-"
ip_url="$5" # set if source = "web" otherwise "-"
ip_interface="$6" # set if source = "interface" itherwiase "-"
ip_script="$7" # set if source = "script" otherwise "-"
proxy="$8" # proxy if set
force_ipversion="0" # not needed but must be set
use_https="0" # not needed but must be set
[ -z "$ip_source" ] && usage_err "command 'get_local_ip': 'ip_source' not set"
[ -n "$proxy" -a "$ip_source" = "web" ] && {
# proxy defined, used for ip_source=web
export HTTP_PROXY="http://$proxy"
@ -76,17 +133,29 @@ case "$1" in
}
# don't need IP only the return code
IP=""
[ "$ip_source" = "web" -o "$ip_source" = "script" ] && {
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
} || {
else
write_log 7 "-----> get_local_ip IP"
get_local_ip IP
}
fi
__RET=$?
;;
start)
[ -z "$SECTION" ] && usage_err "command 'start': 'SECTION' not set"
$DDNSPRG -v $VERBOSE -S $SECTION -- start
;;
reload)
$DDNSPRG -- reload
;;
restart)
$DDNSPRG -- stop
sleep 1
$DDNSPRG -- start
;;
*)
__RET=255
;;

View File

@ -15,48 +15,96 @@
. $(dirname $0)/dynamic_dns_functions.sh # global vars are also defined here
[ $# -lt 1 -o -n "${2//[0-3]/}" -o ${#2} -gt 1 ] && {
local __ME=$(basename $0)
usage() {
cat << EOF
ddns-scripts Version: $VERSION
Usage:
$__ME -V display version and exit
$__ME --version display version and exit
$MYPROG [options] -- command
$__ME <SECTION> <VERBOSE_MODE>
<SECTION> service section as defined in /etc/config/ddns
<VERBOSE_MODE> '0' NO output to console
'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
Commands:
start Start SECTION or NETWORK or all
stop Stop NETWORK or all
Parameters:
-n NETWORK Start/Stop sections in background monitoring NETWORK, force VERBOSE=0
-S SECTION SECTION to start
use either -N NETWORK or -S SECTION
-h show this help and exit
-V show version and exit
-v LEVEL VERBOSE=LEVEL (default 1)
'0' NO output to console
'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
EOF
}
usage_err() {
printf %s\\n "$MYPROG: $@" >&2
usage >&2
exit 1
}
[ "$1" = "-V" -o "$1" = "--version" ] && {
printf %s\\n "ddns-scripts $VERSION"
exit 0
}
while getopts ":hv:n:S:V" OPT; do
case "$OPT" in
h) usage; exit 0;;
v) VERBOSE=$OPTARG;;
n) NETWORK=$OPTARG;;
S) SECTION_ID=$OPTARG;;
V) printf %s\\n "ddns-scripts $VERSION"; exit 0;;
:) usage_err "option -$OPTARG missing argument";;
\?) usage_err "invalid option -$OPTARG";;
*) usage_err "unhandled option -$OPT $OPTARG";;
esac
done
shift $((OPTIND - 1 )) # OPTIND is 1 based
SECTION_ID="$1"
VERBOSE_MODE=${2:-1} # default mode is log to console
[ -n "$NETWORK" -a -n "$SECTION_ID" ] && usage_err "use either option '-N' or '-S' not both"
[ $# -eq 0 ] && usage_err "missing command"
[ $# -gt 1 ] && usage_err "to much commands"
case "$1" in
start)
if [ -n "$NETWORK" ]; then
start_daemon_for_all_ddns_sections "$NETWORK"
exit $?
fi
if [ -z "$SECTION_ID" ]; then
start_daemon_for_all_ddns_sections
exit $?
fi
;;
stop)
if [ -n "$INTERFACE" ]; then
stop_daemon_for_all_ddns_sections "$NETWORK"
else
killall ddns-updater.sh 2>/dev/null
fi
exit $?
;;
reload)
killall -1 ddns-updater.sh 2>/dev/null
exit $?
;;
*) usage_err "unknown command - $1";;
esac
# set file names
PIDFILE="$RUNDIR/$SECTION_ID.pid" # Process ID file
UPDFILE="$RUNDIR/$SECTION_ID.update" # last update successful send (system uptime)
DATFILE="$RUNDIR/$SECTION_ID.dat" # save stdout data of WGet and other extern programs called
ERRFILE="$RUNDIR/$SECTION_ID.err" # save stderr output of WGet and other extern programs called
LOGFILE="$LOGDIR/$SECTION_ID.log" # log file
PIDFILE="$ddns_rundir/$SECTION_ID.pid" # Process ID file
UPDFILE="$ddns_rundir/$SECTION_ID.update" # last update successful send (system uptime)
DATFILE="$ddns_rundir/$SECTION_ID.dat" # save stdout data of WGet and other extern programs called
ERRFILE="$ddns_rundir/$SECTION_ID.err" # save stderr output of WGet and other extern programs called
LOGFILE="$ddns_logdir/$SECTION_ID.log" # log file
# VERBOSE_MODE > 1 delete logfile if exist to create an empty one
# VERBOSE > 1 delete logfile if exist to create an empty one
# only with this data of this run for easier diagnostic
# new one created by write_log function
[ $VERBOSE_MODE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE
[ $VERBOSE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE
# TRAP handler
trap "trap_handler 0 \$?" 0 # handle script exit with exit status
@ -75,7 +123,7 @@ trap "trap_handler 15" 15 # SIGTERM Termination
#
# defined options (also used as variable):
#
# enable self-explanatory
# enabled self-explanatory
# interface network interface used by hotplug.d i.e. 'wan' or 'wan6'
#
# service_name Which DDNS service do you use or "custom"
@ -146,8 +194,8 @@ ERR_LAST=$? # save return code - equal 0 if SECTION_ID found
# SECTION_ID does not exists
[ $ERR_LAST -ne 0 ] && {
[ $VERBOSE_MODE -le 1 ] && VERBOSE_MODE=2 # force console out and logfile output
[ -f $LOGFILE ] && rm -f $LOGFILE # clear logfile before first entry
[ $VERBOSE -le 1 ] && VERBOSE=2 # force console out and logfile output
[ -f $LOGFILE ] && rm -f $LOGFILE # clear logfile before first entry
write_log 7 "************ ************** ************** **************"
write_log 5 "PID '$$' started at $(eval $DATE_PROG)"
write_log 7 "ddns version : $VERSION"
@ -160,12 +208,12 @@ write_log 5 "PID '$$' started at $(eval $DATE_PROG)"
write_log 7 "ddns version : $VERSION"
write_log 7 "uci configuration:\n$(uci -q show ddns.$SECTION_ID | sort)"
# write_log 7 "ddns version : $(opkg list-installed ddns-scripts | cut -d ' ' -f 3)"
case $VERBOSE_MODE in
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_MODE '$VERBOSE_MODE'";;
*) write_log 14 "error detecting VERBOSE '$VERBOSE'";;
esac
# check enabled state otherwise we don't need to continue
@ -174,7 +222,7 @@ 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 SRV_ANSWER
[ -n "$service_name" ] && get_service_data update_url update_script UPD_ANSWER
[ -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!"
@ -250,7 +298,7 @@ if [ $LAST_TIME -eq 0 ]; then
write_log 7 "last update: never"
else
EPOCH_TIME=$(( $(date +%s) - CURR_TIME + LAST_TIME ))
EPOCH_TIME="date -d @$EPOCH_TIME +'$DATE_FORMAT'"
EPOCH_TIME="date -d @$EPOCH_TIME +'$ddns_dateformat'"
write_log 7 "last update: $(eval $EPOCH_TIME)"
fi
@ -293,8 +341,8 @@ while : ; do
# 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_MODE -gt 2 ]; then
write_log 7 "Verbose Mode: $VERBOSE_MODE - NO UPDATE send"
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'"
else
@ -302,8 +350,8 @@ while : ; do
fi
ERR_LAST=0
[ $VERBOSE_MODE -lt 3 ] && {
# only send if VERBOSE_MODE < 3
[ $VERBOSE -lt 3 ] && {
# only send if VERBOSE < 3
send_update "$LOCAL_IP"
ERR_LAST=$? # save return value
}
@ -328,14 +376,14 @@ while : ; do
fi
# now we wait for check interval before testing if update was recognized
# only sleep if VERBOSE_MODE <= 2 because otherwise nothing was send
[ $VERBOSE_MODE -le 2 ] && {
# only sleep if VERBOSE <= 2 because otherwise nothing was send
[ $VERBOSE -le 2 ] && {
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_MODE - NO Check Interval waiting"
} || write_log 7 "Verbose Mode: $VERBOSE - NO Check Interval waiting"
REGISTERED_IP="" # clear variable
get_registered_ip REGISTERED_IP # get registered/public IP
@ -343,7 +391,7 @@ while : ; do
# IP's are still different
if [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
if [ $VERBOSE_MODE -le 1 ]; then # VERBOSE_MODE <=1 then retry
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"
@ -351,17 +399,17 @@ while : ; do
continue # loop to beginning
else
write_log 4 "Updating IP at DDNS provider failed"
write_log 7 "Verbose Mode: $VERBOSE_MODE - NO retry"; exit 1
write_log 7 "Verbose Mode: $VERBOSE - NO retry"; exit 1
fi
else
# we checked successful the last update
ERR_UPDATE=0 # reset error counter
fi
# force_update=0 or VERBOSE_MODE > 1 - leave here
[ $VERBOSE_MODE -gt 1 ] && write_log 7 "Verbose Mode: $VERBOSE_MODE - NO reloop"
# force_update=0 or VERBOSE > 1 - leave here
[ $VERBOSE -gt 1 ] && write_log 7 "Verbose Mode: $VERBOSE - NO reloop"
[ $FORCE_SECONDS -eq 0 ] && write_log 6 "Configured to run once"
[ $VERBOSE_MODE -gt 1 -o $FORCE_SECONDS -eq 0 ] && exit 0
[ $VERBOSE -gt 1 -o $FORCE_SECONDS -eq 0 ] && exit 0
write_log 6 "Rerun IP check at $(eval $DATE_PROG)"
done

View File

@ -33,18 +33,21 @@
#
# 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
#
# cloudflare.com !!! Please install additional package "ddns-scripts_cloudflare"
# no-ip.com / noip.com !!! Please install additional package "ddns-scripts_no-ip_com"
#.cloudflare.com-v1 !!! Please install additional package "ddns-scripts_cloudflare"
#.cloudflare.com-v4 !!! Please install additional package "ddns-scripts_cloudflare.com-v4"
#.godaddy.com-v1 !!! Please install additional package "ddns-scripts_godaddy.com-v1"
#.no-ip.com / noip.com !!! Please install additional package "ddns-scripts_no-ip_com"
"3322.org" "http://[USERNAME]:[PASSWORD]@members.3322.org/dyndns/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]"
"able.or.kr" "http://able.or.kr/ddns/src/update.php?hostname=[DOMAIN]&myip=[IP]&ddnsuser=[USERNAME]&pwd=[PASSWORD]"
"afraid.org" "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
"afraid.org-basicauth" "http://[USERNAME]:[PASSWORD]@freedns.afraid.org/nic/update?hostname=[DOMAIN]&myip=[IP]
"afraid.org-keyauth" "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
"all-inkl.com" "http://[USERNAME]:[PASSWORD]@dyndns.kasserver.com/?myip=[IP]"
"changeip.com" "http://[USERNAME]:[PASSWORD]@nic.changeip.com/nic/update?u=[USERNAME]&p=[PASSWORD]&cmd=update&hostname=[DOMAIN]&ip=[IP]" "Successful"
"changeip.com" "http://[USERNAME]:[PASSWORD]@nic.changeip.com/nic/update?u=[USERNAME]&p=[PASSWORD]&cmd=update&hostname=[DOMAIN]&ip=[IP]" "good|NOCHG"
"core-networks.de" "http://[USERNAME]:[PASSWORD]@dyndns.core-networks.de/?hostname=[DOMAIN]&myip=[IP]&keepipv6=1" "good"
@ -112,8 +115,6 @@
"joker.com" "http://svc.joker.com/nic/update?username=[USERNAME]&password=[PASSWORD]&myip=[IP]&hostname=[DOMAIN]" "good|nochg"
"loopia.com" "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"loopia.se" "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"mydns.jp" "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV4ADDR=[IP]"
@ -128,6 +129,8 @@
"no-ip.pl" "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
"now-dns.com" "http://[USERNAME]:[PASSWORD]@now-dns.com/update?hostname=[DOMAIN]"
"nsupdate.info" "http://[USERNAME]:[PASSWORD]@ipv4.nsupdate.info/nic/update?hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"nubem.com" "http://[USERNAME]:[PASSWORD]@nubem.com/nic/update?hostname=[DOMAIN]&myip=[IP]"

View File

@ -33,10 +33,13 @@
#
# 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
#
# cloudflare.com !!! Please install additional package "ddns-scripts_cloudflare"
# no-ip.com / noip.com !!! Please install additional package "ddns-scripts_no-ip_com"
#.cloudflare.com-v1 !!! Please install additional package "ddns-scripts_cloudflare"
#.cloudflare.com-v4 !!! Please install additional package "ddns-scripts_cloudflare.com-v4"
#.godaddy.com-v1 !!! Please install additional package "ddns-scripts_godaddy.com-v1"
#.no-ip.com / noip.com !!! Please install additional package "ddns-scripts_no-ip_com"
"afraid.org" "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
"afraid.org-basicauth" "http://[USERNAME]:[PASSWORD]@freedns.afraid.org/nic/update?hostname=[DOMAIN]&myip=[IP]
"afraid.org-keyauth" "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
"all-inkl.com" "http://[USERNAME]:[PASSWORD]@dyndns.kasserver.com/?myip=[IP]"
@ -68,8 +71,6 @@
"he.net" "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"loopia.com" "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"loopia.se" "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"mydns.jp" "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV6ADDR=[IP]"
@ -80,6 +81,8 @@
"no-ip.pl" "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
"now-dns.com" "http://[USERNAME]:[PASSWORD]@now-dns.com/update?hostname=[DOMAIN]"
"nsupdate.info" "http://[USERNAME]:[PASSWORD]@ipv6.nsupdate.info/nic/update?hostname=[DOMAIN]&myip=[IP]" "good|nochg"
"regfish.de" "http://dyndns.regfish.de/?fqdn=[DOMAIN]&forcehost=1&authtype=secure&token=[PASSWORD]&ipv6=[IP]" "success|100|101"

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@ __DOMAIN="$__DOMAIN.$__TLD"
# function copied from /usr/share/libubox/jshn.sh
# from BB14.09 for backward compatibility to AA12.09
grep -i "json_get_keys" /usr/share/libubox/jshn.sh >/dev/null 2>&1 || json_get_keys() {
type "json_get_keys" >/dev/null 2>&1 || json_get_keys() {
local __dest="$1"
local _tbl_cur

View File

@ -0,0 +1,178 @@
#!/bin/sh
#
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
#
# script for sending updates to cloudflare.com
#.based on Ben Kulbertis cloudflare-update-record.sh found at http://gist.github.com/benkulbertis
#.and on George Johnson's cf-ddns.sh found at https://github.com/gstuartj/cf-ddns.sh
#.2016 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
# CloudFlare API documentation at https://api.cloudflare.com/
#
# This script is parsed by dynamic_dns_functions.sh inside send_update() function
#
# using following options from /etc/config/ddns
# option username - your cloudflare e-mail
# 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
#
# variable __IP already defined with the ip-address to use for update
#
# check parameters
[ -z "$CURL_SSL" ] && write_log 14 "Cloudflare 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'"
[ $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.cloudflare.com/client/v4"
# split __HOST __DOMAIN from $domain
__HOST=$(printf %s "$domain" | cut -d@ -f1)
__DOMAIN=$(printf %s "$domain" | cut -d@ -f2)
# __HOST != __DOMAIN then host@domain.tld => host.domain.tld
[ "$__HOST" = "$__DOMAIN" ] || __HOST=$(printf %s "$domain" | tr "@" ".")
# set record type
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
# transfer function to use for godaddy
# all needed variables are set global here
# so we can use them directly
cloudflare_transfer() {
local __CNT=0
local __ERR
while : ; do
write_log 7 "#> $__RUNPROG"
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
# check for error
grep -q '"success":true' $DATFILE || {
write_log 4 "CloudFlare reported an error:"
write_log 7 "$(cat $DATFILE)" # report error
return 1 # HTTP-Fehler
}
}
# Build base command to use
__PRGBASE="$CURL -RsS -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 --header 'X-Auth-Email: $username' "
__PRGBASE="$__PRGBASE --header 'X-Auth-Key: $password' "
__PRGBASE="$__PRGBASE --header 'Content-Type: application/json' "
# __PRGBASE="$__PRGBASE --header 'Accept: 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":"[^"]*' $DATFILE | grep -o '[^"]*$' | head -1)
[ -z "$__ZONEID" ] && {
write_log 4 "Could not detect 'zone id' for domain.tld: '$__DOMAIN'"
return 1
}
# read record id for A or AAAA record of host.domain.TLD
__RUNPROG="$__PRGBASE --request GET $__URLBASE/zones/$__ZONEID/dns_records?name=$__HOST&type=$__TYPE"
cloudflare_transfer || return 1
# extract record id
__RECID=$(grep -o '"id":"[^"]*' $DATFILE | grep -o '[^"]*$' | head -1)
[ -z "$__RECID" ] && {
write_log 4 "Could not detect 'record id' for host.domain.tld: '$__HOST'"
return 1
}
# extract current stored IP
__DATA=$(grep -o '"content":"[^"]*' $DATFILE | grep -o '[^"]*$' | head -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 CloudFlare.com already up to date"
return 127
}
else
[ "$__DATA" = "$__IP" ] && { # IPv4 no update needed
write_log 7 "IPv4 at CloudFlare.com already up to date"
return 127
}
fi
}
# update is needed
# let's build data to send,
# use file to work around " needed for json
cat > $DATFILE << EOF
{"id":"$__ZONEID","type":"$__TYPE","name":"$__HOST","content":"$__IP"}
EOF
# let's complete transfer command
__RUNPROG="$__PRGBASE --request PUT --data @$DATFILE $__URLBASE/zones/$__ZONEID/dns_records/$__RECID"
cloudflare_transfer || return 1
return 0

View File

@ -0,0 +1,163 @@
#!/bin/sh
#
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
#
# script for sending updates to godaddy.com
#.based on GoDaddy.sh v1.0 by Nazar78 @ TeaNazaR.com
#.2016 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
# GoDaddy Documentation at https://developer.godaddy.com/doc
#
# This script is parsed by dynamic_dns_functions.sh inside send_update() function
#
# using following options from /etc/config/ddns
# option username - "key" as generated at https://developer.godaddy.com/keys/
# option password - "secret" as generated at https://developer.godaddy.com/keys/
# option domain - "yourdomain.TLD" to update or "hostname@yourdomain.TLD"
#
# variable __IP already defined with the ip-address to use for update
#
# check parameters
[ -z "$CURL_SSL" ] && write_log 14 "GoDaddy 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'"
[ $use_https -eq 0 ] && use_https=1 # force HTTPS
# used variables
local __HOST __DOMAIN __TYPE __URL __PRGBASE __RUNPROG __DATA __IPV6
# split __HOST __DOMAIN from $domain
__HOST=$(printf %s "$domain" | cut -d@ -f1)
__DOMAIN=$(printf %s "$domain" | cut -d@ -f2)
[ -z "$__HOST" -o "$__HOST" = "$__DOMAIN" ] && __HOST="%40" # no expizit host given so set to default "@" => urlencode "%40"
# set record type
[ $use_ipv6 -eq 0 ] && __TYPE="A" || __TYPE="AAAA"
# now we know the url to use
# __URL="https://api.ote-godaddy.com/v1/domains/$__DOMAIN/records/$__TYPE/$__HOST" # api test server
__URL="https://api.godaddy.com/v1/domains/$__DOMAIN/records/$__TYPE/$__HOST" # production server
# transfer function to use for godaddy
# all needed variables are set global here
# so we can use them directly
godaddy_transfer() {
local __CNT=0
local __STATUS __ERR __DEVICE
while : ; do
write_log 7 "#> $__RUNPROG"
__STATUS=$(eval "$__RUNPROG")
__ERR=$? # save communication error
[ $__ERR -eq 0 ] && break # no error break while
write_log 4 "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 "GoDaddy reported an error:"
write_log 7 "$(cat $DATFILE)"
return 1
}
}
# 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 no 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 --header 'Authorization: sso-key $username:$password' "
__PRGBASE="$__PRGBASE --header 'Accept: application/json' "
__PRGBASE="$__PRGBASE --header 'Content-Type: application/json; charset=utf-8' "
# read data from godaddy.com
__RUNPROG="$__PRGBASE --request GET $__URL"
godaddy_transfer || return 1
# HTTP 200 OK, now analyse data and check if update needed
__DATA=$(sed -r 's/.+data":"(.+)","t.+/\1/g' $DATFILE)
# 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 GoDaddy.com already up to date"
return 127
}
else
[ "$__DATA" = "$__IP" ] && { # IPv4 no update needed
write_log 7 "IPv4 at GoDaddy.com already up to date"
return 127
}
fi
}
# update is needed
# let's build data to send,
# use file to work around double quotes '"' needed for json
cat > $DATFILE << EOF
[{"data":"$__IP"}]
EOF
# let's complete transfer command
__RUNPROG="$__PRGBASE --request PUT --data @$DATFILE $__URL"
godaddy_transfer || return 1
# HTTP 200 OK
return 0

0
net/ddns-scripts/files/update_nsupdate.sh Normal file → Executable file
View File

View File

@ -29,31 +29,31 @@ config ddns "global"
# and LuCI web application.
# For codes see man pages of date command.
# default: "%F %R" (ISO 8601 format)
# option date_format "%F %R"
# option ddns_dateformat "%F %R"
###########
# set run directory to use for .pid and .update files
# there will be a separate file for every running service section
# default: "/var/run/ddns"
# option run_dir "/var/run/ddns"
# option ddns_rundir "/var/run/ddns"
###########
# set log directory to use for .log files
# there will be a separate file for every running service section
# default: "/var/log/ddns"
# option log_dir "/var/log/ddns"
# option ddns_logdir "/var/log/ddns"
###########
# set number of lines stored in .log file before auto truncated
# default: "250" lines
# option log_lines "250"
# option ddns_loglines "250"
###########
# Whether to allow to send Private/Special IP's to the DDNS provider
# IPv4: 0.x, 10.x, 127.x, 172.16.x-172.31.x, 192.168.x
# IPv6: ::, Fxxx:
# default: "0" disabled
# option allow_local_ip "0"
# option upd_privateip "0"
#####################################################################
# DDNS service settings

View File

@ -0,0 +1,39 @@
#!/bin/sh
URL="https://publicsuffix.org/list/public_suffix_list.dat"
TMPFILE=$(dirname $0)/public_suffix_list.tmp
DATFILE=$(dirname $0)/public_suffix_list.dat
wget -O $TMPFILE $URL || exit 1
# there might be backslashes (at line end they produce problems)
sed -i 's/\\//g' $TMPFILE
# clear DATFILE if exist
printf %s "" > $DATFILE
L=0; M=0
export CHARSET=UTF-8 # needed for idn
cat ${TMPFILE} | while read LINE; do
L=$(( L + 1 ))
printf "\\r\\t%s\\t%s" "in: $L " "out: $(( $L + $M )) "
printf %s\\n "$LINE" | grep -E "^\/\/" >/dev/null 2>&1 && {
# do not modify lines beginning with "//"
printf %s\\n "$LINE" >> $DATFILE
continue
}
printf %s\\n "$LINE" | grep -E "^$" >/dev/null 2>&1 && {
# do not modify empty lines
printf %s\\n "$LINE" >> $DATFILE
continue
}
ASCII=$(idn -a "$LINE") # write ASCII and UTF-8
if [ "$ASCII" != "$LINE" ]; then
printf %s\\n "$ASCII" >> $DATFILE
printf "\\t%s\\n" "add: $ASCII"
M=$(( M + 1 ))
fi
printf %s\\n "$LINE" >> $DATFILE
done
rm -f $TMPFILE
gzip -f9 $DATFILE