diff --git a/README.md b/README.md index 9e64e61..eb12291 100644 --- a/README.md +++ b/README.md @@ -340,6 +340,7 @@ You don't have to do anything manually! 1. Yandex PDD API (https://pdd.yandex.ru) 1. Hurricane Electric DNS service (https://dns.he.net) 1. UnoEuro API (https://www.unoeuro.com/) +1. INWX (https://www.inwx.de/) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 8a486ae..c16e759 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -618,6 +618,23 @@ acme.sh --issue --dns dns_unoeuro -d example.com -d www.example.com The `UNO_Key` and `UNO_User` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 33. Use INWX + +[INWX](https://www.inwx.de/) offers an [xmlrpc api](https://www.inwx.de/de/help/apidoc) with your standard login credentials, set them like so: + +``` +export INWX_User="yourusername" +export INWX_Password="password" +``` + +Then you can issue your certificates with: + +``` +acme.sh --issue --dns dns_inwx -d example.com -d www.example.com +``` + +The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh new file mode 100755 index 0000000..74440bd --- /dev/null +++ b/dnsapi/dns_inwx.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env sh + +# +#INWX_User="username" +# +#INWX_Password="password" + +INWX_Api="https://api.domrobot.com/xmlrpc/" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_inwx_add() { + fulldomain=$1 + txtvalue=$2 + + INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}" + INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}" + if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then + INWX_User="" + INWX_Password="" + _err "You don't specify inwx user and password yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable INWX_User "$INWX_User" + _saveaccountconf_mutable INWX_Password "$INWX_Password" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug "Getting txt records" + + xml_content=$(printf ' + + nameserver.info + + + + + + domain + + %s + + + + type + + TXT + + + + name + + %s + + + + + + + ' "$_domain" "$_sub_domain") + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then + _err "Error could net get txt records" + return 1 + fi + + if ! printf "%s" "$response" | grep "count" >/dev/null; then + _info "Adding record" + _inwx_add_record "$_domain" "$_sub_domain" "$txtvalue" + else + _record_id=$(printf '%s' "$response" | _egrep_o '.*(record){1}(.*)([0-9]+){1}' | _egrep_o 'id<\/name>[0-9]+' | _egrep_o '[0-9]+') + _info "Updating record" + _inwx_update_record "$_record_id" "$txtvalue" + fi + +} + +#fulldomain txtvalue +dns_inwx_rm() { + + fulldomain=$1 + txtvalue=$2 + + INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}" + INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}" + if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then + INWX_User="" + INWX_Password="" + _err "You don't specify inwx user and password yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable INWX_User "$INWX_User" + _saveaccountconf_mutable INWX_Password "$INWX_Password" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + + xml_content=$(printf ' + + nameserver.info + + + + + + domain + + %s + + + + type + + TXT + + + + name + + %s + + + + + + + ' "$_domain" "$_sub_domain") + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then + _err "Error could not get txt records" + return 1 + fi + + if ! printf "%s" "$response" | grep "count" >/dev/null; then + _info "Do not need to delete record" + else + _record_id=$(printf '%s' "$response" | _egrep_o '.*(record){1}(.*)([0-9]+){1}' | _egrep_o 'id<\/name>[0-9]+' | _egrep_o '[0-9]+') + _info "Deleting record" + _inwx_delete_record "$_record_id" + fi + +} + +#################### Private functions below ################################## + +_inwx_login() { + + xml_content=$(printf ' + + account.login + + + + + + user + + %s + + + + pass + + %s + + + + + + + ' $INWX_User $INWX_Password) + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')" + +} + +_get_root() { + domain=$1 + _debug "get root" + + domain=$1 + i=2 + p=1 + + _H1=$(_inwx_login) + export _H1 + xml_content=' + + nameserver.list + ' + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "$h"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 + +} + +_inwx_delete_record() { + record_id=$1 + xml_content=$(printf ' + + nameserver.deleteRecord + + + + + + id + + %s + + + + + + + ' "$record_id") + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then + _err "Error" + return 1 + fi + return 0 + +} + +_inwx_update_record() { + record_id=$1 + txtval=$2 + xml_content=$(printf ' + + nameserver.updateRecord + + + + + + content + + %s + + + + id + + %s + + + + + + + ' "$txtval" "$record_id") + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then + _err "Error" + return 1 + fi + return 0 + +} + +_inwx_add_record() { + + domain=$1 + sub_domain=$2 + txtval=$3 + + xml_content=$(printf ' + + nameserver.createRecord + + + + + + domain + + %s + + + + type + + TXT + + + + content + + %s + + + + name + + %s + + + + + + + ' "$domain" "$txtval" "$sub_domain") + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then + _err "Error" + return 1 + fi + return 0 +}