Skip to content

Install Certbot for Let's Encrypt SSL certificates. One-command install for Ubuntu/Debian (snap), CentOS, Docker, and Windows with common error fixes. This guide covers production-ready installation patterns, plugin setup, and how to avoid version and permission issues.

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.

Need help with ACME? Try the Axelspire ACME support chatbot for implementation and troubleshooting.

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:


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 admin@example.com
      --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 test@example.com --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):

Protocol & Standards:

Broader Operations:

Troubleshooting:


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.