mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-25 14:41:40 +00:00
commit
dff4d03bd4
43
README.md
43
README.md
@ -220,22 +220,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
|
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
|
||||||
|
|
||||||
|
|
||||||
# 5. Use Standalone TLS server to issue cert
|
# 5. Use Apache mode
|
||||||
|
|
||||||
**(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
|
|
||||||
|
|
||||||
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
|
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
|
||||||
|
|
||||||
@ -255,7 +240,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
|
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)**
|
**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
|
||||||
|
|
||||||
@ -279,7 +264,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
|
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.
|
If your DNS provider supports API access, we can use that API to automatically issue the certs.
|
||||||
|
|
||||||
@ -342,7 +327,7 @@ 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)
|
For more details: [How to use DNS API](dnsapi)
|
||||||
|
|
||||||
# 9. Use DNS manual mode:
|
# 8. Use DNS manual mode:
|
||||||
|
|
||||||
If your dns provider doesn't support any api access, you can add the txt record by your hand.
|
If your dns provider doesn't support any api access, you can add the txt record by your hand.
|
||||||
|
|
||||||
@ -376,7 +361,7 @@ Ok, it's done.
|
|||||||
|
|
||||||
**Please use dns api mode instead.**
|
**Please use dns api mode instead.**
|
||||||
|
|
||||||
# 10. Issue ECC certificates
|
# 9. Issue ECC certificates
|
||||||
|
|
||||||
`Let's Encrypt` can now issue **ECDSA** certificates.
|
`Let's Encrypt` can now issue **ECDSA** certificates.
|
||||||
|
|
||||||
@ -408,7 +393,7 @@ Valid values are:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 11. Issue Wildcard certificates
|
# 10. Issue Wildcard certificates
|
||||||
|
|
||||||
It's simple, just give a wildcard domain as the `-d` parameter.
|
It's simple, just give a wildcard domain as the `-d` parameter.
|
||||||
|
|
||||||
@ -418,7 +403,7 @@ 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.
|
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
|
||||||
|
|
||||||
@ -435,7 +420,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:
|
To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
|
||||||
|
|
||||||
@ -448,7 +433,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.
|
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.
|
acme.sh is in constant development, so it's strongly recommended to use the latest code.
|
||||||
|
|
||||||
@ -473,25 +458,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
|
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".
|
Speak ACME language using shell, directly to "Let's Encrypt".
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
|
|
||||||
# 17. Acknowledgments
|
# 16. Acknowledgments
|
||||||
|
|
||||||
1. Acme-tiny: https://github.com/diafygi/acme-tiny
|
1. Acme-tiny: https://github.com/diafygi/acme-tiny
|
||||||
2. ACME protocol: https://github.com/ietf-wg-acme/acme
|
2. ACME protocol: https://github.com/ietf-wg-acme/acme
|
||||||
|
|
||||||
|
|
||||||
# 18. License & Others
|
# 17. License & Others
|
||||||
|
|
||||||
License is GPLv3
|
License is GPLv3
|
||||||
|
|
||||||
@ -500,7 +485,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.
|
[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:
|
Your donation makes **acme.sh** better:
|
||||||
|
|
||||||
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
|
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
|
||||||
|
60
acme.sh
60
acme.sh
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
VER=2.7.7
|
VER=2.7.8
|
||||||
|
|
||||||
PROJECT_NAME="acme.sh"
|
PROJECT_NAME="acme.sh"
|
||||||
|
|
||||||
@ -47,6 +47,7 @@ DEFAULT_DNS_SLEEP=120
|
|||||||
NO_VALUE="no"
|
NO_VALUE="no"
|
||||||
|
|
||||||
W_TLS="tls"
|
W_TLS="tls"
|
||||||
|
W_DNS="dns"
|
||||||
DNS_ALIAS_PREFIX="="
|
DNS_ALIAS_PREFIX="="
|
||||||
|
|
||||||
MODE_STATELESS="stateless"
|
MODE_STATELESS="stateless"
|
||||||
@ -2341,7 +2342,7 @@ _initpath() {
|
|||||||
fi
|
fi
|
||||||
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)"
|
_ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)"
|
||||||
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
|
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
|
||||||
|
|
||||||
@ -2998,6 +2999,8 @@ _on_before_issue() {
|
|||||||
_chk_pre_hook="$4"
|
_chk_pre_hook="$4"
|
||||||
_chk_local_addr="$5"
|
_chk_local_addr="$5"
|
||||||
_debug _on_before_issue
|
_debug _on_before_issue
|
||||||
|
_debug _chk_main_domain "$_chk_main_domain"
|
||||||
|
_debug _chk_alt_domains "$_chk_alt_domains"
|
||||||
#run pre hook
|
#run pre hook
|
||||||
if [ "$_chk_pre_hook" ]; then
|
if [ "$_chk_pre_hook" ]; then
|
||||||
_info "Run pre hook:'$_chk_pre_hook'"
|
_info "Run pre hook:'$_chk_pre_hook'"
|
||||||
@ -3018,11 +3021,17 @@ _on_before_issue() {
|
|||||||
|
|
||||||
_debug Le_LocalAddress "$_chk_local_addr"
|
_debug Le_LocalAddress "$_chk_local_addr"
|
||||||
|
|
||||||
alldomains=$(echo "$_chk_main_domain,$_chk_alt_domains" | tr ',' ' ')
|
|
||||||
_index=1
|
_index=1
|
||||||
_currentRoot=""
|
_currentRoot=""
|
||||||
_addrIndex=1
|
_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"
|
_debug "Check for domain" "$d"
|
||||||
_currentRoot="$(_getfield "$_chk_web_roots" $_index)"
|
_currentRoot="$(_getfield "$_chk_web_roots" $_index)"
|
||||||
_debug "_currentRoot" "$_currentRoot"
|
_debug "_currentRoot" "$_currentRoot"
|
||||||
@ -3118,7 +3127,7 @@ _on_issue_err() {
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "dns"; then
|
if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then
|
||||||
_err "$_DNS_MANUAL_ERR"
|
_err "$_DNS_MANUAL_ERR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -3154,7 +3163,7 @@ _on_issue_success() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _hasfield "$Le_Webroot" "dns"; then
|
if _hasfield "$Le_Webroot" "$W_DNS"; then
|
||||||
_err "$_DNS_MANUAL_WARN"
|
_err "$_DNS_MANUAL_WARN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -3421,6 +3430,9 @@ issue() {
|
|||||||
_main_domain=$(echo "$2,$3" | cut -d , -f 1)
|
_main_domain=$(echo "$2,$3" | cut -d , -f 1)
|
||||||
_alt_domains=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//")
|
_alt_domains=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//")
|
||||||
fi
|
fi
|
||||||
|
_debug _main_domain "$_main_domain"
|
||||||
|
_debug _alt_domains "$_alt_domains"
|
||||||
|
|
||||||
_key_length="$4"
|
_key_length="$4"
|
||||||
_real_cert="$5"
|
_real_cert="$5"
|
||||||
_real_key="$6"
|
_real_key="$6"
|
||||||
@ -3551,10 +3563,15 @@ issue() {
|
|||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
#make new order request
|
#make new order request
|
||||||
_identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
|
_identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
|
||||||
for d in $(echo "$_alt_domains" | tr ',' ' '); do
|
_w_index=1
|
||||||
if [ "$d" ]; then
|
while true; do
|
||||||
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
|
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
|
||||||
|
_w_index="$(_math "$_w_index" + 1)"
|
||||||
|
_debug d "$d"
|
||||||
|
if [ -z "$d" ]; then
|
||||||
|
break
|
||||||
fi
|
fi
|
||||||
|
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
|
||||||
done
|
done
|
||||||
_debug2 _identifiers "$_identifiers"
|
_debug2 _identifiers "$_identifiers"
|
||||||
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
|
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
|
||||||
@ -3591,6 +3608,8 @@ issue() {
|
|||||||
_debug2 "_authz_url" "$_authz_url"
|
_debug2 "_authz_url" "$_authz_url"
|
||||||
if ! response="$(_get "$_authz_url")"; then
|
if ! response="$(_get "$_authz_url")"; then
|
||||||
_err "get to authz error."
|
_err "get to authz error."
|
||||||
|
_err "_authorizations_seg" "$_authorizations_seg"
|
||||||
|
_err "_authz_url" "$_authz_url"
|
||||||
_clearup
|
_clearup
|
||||||
_on_issue_err "$_post_hook"
|
_on_issue_err "$_post_hook"
|
||||||
return 1
|
return 1
|
||||||
@ -3609,10 +3628,16 @@ $_authorizations_map"
|
|||||||
_debug2 _authorizations_map "$_authorizations_map"
|
_debug2 _authorizations_map "$_authorizations_map"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alldomains=$(echo "$_main_domain,$_alt_domains" | tr ',' ' ')
|
|
||||||
_index=0
|
_index=0
|
||||||
_currentRoot=""
|
_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"
|
_info "Getting webroot for domain" "$d"
|
||||||
_index=$(_math $_index + 1)
|
_index=$(_math $_index + 1)
|
||||||
_w="$(echo $_web_roots | cut -d , -f $_index)"
|
_w="$(echo $_web_roots | cut -d , -f $_index)"
|
||||||
@ -3624,7 +3649,7 @@ $_authorizations_map"
|
|||||||
|
|
||||||
vtype="$VTYPE_HTTP"
|
vtype="$VTYPE_HTTP"
|
||||||
#todo, v2 wildcard force to use dns
|
#todo, v2 wildcard force to use dns
|
||||||
if _startswith "$_currentRoot" "dns"; then
|
if _startswith "$_currentRoot" "$W_DNS"; then
|
||||||
vtype="$VTYPE_DNS"
|
vtype="$VTYPE_DNS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -3641,6 +3666,7 @@ $_authorizations_map"
|
|||||||
_debug2 "response" "$response"
|
_debug2 "response" "$response"
|
||||||
if [ -z "$response" ]; then
|
if [ -z "$response" ]; then
|
||||||
_err "get to authz error."
|
_err "get to authz error."
|
||||||
|
_err "_authorizations_map" "$_authorizations_map"
|
||||||
_clearup
|
_clearup
|
||||||
_on_issue_err "$_post_hook"
|
_on_issue_err "$_post_hook"
|
||||||
return 1
|
return 1
|
||||||
@ -3751,6 +3777,10 @@ $_authorizations_map"
|
|||||||
if [ "$d_api" ]; then
|
if [ "$d_api" ]; then
|
||||||
_info "Found domain api file: $d_api"
|
_info "Found domain api file: $d_api"
|
||||||
else
|
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 "Add the following TXT record:")"
|
||||||
_info "$(__red "Domain: '$(__green "$txtdomain")'")"
|
_info "$(__red "Domain: '$(__green "$txtdomain")'")"
|
||||||
_info "$(__red "TXT value: '$(__green "$txt")'")"
|
_info "$(__red "TXT value: '$(__green "$txt")'")"
|
||||||
@ -4264,7 +4294,7 @@ renew() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
. "$DOMAIN_CONF"
|
. "$DOMAIN_CONF"
|
||||||
|
_debug Le_API "$Le_API"
|
||||||
if [ "$Le_API" ]; then
|
if [ "$Le_API" ]; then
|
||||||
if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
|
if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
|
||||||
export Le_API="$DEFAULT_CA"
|
export Le_API="$DEFAULT_CA"
|
||||||
@ -4868,6 +4898,8 @@ _deactivate() {
|
|||||||
_debug2 "authzUri" "$authzUri"
|
_debug2 "authzUri" "$authzUri"
|
||||||
if ! response="$(_get "$authzUri")"; then
|
if ! response="$(_get "$authzUri")"; then
|
||||||
_err "get to authz error."
|
_err "get to authz error."
|
||||||
|
_err "_authorizations_seg" "$_authorizations_seg"
|
||||||
|
_err "authzUri" "$authzUri"
|
||||||
_clearup
|
_clearup
|
||||||
_on_issue_err "$_post_hook"
|
_on_issue_err "$_post_hook"
|
||||||
return 1
|
return 1
|
||||||
@ -5779,7 +5811,7 @@ _process() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
--dns)
|
--dns)
|
||||||
wvalue="dns"
|
wvalue="$W_DNS"
|
||||||
if [ "$2" ] && ! _startswith "$2" "-"; then
|
if [ "$2" ] && ! _startswith "$2" "-"; then
|
||||||
wvalue="$2"
|
wvalue="$2"
|
||||||
shift
|
shift
|
||||||
|
Loading…
Reference in New Issue
Block a user