From 058f961c237563c38a503f99e1a22bbe93e2635c Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Mon, 28 Oct 2024 23:17:20 +0800 Subject: [PATCH] ddns-scripts: bump version --- net/ddns-scripts/Makefile | 1096 +++++++++++------ net/ddns-scripts/files/ddns.config | 9 - net/ddns-scripts/files/ddns.defaults | 201 --- net/ddns-scripts/files/etc/config/ddns | 32 + .../hotplug.d/iface/ddns} | 0 .../files/{ddns.init => etc/init.d/ddns} | 4 - net/ddns-scripts/files/update_route53_v1.sh | 97 -- net/ddns-scripts/files/usr/bin/ddns.sh | 172 +++ .../lib/ddns}/dynamic_dns_functions.sh | 312 ++--- .../lib/ddns}/dynamic_dns_lucihelper.sh | 8 +- .../{ => usr/lib/ddns}/dynamic_dns_updater.sh | 100 +- .../lib/ddns}/update_cloudflare_com_v4.sh | 58 +- .../files/usr/lib/ddns/update_cnkuai_cn.sh | 86 ++ .../lib/ddns/update_digitalocean_com_v2.sh | 40 + .../files/usr/lib/ddns/update_dnspod_cn.sh | 137 +++ .../lib/ddns}/update_freedns_42_pl.sh | 2 +- .../files/usr/lib/ddns/update_gandi_net.sh | 48 + .../files/usr/lib/ddns/update_gcp_v1.sh | 272 ++++ .../lib/ddns}/update_godaddy_com_v1.sh | 0 .../usr/lib/ddns/update_huaweicloud_com.sh | 152 +++ .../files/usr/lib/ddns/update_luadns_v1.sh | 191 +++ .../{ => usr/lib/ddns}/update_no-ip_com.sh | 4 +- .../files/usr/lib/ddns/update_ns1_com.sh | 77 ++ .../{ => usr/lib/ddns}/update_nsupdate.sh | 4 +- .../files/usr/lib/ddns/update_one_com.sh | 142 +++ .../files/usr/lib/ddns/update_pdns.sh | 63 + .../files/usr/lib/ddns/update_porkbun_v3.sh | 162 +++ .../files/usr/lib/ddns/update_route53_v1.sh | 96 ++ .../files/usr/lib/ddns/update_transip_nl.sh | 134 ++ .../usr/share/ddns/default/3322.org.json | 6 + .../ddns/default/afraid.org-basicauth.json | 9 + .../ddns/default/afraid.org-keyauth.json | 9 + .../ddns/default/afraid.org-v2-basic.json | 9 + .../ddns/default/afraid.org-v2-token.json | 9 + .../usr/share/ddns/default/all-inkl.com.json | 9 + .../usr/share/ddns/default/bind-nsupdate.json | 9 + .../usr/share/ddns/default/changeip.com.json | 7 + .../ddns/default/cloud.google.com-v1.json | 10 + .../share/ddns/default/cloudflare.com-v4.json | 9 + .../usr/share/ddns/default/cnkuai.cn.json | 9 + .../share/ddns/default/core-networks.de.json | 11 + .../usr/share/ddns/default/ddnss.de.json | 7 + .../files/usr/share/ddns/default/ddo.jp.json | 6 + .../usr/share/ddns/default/desec.io.json | 11 + .../usr/share/ddns/default/dhis.org.json | 9 + .../ddns/default/digitalocean.com-v2.json | 9 + .../share/ddns/default/dnsdynamic.org.json | 7 + .../usr/share/ddns/default/dnsever.com.json | 6 + .../usr/share/ddns/default/dnsexit.com.json | 6 + .../usr/share/ddns/default/dnshome.de.json | 9 + .../share/ddns/default/dnsmadeeasy.com.json | 7 + .../usr/share/ddns/default/dnsmax.com.json | 6 + .../usr/share/ddns/default/dnsomatic.com.json | 7 + .../usr/share/ddns/default/dnspark.com.json | 7 + .../usr/share/ddns/default/dnspod.cn.json | 9 + .../files/usr/share/ddns/default/do.de.json | 11 + .../usr/share/ddns/default/domopoli.de.json | 7 + .../usr/share/ddns/default/duckdns.org.json | 11 + .../usr/share/ddns/default/duiadns.net.json | 9 + .../files/usr/share/ddns/default/dy.fi.json | 7 + .../files/usr/share/ddns/default/dyn.com.json | 11 + .../usr/share/ddns/default/dyndns.it.json | 7 + .../usr/share/ddns/default/dyndns.org.json | 11 + .../usr/share/ddns/default/dynu.com.json | 9 + .../usr/share/ddns/default/dynv6.com.json | 11 + .../usr/share/ddns/default/easydns.com.json | 11 + .../usr/share/ddns/default/freedns.42.pl.json | 6 + .../usr/share/ddns/default/gandi.net.json | 9 + .../share/ddns/default/godaddy.com-v1.json | 9 + .../files/usr/share/ddns/default/goip.de.json | 9 + .../usr/share/ddns/default/google.com.json | 11 + .../files/usr/share/ddns/default/he.net.json | 11 + .../usr/share/ddns/default/hosting.de.json | 11 + .../share/ddns/default/huaweicloud.com.json | 9 + .../share/ddns/default/infomaniak.com.json | 11 + .../files/usr/share/ddns/default/inwx.de.json | 11 + .../usr/share/ddns/default/ipnodns.ru.json | 7 + .../usr/share/ddns/default/joker.com.json | 7 + .../usr/share/ddns/default/loopia.se.json | 11 + .../usr/share/ddns/default/luadns.com-v1.json | 9 + .../usr/share/ddns/default/moniker.com.json | 7 + .../usr/share/ddns/default/mydns.jp.json | 9 + .../ddns/default/myonlineportal.net.json | 11 + .../ddns/default/mythic-beasts.com-v2.json | 9 + .../share/ddns/default/mythic-beasts.com.json | 9 + .../usr/share/ddns/default/namecheap.com.json | 6 + .../files/usr/share/ddns/default/njal.la.json | 9 + .../usr/share/ddns/default/no-ip.com.json | 10 + .../usr/share/ddns/default/no-ip.pl.json | 9 + .../usr/share/ddns/default/now-dns.com.json | 11 + .../files/usr/share/ddns/default/ns1.com.json | 9 + .../usr/share/ddns/default/nsupdate.info.json | 11 + .../files/usr/share/ddns/default/one.com.json | 6 + .../usr/share/ddns/default/opendns.com.json | 7 + .../usr/share/ddns/default/oray.com.json | 6 + .../files/usr/share/ddns/default/ovh.com.json | 11 + .../files/usr/share/ddns/default/pdns.json | 9 + .../share/ddns/default/porkbun.com-v3.json | 9 + .../usr/share/ddns/default/regfish.de.json | 11 + .../usr/share/ddns/default/route53-v1.json | 9 + .../share/ddns/default/schokokeks.org.json | 7 + .../usr/share/ddns/default/selfhost.de.json | 7 + .../usr/share/ddns/default/servercow.de.json | 11 + .../usr/share/ddns/default/simply.com.json | 11 + .../share/ddns/default/sitelutions.com.json | 7 + .../usr/share/ddns/default/spdyn.de.json | 11 + .../usr/share/ddns/default/strato.com.json | 11 + .../usr/share/ddns/default/system-ns.com.json | 8 + .../usr/share/ddns/default/thatip.com.json | 6 + .../usr/share/ddns/default/transip.nl.json | 9 + .../usr/share/ddns/default/twodns.de.json | 6 + .../usr/share/ddns/default/udmedia.de.json | 9 + .../usr/share/ddns/default/variomedia.de.json | 11 + .../usr/share/ddns/default/xlhost.de.json | 7 + .../usr/share/ddns/default/zoneedit.com.json | 6 + net/ddns-scripts/files/usr/share/ddns/list | 69 ++ net/ddns-scripts/samples/ddns.config_sample | 5 + net/ddns-scripts/samples/slaac_sample.sh | 59 + net/ddns-scripts/samples/update_sample.sh | 2 +- 119 files changed, 3675 insertions(+), 912 deletions(-) mode change 100755 => 100644 net/ddns-scripts/Makefile delete mode 100644 net/ddns-scripts/files/ddns.config delete mode 100755 net/ddns-scripts/files/ddns.defaults create mode 100644 net/ddns-scripts/files/etc/config/ddns rename net/ddns-scripts/files/{ddns.hotplug => etc/hotplug.d/iface/ddns} (100%) mode change 100755 => 100644 rename net/ddns-scripts/files/{ddns.init => etc/init.d/ddns} (94%) mode change 100755 => 100644 delete mode 100644 net/ddns-scripts/files/update_route53_v1.sh create mode 100644 net/ddns-scripts/files/usr/bin/ddns.sh rename net/ddns-scripts/files/{ => usr/lib/ddns}/dynamic_dns_functions.sh (84%) mode change 100755 => 100644 rename net/ddns-scripts/files/{ => usr/lib/ddns}/dynamic_dns_lucihelper.sh (97%) mode change 100755 => 100644 rename net/ddns-scripts/files/{ => usr/lib/ddns}/dynamic_dns_updater.sh (84%) mode change 100755 => 100644 rename net/ddns-scripts/files/{ => usr/lib/ddns}/update_cloudflare_com_v4.sh (82%) mode change 100755 => 100644 create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_digitalocean_com_v2.sh create mode 100755 net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh rename net/ddns-scripts/files/{ => usr/lib/ddns}/update_freedns_42_pl.sh (98%) mode change 100755 => 100644 create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh create mode 100755 net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh rename net/ddns-scripts/files/{ => usr/lib/ddns}/update_godaddy_com_v1.sh (100%) mode change 100755 => 100644 create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh rename net/ddns-scripts/files/{ => usr/lib/ddns}/update_no-ip_com.sh (87%) mode change 100755 => 100644 create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh rename net/ddns-scripts/files/{ => usr/lib/ddns}/update_nsupdate.sh (92%) mode change 100755 => 100644 create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh create mode 100755 net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh create mode 100644 net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/3322.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/afraid.org-basicauth.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/afraid.org-keyauth.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-basic.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-token.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/all-inkl.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/bind-nsupdate.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/changeip.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/cloudflare.com-v4.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/cnkuai.cn.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/core-networks.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/ddnss.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/ddo.jp.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/desec.io.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dhis.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/digitalocean.com-v2.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsdynamic.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsever.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsexit.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnshome.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsmadeeasy.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsmax.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnsomatic.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnspark.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dnspod.cn.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/do.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/domopoli.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/duckdns.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/duiadns.net.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dyndns.it.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dyndns.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dynu.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/easydns.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/freedns.42.pl.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/gandi.net.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/godaddy.com-v1.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/goip.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/google.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/he.net.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/hosting.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/huaweicloud.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/infomaniak.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/joker.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/luadns.com-v1.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/moniker.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/mydns.jp.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/myonlineportal.net.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com-v2.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/namecheap.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/njal.la.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/no-ip.pl.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/now-dns.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/ns1.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/nsupdate.info.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/one.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/opendns.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/oray.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/pdns.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/porkbun.com-v3.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/regfish.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/route53-v1.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/schokokeks.org.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/selfhost.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/servercow.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/simply.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/sitelutions.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/spdyn.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/strato.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/system-ns.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/thatip.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/twodns.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/udmedia.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/variomedia.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/xlhost.de.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/zoneedit.com.json create mode 100644 net/ddns-scripts/files/usr/share/ddns/list create mode 100755 net/ddns-scripts/samples/slaac_sample.sh diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile old mode 100755 new mode 100644 index aa57c4fc..7ccc9ee9 --- a/net/ddns-scripts/Makefile +++ b/net/ddns-scripts/Makefile @@ -7,440 +7,770 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-scripts -# Version == major.minor.patch -# increase on new functionality (minor) or patches (patch) -PKG_VERSION:=2.7.8 -# Release == build -# increase on changes of services files or tld_names.dat -PKG_RELEASE:=5 +PKG_VERSION:=2.8.2 +PKG_RELEASE:=49 PKG_LICENSE:=GPL-2.0 -PKG_MAINTAINER:= include $(INCLUDE_DIR)/package.mk -# no default dependencies -PKG_DEFAULT_DEPENDS= - define Package/ddns-scripts/Default - SECTION:=net - CATEGORY:=Network - SUBMENU:=IP Addresses and Names - PKGARCH:=all + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + PKGARCH:=all endef -###### ************************************************************************* + define Package/ddns-scripts - $(call Package/ddns-scripts/Default) - TITLE:=Dynamic DNS Client scripts (with IPv6 support) + $(call Package/ddns-scripts/Default) + TITLE:=Dynamic DNS Client scripts (with IPv6 support) + DEPENDS:=+ddns-scripts-services endef -# shown in LuCI package description + define Package/ddns-scripts/description - Dynamic DNS Client scripts (with IPv6 support) - Info: http://wiki.openwrt.org/doc/howto/ddns.client -endef -# shown in menuconfig -define Package/ddns-scripts/config - help - A highly configurable set of scripts for doing dynamic dns updates. - - IPv6 support - - DNS server support - - 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 -endef - -###### ************************************************************************* -define Package/ddns-scripts_cloudflare.com-v4 - $(call Package/ddns-scripts/Default) - TITLE:=CloudFlare.com API v4 (requires cURL) - DEPENDS:=ddns-scripts +curl -endef -define Package/ddns-scripts_cloudflare.com-v4/description - Dynamic DNS Client scripts extension for CloudFlare.com API-v4 (require/install cURL) -endef - -###### ************************************************************************* -define Package/ddns-scripts_freedns_42_pl - $(call Package/ddns-scripts/Default) - TITLE:=DDNS extension for FreeDNS.42.pl (requires cURL) - DEPENDS:=ddns-scripts +curl -endef -define Package/ddns-scripts_freedns_42_pl/description - Dynamic DNS Client scripts extension for freedns.42.pl -endef - -###### ************************************************************************* -define Package/ddns-scripts_godaddy.com-v1 - $(call Package/ddns-scripts/Default) - TITLE:=GoDaddy.com (require cURL) - DEPENDS:=ddns-scripts +curl -endef -define Package/ddns-scripts_godaddy.com-v1/description - Dynamic DNS Client scripts extension for GoDaddy.com (require/install cURL) -endef - -###### ************************************************************************* -define Package/ddns-scripts_no-ip_com - $(call Package/ddns-scripts/Default) - TITLE:=DDNS extension for No-IP.com - DEPENDS:=ddns-scripts -endef -define Package/ddns-scripts_no-ip_com/description - Dynamic DNS Client scripts extension for No-IP.com -endef - -###### ************************************************************************* -define Package/ddns-scripts_nsupdate - $(call Package/ddns-scripts/Default) - TITLE:=DDNS extension using Bind nsupdate - DEPENDS:=ddns-scripts +bind-client -endef -define Package/ddns-scripts_nsupdate/description - Dynamic DNS Client scripts extension for direct updates using Bind nsupdate -endef -define Package/ddns-scripts_nsupdate/config - help - The script directly updates a PowerDNS (or maybe bind server) via nsupdate - from bind-client package. It requires - "option dns_server" to be set to the server to be used by nsupdate. - "option username" should be set to the key name and - "option password" to the base64 encoded shared secret. - -endef - -###### ************************************************************************* -define Package/ddns-scripts_route53-v1 - $(call Package/ddns-scripts/Default) - TITLE:=Amazon AWS Route 53 API v1 - DEPENDS:=ddns-scripts +curl +openssl-util -endef -define Package/ddns-scripts_route53-v1/description - Dynamic DNS Client scripts extension for Amazon AWS Route53. Note: You - must also install ca-certificate or ca-bundle. - It requires: - "option username" to be a valid AWS access key id - "option password" to be the matching AWS secret key id - "option domain" to contain the hosted zone ID -endef - -###### ************************************************************************* -define Build/Configure -endef -define Build/Compile - $(CP) ./files $(PKG_BUILD_DIR) - # ensure that VERSION inside dynamic_dns_functions.sh reflect PKG_VERSION of Makefile - $(SED) '/^VERSION=*/s/.*/VERSION="$(PKG_VERSION)-$(PKG_RELEASE)"/' $(PKG_BUILD_DIR)/files/dynamic_dns_functions.sh - # remove comments, white spaces and empty lines - for FILE in `find $(PKG_BUILD_DIR)/files -type f`; do \ - $(SED) 's/^[[:space:]]*//' \ - -e '/^#[[:space:]]\|^#$$$$/d' \ - -e 's/[[:space:]]#[[:space:]].*$$$$//' \ - -e 's/[[:space:]]*$$$$//' \ - -e '/^\/\/[[:space:]]/d' \ - -e '/^[[:space:]]*$$$$/d' $$$$FILE; \ - done + Dynamic DNS Client scripts (with IPv6 support) + A highly configurable set of scripts for doing dynamic dns updates. + - IPv6 support + - DNS server support + - 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 : https://openwrt.org/docs/guide-user/services/ddns/client endef define Package/ddns-scripts/conffiles /etc/config/ddns endef -###### ************************************************************************* -define Package/ddns-scripts/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors + +define Package/ddns-scripts-services + $(call Package/ddns-scripts/Default) + TITLE:=Common ddns providers + PROVIDES:=ddns-scripts_service endef + +define Package/ddns-scripts-services/description + Dynamic DNS Client definitions for supported services +endef + +define Package/ddns-scripts-utils + $(call Package/ddns-scripts/Default) + TITLE:=Utility scripts for ddns configs + DEPENDS:=ddns-scripts +endef + +define Package/ddns-scripts-utils/description + Dynamic DNS Client utility scripts for config files +endef + + +define Package/ddns-scripts-luadns + $(call Package/ddns-scripts/Default) + TITLE:=Extension for LuaDNS API v1 + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scripts-luadns/description + Dynamic DNS Client scripts extension for LuaDNS API v1 (require curl) +endef + +define Package/ddns-scripts-cloudflare + $(call Package/ddns-scripts/Default) + TITLE:=Extension for cloudflare.com API v4 + DEPENDS:=ddns-scripts +curl + PROVIDES:=ddns-scripts_cloudflare.com-v4 +endef + +define Package/ddns-scripts-cloudflare/description + Dynamic DNS Client scripts extension for cloudflare.com API v4 (require curl) +endef + + +define Package/ddns-scripts-gcp + $(call Package/ddns-scripts/Default) + TITLE:=Extension for Google Cloud DNS API v1 + DEPENDS:=ddns-scripts +curl +openssl-util +endef + +define Package/ddns-scripts-gcp/description + Dynamic DNS Client scripts extension for Google Cloud DNS API v1 (requires curl) +endef + + +define Package/ddns-scripts-freedns + $(call Package/ddns-scripts/Default) + TITLE:=Extension for freedns.42.pl + DEPENDS:=ddns-scripts +curl + PROVIDES:=ddns-scripts_freedns_42_pl +endef + +define Package/ddns-scripts-freedns/description + Dynamic DNS Client scripts extension for "freedns.42.pl". +endef + + +define Package/ddns-scripts-godaddy + $(call Package/ddns-scripts/Default) + TITLE:=Extension for godaddy.com API v1 + DEPENDS:=ddns-scripts +curl + PROVIDES:=ddns-scripts_godaddy.com-v1 +endef + +define Package/ddns-scripts-godaddy/description + Dynamic DNS Client scripts extension for "godaddy.com API v1". +endef + + +define Package/ddns-scripts-digitalocean + $(call Package/ddns-scripts/Default) + TITLE:=Extention for digitalocean.com API v2 + DEPENDS:=ddns-scripts +curl + PROVIDES:=ddns-scripts_digitalocean.com-v2 +endef + +define Package/ddns-scripts-digitalocean/description + Dynamic DNS Client scripts extension for "digitalocean.com API v2". + The script directly updates a DNS record using the DO API. + It requires: + "option dns_server" to be set to the server to be used by nsupdate. + "option domain" the dns domain to update the record for (eg. A-record: home.) + "option username" the dns record name to update (eg. A-record: .example.com) + "option param_opt" the id of the dns record to update (check using chrome inspector in the DO dns tab) + "option password" the api token generated in the DO panel +endef + + +define Package/ddns-scripts-dnspod + $(call Package/ddns-scripts/Default) + TITLE:=Extension for dnspod.cn API + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scripts-dnspod/description + Dynamic DNS Client scripts extension for dnspod.cn API (require curl) +endef + + +define Package/ddns-scripts-noip + $(call Package/ddns-scripts/Default) + TITLE:=Extension for no-ip.com + DEPENDS:=ddns-scripts + PROVIDES:=ddns-scripts_no-ip_com +endef + +define Package/ddns-scripts-noip/description + Dynamic DNS Client scripts extension for "no-ip.com". +endef + +define Package/ddns-scripts-ns1 + $(call Package/ddns-scripts/Default) + TITLE:=NS1 API + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scripts-ns1/description + Dynamic DNS Client scripts extension for "ns1.com". + It requires: + "option username" to be a valid zone for ns1.com + "option password" to be a valid API key for ns1.com +endef + + +define Package/ddns-scripts-nsupdate + $(call Package/ddns-scripts/Default) + TITLE:=Extension for using bind nsupdate. + DEPENDS:=ddns-scripts +bind-client + PROVIDES:=ddns-scripts_nsupdate +endef + +define Package/ddns-scripts-nsupdate/description + Dynamic DNS Client scripts extension for direct updates using bind nsupdate + The script directly updates a PowerDNS (or maybe bind server) via nsupdate + from bind-client package. + It requires: + "option dns_server" to be set to the server to be used by nsupdate. + "option username" should be set to the key name and + "option password" to the base64 encoded shared secret. +endef + + +define Package/ddns-scripts-route53 + $(call Package/ddns-scripts/Default) + TITLE:=Extension for route53 API v1 + DEPENDS:=ddns-scripts +curl +openssl-util + PROVIDES:=ddns-scripts_route53-v1 +endef + +define Package/ddns-scripts-route53/description + Dynamic DNS Client scripts extension for Amazon AWS "route53 API v1". + Note: You must also install ca-certificate or ca-bundle. + It requires: + "option username" to be a valid AWS access key id + "option password" to be the matching AWS secret key id + "option domain" to contain the hosted zone ID +endef + + +define Package/ddns-scripts-cnkuai + $(call Package/ddns-scripts/Default) + TITLE:=CnKuai API + DEPENDS:=ddns-scripts +curl +giflib-utils + PROVIDES:=ddns-scripts_cnkuai_cn +endef + +define Package/ddns-scripts-cnkuai/description + Dynamic DNS Client scripts extension for "cnkuai.cn". + It requires: + "option username" to be a valid CnKuai control panel id + "option password" to be the matching CnKuai control panel password + "option domain" to contain the domain +endef + + +define Package/ddns-scripts-gandi + $(call Package/ddns-scripts/Default) + TITLE:=Gandi API + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scripts-gandi/description + Dynamic DNS Client scripts extension for "gandi.net". + It requires: + "option username" to be a valid subdomain for gandi.net + "option password" to be a valid API key for gandi.net +endef + + +define Package/ddns-scripts-pdns + $(call Package/ddns-scripts/Default) + TITLE:=PowerDNS API + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scripts-pdns/description + Dynamic DNS Client scripts extension for "PowerDNS" via API. + It requires: + "option param_opt(Optional Parameter)" to be a valid root URL for the PowerDNS webserver + "option username" to be a valid subdomain for the PowerDNS domain + "option password" to be a valid API key for the PowerDNS webserver +endef + + +define Package/ddns-scripts-transip + $(call Package/ddns-scripts/Default) + TITLE:=Extension for TransIP API + DEPENDS:=ddns-scripts +curl +openssl-util +!BUSYBOX_CONFIG_MKTEMP:coreutils-mktemp +endef + +define Package/ddns-scripts-transip/description + Dynamic DNS Client scripts extension for "transip.nl". + Note: You must also install ca-certificate or ca-bundle. + It requires: + "option username" to be a valid username for transip.nl + "option password" to be a valid matching private key + "option domain" to contain the base domain + "option param_enc" to contain the name of the DNS record to update + "option param_opt" to contain the TTL of the DNS record to update +endef + +define Package/ddns-scripts-one + $(call Package/ddns-scripts/Default) + TITLE:=Extension for one.com Control Panel + DEPENDS:=ddns-scripts +curl +endef + +define Package/ddns-scrtips-one/description + Dynamic DNS Client scripts extension for "one.com". + It requires: + "option username" to be a valid Email for one.com Control Panel + "option password" to be the matching one.com Control Panel password + "option domain" to contain the domain / subdomain +endef + + +define Package/ddns-scripts-porkbun + $(call Package/ddns-scripts/Default) + TITLE:=Extension for porkbun.com API v3 + DEPENDS:=ddns-scripts +curl + PROVIDES:=ddns-scripts_porkbun.com-v3 +endef + +define Package/ddns-scripts-porkbun/description + Dynamic DNS Client scripts extension for porkbun.com API v3 (require curl) + It requires: + "option username" to be a Porkbun API key + "option password" to be the corresponding Porkbun API secret key + "option domain" to be the FQDN for which to configure DDNS +endef + +define Package/ddns-scripts-huaweicloud + $(call Package/ddns-scripts/Default) + TITLE:=Extension for huaweicloud.com API + DEPENDS:=ddns-scripts +curl +openssl-util +endef + +define Package/ddns-scripts-huaweicloud/description + Dynamic DNS Client scripts extension for huaweicloud.com API (require curl and openssl) +endef + +define Build/Configure +endef + +define Build/Compile +endef + + define Package/ddns-scripts/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_CONF) $(PKG_BUILD_DIR)/files/ddns.config $(1)/etc/config/ddns + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DATA) ./files/etc/hotplug.d/iface/ddns \ + $(1)/etc/hotplug.d/iface/95-ddns + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/ddns \ + $(1)/etc/init.d/ddns + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/ddns \ + $(1)/etc/config/ddns $(INSTALL_DIR) $(1)/etc/ddns - $(INSTALL_DATA) $(PKG_BUILD_DIR)/files/services* $(1)/etc/ddns + $(INSTALL_DATA) ./files/services* $(1)/etc/ddns - $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/dynamic_dns_*.sh $(1)/usr/lib/ddns + $(INSTALL_DIR) $(1)/usr/share/ddns + echo "$(PKG_VERSION)-$(PKG_RELEASE)" > $(1)/usr/share/ddns/version + + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_DATA) ./files/usr/lib/ddns/dynamic_dns_functions.sh \ + $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/dynamic_dns_lucihelper.sh \ + $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/dynamic_dns_updater.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/usr/bin/ddns.sh \ + $(1)/usr/bin/ddns endef + define Package/ddns-scripts/postinst - #!/bin/sh - # if NOT run buildroot and PKG_UPGRADE then (re)start service if enabled - [ -z "$${IPKG_INSTROOT}" -a "$${PKG_UPGRADE}" = "1" ] && { - [ -x /etc/uci-defaults/ddns ] && \ - /etc/uci-defaults/ddns && \ - rm -f /etc/uci-defaults/ddns >/dev/null 2>&1 - /etc/init.d/ddns enabled && \ - /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns enabled + /etc/init.d/ddns start +fi +exit 0 endef + define Package/ddns-scripts/prerm - #!/bin/sh - # if run within buildroot exit - [ -n "$${IPKG_INSTROOT}" ] && exit 0 - # stop running scripts +#!/bin/sh +if [ -n "$${IPKG_INSTROOT}" ]; then /etc/init.d/ddns stop /etc/init.d/ddns disable - # clear LuCI indexcache - rm -f /tmp/luci-indexcache >/dev/null 2>&1 - exit 0 # suppress errors +fi +exit 0 endef -###### ************************************************************************* -define Package/ddns-scripts_cloudflare.com-v4/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors + +define Package/ddns-scripts-services/install + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/* \ + $(1)/usr/share/ddns/default + + # Remove special services + rm $(1)/usr/share/ddns/default/luadns.com-v1.json + rm $(1)/usr/share/ddns/default/cloudflare.com-v4.json + rm $(1)/usr/share/ddns/default/cloud.google.com-v1.json + rm $(1)/usr/share/ddns/default/freedns.42.pl.json + rm $(1)/usr/share/ddns/default/godaddy.com-v1.json + rm $(1)/usr/share/ddns/default/digitalocean.com-v2.json + rm $(1)/usr/share/ddns/default/dnspod.cn.json + rm $(1)/usr/share/ddns/default/no-ip.com.json + rm $(1)/usr/share/ddns/default/bind-nsupdate.json + rm $(1)/usr/share/ddns/default/route53-v1.json + rm $(1)/usr/share/ddns/default/cnkuai.cn.json + rm $(1)/usr/share/ddns/default/gandi.net.json + rm $(1)/usr/share/ddns/default/pdns.json + rm $(1)/usr/share/ddns/default/transip.nl.json + rm $(1)/usr/share/ddns/default/ns1.com.json + rm $(1)/usr/share/ddns/default/one.com.json + rm $(1)/usr/share/ddns/default/porkbun.com-v3.json + rm $(1)/usr/share/ddns/default/huaweicloud.com.json endef -define Package/ddns-scripts_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 + + +define Package/ddns-scripts-utils/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_cloudflare_com_v4.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_cloudflare.com-v4/postinst - #!/bin/sh - # remove old services file entries - /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 - # and create new - 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 - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_cloudflare.com-v4 ] && \ - /etc/uci-defaults/ddns_cloudflare.com-v4 && \ - rm -f /etc/uci-defaults/ddns_cloudflare.com-v4 >/dev/null 2>&1 - /etc/init.d/ddns enabled && \ - /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_cloudflare.com-v4/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /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 - exit 0 # suppress errors + $(INSTALL_BIN) ./samples/slaac_sample.sh \ + $(1)/usr/lib/ddns/slaac.sh + $(INSTALL_BIN) ./samples/getlocalip_sample.sh \ + $(1)/usr/lib/ddns/getlocalip.sh endef -###### ************************************************************************* -define Package/ddns-scripts_freedns_42_pl/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors -endef -define Package/ddns-scripts_freedns_42_pl/install - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_freedns_42_pl + +define Package/ddns-scripts-luadns/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_freedns_42_pl.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_freedns_42_pl/postinst - #!/bin/sh - # remove old services file entries - /bin/sed -i '/freedns\.42\.pl/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - # and create new - printf "%s\\t%s\\n" '"freedns.42.pl"' '"update_freedns_42_pl.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_freedns_42_pl ] && \ - /etc/uci-defaults/ddns_freedns_42_pl && \ - rm -f /etc/uci-defaults/ddns_freedns_42_pl >/dev/null 2>&1 - /etc/init.d/ddns enabled && \ - /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_freedns_42_pl/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /bin/sed -i '/freedns\.42\.pl/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - exit 0 # suppress errors + $(INSTALL_BIN) ./files/usr/lib/ddns/update_luadns_v1.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/luadns.com-v1.json \ + $(1)/usr/share/ddns/default/ endef -###### ************************************************************************* -define Package/ddns-scripts_godaddy.com-v1/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors +define Package/ddns-scripts-luadns/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 endef -define Package/ddns-scripts_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 + + +define Package/ddns-scripts-cloudflare/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_godaddy_com_v1.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_godaddy.com-v1/postinst - #!/bin/sh - # remove old services file entries - /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 - # and create new - 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 - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_godaddy.com-v1 ] && \ - /etc/uci-defaults/ddns_godaddy.com-v1 && \ - rm -f /etc/uci-defaults/ddns_godaddy.com-v1 >/dev/null 2>&1 - /etc/init.d/ddns enabled \ - && /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_godaddy.com-v1/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /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 - exit 0 # suppress errors + $(INSTALL_BIN) ./files/usr/lib/ddns/update_cloudflare_com_v4.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/cloudflare.com-v4.json \ + $(1)/usr/share/ddns/default/ endef -###### ************************************************************************* -define Package/ddns-scripts_no-ip_com/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors +define Package/ddns-scripts-cloudflare/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 endef -define Package/ddns-scripts_no-ip_com/install - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_no-ip_com + + +define Package/ddns-scripts-gcp/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_no-ip_com.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_no-ip_com/postinst - #!/bin/sh - # remove old services file entries - /bin/sed -i '/no-ip\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - # and create new - printf "%s\\t%s\\n" '"no-ip.com"' '"update_no-ip_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_no-ip_com ] && \ - /etc/uci-defaults/ddns_no-ip_com && \ - rm -f /etc/uci-defaults/ddns_no-ip_com >/dev/null 2>&1 - /etc/init.d/ddns enabled && \ - /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_no-ip_com/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /bin/sed -i '/no-ip\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - exit 0 # suppress errors + $(INSTALL_BIN) ./files/usr/lib/ddns/update_gcp_v1.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/cloud.google.com-v1.json \ + $(1)/usr/share/ddns/default/ endef -###### ************************************************************************* -define Package/ddns-scripts_nsupdate/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors +define Package/ddns-scripts-gcp/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 endef -define Package/ddns-scripts_nsupdate/install - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_nsupdate + + +define Package/ddns-scripts-freedns/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_nsupdate.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_nsupdate/postinst - #!/bin/sh - # remove old services file entries - /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 - # and create new - 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 - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_nsupdate ] && \ - /etc/uci-defaults/ddns_nsupdate && \ - rm -f /etc/uci-defaults/ddns_nsupdate >/dev/null 2>&1 - /etc/init.d/ddns enabled && \ - /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_nsupdate/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /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 - exit 0 # suppress errors + $(INSTALL_BIN) ./files/usr/lib/ddns/update_freedns_42_pl.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/freedns.42.pl.json \ + $(1)/usr/share/ddns/default endef -###### ************************************************************************* -define Package/ddns-scripts_route53-v1/preinst - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - exit 0 # suppress errors +define Package/ddns-scripts-freedns/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 endef -define Package/ddns-scripts_route53-v1/install - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_route53-v1 + + +define Package/ddns-scripts-godaddy/install $(INSTALL_DIR) $(1)/usr/lib/ddns - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_route53_v1.sh $(1)/usr/lib/ddns -endef -define Package/ddns-scripts_route53-v1/postinst - #!/bin/sh - # remove old services file entries - /bin/sed -i '/route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - /bin/sed -i '/route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 - # and create new - printf "%s\\t%s\\n" '"route53-v1"' '"update_route53_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services - printf "%s\\t%s\\n" '"route53-v1"' '"update_route53_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6 - # on real system restart service if enabled - [ -z "$${IPKG_INSTROOT}" ] && { - [ -x /etc/uci-defaults/ddns_route53-v1 ] && \ - /etc/uci-defaults/ddns_route53-v1 && \ - rm -f /etc/uci-defaults/route53.com-v1 >/dev/null 2>&1 - /etc/init.d/ddns enabled \ - && /etc/init.d/ddns start >/dev/null 2>&1 - } - exit 0 # suppress errors -endef -define Package/ddns-scripts_route53-v1/prerm - #!/bin/sh - # if NOT run buildroot then stop service - [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 - # remove services file entries - /bin/sed -i 'route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 - /bin/sed -i 'route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 - exit 0 # suppress errors + $(INSTALL_BIN) ./files/usr/lib/ddns/update_godaddy_com_v1.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/godaddy.com-v1.json \ + $(1)/usr/share/ddns/default endef -###### ************************************************************************* +define Package/ddns-scripts-godaddy/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-digitalocean/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_digitalocean_com_v2.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/digitalocean.com-v2.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-digitalocean/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-dnspod/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_dnspod_cn.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/dnspod.cn.json \ + $(1)/usr/share/ddns/default/ +endef + +define Package/ddns-scripts-dnspod/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-noip/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_no-ip_com.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/no-ip.com.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-noip/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-ns1/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_ns1_com.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/ns1.com.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-ns1/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-nsupdate/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_nsupdate.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/bind-nsupdate.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-nsupdate/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-route53/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_route53_v1.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/route53-v1.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-route53/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-cnkuai/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_cnkuai_cn.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/cnkuai.cn.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-cnkuai/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-gandi/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_gandi_net.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/gandi.net.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-gandi/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-pdns/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_pdns.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/pdns.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-pdns/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-transip/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_transip_nl.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/transip.nl.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-transip/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-one/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_one_com.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/one.com.json \ + $(1)/usr/share/ddns/default +endef + +define Package/ddns-scripts-one/prerm +#!/bin/sh +if [-z "${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-porkbun/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_porkbun_v3.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/porkbun.com-v3.json \ + $(1)/usr/share/ddns/default/ +endef + +define Package/ddns-scripts-porkbun/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + +define Package/ddns-scripts-huaweicloud/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_huaweicloud_com.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/huaweicloud.com.json \ + $(1)/usr/share/ddns/default/ +endef + +define Package/ddns-scripts-huaweicloud/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + $(eval $(call BuildPackage,ddns-scripts)) -$(eval $(call BuildPackage,ddns-scripts_cloudflare.com-v4)) -$(eval $(call BuildPackage,ddns-scripts_freedns_42_pl)) -$(eval $(call BuildPackage,ddns-scripts_godaddy.com-v1)) -$(eval $(call BuildPackage,ddns-scripts_no-ip_com)) -$(eval $(call BuildPackage,ddns-scripts_nsupdate)) -$(eval $(call BuildPackage,ddns-scripts_route53-v1)) +$(eval $(call BuildPackage,ddns-scripts-services)) +$(eval $(call BuildPackage,ddns-scripts-utils)) +$(eval $(call BuildPackage,ddns-scripts-luadns)) +$(eval $(call BuildPackage,ddns-scripts-cloudflare)) +$(eval $(call BuildPackage,ddns-scripts-gcp)) +$(eval $(call BuildPackage,ddns-scripts-freedns)) +$(eval $(call BuildPackage,ddns-scripts-godaddy)) +$(eval $(call BuildPackage,ddns-scripts-digitalocean)) +$(eval $(call BuildPackage,ddns-scripts-dnspod)) +$(eval $(call BuildPackage,ddns-scripts-noip)) +$(eval $(call BuildPackage,ddns-scripts-nsupdate)) +$(eval $(call BuildPackage,ddns-scripts-route53)) +$(eval $(call BuildPackage,ddns-scripts-cnkuai)) +$(eval $(call BuildPackage,ddns-scripts-gandi)) +$(eval $(call BuildPackage,ddns-scripts-pdns)) +$(eval $(call BuildPackage,ddns-scripts-transip)) +$(eval $(call BuildPackage,ddns-scripts-ns1)) +$(eval $(call BuildPackage,ddns-scripts-one)) +$(eval $(call BuildPackage,ddns-scripts-porkbun)) +$(eval $(call BuildPackage,ddns-scripts-huaweicloud)) diff --git a/net/ddns-scripts/files/ddns.config b/net/ddns-scripts/files/ddns.config deleted file mode 100644 index 2f3ed522..00000000 --- a/net/ddns-scripts/files/ddns.config +++ /dev/null @@ -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" diff --git a/net/ddns-scripts/files/ddns.defaults b/net/ddns-scripts/files/ddns.defaults deleted file mode 100755 index 7e551d0f..00000000 --- a/net/ddns-scripts/files/ddns.defaults +++ /dev/null @@ -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 - diff --git a/net/ddns-scripts/files/etc/config/ddns b/net/ddns-scripts/files/etc/config/ddns new file mode 100644 index 00000000..b45855f0 --- /dev/null +++ b/net/ddns-scripts/files/etc/config/ddns @@ -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" + diff --git a/net/ddns-scripts/files/ddns.hotplug b/net/ddns-scripts/files/etc/hotplug.d/iface/ddns old mode 100755 new mode 100644 similarity index 100% rename from net/ddns-scripts/files/ddns.hotplug rename to net/ddns-scripts/files/etc/hotplug.d/iface/ddns diff --git a/net/ddns-scripts/files/ddns.init b/net/ddns-scripts/files/etc/init.d/ddns old mode 100755 new mode 100644 similarity index 94% rename from net/ddns-scripts/files/ddns.init rename to net/ddns-scripts/files/etc/init.d/ddns index 49052eab..156ccb4e --- a/net/ddns-scripts/files/ddns.init +++ b/net/ddns-scripts/files/etc/init.d/ddns @@ -2,10 +2,6 @@ START=95 STOP=10 -boot() { - start "$@" -} - reload() { /usr/lib/ddns/dynamic_dns_updater.sh -- reload return 0 diff --git a/net/ddns-scripts/files/update_route53_v1.sh b/net/ddns-scripts/files/update_route53_v1.sh deleted file mode 100644 index 6b9b029e..00000000 --- a/net/ddns-scripts/files/update_route53_v1.sh +++ /dev/null @@ -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 -[ -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=" \ - \ - \ - \ - \ - UPSERT \ - \ - ${RECORD_NAME} \ - ${RECORD_TYPE} \ - ${RECORD_TTL} \ - \ - \ - ${RECORD_VALUE} \ - \ - \ - \ - \ - \ - \ -" - -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 diff --git a/net/ddns-scripts/files/usr/bin/ddns.sh b/net/ddns-scripts/files/usr/bin/ddns.sh new file mode 100644 index 00000000..921465f7 --- /dev/null +++ b/net/ddns-scripts/files/usr/bin/ddns.sh @@ -0,0 +1,172 @@ +#!/bin/sh +# +# Copyright (C) 2020 TDT AG +# +# 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") " + echo "" + echo "Supported ddns :" + echo " service: Command for custom ddns service providers" + echo "" + echo "Supported ddns 'service' command :" + 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 : Install custom service provider" + echo " remove : 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 "$@" diff --git a/net/ddns-scripts/files/dynamic_dns_functions.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh old mode 100755 new mode 100644 similarity index 84% rename from net/ddns-scripts/files/dynamic_dns_functions.sh rename to net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh index 5a76166e..7202469c --- a/net/ddns-scripts/files/dynamic_dns_functions.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh @@ -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 diff --git a/net/ddns-scripts/files/dynamic_dns_lucihelper.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh old mode 100755 new mode 100644 similarity index 97% rename from net/ddns-scripts/files/dynamic_dns_lucihelper.sh rename to net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh index ab3eb78e..f7633484 --- a/net/ddns-scripts/files/dynamic_dns_lucihelper.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh @@ -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=$? ;; diff --git a/net/ddns-scripts/files/dynamic_dns_updater.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh old mode 100755 new mode 100644 similarity index 84% rename from net/ddns-scripts/files/dynamic_dns_updater.sh rename to net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh index b84e8292..e6f91e8e --- a/net/ddns-scripts/files/dynamic_dns_updater.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh @@ -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 diff --git a/net/ddns-scripts/files/update_cloudflare_com_v4.sh b/net/ddns-scripts/files/usr/lib/ddns/update_cloudflare_com_v4.sh old mode 100755 new mode 100644 similarity index 82% rename from net/ddns-scripts/files/update_cloudflare_com_v4.sh rename to net/ddns-scripts/files/usr/lib/ddns/update_cloudflare_com_v4.sh index 6dafc4e6..4fb3a0dd --- a/net/ddns-scripts/files/update_cloudflare_com_v4.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/update_cloudflare_com_v4.sh @@ -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 + diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh b/net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh new file mode 100644 index 00000000..a2b78630 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_cnkuai_cn.sh @@ -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 "/$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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_digitalocean_com_v2.sh b/net/ddns-scripts/files/usr/lib/ddns/update_digitalocean_com_v2.sh new file mode 100644 index 00000000..5ee1b13f --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_digitalocean_com_v2.sh @@ -0,0 +1,40 @@ +# Script for sending user defined updates using the DigitalOcean API +# 2015 Artem Yakimenko +# 2021 George Giannou + +# 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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh b/net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh new file mode 100755 index 00000000..2091be13 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh @@ -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 diff --git a/net/ddns-scripts/files/update_freedns_42_pl.sh b/net/ddns-scripts/files/usr/lib/ddns/update_freedns_42_pl.sh old mode 100755 new mode 100644 similarity index 98% rename from net/ddns-scripts/files/update_freedns_42_pl.sh rename to net/ddns-scripts/files/usr/lib/ddns/update_freedns_42_pl.sh index 14d9713b..f0e91972 --- a/net/ddns-scripts/files/update_freedns_42_pl.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/update_freedns_42_pl.sh @@ -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="xname.updateArecordname[RECORDNAME]zone[ZONENAME]oldaddress*updatereverse0user[USERNAME]ttl600newaddress[IP]password[PASSWORD]" XMLDATA=$(echo $XMLDATA | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \ diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh b/net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh new file mode 100644 index 00000000..321687d7 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_gandi_net.sh @@ -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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh b/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh new file mode 100755 index 00000000..5bd096f4 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh @@ -0,0 +1,272 @@ +#!/bin/sh +# +#.Distributed under the terms of the GNU General Public License (GPL) version 2.0 +#.2022 Chris Barrick +# +# 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 $@ diff --git a/net/ddns-scripts/files/update_godaddy_com_v1.sh b/net/ddns-scripts/files/usr/lib/ddns/update_godaddy_com_v1.sh old mode 100755 new mode 100644 similarity index 100% rename from net/ddns-scripts/files/update_godaddy_com_v1.sh rename to net/ddns-scripts/files/usr/lib/ddns/update_godaddy_com_v1.sh diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh b/net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh new file mode 100644 index 00000000..1c21b1d2 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_huaweicloud_com.sh @@ -0,0 +1,152 @@ +#!/bin/sh +# +# script for sending updates to huaweicloud.com +# 2023-2024 sxlehua +# 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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh b/net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh new file mode 100644 index 00000000..5d7954e1 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_luadns_v1.sh @@ -0,0 +1,191 @@ +#!/bin/sh +# +#.Distributed under the terms of the GNU General Public License (GPL) version 2.0 +#.2023 Jihoon Han +# +#.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 diff --git a/net/ddns-scripts/files/update_no-ip_com.sh b/net/ddns-scripts/files/usr/lib/ddns/update_no-ip_com.sh old mode 100755 new mode 100644 similarity index 87% rename from net/ddns-scripts/files/update_no-ip_com.sh rename to net/ddns-scripts/files/usr/lib/ddns/update_no-ip_com.sh index 7d4354bd..e13058b1 --- a/net/ddns-scripts/files/update_no-ip_com.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/update_no-ip_com.sh @@ -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'" diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh b/net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh new file mode 100644 index 00000000..4b965339 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_ns1_com.sh @@ -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 diff --git a/net/ddns-scripts/files/update_nsupdate.sh b/net/ddns-scripts/files/usr/lib/ddns/update_nsupdate.sh old mode 100755 new mode 100644 similarity index 92% rename from net/ddns-scripts/files/update_nsupdate.sh rename to net/ddns-scripts/files/usr/lib/ddns/update_nsupdate.sh index 983664cb..039196ff --- a/net/ddns-scripts/files/update_nsupdate.sh +++ b/net/ddns-scripts/files/usr/lib/ddns/update_nsupdate.sh @@ -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'" diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh b/net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh new file mode 100644 index 00000000..94ec2ef4 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_one_com.sh @@ -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 "" > $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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh b/net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh new file mode 100755 index 00000000..a19ed13f --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_pdns.sh @@ -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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh b/net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh new file mode 100644 index 00000000..f1824d9d --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_porkbun_v3.sh @@ -0,0 +1,162 @@ +# +# Distributed under the terms of the GNU General Public License (GPL) version 2.0 +# 2024 Ansel Horn +# +# 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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh b/net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh new file mode 100644 index 00000000..0d474051 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh @@ -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 + +[ -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=" \ + \ + \ + \ + \ + UPSERT \ + \ + ${RECORD_NAME} \ + ${RECORD_TYPE} \ + ${RECORD_TTL} \ + \ + \ + ${RECORD_VALUE} \ + \ + \ + \ + \ + \ + \ +" + +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 diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh b/net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh new file mode 100644 index 00000000..fe46987f --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh @@ -0,0 +1,134 @@ +#!/bin/sh +# +# 2021 Martijn Atema +# +# 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 diff --git a/net/ddns-scripts/files/usr/share/ddns/default/3322.org.json b/net/ddns-scripts/files/usr/share/ddns/default/3322.org.json new file mode 100644 index 00000000..d166dc44 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/3322.org.json @@ -0,0 +1,6 @@ +{ + "name": "3322.org", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@members.3322.org/dyndns/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-basicauth.json b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-basicauth.json new file mode 100644 index 00000000..b4f73fa5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-basicauth.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-keyauth.json b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-keyauth.json new file mode 100644 index 00000000..166b004b --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-keyauth.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-basic.json b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-basic.json new file mode 100644 index 00000000..436caf48 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-basic.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-token.json b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-token.json new file mode 100644 index 00000000..0786dd82 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/afraid.org-v2-token.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/all-inkl.com.json b/net/ddns-scripts/files/usr/share/ddns/default/all-inkl.com.json new file mode 100644 index 00000000..d0f5b736 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/all-inkl.com.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/bind-nsupdate.json b/net/ddns-scripts/files/usr/share/ddns/default/bind-nsupdate.json new file mode 100644 index 00000000..f91806a1 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/bind-nsupdate.json @@ -0,0 +1,9 @@ +{ + "name": "bind-nsupdate", + "ipv4": { + "url": "update_nsupdate.sh" + }, + "ipv6": { + "url": "update_nsupdate.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/changeip.com.json b/net/ddns-scripts/files/usr/share/ddns/default/changeip.com.json new file mode 100644 index 00000000..3472f0b3 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/changeip.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json b/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json new file mode 100644 index 00000000..eee707b3 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json @@ -0,0 +1,10 @@ +{ + "name": "cloud.google.com-v1", + "ipv4": { + "url": "update_gcp_v1.sh" + }, + "ipv6": { + "url": "update_gcp_v1.sh" + } +} + diff --git a/net/ddns-scripts/files/usr/share/ddns/default/cloudflare.com-v4.json b/net/ddns-scripts/files/usr/share/ddns/default/cloudflare.com-v4.json new file mode 100644 index 00000000..66a1d118 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/cloudflare.com-v4.json @@ -0,0 +1,9 @@ +{ + "name": "cloudflare.com-v4", + "ipv4": { + "url": "update_cloudflare_com_v4.sh" + }, + "ipv6": { + "url": "update_cloudflare_com_v4.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/cnkuai.cn.json b/net/ddns-scripts/files/usr/share/ddns/default/cnkuai.cn.json new file mode 100644 index 00000000..1e9bebf5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/cnkuai.cn.json @@ -0,0 +1,9 @@ +{ + "name": "cnkuai.cn", + "ipv4": { + "url": "update_cnkuai_cn.sh" + }, + "ipv6": { + "url": "update_cnkuai_cn.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/core-networks.de.json b/net/ddns-scripts/files/usr/share/ddns/default/core-networks.de.json new file mode 100644 index 00000000..c334d773 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/core-networks.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ddnss.de.json b/net/ddns-scripts/files/usr/share/ddns/default/ddnss.de.json new file mode 100644 index 00000000..17cdf0e3 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/ddnss.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ddo.jp.json b/net/ddns-scripts/files/usr/share/ddns/default/ddo.jp.json new file mode 100644 index 00000000..1cf53b57 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/ddo.jp.json @@ -0,0 +1,6 @@ +{ + "name": "ddo.jp", + "ipv4": { + "url": "http://free.ddo.jp/dnsupdate.php?dn=[DOMAIN]&pw=[PASSWORD]&ip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/desec.io.json b/net/ddns-scripts/files/usr/share/ddns/default/desec.io.json new file mode 100644 index 00000000..c28458fe --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/desec.io.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dhis.org.json b/net/ddns-scripts/files/usr/share/ddns/default/dhis.org.json new file mode 100644 index 00000000..cc2ce3e5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dhis.org.json @@ -0,0 +1,9 @@ +{ + "name": "dhis.org", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@is.dhis.org/" + }, + "ipv6": { + "url": "http://[USERNAME]:[PASSWORD]@is.dhis.org/" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/digitalocean.com-v2.json b/net/ddns-scripts/files/usr/share/ddns/default/digitalocean.com-v2.json new file mode 100644 index 00000000..abeac560 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/digitalocean.com-v2.json @@ -0,0 +1,9 @@ +{ + "name": "digitalocean.com-v2", + "ipv4": { + "url": "update_digitalocean_com_v2.sh" + }, + "ipv6": { + "url": "update_digitalocean_com_v2.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsdynamic.org.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsdynamic.org.json new file mode 100644 index 00000000..f1fd1810 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsdynamic.org.json @@ -0,0 +1,7 @@ +{ + "name": "dnsdynamic.org", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@www.dnsdynamic.org/api/?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsever.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsever.com.json new file mode 100644 index 00000000..23f9ac94 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsever.com.json @@ -0,0 +1,6 @@ +{ + "name": "dnsever.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@dyna.dnsever.com/update.php?host[[DOMAIN]]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsexit.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsexit.com.json new file mode 100644 index 00000000..89d7a814 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsexit.com.json @@ -0,0 +1,6 @@ +{ + "name": "dnsexit.com", + "ipv4": { + "url": "http://update.dnsexit.com/RemoteUpdate.sv?login=[USERNAME]&password=[PASSWORD]&host=[DOMAIN]&myip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnshome.de.json b/net/ddns-scripts/files/usr/share/ddns/default/dnshome.de.json new file mode 100644 index 00000000..f767de2b --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnshome.de.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsmadeeasy.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsmadeeasy.com.json new file mode 100644 index 00000000..744301af --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsmadeeasy.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsmax.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsmax.com.json new file mode 100644 index 00000000..e84667a7 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsmax.com.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnsomatic.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnsomatic.com.json new file mode 100644 index 00000000..09df1eb0 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnsomatic.com.json @@ -0,0 +1,7 @@ +{ + "name": "dnsomatic.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnspark.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dnspark.com.json new file mode 100644 index 00000000..f10e1f24 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnspark.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dnspod.cn.json b/net/ddns-scripts/files/usr/share/ddns/default/dnspod.cn.json new file mode 100644 index 00000000..dcfa4a25 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dnspod.cn.json @@ -0,0 +1,9 @@ +{ + "name": "dnspod.cn", + "ipv4": { + "url": "update_dnspod_cn.sh" + }, + "ipv6": { + "url": "update_dnspod_cn.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/do.de.json b/net/ddns-scripts/files/usr/share/ddns/default/do.de.json new file mode 100644 index 00000000..3884a01a --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/do.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/domopoli.de.json b/net/ddns-scripts/files/usr/share/ddns/default/domopoli.de.json new file mode 100644 index 00000000..517751cc --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/domopoli.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/duckdns.org.json b/net/ddns-scripts/files/usr/share/ddns/default/duckdns.org.json new file mode 100644 index 00000000..625c9f99 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/duckdns.org.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/duiadns.net.json b/net/ddns-scripts/files/usr/share/ddns/default/duiadns.net.json new file mode 100644 index 00000000..bbf9998b --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/duiadns.net.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json b/net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json new file mode 100644 index 00000000..ce9e4fd8 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dy.fi.json @@ -0,0 +1,7 @@ +{ + "name": "dy.fi", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@www.dy.fi/nic/update?hostname=[DOMAIN]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json new file mode 100644 index 00000000..0ac779b0 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dyn.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dyndns.it.json b/net/ddns-scripts/files/usr/share/ddns/default/dyndns.it.json new file mode 100644 index 00000000..2cffb347 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dyndns.it.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dyndns.org.json b/net/ddns-scripts/files/usr/share/ddns/default/dyndns.org.json new file mode 100644 index 00000000..a0c064f4 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dyndns.org.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dynu.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dynu.com.json new file mode 100644 index 00000000..2c25ea90 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dynu.com.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json b/net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json new file mode 100644 index 00000000..66c62aa7 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/dynv6.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/easydns.com.json b/net/ddns-scripts/files/usr/share/ddns/default/easydns.com.json new file mode 100644 index 00000000..0642c38d --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/easydns.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/freedns.42.pl.json b/net/ddns-scripts/files/usr/share/ddns/default/freedns.42.pl.json new file mode 100644 index 00000000..c04dc1dd --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/freedns.42.pl.json @@ -0,0 +1,6 @@ +{ + "name": "freedns.42.pl", + "ipv4": { + "url": "update_freedns_42_pl.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/gandi.net.json b/net/ddns-scripts/files/usr/share/ddns/default/gandi.net.json new file mode 100644 index 00000000..de54a16a --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/gandi.net.json @@ -0,0 +1,9 @@ +{ + "name": "gandi.net", + "ipv4": { + "url": "update_gandi_net.sh" + }, + "ipv6": { + "url": "update_gandi_net.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/godaddy.com-v1.json b/net/ddns-scripts/files/usr/share/ddns/default/godaddy.com-v1.json new file mode 100644 index 00000000..211e0e5f --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/godaddy.com-v1.json @@ -0,0 +1,9 @@ +{ + "name": "godaddy.com-v1", + "ipv4": { + "url": "update_godaddy_com_v1.sh" + }, + "ipv6": { + "url": "update_godaddy_com_v1.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/goip.de.json b/net/ddns-scripts/files/usr/share/ddns/default/goip.de.json new file mode 100644 index 00000000..5aaf3bae --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/goip.de.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/google.com.json b/net/ddns-scripts/files/usr/share/ddns/default/google.com.json new file mode 100644 index 00000000..edfe461c --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/google.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/he.net.json b/net/ddns-scripts/files/usr/share/ddns/default/he.net.json new file mode 100644 index 00000000..7043efe6 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/he.net.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/hosting.de.json b/net/ddns-scripts/files/usr/share/ddns/default/hosting.de.json new file mode 100644 index 00000000..c41ee35e --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/hosting.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/huaweicloud.com.json b/net/ddns-scripts/files/usr/share/ddns/default/huaweicloud.com.json new file mode 100644 index 00000000..be549deb --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/huaweicloud.com.json @@ -0,0 +1,9 @@ +{ + "name": "huaweicloud.com", + "ipv4": { + "url": "update_huaweicloud_com.sh" + }, + "ipv6": { + "url": "update_huaweicloud_com.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/infomaniak.com.json b/net/ddns-scripts/files/usr/share/ddns/default/infomaniak.com.json new file mode 100644 index 00000000..80541aca --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/infomaniak.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json b/net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json new file mode 100644 index 00000000..10b16a98 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/inwx.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json b/net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json new file mode 100644 index 00000000..026caa19 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json @@ -0,0 +1,7 @@ +{ + "name": "ipnodns.ru", + "ipv4": { + "url": "https://ipnodns.ru/cgi-bin/dyndns.cgi?login=[USERNAME]&secret=[PASSWORD]", + "answer": "ok" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/joker.com.json b/net/ddns-scripts/files/usr/share/ddns/default/joker.com.json new file mode 100644 index 00000000..af897f18 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/joker.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json b/net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json new file mode 100644 index 00000000..f1c3fc22 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/loopia.se.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/luadns.com-v1.json b/net/ddns-scripts/files/usr/share/ddns/default/luadns.com-v1.json new file mode 100644 index 00000000..c77d55be --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/luadns.com-v1.json @@ -0,0 +1,9 @@ +{ + "name": "luadns.com-v1", + "ipv4": { + "url": "update_luadns_v1.sh" + }, + "ipv6": { + "url": "update_luadns_v1.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/moniker.com.json b/net/ddns-scripts/files/usr/share/ddns/default/moniker.com.json new file mode 100644 index 00000000..c5b7aa98 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/moniker.com.json @@ -0,0 +1,7 @@ +{ + "name": "moniker.com", + "ipv4": { + "url": "https://dynamicdns.key-systems.net/update.php?hostname=[DOMAIN]&password=[PASSWORD]&ip=[IP]", + "answer": "success" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/mydns.jp.json b/net/ddns-scripts/files/usr/share/ddns/default/mydns.jp.json new file mode 100644 index 00000000..11e98873 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/mydns.jp.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/myonlineportal.net.json b/net/ddns-scripts/files/usr/share/ddns/default/myonlineportal.net.json new file mode 100644 index 00000000..b3196d6d --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/myonlineportal.net.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com-v2.json b/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com-v2.json new file mode 100644 index 00000000..e2462238 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com-v2.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com.json b/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com.json new file mode 100644 index 00000000..9b2556be --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/mythic-beasts.com.json @@ -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=." + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/namecheap.com.json b/net/ddns-scripts/files/usr/share/ddns/default/namecheap.com.json new file mode 100644 index 00000000..bbb0c1fc --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/namecheap.com.json @@ -0,0 +1,6 @@ +{ + "name": "namecheap.com", + "ipv4": { + "url": "http://dynamicdns.park-your-domain.com/update?host=[USERNAME]&domain=[DOMAIN]&password=[PASSWORD]&ip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/njal.la.json b/net/ddns-scripts/files/usr/share/ddns/default/njal.la.json new file mode 100644 index 00000000..5da8850d --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/njal.la.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json b/net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json new file mode 100644 index 00000000..e0f8ccb5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/no-ip.com.json @@ -0,0 +1,10 @@ +{ + "name": "no-ip.com", + "ipv4": { + "url": "update_no-ip_com.sh" + }, + "ipv6": { + "url": "update_no-ip_com.sh" + } +} + diff --git a/net/ddns-scripts/files/usr/share/ddns/default/no-ip.pl.json b/net/ddns-scripts/files/usr/share/ddns/default/no-ip.pl.json new file mode 100644 index 00000000..323a415a --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/no-ip.pl.json @@ -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]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/now-dns.com.json b/net/ddns-scripts/files/usr/share/ddns/default/now-dns.com.json new file mode 100644 index 00000000..8c4a2209 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/now-dns.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ns1.com.json b/net/ddns-scripts/files/usr/share/ddns/default/ns1.com.json new file mode 100644 index 00000000..93484b6c --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/ns1.com.json @@ -0,0 +1,9 @@ +{ + "name": "ns1.com", + "ipv4": { + "url": "update_ns1_com.sh" + }, + "ipv6": { + "url": "update_ns1_com.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/nsupdate.info.json b/net/ddns-scripts/files/usr/share/ddns/default/nsupdate.info.json new file mode 100644 index 00000000..435e41df --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/nsupdate.info.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/one.com.json b/net/ddns-scripts/files/usr/share/ddns/default/one.com.json new file mode 100644 index 00000000..9245a730 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/one.com.json @@ -0,0 +1,6 @@ +{ + "name": "one.com", + "ipv4": { + "url": "update_one_com.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/opendns.com.json b/net/ddns-scripts/files/usr/share/ddns/default/opendns.com.json new file mode 100644 index 00000000..35d4953c --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/opendns.com.json @@ -0,0 +1,7 @@ +{ + "name":"opendns.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@updates.opendns.com/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/oray.com.json b/net/ddns-scripts/files/usr/share/ddns/default/oray.com.json new file mode 100644 index 00000000..31728057 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/oray.com.json @@ -0,0 +1,6 @@ +{ + "name": "oray.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@ddns.oray.com/ph/update?hostname=[DOMAIN]&myip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json b/net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json new file mode 100644 index 00000000..446093bc --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/ovh.com.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/pdns.json b/net/ddns-scripts/files/usr/share/ddns/default/pdns.json new file mode 100644 index 00000000..aa6faa65 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/pdns.json @@ -0,0 +1,9 @@ +{ + "name": "PowerDNS", + "ipv4": { + "url": "update_pdns.sh" + }, + "ipv6": { + "url": "update_pdns.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/porkbun.com-v3.json b/net/ddns-scripts/files/usr/share/ddns/default/porkbun.com-v3.json new file mode 100644 index 00000000..69509c19 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/porkbun.com-v3.json @@ -0,0 +1,9 @@ +{ + "name": "porkbun.com-v3", + "ipv4": { + "url": "update_porkbun_v3.sh" + }, + "ipv6": { + "url": "update_porkbun_v3.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/regfish.de.json b/net/ddns-scripts/files/usr/share/ddns/default/regfish.de.json new file mode 100644 index 00000000..9b179959 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/regfish.de.json @@ -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" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/route53-v1.json b/net/ddns-scripts/files/usr/share/ddns/default/route53-v1.json new file mode 100644 index 00000000..bf5d8d37 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/route53-v1.json @@ -0,0 +1,9 @@ +{ + "name": "route53-v1", + "ipv4": { + "url": "update_route53_v1.sh" + }, + "ipv6": { + "url": "update_route53_v1.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/schokokeks.org.json b/net/ddns-scripts/files/usr/share/ddns/default/schokokeks.org.json new file mode 100644 index 00000000..480c0693 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/schokokeks.org.json @@ -0,0 +1,7 @@ +{ + "name": "schokokeks.org", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@dyndns.schokokeks.org/nic/update?myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/selfhost.de.json b/net/ddns-scripts/files/usr/share/ddns/default/selfhost.de.json new file mode 100644 index 00000000..0db3895c --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/selfhost.de.json @@ -0,0 +1,7 @@ +{ + "name": "selfhost.de", + "ipv4": { + "url": "http://carol.selfhost.de/update?username=[USERNAME]&password=[PASSWORD]&myip=[IP]&hostname=1", + "answer": "good|nochg|200|204" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/servercow.de.json b/net/ddns-scripts/files/usr/share/ddns/default/servercow.de.json new file mode 100644 index 00000000..ebe963ab --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/servercow.de.json @@ -0,0 +1,11 @@ +{ + "name": "servercow.de", + "ipv4": { + "url": "http://www.servercow.de/dnsupdate/update.php?username=[USERNAME]&pass=[PASSWORD]&hostname=[DOMAIN]&ipaddr=[IP]", + "answer": "OKv4" + }, + "ipv6": { + "url": "http://www.servercow.de/dnsupdate/update.php?username=[USERNAME]&pass=[PASSWORD]&hostname=[DOMAIN]&ip6addr=[IP]", + "answer": "OKv6" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/simply.com.json b/net/ddns-scripts/files/usr/share/ddns/default/simply.com.json new file mode 100644 index 00000000..5ab9c8d5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/simply.com.json @@ -0,0 +1,11 @@ +{ + "name": "simply.com", + "ipv4": { + "url": "https://[USERNAME]:[PASSWORD]@api.simply.com/2/ddns/?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + }, + "ipv6": { + "url": "https://[USERNAME]:[PASSWORD]@api.simply.com/2/ddns/?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/sitelutions.com.json b/net/ddns-scripts/files/usr/share/ddns/default/sitelutions.com.json new file mode 100644 index 00000000..a9fec1fb --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/sitelutions.com.json @@ -0,0 +1,7 @@ +{ + "name": "sitelutions.com", + "ipv4": { + "url": "https://dnsup.sitelutions.com/dnsup?user=[USERNAME]&pass=[PASSWORD]&id=[DOMAIN]&ip=[IP]", + "answer": "success" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/spdyn.de.json b/net/ddns-scripts/files/usr/share/ddns/default/spdyn.de.json new file mode 100644 index 00000000..a9352efc --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/spdyn.de.json @@ -0,0 +1,11 @@ +{ + "name": "spdyn.de", + "ipv4": { + "url": "https://update.spdyn.de/nic/update?hostname=[DOMAIN]&myip=[IP]&user=[USERNAME]&pass=[PASSWORD]", + "answer": "good|nochg" + }, + "ipv6": { + "url": "https://update.spdyn.de/nic/update?hostname=[DOMAIN]&myip=[IP]&user=[USERNAME]&pass=[PASSWORD]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/strato.com.json b/net/ddns-scripts/files/usr/share/ddns/default/strato.com.json new file mode 100644 index 00000000..9ab43d24 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/strato.com.json @@ -0,0 +1,11 @@ +{ + "name": "strato.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@dyndns.strato.com/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + }, + "ipv6": { + "url": "http://[USERNAME]:[PASSWORD]@dyndns.strato.com/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/system-ns.com.json b/net/ddns-scripts/files/usr/share/ddns/default/system-ns.com.json new file mode 100644 index 00000000..4c4ca7fc --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/system-ns.com.json @@ -0,0 +1,8 @@ +{ + "name": "system-ns.com", + + "ipv4": { + "url": "http://system-ns.com/api?type=dynamic&command=set&domain=[DOMAIN]&token=[PASSWORD]&ip=[IP]", + "answer": "0" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/thatip.com.json b/net/ddns-scripts/files/usr/share/ddns/default/thatip.com.json new file mode 100644 index 00000000..18e72b75 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/thatip.com.json @@ -0,0 +1,6 @@ +{ + "name": "thatip.com", + "ipv4": { + "url": "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=2&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json b/net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json new file mode 100644 index 00000000..1dabb4f6 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json @@ -0,0 +1,9 @@ +{ + "name": "transip.nl", + "ipv4": { + "url": "update_transip_nl.sh" + }, + "ipv6": { + "url": "update_transip_nl.sh" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/twodns.de.json b/net/ddns-scripts/files/usr/share/ddns/default/twodns.de.json new file mode 100644 index 00000000..2d20e76c --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/twodns.de.json @@ -0,0 +1,6 @@ +{ + "name": "twodns.de", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@update.twodns.de/update?hostname=[DOMAIN]&ip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/udmedia.de.json b/net/ddns-scripts/files/usr/share/ddns/default/udmedia.de.json new file mode 100644 index 00000000..fa9ff4c5 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/udmedia.de.json @@ -0,0 +1,9 @@ +{ + "name": "udmedia.de", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@www.udmedia.de/nic/update?myip=[IP]" + }, + "ipv6": { + "url": "http://[USERNAME]:[PASSWORD]@www.udmedia.de/nic/update?myip=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/variomedia.de.json b/net/ddns-scripts/files/usr/share/ddns/default/variomedia.de.json new file mode 100644 index 00000000..fa86f4e6 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/variomedia.de.json @@ -0,0 +1,11 @@ +{ + "name": "variomedia.de", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@dyndns.variomedia.de/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + }, + "ipv6": { + "url": "http://[USERNAME]:[PASSWORD]@dyndns.variomedia.de/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/xlhost.de.json b/net/ddns-scripts/files/usr/share/ddns/default/xlhost.de.json new file mode 100644 index 00000000..302cdc63 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/xlhost.de.json @@ -0,0 +1,7 @@ +{ + "name": "xlhost.de", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@nsupdate.xlhost.de/nic/update?hostname=[DOMAIN]&myip=[IP]", + "answer": "good|nochg" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/default/zoneedit.com.json b/net/ddns-scripts/files/usr/share/ddns/default/zoneedit.com.json new file mode 100644 index 00000000..dd3c2263 --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/zoneedit.com.json @@ -0,0 +1,6 @@ +{ + "name": "zoneedit.com", + "ipv4": { + "url": "http://[USERNAME]:[PASSWORD]@dynamic.zoneedit.com/auth/dynamic.html?host=[DOMAIN]&dnsto=[IP]" + } +} diff --git a/net/ddns-scripts/files/usr/share/ddns/list b/net/ddns-scripts/files/usr/share/ddns/list new file mode 100644 index 00000000..9373aeed --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/list @@ -0,0 +1,69 @@ +3322.org +afraid.org-basicauth +afraid.org-keyauth +afraid.org-v2-basic +afraid.org-v2-token +all-inkl.com +changeip.com +core-networks.de +ddnss.de +ddo.jp +desec.io +dhis.org +dnsdynamic.org +dnsever.com +dnsexit.com +dnshome.de +dnsmadeeasy.com +dnsmax.com +dnsomatic.com +dnspark.com +do.de +domopoli.de +duckdns.org +duiadns.net +dy.fi +dyn.com +dyndns.it +dyndns.org +dynu.com +dynv6.com +easydns.com +goip.de +google.com +he.net +hosting.de +infomaniak.com +ipnodns.ru +inwx.de +joker.com +loopia.se +moniker.com +mydns.jp +myonlineportal.net +mythic-beasts.com +mythic-beasts.com-v2 +namecheap.com +njal.la +no-ip.pl +now-dns.com +nsupdate.info +opendns.com +oray.com +ovh.com +regfish.de +schokokeks.org +selfhost.de +servercow.de +simply.com +sitelutions.com +spdyn.de +strato.com +system-ns.com +thatip.com +transip.nl +twodns.de +udmedia.de +variomedia.de +xlhost.de +zoneedit.com diff --git a/net/ddns-scripts/samples/ddns.config_sample b/net/ddns-scripts/samples/ddns.config_sample index a3aa7e81..46bd8abe 100644 --- a/net/ddns-scripts/samples/ddns.config_sample +++ b/net/ddns-scripts/samples/ddns.config_sample @@ -221,6 +221,11 @@ config service "myddns" # option ip_source "script" # option ip_script "" + # This option can be used in combination with ip_source "web" and ip_url. + # It adds a given user agent string to the request. + # Will only be used when wget or wget-ssl is installed. +# option user_agent "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/95.0" + ########### # force_ipversion option will set the "-4" respectively "-6" parameter # on command line of transfer and DNS lookup program. diff --git a/net/ddns-scripts/samples/slaac_sample.sh b/net/ddns-scripts/samples/slaac_sample.sh new file mode 100755 index 00000000..ea8f24d8 --- /dev/null +++ b/net/ddns-scripts/samples/slaac_sample.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# script to determine and return SLAAC ipv6 address using prefix from a locally configured interface and the MAC address of the device +# (c) 2018 Keve Mueller +# +# activated inside /etc/config/ddns by setting +# +# option ip_source 'script' +# option ip_script '/usr/lib/ddns/slaac_sample.sh br-lan AA:BB:CC:DD:EE:FF' +# +# the script is executed (not parsed) inside get_local_ip() function +# of /usr/lib/ddns/dynamic_dns_functions.sh +# +# useful when this box is the only DDNS client in the network and other clients use SLAAC +# so no need to install ddns client on every "internal" box +# +# NB: this will not catch the actual IPV6 used by the host when it is configured to use temporary addresses + +#NB: we need a valid MAC address that is fully expanded with leading zeroes on all positions +format_eui_64() { + local macaddr="$1" + echo ${macaddr:0:1}$(echo ${macaddr:1:1}|tr 0123456789abcdefABCDEF 23016745ab89efcd89efcd)${macaddr:3:2}:${macaddr:6:2}ff:fe${macaddr:9:2}:${macaddr:12:2}${macaddr:15:2} +} + +# expand :: in an ipv6 address specification to the appropriate series of 0: +# result will have 8 ipv6 fragments separated by single colon +# NB: input must be a valid IPv6 address, e.g. ::1 +# NB: numbers are not prepended with leading zeroes +expand_ipv6_colons() { + local ipv6=$1 +# we need :: to be in the middle, so prepend a 0 if the input starts with : and append 0 if it ends with it + if [ "${ipv6:0:1}" = ":" ]; then ipv6=0${ipv6}; fi + if [ "${ipv6: -1:1}" = ":" ]; then ipv6=${ipv6}0; fi +# retain only the real colons + local colons=${ipv6//::|[0123456789abcdefABCDEF]/} +# count them + local num_colons=${#colons} + local filler=":0:0:0:0:0:0:" +# replace the :: with the appropriate substring from filler + local ipv6_x=${ipv6/::/${filler:0:(7-$num_colons)*2-1}} + echo $ipv6_x +} + +# obtain the first ipv6 address of the device passed in $1 +addr_net=$(ip -6 -o addr show dev $1 scope global up | cut -d" " -f 7 | head -1) +#addr_net=$1 +addr=${addr_net%/*} +# TODO: we assume /64 subnet +# get the first 64 bits of the address +prefix=$(expand_ipv6_colons $addr | cut -d: -f -4) +# compute the SLAAC 64 bits from the MAC +suffix=$(format_eui_64 "$2") + +echo -n $prefix:$suffix +exit 0 + +#echo "Should never come here" >&2 +#exit 2 + diff --git a/net/ddns-scripts/samples/update_sample.sh b/net/ddns-scripts/samples/update_sample.sh index 00b51cbd..316dfa52 100644 --- a/net/ddns-scripts/samples/update_sample.sh +++ b/net/ddns-scripts/samples/update_sample.sh @@ -24,7 +24,7 @@ local __URL="http://[USERNAME]:[PASSWORD]@update.spdns.de/nic/update?hostname=[D [ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'" # do replaces in URL -__URL=$(echo $__URL | | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \ +__URL=$(echo $__URL | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \ -e "s#\[PARAMENC\]#$URL_PENC#g" -e "s#\[PARAMOPT\]#$param_opt#g" \ -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g") [ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')