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.
|
|
#!/usr/bin/env sh
# Namecheap API # https://www.namecheap.com/support/api/intro.aspx # # Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable # Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise.
######## Public functions #####################
if [ "$STAGE" -eq 1 ]; then NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response" else NAMECHEAP_API="https://api.namecheap.com/xml.response" fi
#Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_namecheap_add() { fulldomain=$1 txtvalue=$2
if ! _namecheap_check_config; then _err "$error" return 1 fi
if ! _namecheap_set_publicip; then return 1 fi
_debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi
_debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _debug domain "$_domain" _debug sub_domain "$_sub_domain"
_set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue" }
#Usage: fulldomain txtvalue #Remove the txt record after validation. dns_namecheap_rm() { fulldomain=$1 txtvalue=$2
if ! _namecheap_set_publicip; then return 1 fi
if ! _namecheap_check_config; then _err "$error" return 1 fi
_debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 fi
_debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _debug domain "$_domain" _debug sub_domain "$_sub_domain"
_del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue" }
#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www # _domain=domain.com _get_root() { domain=$1
if ! _namecheap_post "namecheap.domains.getList"; then _err "$error" return 1 fi
i=2 p=1
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 _debug "$h not found" else _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" return 0 fi p="$i" i=$(_math "$i" + 1) done return 1 }
_namecheap_set_publicip() {
if [ -z "$NAMECHEAP_SOURCEIP" ]; then _err "No Source IP specified for Namecheap API." _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 else _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" _debug sourceip "$NAMECHEAP_SOURCEIP"
ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
_debug2 ip "$ip" _debug2 addr "$addr"
if [ -n "$ip" ]; then _publicip="$ip" elif [ -n "$addr" ]; then _publicip=$(_get "$addr") else _err "No Source IP specified for Namecheap API." _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 fi fi
_debug publicip "$_publicip"
return 0 }
_namecheap_post() { command=$1 data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
response="$(_post "$data" "$NAMECHEAP_API" "" "POST")" _debug2 response "$response"
if _contains "$response" "Status=\"ERROR\"" >/dev/null; then error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>') _err "error $error" return 1 fi
return 0 }
_namecheap_parse_host() { _host=$1 _debug _host "$_host"
_hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2) _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2) _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2) _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2) _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2) _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
_debug hostid "$_hostid" _debug hostname "$_hostname" _debug hosttype "$_hosttype" _debug hostaddress "$_hostaddress" _debug hostmxpref "$_hostmxpref" _debug hostttl "$_hostttl" }
_namecheap_check_config() {
if [ -z "$NAMECHEAP_API_KEY" ]; then _err "No API key specified for Namecheap API." _err "Create your key and export it as NAMECHEAP_API_KEY" return 1 fi
if [ -z "$NAMECHEAP_USERNAME" ]; then _err "No username key specified for Namecheap API." _err "Create your key and export it as NAMECHEAP_USERNAME" return 1 fi
_saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY" _saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
return 0 }
_set_namecheap_TXT() { subdomain=$2 txt=$3
if ! _namecheap_set_tld_sld "$1"; then return 1 fi
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
if ! _namecheap_post "$request"; then _err "$error" return 1 fi
hosts=$(echo "$response" | _egrep_o '<host[^>]*') _debug hosts "$hosts"
if [ -z "$hosts" ]; then _error "Hosts not found" return 1 fi
_namecheap_reset_hostList
while read -r host; do if _contains "$host" "<host"; then _namecheap_parse_host "$host" _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl" fi done <<EOT echo "$hosts" EOT
_namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
_debug hostrequestfinal "$_hostrequest"
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
if ! _namecheap_post "$request"; then _err "$error" return 1 fi
return 0 }
_del_namecheap_TXT() { subdomain=$2 txt=$3
if ! _namecheap_set_tld_sld "$1"; then return 1 fi
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
if ! _namecheap_post "$request"; then _err "$error" return 1 fi
hosts=$(echo "$response" | _egrep_o '<host[^>]*') _debug hosts "$hosts"
if [ -z "$hosts" ]; then _error "Hosts not found" return 1 fi
_namecheap_reset_hostList
found=0
while read -r host; do if _contains "$host" "<host"; then _namecheap_parse_host "$host" if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then _debug "TXT entry found" found=1 else _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl" fi fi done <<EOT echo "$hosts" EOT
if [ $found -eq 0 ]; then _debug "TXT entry not found" return 0 fi
_debug hostrequestfinal "$_hostrequest"
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
if ! _namecheap_post "$request"; then _err "$error" return 1 fi
return 0 }
_namecheap_reset_hostList() { _hostindex=0 _hostrequest="" }
#Usage: _namecheap_add_host HostName RecordType Address MxPref TTL _namecheap_add_host() { _hostindex=$(_math "$_hostindex" + 1) _hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5") }
_namecheap_set_tld_sld() { domain=$1 _tld="" _sld=""
i=2
while true; do
_tld=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug tld "$_tld"
if [ -z "$_tld" ]; then _debug "invalid tld" return 1 fi
j=$(_math "$i" - 1)
_sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j") _debug sld "$_sld"
if [ -z "$_sld" ]; then _debug "invalid sld" return 1 fi
request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld"
if ! _namecheap_post "$request"; then _debug "sld($_sld)/tld($_tld) not found" else _debug "sld($_sld)/tld($_tld) found" return 0 fi
i=$(_math "$i" + 1)
done
}
|