CertIntel DNS-01 plugin for Certbot¶
certbot-dns-certintel publishes and removes DNS-01 TXT challenge values through
CertIntel. Certbot handles certificate orders, keys, files and renewal. This
plugin does not install certificates or enroll a CertIntel agent.
Requires Linux/Unix, Python 3.10+, and Certbot 2.9 through 5.x. Tested with Certbot 5.8.0. Use Linux or WSL for Certbot; native Windows is not supported.
Download: use verified downloads, selecting certbot.
Install¶
Install Python with its venv support using your OS package manager. The commands
below assume a root shell for the system paths under /opt, /etc and /var.
For a non-root installation, use writable paths and the same account for renewal.
First complete the Linux/Unix verifier procedure in verified downloads. Use the wheel from the verified output directory, not a direct URL. For source release 0.1.1 the filename is shown below; use the exact verified filename for a later release.
python3 -m venv /opt/certintel-certbot
/opt/certintel-certbot/bin/python -m pip install \\
./verified/certbot/certbot_dns_certintel-0.1.1-py3-none-any.whl
/opt/certintel-certbot/bin/certbot plugins
Pip installs compatible dependencies too. Those dependencies are a separate supply-chain input; use your organization's approved index/constraints for reproducible installs. Pip does not verify the wheel's release attestation: the verifier must succeed first.
Confirm that dns-certintel appears. Always use this environment's certbot
binary for issuance and renewal. A pip-installed plugin is not visible to a
separate Certbot snap or system installation; no snap plugin is supplied.
Create the delegation and CNAME¶
In CertIntel, create a delegated DNS-01 record and save its UUID, update secret and full CNAME target. At your DNS provider, add the permanent CNAME:
Use the exact target supplied by CertIntel. Wait until the CNAME resolves publicly.
An apex/wildcard pair (example.com and *.example.com) shares one delegation.
Other certificate names such as www.example.com require their own mapping
and corresponding challenge CNAME. The CNAME target is not the certificate name.
Configure credentials¶
This Certbot plugin currently uses a JSON mapping file. It does not provide a Posh-ACME-style vault integration. Create a private directory:
Using a text editor, create /etc/certintel/delegations.json with your actual
values. Do not leave the example UUID, label or secret unchanged:
{
"apiBase": "https://api.certin.tel/api/v1",
"delegations": {
"example.com": {
"delegationId": "11111111-1111-1111-1111-111111111111",
"cnameTarget": "YOUR-LABEL.dns01.certin.tel",
"apiKey": "YOUR-DELEGATION-UPDATE-SECRET"
}
}
}
Then restrict access:
The apiBase must include /api/v1; use a different HTTPS endpoint if needed.
apiKey can also be a CertIntel DNS API key explicitly granted access to that
delegation. Add sibling entries under delegations for multiple names, each
with its own UUID, CNAME target and key. An entry can override apiBase for a
different endpoint. Mapping keys exclude *. and _acme-challenge. and match
certificate names exactly.
The renewal account needs read access to this file and write access to its
directory for .certintel-locks. Keep the absolute file path stable for renewal.
Test against the staging CA¶
This example isolates staging state from production:
/opt/certintel-certbot/bin/certbot certonly \
--authenticator dns-certintel \
--dns-certintel-credentials /etc/certintel/delegations.json \
--dns-certintel-propagation-seconds 60 \
--config-dir /etc/letsencrypt-certintel-staging \
--work-dir /var/lib/letsencrypt-certintel-staging \
--logs-dir /var/log/letsencrypt-certintel-staging \
--staging --agree-tos --email [email protected] \
--cert-name example.com-staging \
-d example.com -d '*.example.com'
Replace the domain and email. Quote wildcard names to prevent shell expansion. The default propagation wait is 60 seconds; increase it if DNS caching requires more time. Confirm successful issuance and removal of both TXT challenge values. Staging certificates are not publicly trusted.
Issue a production certificate¶
After staging succeeds, issue using Certbot's normal production directories:
/opt/certintel-certbot/bin/certbot certonly \
--authenticator dns-certintel \
--dns-certintel-credentials /etc/certintel/delegations.json \
--dns-certintel-propagation-seconds 60 \
--agree-tos --email [email protected] \
--cert-name example.com \
-d example.com -d '*.example.com'
With these default paths, the certificate chain is
/etc/letsencrypt/live/example.com/fullchain.pem and the private key is
/etc/letsencrypt/live/example.com/privkey.pem. certonly obtains and stores
them without configuring a web server. Certificate deployment is a separate task.
Renewal¶
Certbot records the authenticator, credentials path and propagation delay for renewal. Test that saved configuration:
The dry run uses the staging CA. Keep the plugin installed and credentials readable under the account that will run unattended. A CA may reuse valid authorizations, so a renewal does not always publish a new TXT challenge.
For a pip/venv installation, configure a scheduler to invoke the exact binary.
For example, a root-owned /etc/cron.d/certintel-certbot file can contain:
Use your existing timer instead if it already invokes this environment; avoid
duplicate schedulers. Credential rotation requires updating the mapping file
and verifying renew --dry-run. Avoid overlapping tests and renewals against
the same delegation.
Troubleshooting¶
| Symptom | Check |
|---|---|
dns-certintel is missing |
Run plugins with the same /opt/certintel-certbot/bin/certbot used for issuance; install the wheel with that environment's Python. |
| No exact delegation mapping | Add the exact certificate name without a wildcard prefix; parent mappings do not cover subdomains. |
| API 401/403 | Check the update secret or granted DNS API key, delegation status and API endpoint. |
| API 404 or CNAME mismatch | Check delegation UUID, endpoint and full CNAME target. |
| DNS validation fails | Check the permanent CNAME and public TXT propagation; increase the propagation wait. |
| Invalid certificate identifier | Remove underscores from the certificate hostname; keep the required underscore in _acme-challenge. |
| Delegation already has two TXT values | Check for another issuer or stale values; do not clear another active challenge. |
| Cleanup warning | Inspect the delegation after issuance; cleanup failures can leave values behind. |
Use one issuing client/host per delegation. The plugin preserves other TXT values and deletes only its own, but CertIntel's API replaces the entire TXT set and permits at most two values. Local file locks cannot serialize another host, the dedicated CertIntel agent, or dashboard edits. Do not run them concurrently against the same delegation.
After a crash or cleanup failure, first confirm that no issuance is active,
then remove stale values in CertIntel before retrying. API errors omit response
bodies and secrets; Certbot logs are normally in /var/log/letsencrypt.
See also the official Certbot user guide.
Optional CertIntel reporting¶
The DNS plugin does not report check-ins or issued certificates. The separate
PowerShell 7 reporting wrappers
can add those reports. Pass the venv binary with -CertbotPath for both issuance
and renewal, and use -Authenticator dns-certintel -CredentialsPath when creating
the certificate. DNS credentials and the write-scoped reporting key are separate.
If you adopt the renewal wrapper, schedule it in place of the bare Certbot command
above so the same lineages are not run by two schedulers.