๐Ÿ” CertMate - SSL Certificate Management System ๐ŸŒŸ Why CertMate? CertMate solves the complexity of SSL certificate management in modern distributed architectures. Whether you're running a single application or managing certificates across multiple datacenters, CertMate provides: ๐Ÿ”„ Zero-Downtime Automation - Certificates renew automatically 30 days before expiry - Certificates renew automatically 30 days before expiry ๐ŸŒ Multi-Cloud Support - Works with 19 DNS providers (Cloudflare, AWS, Azure, GCP, Hetzner, Porkbun, GoDaddy, and more) - Works with 19 DNS providers (Cloudflare, AWS, Azure, GCP, Hetzner, Porkbun, GoDaddy, and more) ๐Ÿš€ Enterprise-Ready - Docker, Kubernetes, REST API, and monitoring built-in - Docker, Kubernetes, REST API, and monitoring built-in ๐Ÿ“ฆ Simple Integration - One-URL certificate downloads for easy automation - One-URL certificate downloads for easy automation ๐Ÿ”’ Security-First - Bearer token authentication, secure file permissions, audit logging โœจ Key Features ๐Ÿ” Certificate Management Let's Encrypt Integration - Free, automated SSL certificates - Free, automated SSL certificates Wildcard Support - Single certificate for *.example.com and example.com - Single certificate for and Multi-Domain Certificates - SAN certificates for multiple domains - SAN certificates for multiple domains Automatic Renewal - Smart renewal 30 days before expiry - Smart renewal 30 days before expiry Certificate Validation - Real-time SSL certificate status checking ๐ŸŒ Multi-DNS Provider Support Cloudflare - Global CDN with edge locations worldwide - Global CDN with edge locations worldwide AWS Route53 - Amazon's scalable DNS service - Amazon's scalable DNS service Azure DNS - Microsoft's cloud DNS solution - Microsoft's cloud DNS solution Google Cloud DNS - Google's high-performance DNS - Google's high-performance DNS PowerDNS - Open-source DNS server with REST API ๐Ÿš€ Enterprise Features REST API - Complete programmatic control with Swagger/OpenAPI docs - Complete programmatic control with Swagger/OpenAPI docs Web Dashboard - Modern, responsive UI built with Tailwind CSS - Modern, responsive UI built with Tailwind CSS Docker Ready - Full containerization with Docker Compose - Full containerization with Docker Compose Kubernetes Compatible - Deploy in any Kubernetes cluster - Deploy in any Kubernetes cluster High Availability - Stateless design for horizontal scaling - Stateless design for horizontal scaling Monitoring Integration - Health checks and structured logging ๏ฟฝ Security & Compliance Bearer Token Authentication - Secure API access control - Secure API access control File Permissions - Proper certificate file security (600/700) - Proper certificate file security (600/700) Audit Logging - Complete certificate lifecycle tracking - Complete certificate lifecycle tracking Environment Variables - Secure credential management - Secure credential management Rate Limit Handling - Let's Encrypt rate limit awareness ๏ฟฝ Developer Experience One-URL Downloads - Simple certificate retrieval for automation - Simple certificate retrieval for automation Multiple Output Formats - PEM, ZIP, individual files - PEM, ZIP, individual files SDK Examples - Python, Bash, Ansible, Terraform examples - Python, Bash, Ansible, Terraform examples Webhook Support - Certificate renewal notifications - Certificate renewal notifications Extensive Documentation - API docs, guides, and examples ๐ŸŒ Supported DNS Providers CertMate supports 19 DNS providers through Let's Encrypt DNS-01 challenge via individual certbot plugins that provide reliable, well-tested DNS challenge support: Provider Credentials Required Use Case Status ๐Ÿ”ถ Cloudflare API Token Global CDN, Free tier available โœ… Stable ๐ŸŸ  AWS Route53 Access Key, Secret Key AWS infrastructure, Enterprise โœ… Stable ๐Ÿ”ต Azure DNS Service Principal credentials Microsoft ecosystem โœ… Stable ๐ŸŸข Google Cloud DNS Service Account JSON Google Cloud Platform โœ… Stable โšซ PowerDNS API URL, API Key Self-hosted, On-premises โœ… Stable ๐Ÿ”ท DigitalOcean API Token Cloud infrastructure โœ… Stable ๐ŸŸฃ Linode API Key Cloud hosting โœ… Stable ๐ŸŸก Gandi API Token Domain registrar โœ… Stable ๐Ÿ”ด OVH API Credentials European hosting โœ… Stable ๐ŸŸข Namecheap Username, API Key Domain registrar โœ… Stable ๐ŸŸฆ Vultr API Key Global cloud infrastructure โœ… Stable ๐Ÿ”บ DNS Made Easy API Key, Secret Key Enterprise DNS management โœ… Stable ๐ŸŸฃ NS1 API Key Intelligent DNS platform โœ… Stable ๐Ÿ”ท RFC2136 Nameserver, TSIG Key/Secret Standard DNS update protocol โœ… Stable ๐ŸŸ  Hetzner API Token European cloud hosting โœ… Stable ๐ŸŸก Porkbun API Key, Secret Key Domain registrar with DNS โœ… Stable ๐ŸŸข GoDaddy API Key, Secret Popular domain registrar โœ… Stable ๐Ÿ”ต Hurricane Electric Username, Password Free DNS hosting โœ… Stable ๐Ÿ”ถ Dynu API Token Dynamic DNS service โœ… Stable ๐ŸŒŸ Provider Categories Cloud Providers : AWS Route53, Azure DNS, Google Cloud DNS, DigitalOcean, Linode, Vultr, Hetzner : AWS Route53, Azure DNS, Google Cloud DNS, DigitalOcean, Linode, Vultr, Hetzner Enterprise DNS : Cloudflare, DNS Made Easy, NS1, PowerDNS : Cloudflare, DNS Made Easy, NS1, PowerDNS Domain Registrars : Gandi, OVH, Namecheap, Porkbun, GoDaddy : Gandi, OVH, Namecheap, Porkbun, GoDaddy European Providers : OVH, Gandi, Hetzner : OVH, Gandi, Hetzner Free Services : Hurricane Electric, Dynu : Hurricane Electric, Dynu Standard Protocols: RFC2136 (for BIND and compatible servers) ๐Ÿ“š Detailed Setup Instructions: See DNS_PROVIDERS.md for provider-specific configuration. ๐Ÿ”ง Step-by-Step Installation: See INSTALLATION.md for complete setup guide. ๐Ÿš€ Quick Start with Docker Get CertMate running in under 5 minutes with Docker Compose: Prerequisites Docker 20.10+ Docker Compose 2.0+ Domain with DNS managed by supported provider 1. Clone and Setup # Clone the repository git clone https://github.com/fabriziosalmi/certmate.git cd certmate # Copy environment template cp .env.example .env 2. Configure Environment Edit .env file with your credentials: # ๐Ÿ”’ Required: API Security API_BEARER_TOKEN=your_super_secure_api_token_here_change_this # ๐ŸŒ DNS Provider Configuration (choose one or multiple) # Option 1: Cloudflare (Recommended for beginners) CLOUDFLARE_TOKEN=your_cloudflare_api_token_here # Option 2: AWS Route53 # AWS_ACCESS_KEY_ID=your_aws_access_key # AWS_SECRET_ACCESS_KEY=your_aws_secret_key # AWS_DEFAULT_REGION=us-east-1 # Option 3: Azure DNS # AZURE_SUBSCRIPTION_ID=your_azure_subscription_id # AZURE_RESOURCE_GROUP=your_resource_group # AZURE_TENANT_ID=your_tenant_id # AZURE_CLIENT_ID=your_client_id # AZURE_CLIENT_SECRET=your_client_secret # Option 4: Google Cloud DNS # GOOGLE_PROJECT_ID=your_gcp_project_id # GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json # Option 5: PowerDNS # POWERDNS_API_URL=https://your-powerdns-server:8081 # POWERDNS_API_KEY=your_powerdns_api_key # โš™๏ธ Optional: Application Settings SECRET_KEY=your_flask_secret_key_here FLASK_ENV=production HOST=0.0.0.0 PORT=8000 3. Deploy # Start all services docker-compose up -d # Check status docker-compose ps # View logs docker-compose logs -f certmate 4. Access CertMate Service URL Description Web Dashboard http://localhost:8000 Main certificate management interface API Documentation http://localhost:8000/docs/ Interactive Swagger/OpenAPI docs Alternative API Docs http://localhost:8000/redoc/ ReDoc documentation Health Check http://localhost:8000/health Service health monitoring 5. Create Your First Certificate Using the Web Interface: Navigate to http://localhost:8000 Go to Settings and configure your DNS provider Add your domain (e.g. example.com ) Click "Create Certificate" Using the API: curl -X POST " http://localhost:8000/api/certificates/create " \ -H " Authorization: Bearer your_api_token_here " \ -H " Content-Type: application/json " \ -d ' {"domain": "example.com"} ' ๐Ÿ“‹ Installation Methods Choose the installation method that best fits your environment: ๐Ÿณ Docker (Recommended) Perfect for production deployments with isolation and easy scaling. Supports multiple architectures: AMD64 (Intel/AMD), ARM64 (Apple Silicon, ARM servers), and ARM v7 (Raspberry Pi). # Quick start with Docker Compose git clone https://github.com/fabriziosalmi/certmate.git cd certmate cp .env.example .env # Edit .env with your configuration docker-compose up -d Multi-Platform Support: # Build for multiple architectures (ARM64 + AMD64) ./build-multiplatform.sh # Build and push to Docker Hub for all platforms ./build-multiplatform.sh -r YOUR_DOCKERHUB_USERNAME -p # Use pre-built multi-platform image docker run --platform linux/arm64 -d --name certmate --env-file .env -p 8000:8000 USERNAME/certmate:latest ๐Ÿ“š Multi-Platform Guide: See DOCKER_MULTIPLATFORM.md for comprehensive multi-architecture setup instructions. ๐Ÿ Python Virtual Environment Ideal for development and testing environments. # Create and activate virtual environment python3 -m venv certmate-env source certmate-env/bin/activate # On Windows: certmate-env\Scripts\activate # Install dependencies git clone https://github.com/fabriziosalmi/certmate.git cd certmate pip install -r requirements.txt # Set environment variables export API_BEARER_TOKEN= " your_token_here " export CLOUDFLARE_TOKEN= " your_cloudflare_token " # Run the application python app.py โ˜ธ๏ธ Kubernetes For container orchestration and high availability deployments. # Example Kubernetes deployment apiVersion : apps/v1 kind : Deployment metadata : name : certmate spec : replicas : 2 selector : matchLabels : app : certmate template : metadata : labels : app : certmate spec : containers : - name : certmate image : certmate:latest ports : - containerPort : 8000 env : - name : API_BEARER_TOKEN valueFrom : secretKeyRef : name : certmate-secrets key : api-token volumeMounts : - name : certificates mountPath : /app/certificates volumes : - name : certificates persistentVolumeClaim : claimName : certmate-certificates ๐Ÿ“ฆ System Package Installation For system-wide installation on Linux distributions. # Install system dependencies (Ubuntu/Debian) sudo apt update sudo apt install python3 python3-pip python3-venv certbot openssl # Clone and install git clone https://github.com/fabriziosalmi/certmate.git sudo mv certmate /opt/ cd /opt/certmate sudo pip3 install -r requirements.txt # Create systemd service (see Service Setup section below for detailed instructions) sudo cp certmate.service /etc/systemd/system/ sudo systemctl enable certmate sudo systemctl start certmate ๐Ÿ“– Detailed Instructions: See INSTALLATION.md for complete setup guides for each method. ๐Ÿ› ๏ธ Service Setup For production deployments, CertMate should run as a system service. This section provides comprehensive instructions for setting up CertMate with systemd on Linux distributions. Prerequisites Linux system with systemd Python 3.9 or higher Root/sudo access 1. Create Dedicated System User Create a dedicated user for running CertMate: # Create system user and group sudo useradd --system --shell /bin/false --home-dir /opt/certmate --create-home certmate # Set proper ownership sudo chown -R certmate:certmate /opt/certmate 2. Prepare Application Directory Set up the application in /opt/certmate : # If not already done, clone the repository git clone https://github.com/fabriziosalmi/certmate.git sudo mv certmate /opt/ cd /opt/certmate # Create Python virtual environment sudo -u certmate python3 -m venv venv sudo -u certmate ./venv/bin/pip install -r requirements.txt # Create necessary directories sudo -u certmate mkdir -p certificates data 3. Configure Environment Variables Create environment file for the service: # Create environment file sudo tee /opt/certmate/.env > /dev/null << EOF # ๐Ÿ”’ SECURITY: Change this token! API_BEARER_TOKEN=your_super_secure_api_token_here_change_this # Optional: Set specific host/port HOST=127.0.0.1 PORT=8000 # Optional: Enable debug mode (not recommended for production) FLASK_DEBUG=false EOF # Set proper permissions sudo chown certmate:certmate /opt/certmate/.env sudo chmod 600 /opt/certmate/.env 4. Install systemd Service Install and configure the systemd service: # Copy service file sudo cp /opt/certmate/certmate.service /etc/systemd/system/ # Reload systemd configuration sudo systemctl daemon-reload # Enable service to start on boot sudo systemctl enable certmate # Start the service sudo systemctl start certmate 5. Verify Service Status Check that the service is running correctly: # Check service status sudo systemctl status certmate # View recent logs sudo journalctl -u certmate --lines=50 # Follow logs in real-time sudo journalctl -u certmate -f 6. Service Management Commands Common commands for managing the CertMate service: # Start service sudo systemctl start certmate # Stop service sudo systemctl stop certmate # Restart service sudo systemctl restart certmate # Reload service configuration sudo systemctl reload certmate # Check if service is enabled sudo systemctl is-enabled certmate # Check if service is active sudo systemctl is-active certmate # Disable service from starting on boot sudo systemctl disable certmate 7. File Permissions Ensure proper file permissions for security: # Set ownership sudo chown -R certmate:certmate /opt/certmate # Set directory permissions sudo chmod 755 /opt/certmate sudo chmod 750 /opt/certmate/certificates /opt/certmate/data # Set file permissions sudo chmod 644 /opt/certmate/ * .py /opt/certmate/ * .md sudo chmod 600 /opt/certmate/.env sudo chmod 755 /opt/certmate/venv/bin/ * ๐Ÿ”’ Security Notes API Bearer Token : Always change the default API bearer token in /opt/certmate/.env : Always change the default API bearer token in File Permissions : The service runs with restricted permissions and limited filesystem access : The service runs with restricted permissions and limited filesystem access Network Access : The service binds to 0.0.0.0:8000 by default - consider using a reverse proxy for production : The service binds to by default - consider using a reverse proxy for production Environment File : The .env file contains sensitive data and should be readable only by the certmate user : The file contains sensitive data and should be readable only by the user Certificates: Generated certificates are stored in /opt/certmate/certificates with restricted access ๐Ÿ” Troubleshooting Service Setup If the service fails to start: Check service status: sudo systemctl status certmate View logs: sudo journalctl -u certmate --lines=100 Verify permissions: Ensure the certmate user can read all necessary files Test manually: sudo -u certmate /opt/certmate/venv/bin/python /opt/certmate/app.py Check dependencies: sudo -u certmate /opt/certmate/venv/bin/python validate_dependencies.py For more detailed installation instructions, see INSTALLATION.md. ๐Ÿ“Š API Usage CertMate provides a comprehensive REST API for programmatic certificate management. All endpoints require Bearer token authentication. ๐Ÿ” Authentication Include the Authorization header in all API requests: Authorization: Bearer your_api_token_here ๐Ÿ“ Core Endpoints Health & Status # Health check GET /health # API documentation GET /docs/ # Swagger UI GET /redoc/ # ReDoc documentation Settings Management # Get current settings GET /api/settings Authorization: Bearer your_token_here # Update settings POST /api/settings Authorization: Bearer your_token_here Content-Type: application/json { " dns_provider " : " cloudflare " , " dns_providers " : { " cloudflare " : { " api_token " : " your_cloudflare_token " } }, " domains " : [ { " domain " : " example.com " , " dns_provider " : " cloudflare " } ], " email " : " [email protected] " , " auto_renew " : true } Certificate Management # List all certificates GET /api/certificates Authorization: Bearer your_token_here # Create new certificate POST /api/certificates/create Authorization: Bearer your_token_here Content-Type: application/json { " domain " : " example.com " , " dns_provider " : " cloudflare " # Optional, uses default from settings } # Renew certificate POST /api/certificates/example.com/renew Authorization: Bearer your_token_here # Download certificate (ZIP format) GET /api/certificates/example.com/download Authorization: Bearer your_token_here # Check certificate deployment status GET /api/certificates/example.com/deployment-status Authorization: Bearer your_token_here ๐ŸŽฏ Automation-Friendly Download URL The most powerful feature for infrastructure automation: # Download certificates via simple URL pattern GET /{domain}/tls Authorization: Bearer your_token_here This endpoint returns a ZIP file containing all certificate files: cert.pem - Server certificate - Server certificate chain.pem - Intermediate certificate chain - Intermediate certificate chain fullchain.pem - Full certificate chain (cert + chain) - Full certificate chain (cert + chain) privkey.pem - Private key ๐Ÿ’ผ Integration Examples cURL Download curl -H " Authorization: Bearer your_token_here " \ -o example.com-tls.zip \ https://your-certmate-server.com/example.com/tls Python SDK Example import requests import zipfile from pathlib import Path class CertMateClient : def __init__ ( self , base_url , token ): self . base_url = base_url . rstrip ( '/' ) self . headers = { "Authorization" : f"Bearer { token } " } def download_certificate ( self , domain , extract_to = None ): """Download and optionally extract certificate for domain""" url = f" { self . base_url } / { domain } /tls" response = requests . get ( url , headers = self . headers ) response . raise_for_status () zip_path = f" { domain } -tls.zip" with open ( zip_path , 'wb' ) as f : f . write ( response . content ) if extract_to : Path ( extract_to ). mkdir ( parents = True , exist_ok = True ) with zipfile . ZipFile ( zip_path , 'r' ) as zip_ref : zip_ref . extractall ( extract_to ) return zip_path def list_certificates ( self ): """List all managed certificates""" response = requests . get ( f" { self . base_url } /api/certificates" , headers = self . headers ) response . raise_for_status () return response . json () def create_certificate ( self , domain , dns_provider = None ): """Create new certificate for domain""" data = { "domain" : domain } if dns_provider : data [ "dns_provider" ] = dns_provider response = requests . post ( f" { self . base_url } /api/certificates/create" , json = data , headers = self . headers ) response . raise_for_status () return response . json () def renew_certificate ( self , domain ): """Renew existing certificate""" response = requests . post ( f" { self . base_url } /api/certificates/ { domain } /renew" , headers = self . headers ) response . raise_for_status () return response . json () # Usage example client = CertMateClient ( "https://certmate.company.com" , "your_token_here" ) # Download certificate client . download_certificate ( "api.company.com" , extract_to = "/etc/ssl/certs/api/" ) # List all certificates certs = client . list_certificates () for cert in certs : print ( f"Domain: { cert [ 'domain' ] } , Expires: { cert [ 'expiry_date' ] } " ) Infrastructure as Code Examples Terraform Provider Example: # Configure the CertMate provider terraform { required_providers { certmate = { source = " local/certmate " version = " ~> 1.0 " } } } provider "certmate" { endpoint = " https://certmate.company.com " token = var . certmate_token } # Create certificates for multiple domains resource "certmate_certificate" "api" { domain = " api.company.com " dns_provider = " cloudflare " } resource "certmate_certificate" "web" { domain = " web.company.com " dns_provider = " route53 " } # Download certificates to local files data "certmate_certificate_download" "api" { domain = certmate_certificate . api . domain } # Use in nginx configuration resource "kubernetes_secret" "api_tls" { metadata { name = " api-tls " namespace = " default " } type = " kubernetes.io/tls " data = { " tls.crt " = data.certmate_certificate_download.api.fullchain_pem " tls.key " = data.certmate_certificate_download.api.private_key_pem } } Bash Automation Script: #! /bin/bash set -euo pipefail # Configuration CERTMATE_URL= " https://certmate.company.com " API_TOKEN= " ${CERTMATE_TOKEN} " DOMAIN= " ${1 :- example.com} " CERT_DIR= " /etc/ssl/certs/ ${DOMAIN} " BACKUP_DIR= " /backup/certs/ ${DOMAIN} / $( date +%Y%m%d_%H%M%S ) " # Functions log () { echo " [ $( date + ' %Y-%m-%d %H:%M:%S ' ) ] $* " >&2 } create_backup () { if [[ -d " $CERT_DIR " ]] ; then log " Creating backup of existing certificates " mkdir -p " $BACKUP_DIR " cp -r " $CERT_DIR " / * " $BACKUP_DIR / " || true fi } download_certificate () { log " Downloading certificate for ${DOMAIN} " # Download with retry logic for i in {1..3} ; do if curl -f -H " Authorization: Bearer $API_TOKEN " \ -o " ${DOMAIN} -tls.zip " \ " $CERTMATE_URL / $DOMAIN /tls " ; then log " Certificate downloaded successfully " return 0 else log " Download attempt $i failed, retrying... " sleep 5 fi done log " Failed to download certificate after 3 attempts " return 1 } extract_certificate () { log " Extracting certificate to ${CERT_DIR} " mkdir -p " $CERT_DIR " unzip -o " ${DOMAIN} -tls.zip " -d " $CERT_DIR " # Set proper permissions chmod 600 " $CERT_DIR " / * .pem chown root:ssl-cert " $CERT_DIR " / * .pem } reload_services () { log " Reloading web services " systemctl reload nginx || log " Failed to reload nginx " systemctl reload apache2 || log " Failed to reload apache2 " systemctl reload haproxy || log " Failed to reload haproxy " } cleanup () { rm -f " ${DOMAIN} -tls.zip " } # Main execution main () { log " Starting certificate update for ${DOMAIN} " create_backup download_certificate extract_certificate reload_services cleanup log " Certificate update completed for ${DOMAIN} " } # Trap cleanup on exit trap cleanup EXIT # Run main function main " $@ " Advanced Ansible Playbook: --- - name : Manage SSL certificates with CertMate hosts : web_servers become : yes vars : certmate_url : " https://certmate.company.com " api_token : " {{ vault_certmate_token }} " certificate_domains : - name : " api.company.com " dns_provider : " cloudflare " nginx_sites : ["api"] services_to_reload : ["nginx"] - name : " web.company.com " dns_provider : " route53 " nginx_sites : ["web", "admin"] services_to_reload : ["nginx", "haproxy"] tasks : - name : Create certificate directories file : path : " /etc/ssl/certs/{{ item.name }} " state : directory owner : root group : ssl-cert mode : ' 0750 ' loop : " {{ certificate_domains }} " - name : Check certificate expiry uri : url : " {{ certmate_url }}/api/certificates/{{ item.name }}/deployment-status " method : GET headers : Authorization : " Bearer {{ api_token }} " register : cert_status loop : " {{ certificate_domains }} " - name : Create new certificates if needed uri : url : " {{ certmate_url }}/api/certificates/create " method : POST headers : Authorization : " Bearer {{ api_token }} " Content-Type : " application/json " body_format : json body : domain : " {{ item.name }} " dns_provider : " {{ item.dns_provider }} " loop : " {{ certificate_domains }} " when : cert_status.results[ansible_loop.index0].json.needs_renewal | default(false) - name : Download certificates uri : url : " {{ certmate_url }}/{{ item.name }}/tls " method : GET headers : Authorization : " Bearer {{ api_token }} " dest : " /tmp/{{ item.name }}-tls.zip " creates : " /tmp/{{ item.name }}-tls.zip " loop : " {{ certificate_domains }} " - name : Extract certificates unarchive : src : " /tmp/{{ item.name }}-tls.zip " dest : " /etc/ssl/certs/{{ item.name }}/ " owner : root group : ssl-cert mode : ' 0640 ' remote_src : yes loop : " {{ certificate_domains }} " notify : - reload nginx - reload haproxy - restart services - name : Verify certificate installation openssl_certificate : path : " /etc/ssl/certs/{{ item.name }}/fullchain.pem " provider : assertonly has_expired : no valid_in : 86400 # Valid for at least 1 day loop : " {{ certificate_domains }} " - name : Update nginx SSL configuration template : src : " nginx-ssl.conf.j2 " dest : " /etc/nginx/sites-available/{{ item.1 }} " backup : yes loop : " {{ certificate_domains | subelements('nginx_sites') }} " notify : reload nginx - name : Cleanup temporary files file : path : " /tmp/{{ item.name }}-tls.zip " state : absent loop : " {{ certificate_domains }} " handlers : - name : reload nginx systemd : name : nginx state : reloaded - name : reload haproxy systemd : name : haproxy state : reloaded - name : restart services systemd : name : " {{ item }} " state : restarted loop : " {{ services_to_restart | default([]) }} " โš™๏ธ Configuration Guide ๐Ÿ”ง Environment Variables Variable Required Default Description API_BEARER_TOKEN โœ… - Bearer token for API authentication SECRET_KEY โŒ auto-generated Flask secret key for sessions HOST โŒ 127.0.0.1 Server bind address PORT โŒ 8000 Server port FLASK_ENV โŒ production Flask environment FLASK_DEBUG โŒ false Enable debug mode ๐ŸŒ DNS Provider Configuration Cloudflare Setup Go to Cloudflare API Tokens Click "Create Token" โ†’ "Custom token" Set permissions: Zone : DNS:Edit + Zone:Read : + Zone Resources: Include specific zones or all zones Copy the generated token # Environment variable CLOUDFLARE_TOKEN=your_cloudflare_api_token_here AWS Route53 Setup Create IAM user with Route53 permissions Attach policy: Route53FullAccess or custom policy: { "Version" : " 2012-10-17 " , "Statement" : [ { "Effect" : " Allow " , "Action" : [ " route53:ListHostedZones " , " route53:GetChange " , " route53:ChangeResourceRecordSets " ], "Resource" : " * " } ] } # Environment variables AWS_ACCESS_KEY_ID=your_access_key_id AWS_SECRET_ACCESS_KEY=your_secret_access_key AWS_DEFAULT_REGION=us-east-1 Azure DNS Setup Create Service Principal: az ad sp create-for-rbac --name " CertMate " --role " DNS Zone Contributor " --scopes " /subscriptions/{subscription-id}/resourceGroups/{resource-group} " # Environment variables AZURE_SUBSCRIPTION_ID=your_subscription_id AZURE_RESOURCE_GROUP=your_resource_group_name AZURE_TENANT_ID=your_tenant_id AZURE_CLIENT_ID=your_client_id AZURE_CLIENT_SECRET=your_client_secret Google Cloud DNS Setup Create service account with DNS Administrator role Download JSON key file # Environment variables GOOGLE_PROJECT_ID=your_project_id GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json PowerDNS Setup # Environment variables POWERDNS_API_URL=https://your-powerdns-server:8081 POWERDNS_API_KEY=your_api_key ๐Ÿ“ Directory Structure certmate/ โ”œโ”€โ”€ ๐Ÿ“„ app.py # Main Flask application โ”œโ”€โ”€ ๐Ÿ“„ requirements.txt # Python dependencies โ”œโ”€โ”€ ๐Ÿ“„ docker-compose.yml # Docker Compose configuration โ”œโ”€โ”€ ๐Ÿ“„ Dockerfile # Container build instructions โ”œโ”€โ”€ ๐Ÿ“„ nginx.conf # Nginx reverse proxy config โ”œโ”€โ”€ ๐Ÿ“„ .env.example # Environment template โ”œโ”€โ”€ ๐Ÿ“š README.md # This documentation โ”œโ”€โ”€ ๐Ÿ“š INSTALLATION.md # Detailed installation guide โ”œโ”€โ”€ ๐Ÿ“š DNS_PROVIDERS.md # DNS provider configuration โ”œโ”€โ”€ ๐Ÿ“š CONTRIBUTING.md # Contribution guidelines โ”œโ”€โ”€ ๐Ÿ“ certificates/ # Certificate storage โ”‚ โ””โ”€โ”€ ๐Ÿ“ {domain}/ โ”‚ โ”œโ”€โ”€ ๐Ÿ” cert.pem # Server certificate โ”‚ โ”œโ”€โ”€ ๐Ÿ” chain.pem # Certificate chain โ”‚ โ”œโ”€โ”€ ๐Ÿ” fullchain.pem # Full chain โ”‚ โ””โ”€โ”€ ๐Ÿ” privkey.pem # Private key โ”œโ”€โ”€ ๐Ÿ“ data/ # Application data โ”‚ โ””โ”€โ”€ โš™๏ธ settings.json # Persistent settings โ”œโ”€โ”€ ๐Ÿ“ logs/ # Application logs โ”œโ”€โ”€ ๐Ÿ“ letsencrypt/ # Let's Encrypt working directory โ”‚ โ”œโ”€โ”€ ๐Ÿ“ config/ # Certbot configuration โ”‚ โ”œโ”€โ”€ ๐Ÿ“ work/ # Certbot working files โ”‚ โ””โ”€โ”€ ๐Ÿ“ logs/ # Certbot logs โ””โ”€โ”€ ๐Ÿ“ templates/ # Web interface templates โ”œโ”€โ”€ ๐ŸŒ index.html # Main dashboard โ””โ”€โ”€ โš™๏ธ settings.html # Settings page ๐Ÿ”’ Security & Best Practices ๐Ÿ›ก๏ธ Security Considerations Authentication & Authorization Strong Bearer Tokens : Use cryptographically secure tokens (32+ characters) : Use cryptographically secure tokens (32+ characters) Token Rotation : Regularly rotate API tokens : Regularly rotate API tokens Environment Variables : Never commit tokens to version control : Never commit tokens to version control HTTPS Only : Always use HTTPS in production environments : Always use HTTPS in production environments IP Restrictions: Implement firewall rules to restrict access Certificate Security File Permissions : Private keys stored with 600 permissions : Private keys stored with permissions Directory Permissions : Certificate directories with 700 permissions : Certificate directories with permissions Backup Encryption : Encrypt certificate backups : Encrypt certificate backups Access Logging: Monitor certificate access patterns Network Security # Example firewall rules (iptables) # Allow only specific IPs to access CertMate iptables -A INPUT -p tcp --dport 8000 -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 8000 -s 192.168.0.0/16 -j ACCEPT iptables -A INPUT -p tcp --dport 8000 -j DROP โšก Performance Optimization Production Deployment # docker-compose.prod.yml version : ' 3.8 ' services : certmate : image : certmate:latest deploy : replicas : 2 resources : limits : cpus : ' 1.0 ' memory : 512M reservations : cpus : ' 0.5 ' memory : 256M environment : - FLASK_ENV=production - GUNICORN_WORKERS=4 - GUNICORN_THREADS=2 healthcheck : test : ["CMD", "curl", "-f", "http://localhost:8000/health"] interval : 30s timeout : 10s retries : 3 start_period : 60s Load Balancing with Nginx upstream certmate_backend { server certmate1:8000; server certmate2:8000; server certmate3:8000; } server { listen 443 ssl http2; server_name certmate.company.com; ssl_certificate /etc/ssl/certs/certmate.company.com/fullchain.pem; ssl_certificate_key /etc/ssl/certs/certmate.company.com/privkey.pem; location / { proxy_pass http://certmate_backend; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $scheme ; # API rate limiting limit_req zone=api burst=10 nodelay; } } ๐Ÿ”„ Backup & Recovery Automated Backup Script #! /bin/bash # /opt/scripts/backup-certmate.sh BACKUP_DIR= " /backup/certmate/ $( date +%Y%m%d_%H%M%S ) " CERT_DIR= " /opt/certmate/certificates " DATA_DIR= " /opt/certmate/data " RETENTION_DAYS=30 # Create backup directory mkdir -p " $BACKUP_DIR " # Backup certificates tar -czf " $BACKUP_DIR /certificates.tar.gz " " $CERT_DIR " # Backup application data tar -czf " $BACKUP_DIR /data.tar.gz " " $DATA_DIR " # Backup database if using external DB # mysqldump certmate > "$BACKUP_DIR/database.sql" # Encrypt backups gpg --cipher-algo AES256 --compress-algo 1 --symmetric \ --output " $BACKUP_DIR /certificates.tar.gz.gpg " \ " $BACKUP_DIR /certificates.tar.gz " # Cleanup old backups find /backup/certmate -type d -mtime + $RETENTION_DAYS -exec rm -rf {} \; echo " Backup completed: $BACKUP_DIR " Recovery Procedure #! /bin/bash # Recovery from backup BACKUP_DATE= " 20241225_120000 " BACKUP_DIR= " /backup/certmate/ $BACKUP_DATE " # Stop services docker-compose down # Restore certificates gpg --decrypt " $BACKUP_DIR /certificates.tar.gz.gpg " | \ tar -xzf - -C /opt/certmate/ # Restore data tar -xzf " $BACKUP_DIR /data.tar.gz " -C /opt/certmate/ # Set permissions chown -R 1000:1000 /opt/certmate/certificates chmod -R 700 /opt/certmate/certificates # Start services docker-compose up -d echo " Recovery completed from backup: $BACKUP_DATE " ๐Ÿ“Š Monitoring & Observability ๐Ÿ” Health Monitoring Built-in Health Checks # Basic health check curl -f http://localhost:8000/health # Detailed health with auth curl -H " Authorization: Bearer your_token " \ http://localhost:8000/api/certificates Prometheus Metrics Integration # Add to app.py for Prometheus monitoring from prometheus_client import Counter , Histogram , generate_latest # Metrics certificate_requests = Counter ( 'certmate_certificate_requests_total' , 'Total certificate requests' , [ 'domain' , 'status' ]) certificate_expiry = Histogram ( 'certmate_certificate_expiry_days' , 'Days until certificate expiry' , [ 'domain' ]) @ app . route ( '/metrics' ) def metrics (): return generate_latest () Log Aggregation # docker-compose.logging.yml version : ' 3.8 ' services : certmate : logging : driver : " fluentd " options : fluentd-address : localhost:24224 tag : certmate fluentd-async-connect : " true " fluentd : image : fluent/fluentd:v1.14 volumes : - ./fluentd/conf:/fluentd/etc - ./logs:/var/log/fluentd ports : - " 24224:24224 " - " 24224:24224/udp " ๐Ÿ“ˆ Grafana Dashboard Example { "dashboard" : { "title" : " CertMate SSL Certificate Monitoring " , "panels" : [ { "title" : " Certificate Expiry Status " , "targets" : [ { "expr" : " certmate_certificate_expiry_days < 30 " , "legendFormat" : " Expiring Soon ({{domain}}) " } ], "alert" : { "conditions" : [ { "query" : { "queryType" : " " , "refId" : " A " }, "reducer" : { "type" : " last " , "params" : []}, "evaluator" : { "params" : [ 30 ], "type" : " lt " } } ], "executionErrorState" : " alerting " , "frequency" : " 1h " , "handler" : 1 , "name" : " Certificate Expiring " , "noDataState" : " no_data " , "notifications" : [] } } ] } } ๐Ÿšจ Alerting Configuration Webhook Notifications # Add webhook notification support import requests def send_webhook_notification ( domain , event_type , details ): webhook_url = os . getenv ( 'WEBHOOK_URL' ) if not webhook_url : return payload = { 'domain' : domain , 'event' : event_type , 'timestamp' : datetime . now (). isoformat (), 'details' : details } try : requests . post ( webhook_url , json = payload , timeout = 10 ) except Exception as e : logger . error ( f"Failed to send webhook: { e } " ) Slack Integration Example # Slack notification script #! /bin/bash SLACK_WEBHOOK= " your_slack_webhook_url " DOMAIN= " $1 " STATUS= " $2 " MESSAGE= " Certificate for $DOMAIN : $STATUS " curl -X POST -H ' Content-type: application/json ' \ --data " { \" text \" : \" ๐Ÿ” $MESSAGE \" } " \ " $SLACK_WEBHOOK " ๐Ÿ”ง Troubleshooting Guide ๐Ÿšจ Common Issues & Solutions Certificate Creation Failures Issue: DNS validation failed # Check DNS propagation dig TXT _acme-challenge.example.com @8.8.8.8 # Verify DNS provider credentials curl -H " Authorization: Bearer cf_token " \ " https://api.cloudflare.com/client/v4/user/tokens/verify " Issue: Rate limit exceeded # Let's Encrypt rate limits: # - 50 certificates per registered domain per week # - 5 duplicate certificates per week # - 300 new orders per account per 3 hours # Check rate limit status curl " https://crt.sh/?q=example.com&output=json " | jq length Issue: Permission denied accessing certificate files # Fix file permissions sudo chown -R certmate:certmate /opt/certmate/certificates sudo chmod -R 700 /opt/certmate/certificates sudo chmod 600 /opt/certmate/certificates/ * /privkey.pem API Authentication Issues Issue: 401 Unauthorized # Verify token format curl -H " Authorization: Bearer your_token_here " \ http://localhost:8000/api/certificates # Check token in settings docker exec certmate cat /app/data/settings.json | jq .api_bearer_token Issue: Token not found # Reset API token docker exec -it certmate python -c " import json with open('/app/data/settings.json', 'r+') as f: data = json.load(f) data['api_bearer_token'] = 'new_secure_token_here' f.seek(0) json.dump(data, f, indent=2) f.truncate() " Docker & Container Issues Issue: Container won't start # Check logs docker-compose logs certmate # Verify environment variables docker-compose config # Check port conflicts netstat -tulpn | grep :8000 Issue: Volume mount issues # Fix volume permissions sudo chown -R 1000:1000 ./certificates ./data ./logs # Check volume mounts docker inspect certmate | jq ' .[0].Mounts ' DNS Provider Specific Issues Cloudflare: # Verify API token permissions curl -X GET " https://api.cloudflare.com/client/v4/user/tokens/verify " \ -H " Authorization: Bearer your_token_here " # Check zone access curl -X GET " https://api.cloudflare.com/client/v4/zones " \ -H " Authorization: Bearer your_token_here " AWS Route53: # Test AWS credentials aws sts get-caller-identity # Check Route53 permissions aws route53 list-hosted-zones Azure DNS: # Verify service principal az login --service-principal \ -u $AZURE_CLIENT_ID \ -p $AZURE_CLIENT_SECRET \ --tenant $AZURE_TENANT_ID # Check DNS zone access az network dns zone list ๐Ÿ” Debug Mode Enable debug logging for troubleshooting: # Environment variable FLASK_DEBUG=true FLASK_ENV=development # Or in Docker Compose docker-compose -f docker-compose.yml -f docker-compose.debug.yml up ๐Ÿ“‹ Support Checklist Before seeking help, please provide: CertMate version/commit hash CertMate version/commit hash DNS provider being used DNS provider being used Error messages from logs Error messages from logs Steps to reproduce the issue Steps to reproduce the issue Environment details (Docker, Python version, OS) # Collect system information echo " === CertMate Debug Info === " echo " Version: $( docker exec certmate python -c ' import app; print(getattr(app, "__version__", "unknown")) ' ) " echo " Python: $( docker exec certmate python --version ) " echo " OS: $( docker exec certmate cat /etc/os-release | head -2 ) " echo " Certbot: $( docker exec certmate certbot --version ) " echo " DNS Plugins: $( docker exec certmate pip list | grep certbot-dns ) " echo " Certificates: $( docker exec certmate ls -la /app/certificates ) " echo " Settings: $( docker exec certmate cat /app/data/settings.json | jq . ) " ๐Ÿ“– Documentation ๐Ÿ“š Complete Documentation Set Document Description Target Audience README.md Main documentation and quick start All users INSTALLATION.md Detailed installation instructions System administrators DNS_PROVIDERS.md DNS provider setup guides DevOps engineers CONTRIBUTING.md Development and contribution guide Developers CODE_OF_CONDUCT.md Community guidelines Contributors ๐Ÿ”— Online Resources API Documentation : http://your-server:8000/docs/ (Swagger UI) : http://your-server:8000/docs/ (Swagger UI) Alternative API Docs : http://your-server:8000/redoc/ (ReDoc) : http://your-server:8000/redoc/ (ReDoc) GitHub Repository : https://github.com/fabriziosalmi/certmate : https://github.com/fabriziosalmi/certmate Docker Hub : https://hub.docker.com/r/certmate/certmate : https://hub.docker.com/r/certmate/certmate Issue Tracker: https://github.com/fabriziosalmi/certmate/issues ๐Ÿ“ Examples Repository Check out our examples repository for: Production deployment configurations Integration scripts for popular tools Terraform modules Kubernetes manifests CI/CD pipeline examples ๐Ÿš€ Roadmap & Future Features ๐Ÿ”ฎ Planned Features ๐Ÿ”„ Certificate Templates - Predefined certificate configurations - Predefined certificate configurations ๐Ÿ“Š Advanced Analytics - Certificate usage and performance metrics - Certificate usage and performance metrics ๐Ÿ” ACME v2 Features - External account binding, certificate transparency - External account binding, certificate transparency ๐ŸŒ Multi-Region Support - Geographic certificate distribution - Geographic certificate distribution ๐Ÿ“ฑ Mobile App - iOS/Android certificate monitoring - iOS/Android certificate monitoring ๐Ÿค– AI-Powered Renewal - Intelligent renewal scheduling - Intelligent renewal scheduling ๐Ÿ”Œ Plugin System - Custom DNS provider plugins - Custom DNS provider plugins ๐Ÿ“ˆ Enterprise Dashboard - Multi-tenant certificate management ๐Ÿ—“๏ธ Version History Version Release Date Key Features v2.0.0 2024-12-25 Multi-DNS provider support, enhanced API v1.5.0 2024-11-15 Docker improvements, monitoring features v1.0.0 2024-10-01 Initial release with Cloudflare support ๐Ÿค Community Contributions We welcome contributions! Areas where we need help: Documentation - Tutorials, use cases, translations - Tutorials, use cases, translations Testing - DNS provider testing, edge cases - DNS provider testing, edge cases Integrations - New DNS providers, monitoring tools - New DNS providers, monitoring tools Features - UI improvements, API enhancements ๐Ÿค Contributing We love contributions! CertMate is an open-source project and we welcome: ๐Ÿ› ๏ธ Types of Contributions ๐Ÿ› Bug Reports - Help us identify and fix issues - Help us identify and fix issues ๐Ÿ’ก Feature Requests - Suggest new functionality - Suggest new functionality ๐Ÿ“– Documentation - Improve guides and examples - Improve guides and examples ๐Ÿงช Testing - Test new features and edge cases - Test new features and edge cases ๐Ÿ’ป Code - Submit pull requests with improvements ๐Ÿš€ Quick Start for Contributors # Fork and clone the repository git clone https://github.com/fabriziosalmi/certmate.git cd certmate # Create development environment python3 -m venv venv source venv/bin/activate pip install -r requirements.txt pip install -r requirements-dev.txt # Set up pre-commit hooks pre-commit install # Run tests pytest # Start development server python app.py ๐Ÿ“‹ Contribution Guidelines Fork the repository Create a feature branch ( git checkout -b feature/amazing-feature ) Commit your changes ( git commit -m 'Add amazing feature' ) Push to the branch ( git push origin feature/amazing-feature ) Open a Pull Request ๐Ÿ† Contributors Thanks to all contributors who make CertMate better! ๐Ÿ“„ License This project is licensed under the MIT License - see the LICENSE file for details. ๐ŸŽฏ MIT License Summary