diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile index 48d28d43f..c481c9379 100644 --- a/net/ddns-scripts/Makefile +++ b/net/ddns-scripts/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-scripts PKG_VERSION:=2.8.2 -PKG_RELEASE:=13 +PKG_RELEASE:=14 PKG_LICENSE:=GPL-2.0 @@ -108,6 +108,17 @@ define Package/ddns-scripts-digitalocean/description 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 @@ -261,6 +272,7 @@ define Package/ddns-scripts-services/install 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 @@ -346,6 +358,25 @@ 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 \ @@ -466,6 +497,7 @@ $(eval $(call BuildPackage,ddns-scripts-cloudflare)) $(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)) 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 000000000..2091be132 --- /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/usr/share/ddns/default/dnspod.cn.json b/net/ddns-scripts/files/usr/share/ddns/default/dnspod.cn.json new file mode 100644 index 000000000..dcfa4a259 --- /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" + } +}