acme-love-cloudflare
v1.1.0
Published
Cloudflare DNS-01 challenge solver for acme-love — automate Let's Encrypt certificates with Cloudflare DNS
Downloads
451
Maintainers
Readme
acme-love-cloudflare
Cloudflare DNS-01 challenge solver for acme-love — automate Let's Encrypt certificates with Cloudflare DNS.
Installation
npm install acme-love acme-love-cloudflareUsage
import { AcmeClient, AcmeAccount, provider, generateKeyPair, createAcmeCsr } from 'acme-love';
import { createCloudflareDns01Solver } from 'acme-love-cloudflare';
const client = new AcmeClient(provider.letsencrypt.production);
const algo = { kind: 'ec', namedCurve: 'P-256', hash: 'SHA-256' } as const;
const accountKeys = await generateKeyPair(algo);
const account = new AcmeAccount(client, accountKeys);
await account.register({ contact: '[email protected]', termsOfServiceAgreed: true });
const order = await account.createOrder(['example.com', '*.example.com']);
// Create Cloudflare DNS-01 solver
const solver = createCloudflareDns01Solver({
apiToken: process.env.CF_API_TOKEN!,
});
// Solve challenges automatically
const ready = await account.solveDns01(order, solver);
// Remove all _acme-challenge TXT records
await solver.cleanupAll();
// Finalize and download certificate
const { derBase64Url } = await createAcmeCsr(['example.com', '*.example.com'], algo);
const finalized = await account.finalize(ready, derBase64Url);
const valid = await account.waitOrder(finalized, ['valid']);
const cert = await account.downloadCertificate(valid);Configuration
const solver = createCloudflareDns01Solver({
// Required: Cloudflare API token with Zone.DNS edit permissions
apiToken: process.env.CF_API_TOKEN!,
// Optional: zone ID (auto-detected if omitted)
zoneId: 'your-zone-id',
// Optional: DNS propagation check interval (default: 5000ms)
propagationInterval: 5_000,
// Optional: max propagation wait time (default: 120000ms)
propagationTimeout: 120_000,
});Cleanup
After certificate issuance, remove all _acme-challenge TXT records created during the solve:
await solver.cleanupAll();To remove a single record, pass the preparation object directly:
await solver.cleanup(preparation);Requirements
- Node.js >= 22
- acme-love >= 2.0.0
- Cloudflare API token with
Zone.DNSedit permissions
License
MIT
