3 # 2021 Martijn Atema <martijn@atema.one>
5 # This script sends ddns updates using the TransIP API (see https://api.transip.nl/)
6 # and is parsed by dynamic_dns_functions.sh inside send_update().
8 # The following options provided by ddns are used:
9 # username - Username of account used for logging in to TransIP
10 # password - Private key generated at https://www.transip.nl/cp/account/api/
11 # (make sure to accept non-whitelisted IP addresses)
12 # domain - Base domain name registered at TransIP
13 # ('domain.tld' when updating 'hostname.domain.tld')
14 # param_enc - Name of DNS record to update
15 # ('hostname' when updating 'hostname.domain.tld')
16 # param_opt - TTL of the DNS record to update (in seconds)
18 # Note: Make sure that there is exactly one record of type A (for IPv4) or
19 # AAAA (for IPv6) with the specified name and TTL. That record will be
20 # updated by this script.
22 # The script requires cURL with SSL and the openssl binary
25 [ -z "${username}" ] && write_log
14 "Service config is missing 'username'"
26 [ -z "${password}" ] && write_log
14 "Service config is missing 'password' (private key)"
27 [ -z "${domain}" ] && write_log
14 "Service config is missing 'domain' (base domain name)"
28 [ -z "${param_enc}" ] && write_log
14 "Service config is missing 'param_enc' (DNS record name)"
29 [ -z "${param_opt}" ] && write_log
14 "Service config is missing 'param_opt' (DNS record TTL)"
31 [ -z "${CURL_SSL}" ] && write_log
14 "TransIP update requires cURL with SSL"
32 [ -z "$(openssl version)" ] && write_log
14 "TransIP update requires openssl binary"
34 .
/usr
/share
/libubox
/jshn.sh
37 # Re-format the private key and write to a temporary file
39 __tmp_keyfile
="$(mktemp -t ddns-transip.XXXXXX)"
41 echo "${password}" | \
42 sed -e "s/-----BEGIN PRIVATE KEY-----\s*/&\n/" \
43 -e "s/-----END PRIVATE KEY-----/\n&/" \
44 -e "s/\S\{64\}\s*/&\n/g" \
48 # Create authentication request
51 json_add_string
"login" "${username}"
52 json_add_string
"label" "DDNS-script ($(openssl rand -hex 4))"
53 json_add_string
"nonce" $
(openssl rand
-hex 16)
54 json_add_boolean
"read_only" 0
55 json_add_boolean
"global_key" 1
56 __auth_body
="$(json_dump)"
59 # Sign body using the private key and encode with base64
61 __auth_signature
=$
(echo -n "${__auth_body}" | \
62 openssl dgst
-sha512 -sign "${__tmp_keyfile}" | \
69 # Send and parse request for a temporary authentication token
71 __auth_status
=$
(curl
-s -X POST
"https://api.transip.nl/v6/auth" \
72 -H "Content-Type: application/json" \
73 -H "Signature: ${__auth_signature}" \
76 -o "${DATFILE}" 2>"${ERRFILE}")
79 # Logging for error and debug
82 write_log
14 "Curl failed: $(cat "${ERRFILE}")"
86 if [ -z ${__auth_status} ] ||
[ ${__auth_status} -ne 201 ]; then
87 write_log
14 "TransIP authentication (status ${__auth_status}) failed: $(cat ${DATFILE})"
91 write_log
7 "TransIP authentication successful"
94 ## Extract token from the response
96 __auth_token
=$
(cat ${DATFILE} |
sed 's/^.*"token" *: *"\([^"]*\)".*$/\1/')
99 # Create request body for update
102 json_add_object
"dnsEntry"
103 json_add_string
"name" "${param_enc}"
104 json_add_string
"type" "$([ $use_ipv6 -ne 0 ] && echo -n AAAA || echo -n A)"
105 json_add_int
"expire" "${param_opt}"
106 json_add_string
"content" "${__IP}"
108 __update_body
="$(json_dump)"
111 # Send update request
113 __update_status
=$
(curl
-s -X PATCH
"https://api.transip.nl/v6/domains/${domain}/dns" \
114 -H "Content-Type: application/json" \
115 -H "Authorization: Bearer ${__auth_token}" \
116 -d "${__update_body}" \
117 -w "%{http_code}\n" \
118 -o "${DATFILE}" 2>"${ERRFILE}")
121 # Logging for error and debug
123 if [ $?
-ne 0 ]; then
124 write_log
14 "Curl failed: $(cat "${ERRFILE}")"
128 if [ -z ${__update_status} ] ||
[ ${__update_status} -ne 204 ]; then
129 write_log
14 "TransIP DNS update (status ${__update_status}) failed: $(cat ${DATFILE})"
133 write_log
7 "TransIP DNS update successful"