Skip to content

hellqvio86/cloudflare-request-cert

Repository files navigation

Cloudflare Request Cert

Python Version PyPI Build Coverage License

A Python tool for requesting and renewing SSL/TLS certificates using Cloudflare DNS API with Let's Encrypt. Built with modern Python tooling using uv for fast dependency management.

Disclaimer: This project is not affiliated with, endorsed by, or supported by Cloudflare.

Features

  • 🔒 Automated SSL/TLS certificate requests using DNS-01 challenge
  • ☁️ Cloudflare DNS API integration
  • ⚡ Fast dependency management with uv
  • 🛠️ Simple Makefile interface
  • 🔄 Support for certificate renewal
  • 🧪 Staging environment support for testing
  • 📝 Configuration via .env file or command-line arguments
  • 🔧 Flexible: use .env, CLI args, or both

Prerequisites

  • Python 3.10 or higher
  • A Cloudflare account with API token
  • Domain managed by Cloudflare DNS

Installation

Quick Setup

# Install dependencies (will install uv if not present)
make install

Manual uv Installation

If you prefer to install uv manually:

curl -LsSf https://astral.sh/uv/install.sh | sh

Configuration

1. Get Cloudflare API Token

  1. Log in to your Cloudflare dashboard
  2. Go to My ProfileAPI Tokens
  3. Create a token with these permissions:
    • Zone:DNS:Edit for the zones you want to manage
    • Zone:Zone:Read for all zones

2. Set Up Credentials

Create a .env file in the project root:

# Copy the example file
cp .env.example .env

# Edit with your credentials
nano .env

Your .env file can contain:

# Required
CLOUDFLARE_API_TOKEN=your_cloudflare_api_token_here

# Optional (can also be passed as CLI arguments)
DOMAIN=example.com
EMAIL=admin@example.com

# Optional settings
STAGING=0                    # Set to 1 for staging/test certificates
PROPAGATION_SECONDS=10       # DNS propagation wait time

Security Note: The .env file is already in .gitignore. Never commit API tokens to version control.

Usage

Three Ways to Use This Tool

1. Using .env File Only

Set everything in .env and run without arguments:

# .env file contains: CLOUDFLARE_API_TOKEN, DOMAIN, EMAIL
cloudflare-request-cert

2. Using Command-Line Arguments Only

# Provide all parameters via CLI (API token still from .env or environment)
cloudflare-request-cert -d example.com -e admin@example.com

3. Mix of Both (Recommended)

# Store sensitive data in .env, pass domain/email via CLI
# This is useful when managing multiple domains
cloudflare-request-cert -d example.com -e admin@example.com

Using Make Commands

Request a certificate with Make:

# Basic usage
make run DOMAIN=example.com EMAIL=admin@example.com

# Test with staging first (recommended)
make run DOMAIN=example.com EMAIL=admin@example.com STAGING=1

Advanced Options

# Custom DNS propagation time
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --propagation-seconds 30

# Use staging environment for testing
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --staging

# Use custom .env file
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --env-file /path/to/custom.env

Priority Order

When the same setting is provided in multiple places, this is the priority order (highest to lowest):

  1. Command-line arguments (highest priority)
  2. .env file
  3. Environment variables (lowest priority)

Example:

# .env has DOMAIN=old.com
# This will use new.com (CLI argument takes precedence)
cloudflare-request-cert -d new.com -e admin@example.com

Makefile Commands

Command Description
make help Show all available commands
make venv Create virtual environment
make install Install uv and sync dependencies (alias for venv)
make sync Sync dependencies with uv
make dev Install development dependencies
make run Run the certificate request tool
make lint Lint code with ruff
make format Format code with ruff
make check Run all checks (lint + format)
make test Run tests
make sbom Generate SBOM (Software Bill of Materials)
make clean Remove virtual environment and cache

Certificate Locations

After successful certificate generation, your certificates will be stored at:

/etc/letsencrypt/live/your-domain.com/
├── cert.pem       # Your certificate
├── chain.pem      # The certificate chain
├── fullchain.pem  # cert.pem + chain.pem
└── privkey.pem    # Your private key

DNS Propagation Time

The tool waits for DNS changes to propagate before Let's Encrypt validates your domain. Default is 10 seconds, but you can adjust this:

# Via CLI
cloudflare-request-cert -d example.com -e admin@example.com --propagation-seconds 30

# Via .env
PROPAGATION_SECONDS=30

Automatic Renewal

Certbot automatically handles renewal. Set up a cron job or systemd timer:

# Cron example (runs daily at 2 AM)
0 2 * * * certbot renew --quiet

# Or use systemd timer (recommended)
sudo systemctl enable --now certbot-renew.timer

Development

Install Development Dependencies

make dev

Run Tests

make test

Run Linting

make lint

Format Code

make format

Run All Checks

make check

Generate SBOM

Generate a Software Bill of Materials (SBOM) in CycloneDX JSON format:

make sbom

The SBOM will be saved to bom.json.

Example Workflows

First Time Setup

# 1. Install dependencies
make install

# 2. Set up configuration
cp .env.example .env
nano .env  # Add your Cloudflare API token

# 3. Test with staging (won't affect rate limits)
cloudflare-request-cert -d example.com -e admin@example.com --staging

# 4. Get production certificate
cloudflare-request-cert -d example.com -e admin@example.com

Managing Multiple Domains

# Store API token in .env
echo "CLOUDFLARE_API_TOKEN=your_token" > .env

# Request certificates for different domains
cloudflare-request-cert -d site1.com -e admin@site1.com
cloudflare-request-cert -d site2.com -e admin@site2.com
cloudflare-request-cert -d site3.com -e admin@site3.com

Automated Script

#!/bin/bash
# renew-certs.sh

DOMAINS=("site1.com" "site2.com" "site3.com")
EMAIL="admin@example.com"

for domain in "${DOMAINS[@]}"; do
    echo "Requesting certificate for $domain..."
    cloudflare-request-cert -d "$domain" -e "$EMAIL"
done

Troubleshooting

"certbot not found"

Install certbot and the Cloudflare plugin:

make install
# or
uv sync

"CLOUDFLARE_API_TOKEN is required"

Make sure your .env file exists and contains:

CLOUDFLARE_API_TOKEN=your_actual_token_here

"DOMAIN is required" or "EMAIL is required"

Either set them in .env:

DOMAIN=example.com
EMAIL=admin@example.com

Or pass them as arguments:

cloudflare-request-cert -d example.com -e admin@example.com

API Token Permissions

Ensure your Cloudflare API token has:

  • Zone:DNS:Edit permissions
  • Zone:Zone:Read permissions

DNS Propagation Issues

If validation fails, try increasing propagation time:

cloudflare-request-cert -d example.com -e admin@example.com --propagation-seconds 60

Or set in .env:

PROPAGATION_SECONDS=60

Rate Limits

Let's Encrypt has rate limits. Use staging for testing:

# Set in .env
STAGING=1

# Or via CLI
cloudflare-request-cert -d example.com -e admin@example.com --staging

Comparison with Original

This is a Cloudflare remake of the loopia-request-cert tool with several improvements:

  • Uses Cloudflare instead of Loopia DNS
  • Uses uv for faster dependency management (10-100x faster than pip)
  • Modern pyproject.toml configuration
  • Improved Makefile with more commands
  • Better error handling and user feedback
  • Flexible configuration: .env file, CLI args, or both
  • Type hints for better code quality
  • Ruff for linting and formatting
  • Comprehensive tests

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Resources

About

Simple Cloudflare script for requesting letsencrypt cert

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •