> ## Documentation Index
> Fetch the complete documentation index at: https://docs.digitalfyre.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installing Let's Encrypt with Certbot

[Certbot](https://certbot.eff.org/) is the recommended client for obtaining free SSL/TLS certificates from Let's Encrypt. This guide covers installation, certificate issuance for Apache and Nginx, standalone mode, wildcard certificates, and automated renewal.

<Info>
  This guide is for VPS and Bare Metal customers managing their own web servers. Web Hosting (Plesk) and WordPress Hosting customers have Let's Encrypt built into their control panels and do not need Certbot.
</Info>

## Installation

<Tabs>
  <Tab title="Debian / Ubuntu">
    ```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
    apt update
    apt install certbot -y

    # For Nginx integration
    apt install python3-certbot-nginx -y

    # For Apache integration
    apt install python3-certbot-apache -y
    ```
  </Tab>

  <Tab title="RHEL / AlmaLinux / Rocky">
    ```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
    dnf install epel-release -y
    dnf install certbot -y

    # For Nginx integration
    dnf install python3-certbot-nginx -y

    # For Apache integration
    dnf install python3-certbot-apache -y
    ```
  </Tab>
</Tabs>

## Obtaining a Certificate

### Nginx Plugin

The Nginx plugin automatically configures SSL in your Nginx server blocks:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
certbot --nginx -d example.com -d www.example.com
```

Certbot will modify your Nginx configuration to add SSL directives, obtain the certificate, and reload Nginx.

### Apache Plugin

The Apache plugin automatically configures SSL in your Apache virtual hosts:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
certbot --apache -d example.com -d www.example.com
```

Certbot will modify your Apache configuration, obtain the certificate, and reload Apache.

### Standalone Mode

If you are not running a web server, or prefer not to let Certbot modify your configuration, use standalone mode. Certbot temporarily starts its own web server on port 80 to complete the HTTP-01 challenge.

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
# Stop your web server first if it is using port 80
systemctl stop nginx  # or apache2 / httpd

certbot certonly --standalone -d example.com -d www.example.com

# Start your web server again
systemctl start nginx  # or apache2 / httpd
```

Standalone mode only obtains the certificate — you must configure your web server to use it manually. Certificates are stored in `/etc/letsencrypt/live/example.com/`.

| File            | Purpose                                                                                                      |
| --------------- | ------------------------------------------------------------------------------------------------------------ |
| `fullchain.pem` | Certificate + intermediate chain (use this for `ssl_certificate` in Nginx or `SSLCertificateFile` in Apache) |
| `privkey.pem`   | Private key (use this for `ssl_certificate_key` in Nginx or `SSLCertificateKeyFile` in Apache)               |

## Wildcard Certificates

Wildcard certificates (`*.example.com`) require DNS-01 validation instead of HTTP-01. This means Certbot needs to create a TXT record in your DNS zone to prove ownership.

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"
```

Certbot will prompt you to create a TXT record at `_acme-challenge.example.com` with a specific value. Add the record in your DNS provider, wait for propagation, then press Enter to continue.

<Warning>
  Wildcard certificates require manual DNS intervention on each renewal unless you automate it with a DNS plugin (e.g., `certbot-dns-cloudflare`, `certbot-dns-route53`). If you cannot automate DNS challenges, consider using individual certificates per subdomain instead.
</Warning>

### Automated DNS Validation (Cloudflare Example)

If your DNS is managed by Cloudflare, you can automate wildcard renewals:

<Tabs>
  <Tab title="Debian / Ubuntu">
    ```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
    apt install python3-certbot-dns-cloudflare -y
    ```
  </Tab>

  <Tab title="RHEL / AlmaLinux / Rocky">
    ```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
    dnf install python3-certbot-dns-cloudflare -y
    ```
  </Tab>
</Tabs>

Create a credentials file:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
mkdir -p /etc/letsencrypt
cat > /etc/letsencrypt/cloudflare.ini << 'EOF'
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/letsencrypt/cloudflare.ini
```

Issue the wildcard certificate:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com \
  -d "*.example.com"
```

This method supports fully automated renewal.

## Automatic Renewal

Let's Encrypt certificates expire after 90 days. Certbot installs a systemd timer (or cron job) that automatically renews certificates before expiration.

### Verify the Timer

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
systemctl status certbot.timer
```

If the timer is active, renewal is handled automatically. To test renewal without making changes:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
certbot renew --dry-run
```

### Manual Cron (If No Systemd Timer)

If the systemd timer is not available or not active, add a cron job:

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
crontab -e
```

Add the following line to attempt renewal twice daily:

```cron lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
0 3,15 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
```

Replace `nginx` with `apache2` or `httpd` depending on your web server. The `--deploy-hook` only runs when a certificate is actually renewed.

## Post-Renewal Hooks

Certbot supports hooks that run after a successful renewal. This is useful for reloading your web server or restarting services that depend on the certificate.

```bash lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
# Reload Nginx after renewal
certbot renew --deploy-hook "systemctl reload nginx"

# Reload Apache after renewal
certbot renew --deploy-hook "systemctl reload apache2"

# Run a custom script
certbot renew --deploy-hook "/opt/scripts/post-renew.sh"
```

To make a deploy hook permanent, create a script in `/etc/letsencrypt/renewal-hooks/deploy/`:

```bash expandable lines theme={"theme":{"light":"light-plus","dark":"ayu-dark"}}
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'EOF'
#!/bin/bash
systemctl reload nginx
EOF
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
```

## Managing Certificates

| Command                                                                 | Description                                              |
| ----------------------------------------------------------------------- | -------------------------------------------------------- |
| `certbot certificates`                                                  | List all managed certificates and their expiration dates |
| `certbot renew`                                                         | Renew all certificates due for renewal                   |
| `certbot renew --dry-run`                                               | Test renewal without making changes                      |
| `certbot delete --cert-name example.com`                                | Remove a certificate                                     |
| `certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem` | Revoke a certificate                                     |

## Troubleshooting

* **"Problem binding to port 80"** — Another service is already using port 80. Stop your web server before using standalone mode, or use the Nginx/Apache plugin instead.
* **"DNS problem: NXDOMAIN"** — The domain does not resolve to your server. Verify your A/AAAA records point to the correct IP and that DNS has propagated.
* **"Too many certificates already issued"** — Let's Encrypt has rate limits of 50 certificates per registered domain per week. Use `--staging` for testing to avoid hitting production limits.
* **"Unauthorized" during renewal** — If your server is behind Cloudflare with proxying enabled, ensure HTTP-01 challenges can reach your origin server. Alternatively, switch to DNS-01 validation.
