4 # https://www.namecheap.com/support/api/intro.aspx
6 # Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable
7 # 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.
9 ######## Public functions #####################
11 if [ "$STAGE" -eq 1 ]; then
12 NAMECHEAP_API
="https://api.sandbox.namecheap.com/xml.response"
14 NAMECHEAP_API
="https://api.namecheap.com/xml.response"
17 #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
22 if ! _namecheap_check_config
; then
27 if ! _namecheap_set_publicip
; then
31 _debug
"First detect the root zone"
32 if ! _get_root
"$fulldomain"; then
37 _debug fulldomain
"$fulldomain"
38 _debug txtvalue
"$txtvalue"
39 _debug domain
"$_domain"
40 _debug sub_domain
"$_sub_domain"
42 _set_namecheap_TXT
"$_domain" "$_sub_domain" "$txtvalue"
45 #Usage: fulldomain txtvalue
46 #Remove the txt record after validation.
51 if ! _namecheap_set_publicip
; then
55 if ! _namecheap_check_config
; then
60 _debug
"First detect the root zone"
61 if ! _get_root
"$fulldomain"; then
66 _debug fulldomain
"$fulldomain"
67 _debug txtvalue
"$txtvalue"
68 _debug domain
"$_domain"
69 _debug sub_domain
"$_sub_domain"
71 _del_namecheap_TXT
"$_domain" "$_sub_domain" "$txtvalue"
75 #################### Private functions below ##################################
76 #_acme-challenge.www.domain.com
78 # _sub_domain=_acme-challenge.www
83 if ! _namecheap_post
"namecheap.domains.getList"; then
93 h
=$
(printf "%s" "$domain" | cut
-d .
-f $i-100)
100 if ! _contains
"$response" "$h"; then
101 _debug
"$h not found"
103 _sub_domain
=$
(printf "%s" "$domain" | cut
-d .
-f 1-$p)
113 _namecheap_set_publicip
() {
115 if [ -z "$NAMECHEAP_SOURCEIP" ]; then
116 _err
"No Source IP specified for Namecheap API."
117 _err
"Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
120 _saveaccountconf NAMECHEAP_SOURCEIP
"$NAMECHEAP_SOURCEIP"
121 _debug sourceip
"$NAMECHEAP_SOURCEIP"
123 ip
=$
(echo "$NAMECHEAP_SOURCEIP" | _egrep_o
'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
124 addr
=$
(echo "$NAMECHEAP_SOURCEIP" | _egrep_o
'(http|https)://.*')
129 if [ -n "$ip" ]; then
131 elif [ -n "$addr" ]; then
132 _publicip
=$
(_get
"$addr")
134 _err
"No Source IP specified for Namecheap API."
135 _err
"Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
140 _debug publicip
"$_publicip"
147 data
="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
149 response
="$(_post "$data" "$NAMECHEAP_API" "" "POST
")"
150 _debug2 response
"$response"
152 if _contains
"$response" "Status=\"ERROR\"" >/dev
/null
; then
153 error
=$
(echo "$response" | _egrep_o
">.*<\\/Error>" | cut
-d '<' -f 1 |
tr -d '>')
162 _namecheap_parse_host
() {
164 _debug _host
"$_host"
166 _hostid
=$
(echo "$_host" | _egrep_o
'\sHostId="[^"]*' | cut
-d '"' -f 2)
167 _hostname
=$
(echo "$_host" | _egrep_o
'\sName="[^"]*' | cut
-d '"' -f 2)
168 _hosttype
=$
(echo "$_host" | _egrep_o
'\sType="[^"]*' | cut
-d '"' -f 2)
169 _hostaddress
=$
(echo "$_host" | _egrep_o
'\sAddress="[^"]*' | cut
-d '"' -f 2)
170 _hostmxpref
=$
(echo "$_host" | _egrep_o
'\sMXPref="[^"]*' | cut
-d '"' -f 2)
171 _hostttl
=$
(echo "$_host" | _egrep_o
'\sTTL="[^"]*' | cut
-d '"' -f 2)
173 _debug hostid
"$_hostid"
174 _debug hostname
"$_hostname"
175 _debug hosttype
"$_hosttype"
176 _debug hostaddress
"$_hostaddress"
177 _debug hostmxpref
"$_hostmxpref"
178 _debug hostttl
"$_hostttl"
182 _namecheap_check_config
() {
184 if [ -z "$NAMECHEAP_API_KEY" ]; then
185 _err
"No API key specified for Namecheap API."
186 _err
"Create your key and export it as NAMECHEAP_API_KEY"
190 if [ -z "$NAMECHEAP_USERNAME" ]; then
191 _err
"No username key specified for Namecheap API."
192 _err
"Create your key and export it as NAMECHEAP_USERNAME"
196 _saveaccountconf NAMECHEAP_API_KEY
"$NAMECHEAP_API_KEY"
197 _saveaccountconf NAMECHEAP_USERNAME
"$NAMECHEAP_USERNAME"
202 _set_namecheap_TXT
() {
205 tld
=$
(echo "$1" | cut
-d '.' -f 2)
206 sld
=$
(echo "$1" | cut
-d '.' -f 1)
207 request
="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
209 if ! _namecheap_post
"$request"; then
214 hosts
=$
(echo "$response" | _egrep_o
'<host[^>]*')
215 _debug hosts
"$hosts"
217 if [ -z "$hosts" ]; then
218 _error
"Hosts not found"
222 _namecheap_reset_hostList
224 while read -r host; do
225 if _contains
"$host" "<host"; then
226 _namecheap_parse_host
"$host"
227 _namecheap_add_host
"$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
233 _namecheap_add_host
"$subdomain" "TXT" "$txt" 10 120
235 _debug hostrequestfinal
"$_hostrequest"
237 request
="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
239 if ! _namecheap_post
"$request"; then
247 _del_namecheap_TXT
() {
250 tld
=$
(echo "$1" | cut
-d '.' -f 2)
251 sld
=$
(echo "$1" | cut
-d '.' -f 1)
252 request
="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
254 if ! _namecheap_post
"$request"; then
259 hosts
=$
(echo "$response" | _egrep_o
'<host[^>]*')
260 _debug hosts
"$hosts"
262 if [ -z "$hosts" ]; then
263 _error
"Hosts not found"
267 _namecheap_reset_hostList
271 while read -r host; do
272 if _contains
"$host" "<host"; then
273 _namecheap_parse_host
"$host"
274 if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then
275 _debug
"TXT entry found"
278 _namecheap_add_host
"$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
285 if [ $found -eq 0 ]; then
286 _debug
"TXT entry not found"
290 _debug hostrequestfinal
"$_hostrequest"
292 request
="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
294 if ! _namecheap_post
"$request"; then
302 _namecheap_reset_hostList
() {
307 #Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
308 _namecheap_add_host
() {
309 _hostindex
=$
(_math
"$_hostindex" + 1)
310 _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")