Skip to content

Certbot Installation Guide

TL;DR: Certbot is the EFF's official ACME client for Let's Encrypt, providing automated SSL/TLS certificate management. Installation method matters: snap packages offer automatic updates and latest features (recommended), distribution packages provide OS-native integration, and Docker deployments enable containerized certificate automation. Proper installation prevents version conflicts, plugin issues, and permission problems in production.

Quick Install (Choose Your Platform)

Ubuntu/Debian (Recommended - snap method):

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

CentOS/RHEL 8+:

sudo dnf install certbot
# For nginx plugin:
sudo dnf install python3-certbot-nginx
# For apache plugin:
sudo dnf install python3-certbot-apache

Docker:

docker run -it --rm --name certbot \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  certbot/certbot certonly --standalone

Windows (PowerShell as Administrator):

# Install Chocolatey first (if not installed):
# https://chocolatey.org/install
choco install certbot

macOS (Homebrew):

brew install certbot

** Why use snap?** - Always latest version (auto-updates every 6 hours) - All DNS plugins available - Works on any Linux distro - Official EFF recommendation - Sandboxed and secure

[See detailed installation guide below ↓]

Overview: Foundation for ACME Automation

Certbot installation represents the first step in ACME certificate automation—getting it wrong compounds problems throughout your certificate lifecycle. While installation seems straightforward ("just install a package"), production deployments require understanding installation method trade-offs, plugin availability, version compatibility, and integration with existing infrastructure.

The installation decision: Organizations face three primary installation approaches—snap packages (EFF's recommended method with automatic updates), distribution packages (OS-native with stable but potentially outdated versions), and manual installation (deprecated but necessary for legacy systems). Each method affects update procedures, plugin availability, file system layout, and compatibility with Infrastructure-as-Code tooling.

Why This Belongs in ACME Client Operations

This guide focuses on production-ready installation patterns rather than "quick start" tutorials. While Let's Encrypt documentation shows simple apt install certbot, enterprise environments face complications:

  • Multi-distribution standardization: How to install Certbot consistently across Ubuntu, CentOS, Debian, RHEL deployments
  • Version pinning: Balancing security updates with stability requirements
  • Plugin management: Ensuring nginx/apache/dns plugins are available
  • Container deployments: Installing Certbot in Docker, Kubernetes, immutable infrastructure
  • Air-gapped environments: Installing without internet access
  • Enterprise proxies: Installing through corporate HTTP proxies and artifact repositories

Real-world installation scenario: Your organization operates 50 web servers across 3 cloud providers—25 Ubuntu 22.04 (AWS), 15 CentOS 8 (Azure), 10 RHEL 8 (GCP). Some servers are internet-connected, others are air-gapped. You need consistent Certbot installation across all systems, with automatic updates enabled for internet-connected servers and manual update procedures for air-gapped systems. Your Infrastructure-as-Code (Ansible) must support all three distributions with the same playbook.

Installation Method Comparison

Method Auto-Updates Latest Version OS Integration Use Case
Snap Automatic Always latest Containerized Modern systems, recommended
Distribution Pkg Manual (apt/dnf) May lag behind Native Enterprise with strict change control
Docker Image updates Configurable Containerized Immutable infrastructure
Manual (certbot-auto) Deprecated Frozen Manual Legacy systems only

Recommendation: - Production (internet-connected): Snap installation - Enterprise (change control): Distribution packages with update policy - Containers: Docker with version pinning - Legacy systems: Distribution packages or manual (last resort)

This page is part of the Operating ACME Clients section:

Recommended reading order for new Certbot users: 1. Certbot Installation (this page) - Start here 2. A Record Configuration - Ensure DNS is correct 3. Certbot Renewal Automation - Set up automation 4. X.509 Certificate Verification - Verify certificates work

For broader context: - ACME Protocol - Understanding ACME before using Certbot - Certificate Lifecycle Management - Broader lifecycle operations - Renewal Automation - Platform-agnostic automation strategies


Problem Statement

Organizations implementing Certbot face installation challenges that affect long-term operational success:

  • Version conflicts: Multiple Certbot installations (snap + apt + pip) causing command conflicts and unpredictable behavior
  • Missing plugins: Base Certbot installed without nginx/apache/dns plugins, breaking automation scripts
  • Update management: Balancing automatic updates (snap) with enterprise change control requirements
  • Path issues: Certbot installed but not in system PATH, breaking cron jobs and systemd timers
  • Permission errors: Certbot cannot write to /etc/letsencrypt or web roots due to permission restrictions
  • Firewall blocking: ACME validation fails because ports 80/443 blocked by OS firewall or cloud security groups
  • Enterprise proxy: Installation fails in environments requiring HTTP proxy for internet access
  • Air-gapped systems: Cannot install from internet repositories without mirror setup

Common installation failure: Administrator runs sudo apt install certbot, believes Certbot is ready, attempts to issue nginx certificate with certbot --nginx, encounters error "unrecognized arguments: --nginx" because python3-certbot-nginx plugin wasn't installed. Certificate issuance fails, manual troubleshooting required.

Architecture

Certbot System Architecture

┌─────────────────────────────────────────┐
│         Certbot Installation            │
├─────────────────────────────────────────┤
│  Core Binary                            │
│  ├─ /snap/bin/certbot (snap)            │
│  ├─ /usr/bin/certbot (apt/dnf)          │
│  └─ /usr/local/bin/certbot (manual)     │
├─────────────────────────────────────────┤
│  Plugins (Authenticators/Installers)    │
│  ├─ nginx (python3-certbot-nginx)       │
│  ├─ apache (python3-certbot-apache)     │
│  ├─ dns-cloudflare                      │
│  ├─ dns-route53                         │
│  └─ standalone (built-in)               │
├─────────────────────────────────────────┤
│  Configuration & Data                   │
│  ├─ /etc/letsencrypt/ (certificates)    │
│  ├─ /var/lib/letsencrypt/ (work dir)    │
│  └─ /var/log/letsencrypt/ (logs)        │
└─────────────────────────────────────────┘

Installation Flow

┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│   Install   │────────▶│   Verify    │────────▶│  Configure  │
│   Certbot   │         │  Plugins    │         │  Automation │
└─────────────┘         └─────────────┘         └─────────────┘
       │                       │                        │
       │                       │                        │
    Snap/Apt               certbot               systemd timer
    packages               plugins                or cron job

Installation Components: 1. Core binary: certbot command-line tool 2. Plugins: Web server and DNS provider integrations 3. Configuration directories: /etc/letsencrypt, /var/lib/letsencrypt, /var/log/letsencrypt 4. Systemd timer (snap) or cron job for automatic renewal

Implementation

Why Snap is Recommended: - Automatic security updates from EFF - Latest Certbot version always available - Consistent across distributions - Self-contained (no system Python conflicts) - Automatic renewal timer configured

Ubuntu 20.04+ / Debian 11+:

# Remove existing Certbot installations (if any)
sudo apt remove certbot

# Install snapd (if not present)
sudo apt update
sudo apt install snapd

# Install core snap (foundation)
sudo snap install core
sudo snap refresh core

# Install Certbot
sudo snap install --classic certbot

# Create system-wide symlink
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Verify installation
certbot --version
# Output: certbot 2.7.4

CentOS 8+ / RHEL 8+ / Rocky Linux / AlmaLinux:

# Enable EPEL repository
sudo dnf install epel-release

# Install snapd
sudo dnf install snapd

# Enable snapd socket
sudo systemctl enable --now snapd.socket

# Create classic snap support symlink
sudo ln -s /var/lib/snapd/snap /snap

# Install Certbot
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Verify
certbot --version

CentOS 7 / RHEL 7 (Snap support limited):

# CentOS 7 snap support is experimental
# Recommended: Use distribution packages instead

sudo yum install epel-release
sudo yum install certbot python2-certbot-nginx

Distribution Package Installation

Ubuntu 20.04 LTS / 22.04 LTS / Debian 11+:

# Update package index
sudo apt update

# Install Certbot with web server plugins
sudo apt install certbot \
  python3-certbot-nginx \
  python3-certbot-apache

# Verify installation
certbot --version
dpkg -l | grep certbot

# Check available plugins
certbot plugins

CentOS Stream 8+ / RHEL 8+ / Rocky Linux:

# Enable EPEL repository
sudo dnf install epel-release

# Install Certbot with plugins
sudo dnf install certbot \
  python3-certbot-nginx \
  python3-certbot-apache

# Verify
certbot --version
certbot plugins

CentOS 7 / RHEL 7:

# Enable EPEL
sudo yum install epel-release

# Install Certbot (Python 2 based)
sudo yum install certbot \
  python2-certbot-nginx \
  python2-certbot-apache

# Note: CentOS 7 uses Python 2, consider upgrading OS

DNS Plugin Installation

Cloudflare DNS Plugin:

# Snap method
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

# Distribution package method
sudo apt install python3-certbot-dns-cloudflare  # Ubuntu/Debian
sudo dnf install python3-certbot-dns-cloudflare  # CentOS 8+

# Pip method (if plugins not in repository)
sudo pip3 install certbot-dns-cloudflare

Route53 DNS Plugin:

# Snap
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-route53

# Distribution
sudo apt install python3-certbot-dns-route53
sudo dnf install python3-certbot-dns-route53

Other DNS Plugins:

# Available DNS plugins (install similarly)
certbot-dns-cloudflare
certbot-dns-route53
certbot-dns-google
certbot-dns-azure
certbot-dns-digitalocean
certbot-dns-ovh
certbot-dns-rfc2136  # Generic RFC2136 (BIND nsupdate)

Legacy: Manual Installation (Only for Legacy Systems)

⚠️ Warning: certbot-auto is deprecated since January 2021. Use only when snap and distribution packages are unavailable.

# Download certbot-auto (deprecated)
sudo wget https://dl.eff.org/certbot-auto -O /usr/local/bin/certbot-auto
sudo chmod a+x /usr/local/bin/certbot-auto

# First run installs dependencies
sudo /usr/local/bin/certbot-auto --version

# Usage (similar to certbot)
sudo /usr/local/bin/certbot-auto certonly --nginx

Enterprise Docker Deployment

Production Dockerfile:

FROM alpine:3.18

# Install Certbot and required tools
RUN apk add --no-cache \
    certbot \
    py3-pip \
    openssl \
    bash \
    curl

# Install DNS plugins
RUN pip3 install --no-cache-dir \
    certbot-dns-cloudflare \
    certbot-dns-route53

# Create required directories
RUN mkdir -p /etc/letsencrypt /var/lib/letsencrypt /var/log/letsencrypt

# Copy entrypoint script
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Volume for certificate persistence
VOLUME /etc/letsencrypt

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["renew"]

Entrypoint Script (entrypoint.sh):

#!/bin/bash
set -e

case "$1" in
  certonly)
    exec certbot certonly "${@:2}"
    ;;
  renew)
    exec certbot renew --quiet
    ;;
  *)
    exec certbot "$@"
    ;;
esac

Docker Compose Configuration:

version: '3.8'

services:
  certbot:
    build: ./certbot
    volumes:
      - ./letsencrypt:/etc/letsencrypt
      - ./logs:/var/log/letsencrypt
      - ./webroot:/var/www/html
    environment:
      - CF_API_TOKEN=${CLOUDFLARE_TOKEN}
    command: >
      certonly
      --webroot
      -w /var/www/html
      -d example.com
      --email [email protected]
      --agree-tos
      --non-interactive

Kubernetes CronJob for Renewal:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: certbot-renewal
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: certbot
            image: certbot/certbot:latest
            args:
            - renew
            - --dns-cloudflare
            - --dns-cloudflare-credentials
            - /etc/cloudflare/credentials.ini
            volumeMounts:
            - name: letsencrypt
              mountPath: /etc/letsencrypt
            - name: cloudflare-creds
              mountPath: /etc/cloudflare
              readOnly: true
          volumes:
          - name: letsencrypt
            persistentVolumeClaim:
              claimName: letsencrypt-pvc
          - name: cloudflare-creds
            secret:
              secretName: cloudflare-credentials
          restartPolicy: OnFailure

Common Pitfalls

1. Version Conflicts from Multiple Installations

Problem: Multiple Certbot installations causing command conflicts

# Symptom: Certbot behavior inconsistent
which certbot
# Output: /usr/bin/certbot

# But multiple installations exist:
which -a certbot
# /usr/bin/certbot       (snap symlink)
# /usr/local/bin/certbot (manual install)

dpkg -l | grep certbot
# certbot (apt package also installed)

snap list certbot
# certbot installed via snap

Impact: Different versions may use different config directories, causing certificates to "disappear"

Solution: Clean install with single method

# Remove all existing Certbot installations
sudo apt remove certbot python3-certbot-*
sudo snap remove certbot
sudo rm -f /usr/local/bin/certbot-auto

# Verify removed
which -a certbot  # Should return nothing

# Fresh install via recommended method
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Verify single installation
which certbot
# /usr/bin/certbot (symlink to /snap/bin/certbot)

2. Missing Web Server Plugin Dependencies

Problem: Installed Certbot but web server plugins not available

# Attempt to use nginx plugin
sudo certbot --nginx -d example.com

# Error: certbot: error: unrecognized arguments: --nginx

Cause: Base package installed without plugin packages

Solution: Install complete plugin set

# Snap method (plugins separate)
sudo snap install --classic certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare  # If DNS-01 needed

# Distribution method (explicit plugin packages)
sudo apt install certbot \
  python3-certbot-nginx \      # Nginx plugin
  python3-certbot-apache \     # Apache plugin
  python3-certbot-dns-cloudflare  # DNS plugin

# Verify plugins available
certbot plugins
# Should show: nginx, apache, standalone, webroot, dns-cloudflare

3. Snap PATH Configuration Issues

Problem: Certbot not found after snap installation

$ certbot --version
bash: certbot: command not found

# But snap installed successfully
$ snap list certbot
Name     Version  Rev   Tracking       Publisher    Notes
certbot  2.7.4    3487  latest/stable  certbot-eff  classic

Cause: /snap/bin not in PATH or symlink missing

Solution: Add to PATH and create symlink

# Add snap bin to PATH
echo 'export PATH="/snap/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Create system-wide symlink
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Verify
which certbot
# /usr/bin/certbot

certbot --version
# certbot 2.7.4

4. Permission Errors During Certificate Operations

Problem: Certbot cannot write to configuration directories

$ certbot certonly --standalone -d example.com
# Error: [Errno 13] Permission denied: '/etc/letsencrypt'

Cause: Running Certbot without sudo

Solution: Use sudo for certificate operations

# WRONG - insufficient permissions
certbot certonly --standalone -d example.com

# CORRECT - run with sudo
sudo certbot certonly --standalone -d example.com

# Verify directory permissions
ls -ld /etc/letsencrypt
# drwx------ 3 root root ... /etc/letsencrypt

Directory Permissions Setup:

# Ensure proper ownership
sudo chown -R root:root /etc/letsencrypt
sudo chmod 700 /etc/letsencrypt

# Create log directory if missing
sudo mkdir -p /var/log/letsencrypt
sudo chmod 755 /var/log/letsencrypt

5. Firewall Blocking ACME Validation

Problem: HTTP-01 validation fails due to firewall blocking port 80

sudo certbot certonly --standalone -d example.com

# Error: Timeout during connect (likely firewall problem)

Solution: Configure firewall to allow HTTP/HTTPS

# UFW (Ubuntu)
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

# firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# iptables (manual)
sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4

# Cloud provider security groups (AWS, Azure, GCP)
# Add rules allowing inbound TCP 80 and 443 from 0.0.0.0/0

6. Enterprise HTTP Proxy Configuration

Problem: Installation fails behind corporate proxy

# Snap installation fails
sudo snap install --classic certbot
# Error: cannot communicate with store

# Apt installation fails
sudo apt install certbot
# Error: Failed to fetch http://...

Solution: Configure proxy environment variables

# Set proxy for package managers
export http_proxy=http://proxy.company.com:8080
export https_proxy=http://proxy.company.com:8080
export no_proxy=localhost,127.0.0.1,.company.com

# For snap
sudo snap set system proxy.http="http://proxy.company.com:8080"
sudo snap set system proxy.https="http://proxy.company.com:8080"

# For apt (in /etc/apt/apt.conf.d/proxy.conf)
Acquire::http::Proxy "http://proxy.company.com:8080";
Acquire::https::Proxy "http://proxy.company.com:8080";

# For Certbot ACME communication
sudo tee -a /etc/environment << 'EOF'
http_proxy="http://proxy.company.com:8080"
https_proxy="http://proxy.company.com:8080"
EOF

7. Python Version Conflicts

Problem: Certbot requires specific Python version

# CentOS 7 with Python 2.7 (deprecated)
sudo yum install certbot
# Warning: Python 2.7 will not be maintained past 2020

# System has Python 3 but Certbot installed for Python 2
certbot --version
# Uses Python 2.7 (unsupported)

Solution: Use snap (bypasses Python version issues) or upgrade OS

# Option 1: Use snap (recommended)
sudo snap install --classic certbot

# Option 2: Upgrade to CentOS 8+ / RHEL 8+ / Rocky Linux
# (Python 3 based)

# Option 3: Manual Python 3 Certbot installation
sudo pip3 install certbot certbot-nginx certbot-apache

Best Practices

1. Production Deployment Standardization

Single Installation Method Across Fleet

# Choose ONE method for entire infrastructure
# Document in runbook, enforce in automation

# Example: Snap for all Ubuntu/Debian/CentOS 8+ servers
# Ansible playbook ensures consistency

Ansible Playbook for Standardized Installation:

---
- name: Install Certbot via snap (standardized)
  hosts: webservers
  become: yes

  tasks:
    - name: Ensure snapd installed
      package:
        name: snapd
        state: present

    - name: Install core snap
      snap:
        name: core
        state: present

    - name: Refresh core snap
      command: snap refresh core
      changed_when: false

    - name: Install Certbot snap
      snap:
        name: certbot
        classic: yes
        state: present

    - name: Create Certbot symlink
      file:
        src: /snap/bin/certbot
        dest: /usr/bin/certbot
        state: link

    - name: Verify Certbot installation
      command: certbot --version
      register: certbot_version
      changed_when: false

    - name: Display Certbot version
      debug:
        msg: "Certbot {{ certbot_version.stdout }} installed successfully"

2. Plugin Management Strategy

Install All Required Plugins During Initial Setup

# Snap method - install plugins upfront
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
sudo snap install certbot-dns-route53

# Verify plugins
snap list | grep certbot

# Distribution method - comprehensive package list
sudo apt install \
  certbot \
  python3-certbot-nginx \
  python3-certbot-apache \
  python3-certbot-dns-cloudflare \
  python3-certbot-dns-route53

Plugin Verification Script:

#!/bin/bash
# Verify required plugins are available

REQUIRED_PLUGINS=("nginx" "apache" "dns-cloudflare")

echo "Checking Certbot plugins:"
for plugin in "${REQUIRED_PLUGINS[@]}"; do
  if certbot plugins | grep -q "$plugin"; then
    echo "  ✓ $plugin"
  else
    echo "  ✗ $plugin (missing - install required)"
  fi
done

3. Configuration Directory Management

Standard Directory Structure:

/etc/letsencrypt/
├── accounts/           # ACME account keys
├── archive/            # All certificate versions
├── csr/               # Certificate signing requests
├── keys/              # Private keys
├── live/              # Symlinks to latest certificates
   └── example.com/
       ├── cert.pem       # Certificate only
       ├── chain.pem      # Intermediate certificate
       ├── fullchain.pem  # Certificate + intermediate
       └── privkey.pem    # Private key
├── renewal/           # Renewal configuration files
└── renewal-hooks/
    ├── deploy/        # Deployment hooks
    ├── post/          # Post-renewal hooks
    └── pre/           # Pre-renewal hooks

Backup Strategy:

#!/bin/bash
# Backup Certbot configuration and certificates

BACKUP_DIR="/backup/letsencrypt-$(date +%Y%m%d)"
sudo mkdir -p "$BACKUP_DIR"

# Backup entire Certbot directory
sudo tar czf "$BACKUP_DIR/letsencrypt.tar.gz" /etc/letsencrypt

# Backup to remote storage
sudo rsync -av /etc/letsencrypt/ backup-server:/backup/letsencrypt/

# Verify backup
tar tzf "$BACKUP_DIR/letsencrypt.tar.gz" | head -n 20

4. Update Management

Snap Auto-Updates (Default):

# Check snap refresh timer
snap refresh --time

# Manually refresh Certbot
sudo snap refresh certbot

# View refresh history
snap changes certbot

Distribution Package Updates:

# Ubuntu/Debian - check for updates
sudo apt update
apt list --upgradable | grep certbot

# Update Certbot
sudo apt install --only-upgrade certbot python3-certbot-*

# CentOS/RHEL
sudo dnf check-update | grep certbot
sudo dnf update certbot python3-certbot-*

Version Pinning for Enterprise:

# Pin Certbot version for stability (Ubuntu/Debian)
sudo apt-mark hold certbot python3-certbot-nginx

# Verify pinned
apt-mark showhold

# Unpin when ready to upgrade
sudo apt-mark unhold certbot python3-certbot-nginx

5. Monitoring and Validation

Post-Installation Validation

#!/bin/bash
# Validate Certbot installation

echo "=== Certbot Installation Validation ==="

# Check version
if certbot --version > /dev/null 2>&1; then
  version=$(certbot --version 2>&1 | grep -oP '\d+\.\d+\.\d+')
  echo "✓ Certbot installed: version $version"
else
  echo "✗ Certbot not installed or not in PATH"
  exit 1
fi

# Check required plugins
REQUIRED_PLUGINS=("nginx" "standalone" "webroot")
for plugin in "${REQUIRED_PLUGINS[@]}"; do
  if certbot plugins 2>&1 | grep -q "$plugin"; then
    echo "✓ Plugin available: $plugin"
  else
    echo "✗ Plugin missing: $plugin"
  fi
done

# Check directories exist and have correct permissions
for dir in /etc/letsencrypt /var/lib/letsencrypt /var/log/letsencrypt; do
  if [ -d "$dir" ] && [ -w "$dir" ]; then
    echo "✓ Directory accessible: $dir"
  else
    echo "✗ Directory issue: $dir"
  fi
done

# Test dry-run certificate request
if sudo certbot register --agree-tos --email [email protected] --dry-run > /dev/null 2>&1; then
  echo "✓ ACME communication working"
else
  echo "✗ Cannot communicate with ACME server (check firewall/proxy)"
fi

echo "=== Validation Complete ==="

Monitor Installation Across Fleet:

#!/usr/bin/env python3
"""Check Certbot installation status across server fleet"""

import subprocess
import json

def check_certbot_on_server(hostname):
    """Check Certbot installation remotely"""
    try:
        result = subprocess.run(
            ['ssh', hostname, 'certbot', '--version'],
            capture_output=True,
            text=True,
            timeout=10
        )

        if result.returncode == 0:
            version = result.stdout.strip()
            return {'status': 'installed', 'version': version}
        else:
            return {'status': 'error', 'message': result.stderr}
    except Exception as e:
        return {'status': 'unreachable', 'error': str(e)}

# Check fleet
servers = ['web1.example.com', 'web2.example.com', 'web3.example.com']

for server in servers:
    result = check_certbot_on_server(server)
    print(f"{server}: {result}")

6. Security Hardening Post-Installation

Restrict Certbot Directory Permissions:

# Secure Certbot directories
sudo chmod 700 /etc/letsencrypt
sudo chmod 700 /etc/letsencrypt/live
sudo chmod 700 /etc/letsencrypt/archive

# Private keys should be 600
sudo find /etc/letsencrypt -name 'privkey*.pem' -exec chmod 600 {} \;

# Verify permissions
sudo find /etc/letsencrypt -type f -name '*.pem' -ls

Limit Certbot Execution:

# Create dedicated user for automated renewals (optional)
sudo useradd -r -s /bin/false certbot-automation

# Configure sudoers for limited certbot access
sudo tee /etc/sudoers.d/certbot << 'EOF'
certbot-automation ALL=(root) NOPASSWD: /usr/bin/certbot renew
certbot-automation ALL=(root) NOPASSWD: /usr/sbin/nginx -t
certbot-automation ALL=(root) NOPASSWD: /bin/systemctl reload nginx
EOF

7. Enterprise Compliance and Audit

Document Installation for Compliance:

# Certbot Installation Documentation

## Installation Method
- Method: Snap packages (certbot 2.7.4)
- Installation Date: 2026-01-24
- Installed By: ops-team
- Approval: Change request CR-12345

## Installed Components
- Core: certbot 2.7.4
- Plugins: nginx, dns-cloudflare
- Configuration: /etc/letsencrypt
- Logs: /var/log/letsencrypt

## Update Policy
- Automatic updates: Enabled (snap refresh)
- Testing: All updates tested in staging before production
- Rollback procedure: snap revert certbot

## Access Control
- Certbot execution: Root only
- Configuration access: Root only
- Certificate files: 600 permissions (root owner)

## Audit Trail
- Installation logged in: /var/log/syslog
- Compliance framework: SOC 2, ISO 27001
- Review frequency: Quarterly

Track Certbot Versions Across Infrastructure:

#!/bin/bash
# Audit Certbot versions for compliance

SERVERS_FILE="/etc/infrastructure/webservers.txt"
AUDIT_FILE="/var/log/certbot-audit-$(date +%Y%m%d).log"

echo "=== Certbot Version Audit: $(date) ===" | tee "$AUDIT_FILE"

while read -r server; do
  version=$(ssh "$server" "certbot --version 2>&1" | grep -oP '\d+\.\d+\.\d+' || echo "NOT_INSTALLED")
  echo "$server: $version" | tee -a "$AUDIT_FILE"
done < "$SERVERS_FILE"

echo "=== Audit Complete ===" | tee -a "$AUDIT_FILE"


Operational Checklist

Pre-installation preparation:

  • [ ] Determine installation method (snap recommended for most environments)
  • [ ] Check OS version and distribution
  • [ ] Verify internet connectivity or configure local repository mirror
  • [ ] Configure HTTP proxy if required
  • [ ] Document installation method in runbook

Installation:

  • [ ] Remove any existing Certbot installations
  • [ ] Install Certbot core package
  • [ ] Install required web server plugins (nginx/apache)
  • [ ] Install DNS provider plugins (if using DNS-01)
  • [ ] Verify Certbot in PATH (which certbot)
  • [ ] Check Certbot version (certbot --version)
  • [ ] Verify plugins available (certbot plugins)

Post-installation:

  • [ ] Configure firewall to allow ports 80 and 443
  • [ ] Verify directory permissions (700 for /etc/letsencrypt)
  • [ ] Test ACME communication (certbot register --dry-run)
  • [ ] Document installation in compliance records
  • [ ] Configure automatic updates (snap) or update schedule (apt/dnf)
  • [ ] Set up monitoring for Certbot version tracking
  • [ ] Create backup procedures for /etc/letsencrypt
  • [ ] Test certificate issuance in staging (--staging)
  • [ ] Configure automated renewal (systemd timer or cron)
  • [ ] Document troubleshooting procedures

ACME Operations (Read After Installation): - Operating ACME Clients Overview - Section navigation - Certbot Installation (this page) - Installing Certbot - A Record Configuration - Next: Configure DNS - Certbot Renewal Automation - Next: Set up automation - X.509 Certificate Verification - Understanding validation - DNS-01 Challenge Validation - For wildcard certificates

Protocol & Standards: - ACME Protocol - Understand ACME before installing clients - TLS Protocol - How certificates are used

Broader Operations: - Certificate Lifecycle Management - Complete lifecycle - Renewal Automation - Platform-agnostic automation

Troubleshooting: - Common Misconfigurations - Configuration issues and quick fixes - Chain Validation Errors - Certificate verification failures - Expired Certificate Outages - Incident response and prevention - Performance Bottlenecks - Timeout and performance issues


This comprehensive installation guide ensures production-ready Certbot deployment across diverse Linux distributions, container environments, and enterprise infrastructure with proper security, monitoring, and compliance considerations.