Certbot Cloudflare DNS Authenticator

5.5.0 · active · verified Thu Apr 09

The `certbot-dns-cloudflare` plugin provides a DNS authenticator for Certbot, allowing you to obtain Let's Encrypt certificates using Cloudflare's DNS API. This is particularly useful for wildcard certificates. It is part of the larger Certbot project, currently at version 5.5.0, with minor releases typically aligned with Certbot's bimonthly schedule.

Warnings

Install

Imports

Quickstart

This quickstart script demonstrates how to obtain a certificate for your domain(s) using Certbot and the `certbot-dns-cloudflare` plugin. It creates a temporary credentials file for your Cloudflare API token (read from `CLOUDFLARE_API_TOKEN` environment variable for security) and then executes the `certbot` command. Remember to replace `yourdomain.com` and `your@email.com` with your actual details, and set the `CLOUDFLARE_API_TOKEN` environment variable. Use `--test-cert` for initial testing.

import os
import subprocess
import tempfile
import stat

# --- Configuration for your domain and Cloudflare ---
DOMAIN = "yourdomain.com" # Replace with your actual domain
EMAIL = "your@email.com"  # Replace with your actual email

# --- Cloudflare API Token (recommended) ---
# For production, ensure this token has Zone DNS Write permissions for your domain.
# Generate it at: https://dash.cloudflare.com/profile/api-tokens
# Set this as an environment variable: export CLOUDFLARE_API_TOKEN="YOUR_TOKEN"
CLOUDFLARE_API_TOKEN = os.environ.get('CLOUDFLARE_API_TOKEN', 'YOUR_PLACEHOLDER_TOKEN')

if CLOUDFLARE_API_TOKEN == 'YOUR_PLACEHOLDER_TOKEN':
    print("WARNING: CLOUDFLARE_API_TOKEN environment variable not set. Using a placeholder.")
    print("         This quickstart will likely fail without a valid token.")
    print("         Set it using: export CLOUDFLARE_API_TOKEN=\"<YOUR_TOKEN>\"")

# --- Create a temporary credentials file ---
# This file will store your Cloudflare API token securely.
# Certbot requires this file to have restricted permissions (read-only for owner).
temp_dir = tempfile.mkdtemp()
credentials_path = os.path.join(temp_dir, 'cloudflare.ini')

try:
    with open(credentials_path, 'w') as f:
        f.write(f"dns_cloudflare_api_token = {CLOUDFLARE_API_TOKEN}\n")
    # Set permissions: owner read-only (0o400)
    os.chmod(credentials_path, stat.S_IRUSR)
    print(f"Created temporary credentials file: {credentials_path}")

    # --- Construct and run the Certbot command ---
    # This command obtains a certificate for your domain(s) using Cloudflare DNS.
    # --dns-cloudflare-propagation-seconds: Adjust if DNS changes are slow to propagate.
    # --test-cert: Use for testing to avoid hitting Let's Encrypt rate limits. Remove for production.
    certbot_command = [
        "certbot",
        "certonly",
        "--dns-cloudflare",
        f"--dns-cloudflare-credentials={credentials_path}",
        "--dns-cloudflare-propagation-seconds", "60",
        "-d", DOMAIN,
        "-d", f"*.{DOMAIN}", # Uncomment if you need a wildcard certificate
        "--email", EMAIL,
        "--agree-tos",
        "--non-interactive",
        "--keep-until-expiring",
        "--test-cert" # IMPORTANT: Use this for initial testing! Remove for actual certificate issuance.
    ]

    print("\nAttempting to run Certbot command:")
    print(f"$ {' '.join(certbot_command)}")

    # Execute the command
    result = subprocess.run(certbot_command, capture_output=True, text=True, check=False) # check=False to capture output on error

    print("\n--- Certbot Output ---")
    print(result.stdout)
    if result.stderr:
        print("\n--- Certbot Errors ---")
        print(result.stderr)

    if result.returncode == 0:
        print("\nSUCCESS: Certbot command completed. Check output for certificate path.")
    else:
        print(f"\nFAILURE: Certbot command exited with code {result.returncode}.")
        print("Please review the output above, ensure your Cloudflare API token is valid and has correct permissions, and that your domain is managed by Cloudflare.")

except FileNotFoundError:
    print("\nERROR: 'certbot' command not found. Please ensure Certbot is installed and in your PATH.")
    print("       (e.g., pip install certbot certbot-dns-cloudflare or snap install certbot --classic)")
except Exception as e:
    print(f"\nAn unexpected Python error occurred: {e}")
finally:
    # --- Clean up temporary files ---
    if os.path.exists(credentials_path):
        os.remove(credentials_path)
        print(f"\nRemoved temporary credentials file: {credentials_path}")
    if os.path.exists(temp_dir):
        os.rmdir(temp_dir)
        print(f"Removed temporary directory: {temp_dir}")

view raw JSON →