ddns-scripts: Add script for TransIP.nl
authorMartijn Atema <redacted>
Sun, 14 Nov 2021 23:45:54 +0000 (00:45 +0100)
committerFlorian Eckert <redacted>
Tue, 30 Nov 2021 12:10:57 +0000 (13:10 +0100)
Signed-off-by: Martijn Atema <redacted>
Signed-off-by: Florian Eckert <redacted>
- PKG_RELEASE number updated

net/ddns-scripts/Makefile
net/ddns-scripts/files/usr/lib/ddns/update_transip_nl.sh [new file with mode: 0644]
net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json [new file with mode: 0644]
net/ddns-scripts/files/usr/share/ddns/list

index 03073a0a81a89af00101cdbcbee715b8f8824023..17430a807e86198c9351b98b8cb33590c6af9b88 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ddns-scripts
 PKG_VERSION:=2.8.2
-PKG_RELEASE:=18
+PKG_RELEASE:=19
 
 PKG_LICENSE:=GPL-2.0
 
@@ -207,6 +207,24 @@ define Package/ddns-scripts-pdns/description
 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 Build/Configure
 endef
 
@@ -279,6 +297,7 @@ define Package/ddns-scripts-services/install
        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
 endef
 
 
@@ -491,6 +510,25 @@ 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
+
+
 $(eval $(call BuildPackage,ddns-scripts))
 $(eval $(call BuildPackage,ddns-scripts-services))
 $(eval $(call BuildPackage,ddns-scripts-cloudflare))
@@ -504,3 +542,4 @@ $(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))
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 (file)
index 0000000..fe46987
--- /dev/null
@@ -0,0 +1,134 @@
+#!/bin/sh
+#
+# 2021 Martijn Atema <martijn@atema.one>
+#
+# This script sends ddns updates using the TransIP API (see https://api.transip.nl/)
+# and is parsed by dynamic_dns_functions.sh inside send_update().
+#
+# The following options provided by ddns are used:
+# username  - Username of account used for logging in to TransIP
+# password  - Private key generated at https://www.transip.nl/cp/account/api/
+#            (make sure to accept non-whitelisted IP addresses)
+# domain    - Base domain name registered at TransIP
+#             ('domain.tld' when updating 'hostname.domain.tld')
+# param_enc - Name of DNS record to update
+#             ('hostname' when updating 'hostname.domain.tld')
+# param_opt - TTL of the DNS record to update (in seconds)
+#
+# Note: Make sure that there is exactly one record of type A (for IPv4) or
+#       AAAA (for IPv6) with the specified name and TTL. That record will be
+#       updated by this script.
+#
+# The script requires cURL with SSL and the openssl binary
+
+
+[ -z "${username}" ] && write_log 14 "Service config is missing 'username'"
+[ -z "${password}" ] && write_log 14 "Service config is missing 'password' (private key)"
+[ -z "${domain}" ] && write_log 14 "Service config is missing 'domain' (base domain name)"
+[ -z "${param_enc}" ] && write_log 14 "Service config is missing 'param_enc' (DNS record name)"
+[ -z "${param_opt}" ] && write_log 14 "Service config is missing 'param_opt' (DNS record TTL)"
+
+[ -z "${CURL_SSL}" ] && write_log 14 "TransIP update requires cURL with SSL"
+[ -z "$(openssl version)" ] && write_log 14 "TransIP update requires openssl binary"
+
+. /usr/share/libubox/jshn.sh
+
+
+# Re-format the private key and write to a temporary file
+
+__tmp_keyfile="$(mktemp -t ddns-transip.XXXXXX)"
+
+echo "${password}" | \
+        sed -e "s/-----BEGIN PRIVATE KEY-----\s*/&\n/" \
+        -e "s/-----END PRIVATE KEY-----/\n&/" \
+        -e "s/\S\{64\}\s*/&\n/g" \
+        > "${__tmp_keyfile}"
+
+
+# Create authentication request
+
+json_init
+json_add_string "login" "${username}"
+json_add_string "label" "DDNS-script ($(openssl rand -hex 4))"
+json_add_string "nonce" $(openssl rand -hex 16)
+json_add_boolean "read_only" 0
+json_add_boolean "global_key" 1
+__auth_body="$(json_dump)"
+
+
+# Sign body using the private key and encode with base64
+
+__auth_signature=$(echo -n "${__auth_body}" | \
+        openssl dgst -sha512 -sign "${__tmp_keyfile}" | \
+        openssl base64 | \
+        tr -d " \t\n\r")
+
+rm "${__tmp_keyfile}"
+
+
+# Send and parse request for a temporary authentication token
+
+__auth_status=$(curl -s -X POST "https://api.transip.nl/v6/auth" \
+        -H "Content-Type: application/json" \
+        -H "Signature: ${__auth_signature}" \
+        -d "${__auth_body}" \
+        -w "%{http_code}\n" \
+        -o "${DATFILE}" 2>"${ERRFILE}")
+
+
+# Logging for error and debug
+
+if [ $? -ne 0 ]; then
+        write_log 14 "Curl failed: $(cat "${ERRFILE}")"
+        return 1
+fi
+
+if [ -z ${__auth_status} ] || [ ${__auth_status} -ne 201 ]; then
+        write_log 14 "TransIP authentication (status ${__auth_status}) failed: $(cat ${DATFILE})"
+        return 1
+fi
+
+write_log 7 "TransIP authentication successful"
+
+
+## Extract token from the response
+
+__auth_token=$(cat ${DATFILE} | sed 's/^.*"token" *: *"\([^"]*\)".*$/\1/')
+
+
+# Create request body for update
+
+json_init
+json_add_object "dnsEntry"
+json_add_string "name" "${param_enc}"
+json_add_string "type" "$([ $use_ipv6 -ne 0 ] && echo -n AAAA || echo -n A)"
+json_add_int "expire" "${param_opt}"
+json_add_string "content" "${__IP}"
+json_close_object
+__update_body="$(json_dump)"
+
+
+# Send update request
+
+__update_status=$(curl -s -X PATCH "https://api.transip.nl/v6/domains/${domain}/dns" \
+        -H "Content-Type: application/json" \
+        -H "Authorization: Bearer ${__auth_token}" \
+        -d "${__update_body}" \
+        -w "%{http_code}\n" \
+        -o "${DATFILE}" 2>"${ERRFILE}")
+
+
+# Logging for error and debug
+
+if [ $? -ne 0 ]; then
+        write_log 14 "Curl failed: $(cat "${ERRFILE}")"
+        return 1
+fi
+
+if [ -z ${__update_status} ] || [ ${__update_status} -ne 204 ]; then
+        write_log 14 "TransIP DNS update (status ${__update_status}) failed: $(cat ${DATFILE})"
+        return 1
+fi
+
+write_log 7 "TransIP DNS update successful"
+return 0
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 (file)
index 0000000..1dabb4f
--- /dev/null
@@ -0,0 +1,9 @@
+{
+       "name": "transip.nl",
+       "ipv4": {
+               "url": "update_transip_nl.sh"
+       },
+       "ipv6": {
+               "url": "update_transip_nl.sh"
+       }
+}
index 55c61f2bc93be3ac22a70e21f315021129ef5baf..cae99b043b059e0564e028052e04300f7b469a01 100644 (file)
@@ -62,6 +62,7 @@ spdyn.de
 strato.com
 system-ns.com
 thatip.com
+transip.nl
 twodns.de
 udmedia.de
 variomedia.de
git clone https://git.99rst.org/PROJECT