From aa820a2cae321311097e59de9b67dfa5c648cbeb Mon Sep 17 00:00:00 2001 From: Martijn Atema Date: Mon, 15 Nov 2021 00:45:54 +0100 Subject: [PATCH] ddns-scripts: Add script for TransIP.nl Signed-off-by: Martijn Atema Signed-off-by: Florian Eckert - PKG_RELEASE number updated --- net/ddns-scripts/Makefile | 41 +++++- .../files/usr/lib/ddns/update_transip_nl.sh | 134 ++++++++++++++++++ .../usr/share/ddns/default/transip.nl.json | 9 ++ net/ddns-scripts/files/usr/share/ddns/list | 1 + 4 files changed, 184 insertions(+), 1 deletion(-) 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/transip.nl.json diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile index 03073a0a8..17430a807 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:=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 index 000000000..fe46987f7 --- /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/transip.nl.json b/net/ddns-scripts/files/usr/share/ddns/default/transip.nl.json new file mode 100644 index 000000000..1dabb4f6e --- /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/list b/net/ddns-scripts/files/usr/share/ddns/list index 55c61f2bc..cae99b043 100644 --- a/net/ddns-scripts/files/usr/share/ddns/list +++ b/net/ddns-scripts/files/usr/share/ddns/list @@ -62,6 +62,7 @@ spdyn.de strato.com system-ns.com thatip.com +transip.nl twodns.de udmedia.de variomedia.de