https://github.com/hellqvio86/cloudflare-request-cert
Simple Cloudflare script for requesting letsencrypt cert
https://github.com/hellqvio86/cloudflare-request-cert
Last synced: 4 months ago
JSON representation
Simple Cloudflare script for requesting letsencrypt cert
- Host: GitHub
- URL: https://github.com/hellqvio86/cloudflare-request-cert
- Owner: hellqvio86
- License: mit
- Created: 2026-01-06T08:30:42.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-03-23T19:02:02.000Z (4 months ago)
- Last Synced: 2026-03-24T17:16:01.527Z (4 months ago)
- Language: Python
- Homepage:
- Size: 728 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Cloudflare Request Cert





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](https://github.com/astral-sh/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
```bash
# Install dependencies (will install uv if not present)
make install
```
### Manual uv Installation
If you prefer to install uv manually:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
## Configuration
### 1. Get Cloudflare API Token
1. Log in to your [Cloudflare dashboard](https://dash.cloudflare.com/)
2. Go to **My Profile** โ **API 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:
```bash
# Copy the example file
cp .env.example .env
# Edit with your credentials
nano .env
```
Your `.env` file can contain:
```bash
# 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:
```bash
# .env file contains: CLOUDFLARE_API_TOKEN, DOMAIN, EMAIL
cloudflare-request-cert
```
#### 2. Using Command-Line Arguments Only
```bash
# 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)
```bash
# 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:
```bash
# 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
```bash
# 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:
```bash
# .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:
```bash
# 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:
```bash
# 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
```bash
make dev
```
### Run Tests
```bash
make test
```
### Run Linting
```bash
make lint
```
### Format Code
```bash
make format
```
### Run All Checks
```bash
make check
```
### Generate SBOM
Generate a Software Bill of Materials (SBOM) in CycloneDX JSON format:
```bash
make sbom
```
The SBOM will be saved to `bom.json`.
## Example Workflows
### First Time Setup
```bash
# 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
```bash
# 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
```bash
#!/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:
```bash
make install
# or
uv sync
```
### "CLOUDFLARE_API_TOKEN is required"
Make sure your `.env` file exists and contains:
```bash
CLOUDFLARE_API_TOKEN=your_actual_token_here
```
### "DOMAIN is required" or "EMAIL is required"
Either set them in `.env`:
```bash
DOMAIN=example.com
EMAIL=admin@example.com
```
Or pass them as arguments:
```bash
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:
```bash
cloudflare-request-cert -d example.com -e admin@example.com --propagation-seconds 60
```
Or set in `.env`:
```bash
PROPAGATION_SECONDS=60
```
### Rate Limits
Let's Encrypt has rate limits. Use staging for testing:
```bash
# 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](https://github.com/hellqvio86/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
- [Cloudflare API Documentation](https://developers.cloudflare.com/api/)
- [Certbot Documentation](https://eff-certbot.readthedocs.io/)
- [Let's Encrypt](https://letsencrypt.org/)
- [uv Documentation](https://github.com/astral-sh/uv)