mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-05-18 20:03:55 +08:00
add --dns-persist-days
This commit is contained in:
43
README.md
43
README.md
@@ -406,7 +406,7 @@ DNS persist mode lets you place a **single, long‑lived `_validation-persist` T
|
||||
#### 🪄 Step 1: Print the TXT record value
|
||||
|
||||
```bash
|
||||
acme.sh --make-dns-persist-value -d example.com [--server letsencrypt] [--dns-persist-wildcard] [--dns-persist-ca-name "sectigo.com"]
|
||||
acme.sh --make-dns-persist-value -d example.com [--server letsencrypt] [--dns-persist-wildcard] [--dns-persist-ca-name "sectigo.com"] [--dns-persist-days 365]
|
||||
```
|
||||
|
||||
Options:
|
||||
@@ -416,17 +416,18 @@ Options:
|
||||
| `--server <ca>` | Pick the CA (default is your configured default). The account is registered automatically if you have not used this CA before. |
|
||||
| `--dns-persist-wildcard` | Adds `policy=wildcard` to the record so it also authorizes wildcard / subdomain certs. |
|
||||
| `--dns-persist-ca-name <name>` | Use a specific CA identity domain (e.g. `sectigo.com`). If omitted, identities are read from the ACME directory's `caaIdentities` field and one record per identity is printed — you only need to add **any one** of them. |
|
||||
| `--dns-persist-days <N>` | Adds `persistUntil=<unix-timestamp>` to the record, set to N days from now. The CA will refuse new validations against the record after that time. Omit for a record with no expiry. |
|
||||
|
||||
You should get an output like:
|
||||
|
||||
```sh
|
||||
TXT domain: _validation-persist.example.com
|
||||
TXT value: "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789"
|
||||
TXT persist domain:_validation-persist.example.com
|
||||
TXT persist value :"letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789"
|
||||
```
|
||||
|
||||
#### ✍️ Step 2: Add the TXT record to your DNS
|
||||
|
||||
Add the printed `TXT domain` / `TXT value` pair as a TXT record at your DNS provider, then wait for it to propagate.
|
||||
Add the printed `TXT persist domain` / `TXT persist value` pair as a TXT record at your DNS provider, then wait for it to propagate.
|
||||
|
||||
#### 📜 Step 3: Issue the certificate
|
||||
|
||||
@@ -485,7 +486,7 @@ acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
|
||||
|
||||
### 1️⃣3️⃣ How to Renew Certificates
|
||||
|
||||
> 🔄 No need to renew manually! All certs will be renewed automatically every **30** days.
|
||||
> 🔄 No need to renew manually! All certs will be renewed automatically every **30** days, **or earlier when the CA's ARI says so** (see below).
|
||||
|
||||
However, you can force a renewal:
|
||||
|
||||
@@ -499,6 +500,38 @@ acme.sh --renew -d example.com --force
|
||||
acme.sh --renew -d example.com --force --ecc
|
||||
```
|
||||
|
||||
#### 📡 ACME Renewal Information (ARI) — RFC 9773
|
||||
|
||||
If the CA exposes a `renewalInfo` endpoint in its ACME directory (Let's Encrypt, ZeroSSL, etc.), `acme.sh` follows [RFC 9773](https://www.rfc-editor.org/rfc/rfc9773.html) automatically — **no flag needed, no opt-in**:
|
||||
|
||||
| What | When | Why |
|
||||
|------|------|-----|
|
||||
| 🔍 **Polls `suggestedWindow`** | Every cron run, before deciding to skip | Lets the CA shift the renewal time forward in case of an incident (key compromise, mass revocation, etc.) |
|
||||
| 🎯 **Picks a random renewal time** inside the window | Right after a successful issuance/renewal | Disperses renewals across the network so all clients don't hit the CA at the same instant |
|
||||
| 🔗 **Sends `replaces=<certID>`** in `newOrder` | On renewal | Lets the CA correlate the new order with the certificate it supersedes (RFC 9773 §5) |
|
||||
| ↩️ **Retries without `replaces`** | If the CA rejects with `alreadyReplaced` or an ARI validation error | Robust against edge cases (e.g. switching CAs, retired issuers) |
|
||||
|
||||
**Renewal trigger logic:** the cert is renewed if **any one** of the following becomes true:
|
||||
|
||||
1. `--force` is given
|
||||
2. The CA's **ARI `suggestedWindow` has started**
|
||||
3. The cached `Le_NextRenewTime` has passed (default fallback for CAs without ARI)
|
||||
|
||||
You can see the resulting next renewal time (already ARI-picked when applicable) in:
|
||||
|
||||
```sh
|
||||
acme.sh --info -d example.com
|
||||
# Look for: Le_NextRenewTimeStr=...
|
||||
```
|
||||
|
||||
For the live ARI window the CA is currently advertising, run with `--debug 2`:
|
||||
|
||||
```sh
|
||||
acme.sh --renew -d example.com --debug 2 2>&1 | grep -i 'ARI suggestedWindow'
|
||||
```
|
||||
|
||||
> 💡 If your CA does not advertise `renewalInfo`, `acme.sh` falls back to the classic 30-day rule — no behavior change.
|
||||
|
||||
---
|
||||
|
||||
### 1️⃣4️⃣ How to Stop Certificate Renewal
|
||||
|
||||
32
acme.sh
32
acme.sh
@@ -4030,19 +4030,33 @@ deactivateaccount() {
|
||||
fi
|
||||
}
|
||||
|
||||
#domain wildcard ca_name
|
||||
#domain wildcard ca_name days
|
||||
#Print the TXT record(s) the user must add to enable persistent DNS validation
|
||||
#per draft-ietf-acme-dns-persist-01.
|
||||
makednspersistvalue() {
|
||||
_mdpv_domain="$1"
|
||||
_mdpv_wildcard="$2"
|
||||
_mdpv_ca_name="$3"
|
||||
_mdpv_days="$4"
|
||||
|
||||
if [ -z "$_mdpv_domain" ]; then
|
||||
_err "Please specify a domain with -d."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$_mdpv_days" ]; then
|
||||
case "$_mdpv_days" in
|
||||
'' | *[!0-9]*)
|
||||
_err "--dns-persist-days must be a positive integer, got: $_mdpv_days"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
if [ "$_mdpv_days" -lt 1 ]; then
|
||||
_err "--dns-persist-days must be at least 1."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_initpath
|
||||
|
||||
_accUri="$(_readcaconf ACCOUNT_URL)"
|
||||
@@ -4067,6 +4081,11 @@ makednspersistvalue() {
|
||||
if [ "$_mdpv_wildcard" = "1" ]; then
|
||||
_txt_suffix="$_txt_suffix; policy=wildcard"
|
||||
fi
|
||||
if [ -n "$_mdpv_days" ]; then
|
||||
_persist_until=$(_math "$(_time)" + "$_mdpv_days" \* 86400)
|
||||
_txt_suffix="$_txt_suffix; persistUntil=$_persist_until"
|
||||
_info "persistUntil set to $(__green "$(_time2str "$_persist_until")") ($_mdpv_days days from now)"
|
||||
fi
|
||||
|
||||
if [ -n "$_mdpv_ca_name" ]; then
|
||||
_info ""
|
||||
@@ -7402,6 +7421,10 @@ Parameters:
|
||||
(e.g. 'ssl.com') as the issuer-domain-name in the TXT record. If
|
||||
omitted, the identities are read from the ACME directory's
|
||||
'caaIdentities' field and one record is printed per identity.
|
||||
--dns-persist-days <N> Used with '--make-dns-persist-value'. Add a 'persistUntil' field to
|
||||
the TXT record so the record self-expires N days from now (the CA
|
||||
will refuse new validations against the record after that time).
|
||||
If omitted, the record has no expiry.
|
||||
|
||||
|
||||
These parameters are to install the cert to nginx/Apache or any other server after issue/renew a cert:
|
||||
@@ -7775,6 +7798,7 @@ _process() {
|
||||
_extended_key_usage=""
|
||||
_dns_persist_wildcard=""
|
||||
_dns_persist_ca_name=""
|
||||
_dns_persist_days=""
|
||||
while [ ${#} -gt 0 ]; do
|
||||
case "${1}" in
|
||||
|
||||
@@ -7879,6 +7903,10 @@ _process() {
|
||||
_dns_persist_ca_name="$2"
|
||||
shift
|
||||
;;
|
||||
--dns-persist-days | --dnspersistdays)
|
||||
_dns_persist_days="$2"
|
||||
shift
|
||||
;;
|
||||
--set-notify)
|
||||
_CMD="setnotify"
|
||||
;;
|
||||
@@ -8447,7 +8475,7 @@ _process() {
|
||||
deactivateaccount
|
||||
;;
|
||||
makednspersistvalue)
|
||||
makednspersistvalue "$_domain" "$_dns_persist_wildcard" "$_dns_persist_ca_name"
|
||||
makednspersistvalue "$_domain" "$_dns_persist_wildcard" "$_dns_persist_ca_name" "$_dns_persist_days"
|
||||
;;
|
||||
list)
|
||||
list "$_listraw" "$_domain"
|
||||
|
||||
Reference in New Issue
Block a user