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.

362 lines
8.4 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
  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
  6. #NAMECHEAP_API_KEY,
  7. #NAMECHEAP_USERNAME,
  8. #NAMECHEAP_SOURCEIP
  9. # 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.
  10. ######## Public functions #####################
  11. NAMECHEAP_API="https://api.namecheap.com/xml.response"
  12. #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  13. dns_namecheap_add() {
  14. fulldomain=$1
  15. txtvalue=$2
  16. if ! _namecheap_check_config; then
  17. _err "$error"
  18. return 1
  19. fi
  20. if ! _namecheap_set_publicip; then
  21. return 1
  22. fi
  23. _debug "First detect the root zone"
  24. if ! _get_root "$fulldomain"; then
  25. _err "invalid domain"
  26. return 1
  27. fi
  28. _debug fulldomain "$fulldomain"
  29. _debug txtvalue "$txtvalue"
  30. _debug domain "$_domain"
  31. _debug sub_domain "$_sub_domain"
  32. _set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  33. }
  34. #Usage: fulldomain txtvalue
  35. #Remove the txt record after validation.
  36. dns_namecheap_rm() {
  37. fulldomain=$1
  38. txtvalue=$2
  39. if ! _namecheap_set_publicip; then
  40. return 1
  41. fi
  42. if ! _namecheap_check_config; then
  43. _err "$error"
  44. return 1
  45. fi
  46. _debug "First detect the root zone"
  47. if ! _get_root "$fulldomain"; then
  48. _err "invalid domain"
  49. return 1
  50. fi
  51. _debug fulldomain "$fulldomain"
  52. _debug txtvalue "$txtvalue"
  53. _debug domain "$_domain"
  54. _debug sub_domain "$_sub_domain"
  55. _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
  56. }
  57. #################### Private functions below ##################################
  58. #_acme-challenge.www.domain.com
  59. #returns
  60. # _sub_domain=_acme-challenge.www
  61. # _domain=domain.com
  62. _get_root() {
  63. domain=$1
  64. if ! _namecheap_post "namecheap.domains.getList"; then
  65. _err "$error"
  66. return 1
  67. fi
  68. i=2
  69. p=1
  70. while true; do
  71. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  72. _debug h "$h"
  73. if [ -z "$h" ]; then
  74. #not valid
  75. return 1
  76. fi
  77. if ! _contains "$response" "$h"; then
  78. _debug "$h not found"
  79. else
  80. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  81. _domain="$h"
  82. return 0
  83. fi
  84. p="$i"
  85. i=$(_math "$i" + 1)
  86. done
  87. return 1
  88. }
  89. _namecheap_set_publicip() {
  90. if [ -z "$NAMECHEAP_SOURCEIP" ]; then
  91. _err "No Source IP specified for Namecheap API."
  92. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  93. return 1
  94. else
  95. _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
  96. _debug sourceip "$NAMECHEAP_SOURCEIP"
  97. ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
  98. addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
  99. _debug2 ip "$ip"
  100. _debug2 addr "$addr"
  101. if [ -n "$ip" ]; then
  102. _publicip="$ip"
  103. elif [ -n "$addr" ]; then
  104. _publicip=$(_get "$addr")
  105. else
  106. _err "No Source IP specified for Namecheap API."
  107. _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
  108. return 1
  109. fi
  110. fi
  111. _debug publicip "$_publicip"
  112. return 0
  113. }
  114. _namecheap_post() {
  115. command=$1
  116. data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
  117. _debug2 "_namecheap_post data" "$data"
  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. _debug2 _hostname "_hostname"
  180. _debug2 _hosttype "_hosttype"
  181. _debug2 _hostaddress "_hostaddress"
  182. _debug2 _hostmxpref "_hostmxpref"
  183. _hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
  184. _debug2 "encoded _hostaddress" "_hostaddress"
  185. _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
  186. fi
  187. done <<EOT
  188. echo "$hosts"
  189. EOT
  190. _namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
  191. _debug hostrequestfinal "$_hostrequest"
  192. request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
  193. if ! _namecheap_post "$request"; then
  194. _err "$error"
  195. return 1
  196. fi
  197. return 0
  198. }
  199. _del_namecheap_TXT() {
  200. subdomain=$2
  201. txt=$3
  202. if ! _namecheap_set_tld_sld "$1"; then
  203. return 1
  204. fi
  205. request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
  206. if ! _namecheap_post "$request"; then
  207. _err "$error"
  208. return 1
  209. fi
  210. hosts=$(echo "$response" | _egrep_o '<host[^>]*')
  211. _debug hosts "$hosts"
  212. if [ -z "$hosts" ]; then
  213. _error "Hosts not found"
  214. return 1
  215. fi
  216. _namecheap_reset_hostList
  217. found=0
  218. while read -r host; do
  219. if _contains "$host" "<host"; then
  220. _namecheap_parse_host "$host"
  221. if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then
  222. _debug "TXT entry found"
  223. found=1
  224. else
  225. _hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
  226. _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
  227. fi
  228. fi
  229. done <<EOT
  230. echo "$hosts"
  231. EOT
  232. if [ $found -eq 0 ]; then
  233. _debug "TXT entry not found"
  234. return 0
  235. fi
  236. _debug hostrequestfinal "$_hostrequest"
  237. request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
  238. if ! _namecheap_post "$request"; then
  239. _err "$error"
  240. return 1
  241. fi
  242. return 0
  243. }
  244. _namecheap_reset_hostList() {
  245. _hostindex=0
  246. _hostrequest=""
  247. }
  248. #Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
  249. _namecheap_add_host() {
  250. _hostindex=$(_math "$_hostindex" + 1)
  251. _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")
  252. }
  253. _namecheap_set_tld_sld() {
  254. domain=$1
  255. _tld=""
  256. _sld=""
  257. i=2
  258. while true; do
  259. _tld=$(printf "%s" "$domain" | cut -d . -f $i-100)
  260. _debug tld "$_tld"
  261. if [ -z "$_tld" ]; then
  262. _debug "invalid tld"
  263. return 1
  264. fi
  265. j=$(_math "$i" - 1)
  266. _sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j")
  267. _debug sld "$_sld"
  268. if [ -z "$_sld" ]; then
  269. _debug "invalid sld"
  270. return 1
  271. fi
  272. request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld"
  273. if ! _namecheap_post "$request"; then
  274. _debug "sld($_sld)/tld($_tld) not found"
  275. else
  276. _debug "sld($_sld)/tld($_tld) found"
  277. return 0
  278. fi
  279. i=$(_math "$i" + 1)
  280. done
  281. }