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.

356 lines
8.1 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. #!/usr/bin/env sh
  2. # Namecheap API
  3. # https://www.namecheap.com/support/api/intro.aspx
  4. #
  5. # Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable
  6. # 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.
  7. ######## Public functions #####################
  8. if [ "$STAGE" -eq 1 ]; then
  9. NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response"
  10. else
  11. NAMECHEAP_API="https://api.namecheap.com/xml.response"
  12. fi
  13. #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  14. dns_namecheap_add() {
  15. fulldomain=$1
  16. txtvalue=$2
  17. if ! _namecheap_check_config; then
  18. _err "$error"
  19. return 1
  20. fi
  21. if ! _namecheap_set_publicip; then
  22. return 1
  23. fi
  24. _debug "First detect the root zone"
  25. if ! _get_root "$fulldomain"; then
  26. _err "invalid domain"
  27. return 1
  28. fi
  29. _debug fulldomain "$fulldomain"
  30. _debug txtvalue "$txtvalue"
  31. _debug domain "$_domain"
  32. _debug sub_domain "$_sub_domain"
  33. _set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  34. }
  35. #Usage: fulldomain txtvalue
  36. #Remove the txt record after validation.
  37. dns_namecheap_rm() {
  38. fulldomain=$1
  39. txtvalue=$2
  40. if ! _namecheap_set_publicip; then
  41. return 1
  42. fi
  43. if ! _namecheap_check_config; then
  44. _err "$error"
  45. return 1
  46. fi
  47. _debug "First detect the root zone"
  48. if ! _get_root "$fulldomain"; then
  49. _err "invalid domain"
  50. return 1
  51. fi
  52. _debug fulldomain "$fulldomain"
  53. _debug txtvalue "$txtvalue"
  54. _debug domain "$_domain"
  55. _debug sub_domain "$_sub_domain"
  56. _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  57. }
  58. #################### Private functions below ##################################
  59. #_acme-challenge.www.domain.com
  60. #returns
  61. # _sub_domain=_acme-challenge.www
  62. # _domain=domain.com
  63. _get_root() {
  64. domain=$1
  65. if ! _namecheap_post "namecheap.domains.getList"; then
  66. _err "$error"
  67. return 1
  68. fi
  69. i=2
  70. p=1
  71. while true; do
  72. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  73. _debug h "$h"
  74. if [ -z "$h" ]; then
  75. #not valid
  76. return 1
  77. fi
  78. if ! _contains "$response" "$h"; then
  79. _debug "$h not found"
  80. else
  81. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  82. _domain="$h"
  83. return 0
  84. fi
  85. p="$i"
  86. i=$(_math "$i" + 1)
  87. done
  88. return 1
  89. }
  90. _namecheap_set_publicip() {
  91. if [ -z "$NAMECHEAP_SOURCEIP" ]; then
  92. _err "No Source IP specified for Namecheap API."
  93. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  94. return 1
  95. else
  96. _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
  97. _debug sourceip "$NAMECHEAP_SOURCEIP"
  98. ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
  99. addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
  100. _debug2 ip "$ip"
  101. _debug2 addr "$addr"
  102. if [ -n "$ip" ]; then
  103. _publicip="$ip"
  104. elif [ -n "$addr" ]; then
  105. _publicip=$(_get "$addr")
  106. else
  107. _err "No Source IP specified for Namecheap API."
  108. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  109. return 1
  110. fi
  111. fi
  112. _debug publicip "$_publicip"
  113. return 0
  114. }
  115. _namecheap_post() {
  116. command=$1
  117. data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
  118. response="$(_post "$data" "$NAMECHEAP_API" "" "POST")"
  119. _debug2 response "$response"
  120. if _contains "$response" "Status=\"ERROR\"" >/dev/null; then
  121. error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>')
  122. _err "error $error"
  123. return 1
  124. fi
  125. return 0
  126. }
  127. _namecheap_parse_host() {
  128. _host=$1
  129. _debug _host "$_host"
  130. _hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2)
  131. _hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2)
  132. _hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2)
  133. _hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2)
  134. _hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2)
  135. _hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
  136. _debug hostid "$_hostid"
  137. _debug hostname "$_hostname"
  138. _debug hosttype "$_hosttype"
  139. _debug hostaddress "$_hostaddress"
  140. _debug hostmxpref "$_hostmxpref"
  141. _debug hostttl "$_hostttl"
  142. }
  143. _namecheap_check_config() {
  144. if [ -z "$NAMECHEAP_API_KEY" ]; then
  145. _err "No API key specified for Namecheap API."
  146. _err "Create your key and export it as NAMECHEAP_API_KEY"
  147. return 1
  148. fi
  149. if [ -z "$NAMECHEAP_USERNAME" ]; then
  150. _err "No username key specified for Namecheap API."
  151. _err "Create your key and export it as NAMECHEAP_USERNAME"
  152. return 1
  153. fi
  154. _saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
  155. _saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
  156. return 0
  157. }
  158. _set_namecheap_TXT() {
  159. subdomain=$2
  160. txt=$3
  161. if ! _namecheap_set_tld_sld "$1"; then
  162. return 1
  163. fi
  164. request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
  165. if ! _namecheap_post "$request"; then
  166. _err "$error"
  167. return 1
  168. fi
  169. hosts=$(echo "$response" | _egrep_o '<host[^>]*')
  170. _debug hosts "$hosts"
  171. if [ -z "$hosts" ]; then
  172. _error "Hosts not found"
  173. return 1
  174. fi
  175. _namecheap_reset_hostList
  176. while read -r host; do
  177. if _contains "$host" "<host"; then
  178. _namecheap_parse_host "$host"
  179. _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
  180. fi
  181. done <<EOT
  182. echo "$hosts"
  183. EOT
  184. _namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
  185. _debug hostrequestfinal "$_hostrequest"
  186. request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
  187. if ! _namecheap_post "$request"; then
  188. _err "$error"
  189. return 1
  190. fi
  191. return 0
  192. }
  193. _del_namecheap_TXT() {
  194. subdomain=$2
  195. txt=$3
  196. if ! _namecheap_set_tld_sld "$1"; then
  197. return 1
  198. fi
  199. request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
  200. if ! _namecheap_post "$request"; then
  201. _err "$error"
  202. return 1
  203. fi
  204. hosts=$(echo "$response" | _egrep_o '<host[^>]*')
  205. _debug hosts "$hosts"
  206. if [ -z "$hosts" ]; then
  207. _error "Hosts not found"
  208. return 1
  209. fi
  210. _namecheap_reset_hostList
  211. found=0
  212. while read -r host; do
  213. if _contains "$host" "<host"; then
  214. _namecheap_parse_host "$host"
  215. if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then
  216. _debug "TXT entry found"
  217. found=1
  218. else
  219. _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
  220. fi
  221. fi
  222. done <<EOT
  223. echo "$hosts"
  224. EOT
  225. if [ $found -eq 0 ]; then
  226. _debug "TXT entry not found"
  227. return 0
  228. fi
  229. _debug hostrequestfinal "$_hostrequest"
  230. request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
  231. if ! _namecheap_post "$request"; then
  232. _err "$error"
  233. return 1
  234. fi
  235. return 0
  236. }
  237. _namecheap_reset_hostList() {
  238. _hostindex=0
  239. _hostrequest=""
  240. }
  241. #Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
  242. _namecheap_add_host() {
  243. _hostindex=$(_math "$_hostindex" + 1)
  244. _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")
  245. }
  246. _namecheap_set_tld_sld() {
  247. domain=$1
  248. _tld=""
  249. _sld=""
  250. i=2
  251. while true; do
  252. _tld=$(printf "%s" "$domain" | cut -d . -f $i-100)
  253. _debug tld "$_tld"
  254. if [ -z "$_tld" ]; then
  255. _debug "invalid tld"
  256. return 1
  257. fi
  258. j=$(_math "$i" - 1)
  259. _sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j")
  260. _debug sld "$_sld"
  261. if [ -z "$_sld" ]; then
  262. _debug "invalid sld"
  263. return 1
  264. fi
  265. request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld"
  266. if ! _namecheap_post "$request"; then
  267. _debug "sld($_sld)/tld($_tld) not found"
  268. else
  269. _debug "sld($_sld)/tld($_tld) found"
  270. return 0
  271. fi
  272. i=$(_math "$i" + 1)
  273. done
  274. }