CertsD-open - open-source, automated, asynchronous LE certificate issuer
Daniel (@dmilith) Dettlaff
Generates separate certificates for the root domain and its wildcard version.
Uses RON formatted configuration.
Supports multiple CloudFlare accounts and multiple domains/ zones at once.
Automatic management of DNS TXT records via the CloudFlare API.
Notifies Slack using a Webhook after a successful renewal.
Asynchronous by default.
CloudFlare API Token (with "Edit zone DNS" permission).
CloudFlare Zone ID
A domain
CertsD reads the input configuration from one of the existing paths.
The ACME registration process starts in the current working directory.
Attempt to reuse all non-existent key files (account.key + example.com/domain.key + wild_example.com/domain.key) or generates them automatically.
Validate the expiration date of both certs (example.com/chained.pem and wild_example.com/chained.pem). By default, ACME provides certificates valid for 90 days. Based on that CertsD will only renew certificates that have less than 60 days of validity time.
ACME process creates the DNS challenge.
A DNS TXT record for a given domain (with the value of the challenge) is created using CF API.
Await confirmation of the order from the ACME response.
A DNS TXT record for a given domain is deleted using CF API.
After order confirmation, the (example.com/chained.pem + wild_example.com/chained.pem) are fetched from ACME.
CertsD stability relies on the stability of ACME services. Don't panic. Be patient.
From time to time the ACME API responds with a random "invalid" status just because. Don't panic. Be patient.
If you won't remove one of (account.key+example.com/domain.key+wild_example.com/domain.key`) too often, the ACME is likely to renew your certs faster without any issues (ACME cert caching mechanism).
If you want to use ACME Staging for testing, set the acme_staging: true in your configuration.
NOTE: I hold the configuration under
/Services/Certsd/service.conf, all keys and generated certificates under/Services/Certsd.
```ron ( acmestaging: false, accounts: [ ( cloudflareapitoken: "cloudflare-api-token", cloudflarezone_id: "cloudflare-zone-id", domain: "myexample.com", contacts: ["domains@example.com"], ), ],
slack_webhook: "https://hooks.slack.com/services/AAAAAAAAAAA/AAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAA",
) ```
```cron
30 23 7,14,24 * * "cd /Services/Certsd && /Software/Certsd/exports/certsd >> /var/log/renew-example.com.log" ```
chained.pem to remote hosts):```conf server { listen 80; server_name my.example.com; autoindex off;
location ~ .*/chained.pem { root /var/www/certsd; }
location / { deny all; } } ```