You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.2 KiB

  1. #!/bin/sh
  2. #
  3. # 2021 Martijn Atema <martijn@atema.one>
  4. #
  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().
  7. #
  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)
  17. #
  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.
  21. #
  22. # The script requires cURL with SSL and the openssl binary
  23. [ -z "${username}" ] && write_log 14 "Service config is missing 'username'"
  24. [ -z "${password}" ] && write_log 14 "Service config is missing 'password' (private key)"
  25. [ -z "${domain}" ] && write_log 14 "Service config is missing 'domain' (base domain name)"
  26. [ -z "${param_enc}" ] && write_log 14 "Service config is missing 'param_enc' (DNS record name)"
  27. [ -z "${param_opt}" ] && write_log 14 "Service config is missing 'param_opt' (DNS record TTL)"
  28. [ -z "${CURL_SSL}" ] && write_log 14 "TransIP update requires cURL with SSL"
  29. [ -z "$(openssl version)" ] && write_log 14 "TransIP update requires openssl binary"
  30. . /usr/share/libubox/jshn.sh
  31. # Re-format the private key and write to a temporary file
  32. __tmp_keyfile="$(mktemp -t ddns-transip.XXXXXX)"
  33. echo "${password}" | \
  34. sed -e "s/-----BEGIN PRIVATE KEY-----\s*/&\n/" \
  35. -e "s/-----END PRIVATE KEY-----/\n&/" \
  36. -e "s/\S\{64\}\s*/&\n/g" \
  37. > "${__tmp_keyfile}"
  38. # Create authentication request
  39. json_init
  40. json_add_string "login" "${username}"
  41. json_add_string "label" "DDNS-script ($(openssl rand -hex 4))"
  42. json_add_string "nonce" $(openssl rand -hex 16)
  43. json_add_boolean "read_only" 0
  44. json_add_boolean "global_key" 1
  45. __auth_body="$(json_dump)"
  46. # Sign body using the private key and encode with base64
  47. __auth_signature=$(echo -n "${__auth_body}" | \
  48. openssl dgst -sha512 -sign "${__tmp_keyfile}" | \
  49. openssl base64 | \
  50. tr -d " \t\n\r")
  51. rm "${__tmp_keyfile}"
  52. # Send and parse request for a temporary authentication token
  53. __auth_status=$(curl -s -X POST "https://api.transip.nl/v6/auth" \
  54. -H "Content-Type: application/json" \
  55. -H "Signature: ${__auth_signature}" \
  56. -d "${__auth_body}" \
  57. -w "%{http_code}\n" \
  58. -o "${DATFILE}" 2>"${ERRFILE}")
  59. # Logging for error and debug
  60. if [ $? -ne 0 ]; then
  61. write_log 14 "Curl failed: $(cat "${ERRFILE}")"
  62. return 1
  63. fi
  64. if [ -z ${__auth_status} ] || [ ${__auth_status} -ne 201 ]; then
  65. write_log 14 "TransIP authentication (status ${__auth_status}) failed: $(cat ${DATFILE})"
  66. return 1
  67. fi
  68. write_log 7 "TransIP authentication successful"
  69. ## Extract token from the response
  70. __auth_token=$(cat ${DATFILE} | sed 's/^.*"token" *: *"\([^"]*\)".*$/\1/')
  71. # Create request body for update
  72. json_init
  73. json_add_object "dnsEntry"
  74. json_add_string "name" "${param_enc}"
  75. json_add_string "type" "$([ $use_ipv6 -ne 0 ] && echo -n AAAA || echo -n A)"
  76. json_add_int "expire" "${param_opt}"
  77. json_add_string "content" "${__IP}"
  78. json_close_object
  79. __update_body="$(json_dump)"
  80. # Send update request
  81. __update_status=$(curl -s -X PATCH "https://api.transip.nl/v6/domains/${domain}/dns" \
  82. -H "Content-Type: application/json" \
  83. -H "Authorization: Bearer ${__auth_token}" \
  84. -d "${__update_body}" \
  85. -w "%{http_code}\n" \
  86. -o "${DATFILE}" 2>"${ERRFILE}")
  87. # Logging for error and debug
  88. if [ $? -ne 0 ]; then
  89. write_log 14 "Curl failed: $(cat "${ERRFILE}")"
  90. return 1
  91. fi
  92. if [ -z ${__update_status} ] || [ ${__update_status} -ne 204 ]; then
  93. write_log 14 "TransIP DNS update (status ${__update_status}) failed: $(cat ${DATFILE})"
  94. return 1
  95. fi
  96. write_log 7 "TransIP DNS update successful"
  97. return 0