mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-12-26 13:42:09 +08:00
Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
521d8c4b1f | ||
|
|
4a62385dcc | ||
|
|
98e15f658e | ||
|
|
0a3fa35c5d | ||
|
|
02e095bec2 | ||
|
|
87a8dda955 | ||
|
|
d7c73f590c | ||
|
|
d1b197e339 | ||
|
|
8f5ee989ba | ||
|
|
ce9c227425 | ||
|
|
e32c2b84ee | ||
|
|
ce9f77afed | ||
|
|
2bc38b2063 | ||
|
|
b4f4c28871 | ||
|
|
b14ef537e1 | ||
|
|
84ac386481 | ||
|
|
f0365d32aa | ||
|
|
795764f22f | ||
|
|
986f61ac92 | ||
|
|
09576f2f4f | ||
|
|
bba474dc6b | ||
|
|
fde971fe81 | ||
|
|
882e1db1d6 | ||
|
|
6b0333e919 | ||
|
|
914808b867 | ||
|
|
2d1d512d0f | ||
|
|
37bc099d39 | ||
|
|
f8fb0e67b4 | ||
|
|
86ef6e6987 | ||
|
|
e8fd373e6c | ||
|
|
7efa546665 | ||
|
|
4d2a0697ed | ||
|
|
c6023782a4 | ||
|
|
30283282d2 | ||
|
|
7588fc0989 | ||
|
|
fe843bc466 | ||
|
|
9c88971bc1 | ||
|
|
aad309ee4f | ||
|
|
e80ca4ddbc | ||
|
|
28ccad28c2 | ||
|
|
ba9e7fbf64 | ||
|
|
28c85cf8e7 | ||
|
|
526b5a8d25 | ||
|
|
6b15cf3f72 | ||
|
|
fbd8ab47ea | ||
|
|
46ac97a3ff | ||
|
|
db3264ab8c | ||
|
|
a0923622ae | ||
|
|
aa9975ad0d | ||
|
|
6787c81abe | ||
|
|
72205176e1 | ||
|
|
480742cc15 | ||
|
|
48bdfa2377 | ||
|
|
2ff6f4d3cf | ||
|
|
ae32938531 | ||
|
|
d3da603292 | ||
|
|
912bcf9487 | ||
|
|
668c43abf3 | ||
|
|
43e9553ebc | ||
|
|
e8b54a5087 | ||
|
|
39852662a6 | ||
|
|
6a66ba8a21 | ||
|
|
36a7a84080 | ||
|
|
7e0b334b38 | ||
|
|
5d8d217a13 | ||
|
|
f2aa5c0235 | ||
|
|
323febe8c7 | ||
|
|
32d8f349c9 | ||
|
|
3910495cce | ||
|
|
fe69afdefb | ||
|
|
9082862b9d | ||
|
|
4ae108009c | ||
|
|
a5c1c30368 | ||
|
|
8cd3086be0 | ||
|
|
dd37ae26a5 | ||
|
|
fdaebc7365 | ||
|
|
a8b62261f6 | ||
|
|
47eb913c22 | ||
|
|
6b26d2b62d | ||
|
|
dff4d03bd4 | ||
|
|
28d83d42e2 | ||
|
|
38f1b4d205 | ||
|
|
931d19eece | ||
|
|
88bbe55b85 | ||
|
|
dd17124ec6 | ||
|
|
674b50889e | ||
|
|
263c38caec | ||
|
|
3881f22192 | ||
|
|
664446631f | ||
|
|
c5f1cca3a0 | ||
|
|
a7407097e1 | ||
|
|
14bb60c61f | ||
|
|
749c0e51e6 | ||
|
|
0f120c41f1 | ||
|
|
224e0c298a | ||
|
|
c1f8ffa386 | ||
|
|
9c4f7aa688 | ||
|
|
e75b56073b |
51
README.md
51
README.md
@@ -37,6 +37,8 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|
||||
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
|
||||
- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
|
||||
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
|
||||
- [CentOS Web Panel](http://centos-webpanel.com/)
|
||||
- [lnmp.org](https://lnmp.org/)
|
||||
- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
|
||||
|
||||
# Tested OS
|
||||
@@ -220,22 +222,7 @@ acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
|
||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
|
||||
|
||||
|
||||
# 5. Use Standalone TLS server to issue cert
|
||||
|
||||
**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))**
|
||||
|
||||
acme.sh supports `tls-sni-01` validation.
|
||||
|
||||
Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
|
||||
|
||||
```bash
|
||||
acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
|
||||
```
|
||||
|
||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
|
||||
|
||||
|
||||
# 6. Use Apache mode
|
||||
# 5. Use Apache mode
|
||||
|
||||
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
|
||||
|
||||
@@ -255,7 +242,7 @@ We don't want to mess your apache server, don't worry.**
|
||||
|
||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
|
||||
|
||||
# 7. Use Nginx mode
|
||||
# 6. Use Nginx mode
|
||||
|
||||
**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
|
||||
|
||||
@@ -279,7 +266,7 @@ We don't want to mess your nginx server, don't worry.**
|
||||
|
||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
|
||||
|
||||
# 8. Automatic DNS API integration
|
||||
# 7. Automatic DNS API integration
|
||||
|
||||
If your DNS provider supports API access, we can use that API to automatically issue the certs.
|
||||
|
||||
@@ -328,6 +315,8 @@ You don't have to do anything manually!
|
||||
1. zonomi.com DNS API
|
||||
1. DreamHost.com API
|
||||
1. DirectAdmin API
|
||||
1. KingHost (https://www.kinghost.com.br/)
|
||||
1. Zilore (https://zilore.com)
|
||||
|
||||
|
||||
And:
|
||||
@@ -342,7 +331,9 @@ If your DNS provider is not on the supported list above, you can write your own
|
||||
|
||||
For more details: [How to use DNS API](dnsapi)
|
||||
|
||||
# 9. Use DNS manual mode:
|
||||
# 8. Use DNS manual mode:
|
||||
|
||||
See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first.
|
||||
|
||||
If your dns provider doesn't support any api access, you can add the txt record by your hand.
|
||||
|
||||
@@ -376,7 +367,7 @@ Ok, it's done.
|
||||
|
||||
**Please use dns api mode instead.**
|
||||
|
||||
# 10. Issue ECC certificates
|
||||
# 9. Issue ECC certificates
|
||||
|
||||
`Let's Encrypt` can now issue **ECDSA** certificates.
|
||||
|
||||
@@ -408,17 +399,17 @@ Valid values are:
|
||||
|
||||
|
||||
|
||||
# 11. Issue Wildcard certificates
|
||||
# 10. Issue Wildcard certificates
|
||||
|
||||
It's simple, just give a wildcard domain as the `-d` parameter.
|
||||
|
||||
```sh
|
||||
acme.sh --issue -d example.com -d *.example.com --dns dns_cf
|
||||
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
|
||||
```
|
||||
|
||||
|
||||
|
||||
# 12. How to renew the certs
|
||||
# 11. How to renew the certs
|
||||
|
||||
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
|
||||
|
||||
@@ -435,7 +426,7 @@ acme.sh --renew -d example.com --force --ecc
|
||||
```
|
||||
|
||||
|
||||
# 13. How to stop cert renewal
|
||||
# 12. How to stop cert renewal
|
||||
|
||||
To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
|
||||
|
||||
@@ -448,7 +439,7 @@ The cert/key file is not removed from the disk.
|
||||
You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself.
|
||||
|
||||
|
||||
# 14. How to upgrade `acme.sh`
|
||||
# 13. How to upgrade `acme.sh`
|
||||
|
||||
acme.sh is in constant development, so it's strongly recommended to use the latest code.
|
||||
|
||||
@@ -473,25 +464,25 @@ acme.sh --upgrade --auto-upgrade 0
|
||||
```
|
||||
|
||||
|
||||
# 15. Issue a cert from an existing CSR
|
||||
# 14. Issue a cert from an existing CSR
|
||||
|
||||
https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
|
||||
|
||||
|
||||
# 16. Under the Hood
|
||||
# 15. Under the Hood
|
||||
|
||||
Speak ACME language using shell, directly to "Let's Encrypt".
|
||||
|
||||
TODO:
|
||||
|
||||
|
||||
# 17. Acknowledgments
|
||||
# 16. Acknowledgments
|
||||
|
||||
1. Acme-tiny: https://github.com/diafygi/acme-tiny
|
||||
2. ACME protocol: https://github.com/ietf-wg-acme/acme
|
||||
|
||||
|
||||
# 18. License & Others
|
||||
# 17. License & Others
|
||||
|
||||
License is GPLv3
|
||||
|
||||
@@ -500,7 +491,7 @@ Please Star and Fork me.
|
||||
[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome.
|
||||
|
||||
|
||||
# 19. Donate
|
||||
# 18. Donate
|
||||
Your donation makes **acme.sh** better:
|
||||
|
||||
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
|
||||
|
||||
132
acme.sh
132
acme.sh
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
VER=2.7.7
|
||||
VER=2.7.8
|
||||
|
||||
PROJECT_NAME="acme.sh"
|
||||
|
||||
@@ -47,6 +47,7 @@ DEFAULT_DNS_SLEEP=120
|
||||
NO_VALUE="no"
|
||||
|
||||
W_TLS="tls"
|
||||
W_DNS="dns"
|
||||
DNS_ALIAS_PREFIX="="
|
||||
|
||||
MODE_STATELESS="stateless"
|
||||
@@ -109,10 +110,14 @@ _STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode"
|
||||
|
||||
_DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode"
|
||||
|
||||
_DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode"
|
||||
|
||||
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
|
||||
|
||||
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
|
||||
|
||||
_DNS_MANUAL_ERROR="It seems that you are using dns manual mode. Read this link first: $_DNS_MANUAL_WIKI"
|
||||
|
||||
__INTERACTIVE=""
|
||||
if [ -t 1 ]; then
|
||||
__INTERACTIVE="1"
|
||||
@@ -1616,6 +1621,7 @@ _post() {
|
||||
_debug $httpmethod
|
||||
_debug "_post_url" "$_post_url"
|
||||
_debug2 "body" "$body"
|
||||
_debug2 "_postContentType" "$_postContentType"
|
||||
|
||||
_inithttp
|
||||
|
||||
@@ -1624,14 +1630,19 @@ _post() {
|
||||
if [ "$HTTPS_INSECURE" ]; then
|
||||
_CURL="$_CURL --insecure "
|
||||
fi
|
||||
if [ "$_postContentType" ]; then
|
||||
_CURL="$_CURL -H \"Content-Type: $_postContentType\" "
|
||||
fi
|
||||
_debug "_CURL" "$_CURL"
|
||||
if [ "$needbase64" ]; then
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
|
||||
if [ "$_postContentType" ]; then
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
|
||||
fi
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
|
||||
if [ "$_postContentType" ]; then
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
|
||||
fi
|
||||
fi
|
||||
_ret="$?"
|
||||
if [ "$_ret" != "0" ]; then
|
||||
@@ -1784,19 +1795,25 @@ _send_signed_request() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$ACME_VERSION" = "2" ]; then
|
||||
__request_conent_type="$CONTENT_TYPE_JSON"
|
||||
else
|
||||
__request_conent_type=""
|
||||
fi
|
||||
payload64=$(printf "%s" "$payload" | _base64 | _url_replace)
|
||||
_debug3 payload64 "$payload64"
|
||||
|
||||
MAX_REQUEST_RETRY_TIMES=5
|
||||
_request_retry_times=0
|
||||
while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do
|
||||
_request_retry_times=$(_math "$_request_retry_times" + 1)
|
||||
_debug3 _request_retry_times "$_request_retry_times"
|
||||
if [ -z "$_CACHED_NONCE" ]; then
|
||||
_headers=""
|
||||
if [ "$ACME_NEW_NONCE" ]; then
|
||||
_debug2 "Get nonce. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
|
||||
nonceurl="$ACME_NEW_NONCE"
|
||||
if _post "" "$nonceurl" "" "HEAD" "$CONTENT_TYPE_JSON"; then
|
||||
if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then
|
||||
_headers="$(cat "$HTTP_HEADER")"
|
||||
fi
|
||||
fi
|
||||
@@ -1820,7 +1837,11 @@ _send_signed_request() {
|
||||
fi
|
||||
nonce="$_CACHED_NONCE"
|
||||
_debug2 nonce "$nonce"
|
||||
|
||||
if [ -z "$nonce" ]; then
|
||||
_info "Could not get nonce, let's try again."
|
||||
_sleep 2
|
||||
continue
|
||||
fi
|
||||
if [ "$ACME_VERSION" = "2" ]; then
|
||||
if [ "$url" = "$ACME_NEW_ACCOUNT" ] || [ "$url" = "$ACME_REVOKE_CERT" ]; then
|
||||
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
|
||||
@@ -1851,7 +1872,7 @@ _send_signed_request() {
|
||||
fi
|
||||
_debug3 body "$body"
|
||||
|
||||
response="$(_post "$body" "$url" "$needbase64" "POST" "$CONTENT_TYPE_JSON")"
|
||||
response="$(_post "$body" "$url" "$needbase64" "POST" "$__request_conent_type")"
|
||||
_CACHED_NONCE=""
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
@@ -1878,7 +1899,6 @@ _send_signed_request() {
|
||||
|
||||
if _contains "$_body" "JWS has invalid anti-replay nonce"; then
|
||||
_info "It seems the CA server is busy now, let's wait and retry."
|
||||
_request_retry_times=$(_math "$_request_retry_times" + 1)
|
||||
_sleep 5
|
||||
continue
|
||||
fi
|
||||
@@ -2341,7 +2361,7 @@ _initpath() {
|
||||
fi
|
||||
fi
|
||||
|
||||
_debug2 ACME_DIRECTORY "$ACME_DIRECTORY"
|
||||
_debug ACME_DIRECTORY "$ACME_DIRECTORY"
|
||||
_ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)"
|
||||
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
|
||||
|
||||
@@ -2998,6 +3018,8 @@ _on_before_issue() {
|
||||
_chk_pre_hook="$4"
|
||||
_chk_local_addr="$5"
|
||||
_debug _on_before_issue
|
||||
_debug _chk_main_domain "$_chk_main_domain"
|
||||
_debug _chk_alt_domains "$_chk_alt_domains"
|
||||
#run pre hook
|
||||
if [ "$_chk_pre_hook" ]; then
|
||||
_info "Run pre hook:'$_chk_pre_hook'"
|
||||
@@ -3018,11 +3040,17 @@ _on_before_issue() {
|
||||
|
||||
_debug Le_LocalAddress "$_chk_local_addr"
|
||||
|
||||
alldomains=$(echo "$_chk_main_domain,$_chk_alt_domains" | tr ',' ' ')
|
||||
_index=1
|
||||
_currentRoot=""
|
||||
_addrIndex=1
|
||||
for d in $alldomains; do
|
||||
_w_index=1
|
||||
while true; do
|
||||
d="$(echo "$_chk_main_domain,$_chk_alt_domains," | cut -d , -f "$_w_index")"
|
||||
_w_index="$(_math "$_w_index" + 1)"
|
||||
_debug d "$d"
|
||||
if [ -z "$d" ]; then
|
||||
break
|
||||
fi
|
||||
_debug "Check for domain" "$d"
|
||||
_currentRoot="$(_getfield "$_chk_web_roots" $_index)"
|
||||
_debug "_currentRoot" "$_currentRoot"
|
||||
@@ -3118,7 +3146,7 @@ _on_issue_err() {
|
||||
)
|
||||
fi
|
||||
|
||||
if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "dns"; then
|
||||
if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then
|
||||
_err "$_DNS_MANUAL_ERR"
|
||||
fi
|
||||
|
||||
@@ -3154,7 +3182,7 @@ _on_issue_success() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if _hasfield "$Le_Webroot" "dns"; then
|
||||
if _hasfield "$Le_Webroot" "$W_DNS"; then
|
||||
_err "$_DNS_MANUAL_WARN"
|
||||
fi
|
||||
|
||||
@@ -3238,10 +3266,16 @@ _regAccount() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 responseHeaders "$responseHeaders"
|
||||
_accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")"
|
||||
_debug "_accUri" "$_accUri"
|
||||
if [ -z "$_accUri" ]; then
|
||||
_err "Can not find account id url."
|
||||
_err "$responseHeaders"
|
||||
return 1
|
||||
fi
|
||||
_savecaconf "ACCOUNT_URL" "$_accUri"
|
||||
export ACCOUNT_URL="$ACCOUNT_URL"
|
||||
export ACCOUNT_URL="$_accUri"
|
||||
|
||||
CA_KEY_HASH="$(__calcAccountKeyHash)"
|
||||
_debug "Calc CA_KEY_HASH" "$CA_KEY_HASH"
|
||||
@@ -3421,6 +3455,9 @@ issue() {
|
||||
_main_domain=$(echo "$2,$3" | cut -d , -f 1)
|
||||
_alt_domains=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//")
|
||||
fi
|
||||
_debug _main_domain "$_main_domain"
|
||||
_debug _alt_domains "$_alt_domains"
|
||||
|
||||
_key_length="$4"
|
||||
_real_cert="$5"
|
||||
_real_key="$6"
|
||||
@@ -3448,6 +3485,11 @@ issue() {
|
||||
mkdir -p "$DOMAIN_PATH"
|
||||
fi
|
||||
|
||||
if _hasfield "$_web_roots" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then
|
||||
_err "$_DNS_MANUAL_ERROR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
|
||||
|
||||
_initAPI
|
||||
@@ -3509,7 +3551,7 @@ issue() {
|
||||
_saved_account_key_hash="$(_readcaconf "CA_KEY_HASH")"
|
||||
_debug2 _saved_account_key_hash "$_saved_account_key_hash"
|
||||
|
||||
if [ -z "$_saved_account_key_hash" ] || [ "$_saved_account_key_hash" != "$(__calcAccountKeyHash)" ]; then
|
||||
if [ -z "$ACCOUNT_URL" ] || [ -z "$_saved_account_key_hash" ] || [ "$_saved_account_key_hash" != "$(__calcAccountKeyHash)" ]; then
|
||||
if ! _regAccount "$_accountkeylength"; then
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
@@ -3551,10 +3593,15 @@ issue() {
|
||||
if [ "$ACME_VERSION" = "2" ]; then
|
||||
#make new order request
|
||||
_identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
|
||||
for d in $(echo "$_alt_domains" | tr ',' ' '); do
|
||||
if [ "$d" ]; then
|
||||
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
|
||||
_w_index=1
|
||||
while true; do
|
||||
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
|
||||
_w_index="$(_math "$_w_index" + 1)"
|
||||
_debug d "$d"
|
||||
if [ -z "$d" ]; then
|
||||
break
|
||||
fi
|
||||
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
|
||||
done
|
||||
_debug2 _identifiers "$_identifiers"
|
||||
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
|
||||
@@ -3591,6 +3638,8 @@ issue() {
|
||||
_debug2 "_authz_url" "$_authz_url"
|
||||
if ! response="$(_get "$_authz_url")"; then
|
||||
_err "get to authz error."
|
||||
_err "_authorizations_seg" "$_authorizations_seg"
|
||||
_err "_authz_url" "$_authz_url"
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
@@ -3609,10 +3658,16 @@ $_authorizations_map"
|
||||
_debug2 _authorizations_map "$_authorizations_map"
|
||||
fi
|
||||
|
||||
alldomains=$(echo "$_main_domain,$_alt_domains" | tr ',' ' ')
|
||||
_index=0
|
||||
_currentRoot=""
|
||||
for d in $alldomains; do
|
||||
_w_index=1
|
||||
while true; do
|
||||
d="$(echo "$_main_domain,$_alt_domains," | cut -d , -f "$_w_index")"
|
||||
_w_index="$(_math "$_w_index" + 1)"
|
||||
_debug d "$d"
|
||||
if [ -z "$d" ]; then
|
||||
break
|
||||
fi
|
||||
_info "Getting webroot for domain" "$d"
|
||||
_index=$(_math $_index + 1)
|
||||
_w="$(echo $_web_roots | cut -d , -f $_index)"
|
||||
@@ -3624,7 +3679,7 @@ $_authorizations_map"
|
||||
|
||||
vtype="$VTYPE_HTTP"
|
||||
#todo, v2 wildcard force to use dns
|
||||
if _startswith "$_currentRoot" "dns"; then
|
||||
if _startswith "$_currentRoot" "$W_DNS"; then
|
||||
vtype="$VTYPE_DNS"
|
||||
fi
|
||||
|
||||
@@ -3641,6 +3696,7 @@ $_authorizations_map"
|
||||
_debug2 "response" "$response"
|
||||
if [ -z "$response" ]; then
|
||||
_err "get to authz error."
|
||||
_err "_authorizations_map" "$_authorizations_map"
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
@@ -3751,6 +3807,10 @@ $_authorizations_map"
|
||||
if [ "$d_api" ]; then
|
||||
_info "Found domain api file: $d_api"
|
||||
else
|
||||
if [ "$_currentRoot" != "$W_DNS" ]; then
|
||||
_err "Can not find dns api hook for: $_currentRoot"
|
||||
_info "You need to add the txt record manually."
|
||||
fi
|
||||
_info "$(__red "Add the following TXT record:")"
|
||||
_info "$(__red "Domain: '$(__green "$txtdomain")'")"
|
||||
_info "$(__red "TXT value: '$(__green "$txt")'")"
|
||||
@@ -3789,7 +3849,7 @@ $_authorizations_map"
|
||||
if [ "$dnsadded" = '0' ]; then
|
||||
_savedomainconf "Le_Vlist" "$vlist"
|
||||
_debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit."
|
||||
_err "Please add the TXT records to the domains, and retry again."
|
||||
_err "Please add the TXT records to the domains, and re-run with --renew."
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
@@ -4053,13 +4113,15 @@ $_authorizations_map"
|
||||
fi
|
||||
if [ "$code" != "200" ]; then
|
||||
_err "Sign failed, code is not 200."
|
||||
_err "$response"
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
fi
|
||||
Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
|
||||
|
||||
if ! _get "$Le_LinkCert" >"$CERT_PATH"; then
|
||||
_err "Sign failed, code is not 200."
|
||||
_err "Sign failed, can not download cert:$Le_LinkCert."
|
||||
_err "$response"
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
fi
|
||||
@@ -4075,12 +4137,12 @@ $_authorizations_map"
|
||||
fi
|
||||
else
|
||||
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
|
||||
_err "Sign failed."
|
||||
_err "Sign failed. $response"
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
fi
|
||||
_rcert="$response"
|
||||
Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _head_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
|
||||
Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
|
||||
echo "$BEGIN_CERT" >"$CERT_PATH"
|
||||
|
||||
#if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then
|
||||
@@ -4151,7 +4213,7 @@ $_authorizations_map"
|
||||
echo "$BEGIN_CERT" >"$CA_CERT_PATH"
|
||||
_base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH"
|
||||
echo "$END_CERT" >>"$CA_CERT_PATH"
|
||||
if !_checkcert "$CA_CERT_PATH"; then
|
||||
if ! _checkcert "$CA_CERT_PATH"; then
|
||||
_err "Can not get the ca cert."
|
||||
break
|
||||
fi
|
||||
@@ -4264,7 +4326,7 @@ renew() {
|
||||
fi
|
||||
|
||||
. "$DOMAIN_CONF"
|
||||
|
||||
_debug Le_API "$Le_API"
|
||||
if [ "$Le_API" ]; then
|
||||
if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
|
||||
export Le_API="$DEFAULT_CA"
|
||||
@@ -4868,6 +4930,8 @@ _deactivate() {
|
||||
_debug2 "authzUri" "$authzUri"
|
||||
if ! response="$(_get "$authzUri")"; then
|
||||
_err "get to authz error."
|
||||
_err "_authorizations_seg" "$_authorizations_seg"
|
||||
_err "authzUri" "$authzUri"
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
@@ -5424,8 +5488,8 @@ Parameters:
|
||||
--cert-home Specifies the home dir to save all the certs, only valid for '--install' command.
|
||||
--config-home Specifies the home dir to save all the configurations.
|
||||
--useragent Specifies the user agent string. it will be saved for future use too.
|
||||
--accountemail Specifies the account email for registering, Only valid for the '--install' command.
|
||||
--accountkey Specifies the account key path, Only valid for the '--install' command.
|
||||
--accountemail Specifies the account email, only valid for the '--install' and '--update-account' command.
|
||||
--accountkey Specifies the account key path, only valid for the '--install' command.
|
||||
--days Specifies the days to renew the cert when using '--issue' command. The max value is $MAX_RENEW days.
|
||||
--httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
||||
--local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
|
||||
@@ -5449,6 +5513,7 @@ Parameters:
|
||||
--listen-v6 Force standalone/tls server to listen at ipv6.
|
||||
--openssl-bin Specifies a custom openssl bin location.
|
||||
--use-wget Force to use wget, if you have both curl and wget installed.
|
||||
--yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI
|
||||
"
|
||||
}
|
||||
|
||||
@@ -5779,7 +5844,7 @@ _process() {
|
||||
fi
|
||||
;;
|
||||
--dns)
|
||||
wvalue="dns"
|
||||
wvalue="$W_DNS"
|
||||
if [ "$2" ] && ! _startswith "$2" "-"; then
|
||||
wvalue="$2"
|
||||
shift
|
||||
@@ -5937,6 +6002,9 @@ _process() {
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--yes-I-know-dns-manual-mode-enough-go-ahead-please)
|
||||
export FORCE_DNS_MANUAL=1
|
||||
;;
|
||||
--log | --logfile)
|
||||
_log="1"
|
||||
_logfile="$2"
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a sample custom api script.
|
||||
#This file name is "myapi.sh"
|
||||
#So, here must be a method myapi_deploy()
|
||||
#Which will be called by acme.sh to deploy the cert
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
|
||||
@@ -51,6 +51,7 @@ vault_cli_deploy() {
|
||||
|
||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
|
||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
|
||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
|
||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
|
||||
|
||||
}
|
||||
|
||||
@@ -325,6 +325,8 @@ The `CY_Username`, `CY_Password` and `CY_OTP_Secret` will be saved in `~/.acme.s
|
||||
|
||||
## 17. Use Domain-Offensive/Resellerinterface/Domainrobot API
|
||||
|
||||
ATTENTION: You need to be a registered Reseller to be able to use the ResellerInterface. As a normal user you can not use this method.
|
||||
|
||||
You will need your login credentials (Partner ID+Password) to the Resellerinterface, and export them before you run `acme.sh`:
|
||||
```
|
||||
export DO_PID="KD-1234567"
|
||||
@@ -525,8 +527,9 @@ For issues, please report to https://github.com/raidenii/acme.sh/issues.
|
||||
|
||||
## 28. Use Name.com API
|
||||
|
||||
You'll need to fill out the form at https://www.name.com/reseller/apply to apply
|
||||
for API username and token.
|
||||
Create your API token here: https://www.name.com/account/settings/api
|
||||
|
||||
Note: `Namecom_Username` should be your Name.com username and not the token name. If you accidentally run the script with the token name as the username see `~/.acme.sh/account.conf` to fix the issue
|
||||
|
||||
```
|
||||
export Namecom_Username="testuser"
|
||||
@@ -784,6 +787,32 @@ acme.sh --issue --dns dns_da -d example.com -d www.example.com
|
||||
|
||||
The `DA_Api` and `DA_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
## 42. Use KingHost DNS API
|
||||
|
||||
API access must be enabled at https://painel.kinghost.com.br/painel.api.php
|
||||
|
||||
```
|
||||
export KINGHOST_Username="yourusername"
|
||||
export KINGHOST_Password="yourpassword"
|
||||
acme.sh --issue --dns dns_kinghost -d example.com -d *.example.com
|
||||
```
|
||||
|
||||
The `KINGHOST_username` and `KINGHOST_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
## 43. Use Zilore DNS API
|
||||
|
||||
First, get your API key at https://my.zilore.com/account/api
|
||||
|
||||
```
|
||||
export Zilore_Key="5dcad3a2-36cb-50e8-cb92-000002f9"
|
||||
```
|
||||
|
||||
Ok, let's issue a cert now:
|
||||
```
|
||||
acme.sh --issue --dns dns_zilore -d example.com -d *.example.com
|
||||
```
|
||||
|
||||
The `Zilore_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
# Use custom API
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ dns_azure_add() {
|
||||
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
|
||||
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
|
||||
_info "validation value added"
|
||||
return 0
|
||||
else
|
||||
_err "error adding validation value ($_code)"
|
||||
return 1
|
||||
@@ -194,6 +195,7 @@ dns_azure_rm() {
|
||||
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
|
||||
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
|
||||
_info "validation value removed"
|
||||
return 0
|
||||
else
|
||||
_err "error removing validation value ($_code)"
|
||||
return 1
|
||||
@@ -226,6 +228,7 @@ _azure_rest() {
|
||||
else
|
||||
response="$(_get "$ep")"
|
||||
fi
|
||||
_ret="$?"
|
||||
_secure_debug2 "response $response"
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
_debug "http response code $_code"
|
||||
@@ -236,7 +239,7 @@ _azure_rest() {
|
||||
return 1
|
||||
fi
|
||||
# See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
|
||||
if [ "$?" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
|
||||
if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
|
||||
_request_retry_times="$(_math "$_request_retry_times" + 1)"
|
||||
_info "REST call error $_code retrying $ep in $_request_retry_times s"
|
||||
_sleep "$_request_retry_times"
|
||||
@@ -281,6 +284,7 @@ _azure_getaccess_token() {
|
||||
body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials"
|
||||
_secure_debug2 "data $body"
|
||||
response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")"
|
||||
_ret="$?"
|
||||
_secure_debug2 "response $response"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||
@@ -290,7 +294,7 @@ _azure_getaccess_token() {
|
||||
_err "no acccess token received. Check your Azure settings see $WIKI"
|
||||
return 1
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$_ret" != "0" ]; then
|
||||
_err "error $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -19,8 +19,8 @@ dns_cf_add() {
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You don't specify cloudflare api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
_err "You didn't specify a cloudflare api key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -94,8 +94,8 @@ dns_cf_rm() {
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You don't specify cloudflare api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
_err "You didn't specify a cloudflare api key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -20,12 +20,22 @@
|
||||
dns_dgon_add() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
|
||||
# Check if API Key Exist
|
||||
if [ -z "$DO_API_KEY" ]; then
|
||||
DO_API_KEY=""
|
||||
_err "You did not specify DigitalOcean API key."
|
||||
_err "Please export DO_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using digitalocean dns validation - add record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
## save the env vars (key and domain split location) for later automated use
|
||||
_saveaccountconf DO_API_KEY "$DO_API_KEY"
|
||||
_saveaccountconf_mutable DO_API_KEY "$DO_API_KEY"
|
||||
|
||||
## split the domain for DO API
|
||||
if ! _get_base_domain "$fulldomain"; then
|
||||
@@ -39,7 +49,7 @@ dns_dgon_add() {
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $DO_API_KEY"
|
||||
PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
|
||||
PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'"}'
|
||||
PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'","ttl":120}'
|
||||
|
||||
_debug PURL "$PURL"
|
||||
_debug PBODY "$PBODY"
|
||||
@@ -65,6 +75,16 @@ dns_dgon_add() {
|
||||
dns_dgon_rm() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
|
||||
# Check if API Key Exist
|
||||
if [ -z "$DO_API_KEY" ]; then
|
||||
DO_API_KEY=""
|
||||
_err "You did not specify DigitalOcean API key."
|
||||
_err "Please export DO_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using digitalocean dns validation - remove record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
@@ -92,11 +112,11 @@ dns_dgon_rm() {
|
||||
domain_list="$(_get "$GURL")"
|
||||
## 2) find record
|
||||
## check for what we are looing for: "type":"A","name":"$_sub_domain"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*\d+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
## 3) check record and get next page
|
||||
if [ -z "$record" ]; then
|
||||
## find the next page if we dont have a match
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=\d+")"
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
|
||||
if [ -z "$nextpage" ]; then
|
||||
_err "no record and no nextpage in digital ocean DNS removal"
|
||||
return 1
|
||||
@@ -108,7 +128,7 @@ dns_dgon_rm() {
|
||||
done
|
||||
|
||||
## we found the record
|
||||
rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*\d+" | _egrep_o "\d+")"
|
||||
rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug rec_id "$rec_id"
|
||||
|
||||
## delete the record
|
||||
|
||||
@@ -39,34 +39,17 @@ dns_dnsimple_add() {
|
||||
|
||||
_get_records "$_account_id" "$_domain" "$_sub_domain"
|
||||
|
||||
if [ "$_records_count" = "0" ]; then
|
||||
_info "Adding record"
|
||||
if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
|
||||
if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
|
||||
_info "Added"
|
||||
return 0
|
||||
else
|
||||
_err "Unexpected response while adding text record."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
else
|
||||
_info "Updating record"
|
||||
_extract_record_id "$_records" "$_sub_domain"
|
||||
|
||||
if _dnsimple_rest \
|
||||
PATCH \
|
||||
"$_account_id/zones/$_domain/records/$_record_id" \
|
||||
"{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
|
||||
|
||||
_info "Updated!"
|
||||
_info "Adding record"
|
||||
if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
|
||||
if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
|
||||
_info "Added"
|
||||
return 0
|
||||
else
|
||||
_err "Unexpected response while adding text record."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_err "Update error"
|
||||
return 1
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
}
|
||||
|
||||
# fulldomain
|
||||
@@ -84,19 +67,19 @@ dns_dnsimple_rm() {
|
||||
fi
|
||||
|
||||
_get_records "$_account_id" "$_domain" "$_sub_domain"
|
||||
|
||||
_extract_record_id "$_records" "$_sub_domain"
|
||||
|
||||
if [ "$_record_id" ]; then
|
||||
|
||||
if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$_record_id"; then
|
||||
_info "removed record" "$_record_id"
|
||||
return 0
|
||||
fi
|
||||
echo "$_record_id" | while read -r item; do
|
||||
if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$item"; then
|
||||
_info "removed record" "$item"
|
||||
return 0
|
||||
else
|
||||
_err "failed to remove record" "$item"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
_err "failed to remove record" "$_record_id"
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions bellow ##################################
|
||||
|
||||
@@ -279,7 +279,7 @@ _freedns_add_txt_record() {
|
||||
domain_id="$2"
|
||||
subdomain="$3"
|
||||
value="$(printf '%s' "$4" | _url_encode)"
|
||||
url="http://freedns.afraid.org/subdomain/save.php?step=2"
|
||||
url="https://freedns.afraid.org/subdomain/save.php?step=2"
|
||||
|
||||
htmlpage="$(_post "type=TXT&domain_id=$domain_id&subdomain=$subdomain&address=%22$value%22&send=Save%21" "$url")"
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ _find_zone() {
|
||||
|
||||
_debug "Looking for zone \"${_attempted_zone}\""
|
||||
|
||||
line_num="$(echo "$_zone_names" | grep -n "$_attempted_zone" | cut -d : -f 1)"
|
||||
line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)"
|
||||
|
||||
if [ "$line_num" ]; then
|
||||
_zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
|
||||
|
||||
107
dnsapi/dns_kinghost.sh
Normal file
107
dnsapi/dns_kinghost.sh
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
############################################################
|
||||
# KingHost API support #
|
||||
# http://api.kinghost.net/doc/ #
|
||||
# #
|
||||
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
|
||||
# Report Bugs here: https://github.com/kinghost/acme.sh #
|
||||
# #
|
||||
# Values to export: #
|
||||
# export KINGHOST_Username="email@provider.com" #
|
||||
# export KINGHOST_Password="xxxxxxxxxx" #
|
||||
############################################################
|
||||
|
||||
KING_Api="https://api.kinghost.net/acme"
|
||||
|
||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
# Used to add txt record
|
||||
dns_kinghost_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
|
||||
KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
|
||||
if [ -z "$KINGHOST_Username" ] || [ -z "$KINGHOST_Password" ]; then
|
||||
KINGHOST_Username=""
|
||||
KINGHOST_Password=""
|
||||
_err "You don't specify KingHost api password and email yet."
|
||||
_err "Please create you key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the credentials to the account conf file.
|
||||
_saveaccountconf_mutable KINGHOST_Username "$KINGHOST_Username"
|
||||
_saveaccountconf_mutable KINGHOST_Password "$KINGHOST_Password"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_kinghost_rest GET "dns" "name=$fulldomain&content=$txtvalue"
|
||||
|
||||
#This API call returns "status":"ok" if dns record does not exists
|
||||
#We are creating a new txt record here, so we expect the "ok" status
|
||||
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
|
||||
_err "Error"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_kinghost_rest POST "dns" "name=$fulldomain&content=$txtvalue"
|
||||
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
|
||||
_err "Error"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Usage: fulldomain txtvalue
|
||||
# Used to remove the txt record after validation
|
||||
dns_kinghost_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
|
||||
KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
|
||||
if [ -z "$KINGHOST_Password" ] || [ -z "$KINGHOST_Username" ]; then
|
||||
KINGHOST_Password=""
|
||||
KINGHOST_Username=""
|
||||
_err "You don't specify KingHost api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_kinghost_rest DELETE "dns" "name=$fulldomain&content=$txtvalue"
|
||||
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
|
||||
_err "Error"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
_kinghost_rest() {
|
||||
method=$1
|
||||
uri="$2"
|
||||
data="$3"
|
||||
_debug "$uri"
|
||||
|
||||
export _H1="X-Auth-Email: $KINGHOST_Username"
|
||||
export _H2="X-Auth-Key: $KINGHOST_Password"
|
||||
|
||||
if [ "$method" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$KING_Api/$uri.json" "" "$method")"
|
||||
else
|
||||
response="$(_get "$KING_Api/$uri.json?$data")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $uri"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
@@ -123,7 +123,7 @@ _namecom_login() {
|
||||
# Auth string
|
||||
# Name.com API v4 uses http basic auth to authenticate
|
||||
# need to convert the token for http auth
|
||||
_namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | base64)
|
||||
_namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64)
|
||||
|
||||
if _namecom_rest GET "hello"; then
|
||||
retcode=$(printf "%s\n" "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"")
|
||||
|
||||
@@ -90,7 +90,7 @@ set_record() {
|
||||
full=$2
|
||||
txtvalue=$3
|
||||
|
||||
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then
|
||||
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then
|
||||
_err "Set txt record error."
|
||||
return 1
|
||||
fi
|
||||
@@ -107,7 +107,7 @@ rm_record() {
|
||||
root=$1
|
||||
full=$2
|
||||
|
||||
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
|
||||
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
|
||||
_err "Delete txt record error."
|
||||
return 1
|
||||
fi
|
||||
@@ -122,7 +122,7 @@ rm_record() {
|
||||
notify_slaves() {
|
||||
root=$1
|
||||
|
||||
if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then
|
||||
if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root/notify"; then
|
||||
_err "Notify slaves error."
|
||||
return 1
|
||||
fi
|
||||
@@ -144,15 +144,18 @@ _get_root() {
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$_zones_response" "\"name\": \"$h.\""; then
|
||||
_domain="$h"
|
||||
_domain="$h."
|
||||
if [ -z "$h" ]; then
|
||||
_domain="=2E"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
i=$(_math $i + 1)
|
||||
done
|
||||
_debug "$domain not found"
|
||||
|
||||
@@ -50,9 +50,9 @@ _PDD_get_domain() {
|
||||
__last=0
|
||||
while [ $__last -eq 0 ]; do
|
||||
uri1="https://pddimp.yandex.ru/api2/admin/domain/domains?page=${__page}&on_page=20"
|
||||
res1=$(_get "$uri1" | _normalizeJson)
|
||||
#_debug "$res1"
|
||||
__found=$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')
|
||||
res1="$(_get "$uri1" | _normalizeJson)"
|
||||
_debug2 "res1" "$res1"
|
||||
__found="$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')"
|
||||
_debug "found: $__found results on page"
|
||||
if [ "$__found" -lt 20 ]; then
|
||||
_debug "last page: $__page"
|
||||
|
||||
139
dnsapi/dns_zilore.sh
Normal file
139
dnsapi/dns_zilore.sh
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
Zilore_API="https://api.zilore.com/dns/v1"
|
||||
# Zilore_Key="YOUR-ZILORE-API-KEY"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
dns_zilore_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_info "Using Zilore"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
Zilore_Key="${Zilore_Key:-$(_readaccountconf_mutable Zilore_Key)}"
|
||||
if [ -z "$Zilore_Key" ]; then
|
||||
Zilore_Key=""
|
||||
_err "Please define Zilore API key"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable Zilore_Key "$Zilore_Key"
|
||||
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "Unable to determine root domain"
|
||||
return 1
|
||||
else
|
||||
_debug _domain "$_domain"
|
||||
fi
|
||||
|
||||
if _zilore_rest POST "domains/$_domain/records?record_type=TXT&record_ttl=600&record_name=$fulldomain&record_value=\"$txtvalue\""; then
|
||||
if _contains "$response" '"added"' >/dev/null; then
|
||||
_info "Added TXT record, waiting for validation"
|
||||
return 0
|
||||
else
|
||||
_debug response "$response"
|
||||
_err "Error while adding DNS records"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_zilore_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_info "Using Zilore"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
Zilore_Key="${Zilore_Key:-$(_readaccountconf_mutable Zilore_Key)}"
|
||||
if [ -z "$Zilore_Key" ]; then
|
||||
Zilore_Key=""
|
||||
_err "Please define Zilore API key"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable Zilore_Key "$Zilore_Key"
|
||||
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "Unable to determine root domain"
|
||||
return 1
|
||||
else
|
||||
_debug _domain "$_domain"
|
||||
fi
|
||||
|
||||
_debug "Getting TXT records"
|
||||
_zilore_rest GET "domains/${_domain}/records?search_text=$txtvalue&search_record_type=TXT"
|
||||
_debug response "$response"
|
||||
|
||||
if ! _contains "$response" '"ok"' >/dev/null; then
|
||||
_err "Error while getting records list"
|
||||
return 1
|
||||
else
|
||||
_record_id=$(printf "%s\n" "$response" | _egrep_o "\"record_id\":\"[^\"]+\"" | cut -d : -f 2 | tr -d \" | _head_n 1)
|
||||
if [ -z "$_record_id" ]; then
|
||||
_err "Cannot determine _record_id"
|
||||
return 1
|
||||
else
|
||||
_debug _record_id "$_record_id"
|
||||
fi
|
||||
if ! _zilore_rest DELETE "domains/${_domain}/records?record_id=$_record_id"; then
|
||||
_err "Error while deleting chosen record"
|
||||
return 1
|
||||
fi
|
||||
_contains "$response" '"ok"'
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=2
|
||||
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 ! _zilore_rest GET "domains?search_text=$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"$h\"" >/dev/null; then
|
||||
_domain=$h
|
||||
return 0
|
||||
else
|
||||
_debug "$h not found"
|
||||
fi
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_zilore_rest() {
|
||||
method=$1
|
||||
param=$2
|
||||
data=$3
|
||||
|
||||
export _H1="X-Auth-Key: $Zilore_Key"
|
||||
|
||||
if [ "$method" != "GET" ]; then
|
||||
response="$(_post "$data" "$Zilore_API/$param" "" "$method")"
|
||||
else
|
||||
response="$(_get "$Zilore_API/$param")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $param"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user