Skip to content
Back to skills

Letsencrypt

BSecurity

Let's Encrypt is a free, automated certificate authority, and Certbot is its official ACME client for getting and renewing TLS certificates. Use this skill when asked to add HTTPS to a website, get a free SSL certificate, issue a wildcard certificate, set up automatic renewal, fix a Certbot renewal failure, or get certificates automatically in Docker with Traefik.

  • 142 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 29, 2026
devopspythonrustgoshellbashdockergitapidevops

Works with

  • terminal
  • cli
  • api

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill letsencrypt --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Letsencrypt?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Letsencrypt
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-letsencrypt/badge)](https://www.skillsdirectory.com/skills/terminalskills-letsencrypt)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: letsencrypt
description: >-
  Let's Encrypt is a free, automated certificate authority, and Certbot is its
  official ACME client for getting and renewing TLS certificates. Use this skill
  when asked to add HTTPS to a website, get a free SSL certificate, issue a
  wildcard certificate, set up automatic renewal, fix a Certbot renewal
  failure, or get certificates automatically in Docker with Traefik.
license: Apache-2.0
compatibility: "Linux server with a public DNS name; Nginx, Apache, standalone or any web server; Certbot 4+"
metadata:
  author: terminal-skills
  version: "1.1.0"
  category: devops
  repository: https://github.com/certbot/certbot
  tags: ["letsencrypt", "tls", "ssl", "https", "certbot"]
---

# Let's Encrypt

## Overview

Let's Encrypt issues free domain-validated certificates over the ACME protocol. Certbot (from the EFF) proves you control a domain, stores the certificate under `/etc/letsencrypt/live/<name>/`, and renews it. Validation methods: HTTP-01 (port 80 must be reachable from the internet), TLS-ALPN-01, and DNS-01 (the only way to get wildcard certificates, and works for servers that are not public).

Certificate lifetimes are shrinking. Today the default `classic` profile still issues 90-day certificates; Let's Encrypt has announced 64 days from 10 February 2027 and 45 days from 16 February 2028, with an opt-in `tlsserver` profile (45 days) and a `shortlived` profile (6 days) available earlier. Renew automatically and monitor, because manual calendar reminders will not keep up. Expiry-notification emails from Let's Encrypt have been discontinued, so use your own monitoring.

## Instructions

### Step 1: Install Certbot

The Certbot project recommends the snap on most Linux distributions:

```bash
sudo apt-get remove certbot            # remove any distro package first
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
```

Distro packages also work (`sudo apt install certbot python3-certbot-nginx` or `python3-certbot-apache`) but are often older. Before issuing, confirm the domain's DNS A/AAAA records point at this server and ports 80 and 443 are open.

### Step 2: Get a certificate

```bash
# Nginx: obtain and edit the config (redirects HTTP to HTTPS)
sudo certbot --nginx -d shop.northwind.dev -d www.shop.northwind.dev

# Obtain only, configure the server yourself
sudo certbot certonly --nginx -d shop.northwind.dev

# Existing webroot (server keeps running)
sudo certbot certonly --webroot -w /var/www/shop -d shop.northwind.dev

# No web server running yet: Certbot binds port 80 itself
sudo certbot certonly --standalone -d shop.northwind.dev
```

Add `--staging` (alias `--test-cert`) while experimenting; staging certificates are not trusted but have far higher rate limits.

### Step 3: Wildcards with a DNS plugin

Wildcards need DNS-01. Use a DNS provider plugin so renewals run unattended. Example with Cloudflare (snap install):

```bash
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
sudo install -d -m 700 /root/.secrets/certbot
sudoedit /root/.secrets/certbot/cloudflare.ini       # one line: dns_cloudflare_api_token = followed by your zone-scoped API token
sudo chmod 600 /root/.secrets/certbot/cloudflare.ini

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
  -d northwind.dev -d "*.northwind.dev"
```

Use a token scoped to DNS edit on that one zone. A wildcard does not cover the bare domain, so list both names. `certbot certonly --manual --preferred-challenges dns` works once but cannot renew automatically unless you also give `--manual-auth-hook` and `--manual-cleanup-hook` scripts.

### Step 4: Renewal

```bash
systemctl list-timers | grep certbot       # snap and distro packages install a timer (or a cron entry)
sudo certbot renew --dry-run               # full simulated renewal against staging
sudo certbot certificates                  # names, domains, expiry dates, paths
```

Certbot 4 and later renews when about a third of the lifetime remains. Reload the server after renewal with a deploy hook; it runs only when a certificate was actually renewed:

```bash
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
```

Or pass `--deploy-hook "systemctl reload nginx"` when issuing. The `--nginx` and `--apache` plugins reload the server for you.

### Step 5: Containers with Traefik (v3)

Traefik has its own ACME client and needs no Certbot:

```yaml
# docker-compose.yml
services:
  traefik:
    image: traefik:v3
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --certificatesresolvers.le.acme.email=ops@northwind.dev
      - --certificatesresolvers.le.acme.storage=/acme/acme.json
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
    ports: ["80:80", "443:443"]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - acme:/acme
  shop:
    image: ghcr.io/northwind/shop:2.4.1
    labels:
      - traefik.enable=true
      - traefik.http.routers.shop.rule=Host(`shop.northwind.dev`)
      - traefik.http.routers.shop.entrypoints=websecure
      - traefik.http.routers.shop.tls.certresolver=le
volumes:
  acme:
```

For tests add `--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory`. Caddy is another option that obtains certificates with no configuration beyond the site name.

## Examples

### Example 1: HTTPS for an Nginx site

Request: "Put HTTPS on shop.northwind.dev, it already runs on Nginx."

```bash
sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
sudo certbot --nginx -d shop.northwind.dev -d www.shop.northwind.dev
sudo certbot renew --dry-run
```

Certbot asks for an email address, edits the matching `server` blocks to listen on 443 with `ssl_certificate /etc/letsencrypt/live/shop.northwind.dev/fullchain.pem`, adds the HTTP-to-HTTPS redirect, and the dry run ends with "Congratulations, all simulated renewals succeeded".

### Example 2: A wildcard for internal services

Request: "I need *.northwind.dev for staging hosts that are not reachable from the internet."

Use DNS-01 as in Step 3. The result is one certificate in `/etc/letsencrypt/live/northwind.dev/` that you copy or mount into each service; add a deploy hook that distributes `fullchain.pem` and `privkey.pem` after every renewal.

## Guidelines

- Use `fullchain.pem` (leaf plus intermediates) as the server certificate and `privkey.pem` as the key; never the old `cert.pem` alone.
- Rate limits (production): 50 new certificates per registered domain per 7 days, 5 per exact identical name set per 7 days, 5 failed validations per hostname per hour, 300 new orders per account per 3 hours. Renewals that follow ACME Renewal Information (ARI) are exempt; Certbot supports ARI. Test with `--staging` or `--dry-run`.
- Keep private keys and DNS API tokens readable by root only (mode 600) and out of Git and backups that others can read.
- A common renewal failure is port 80 blocked or redirected by a firewall, CDN or WAF; check the `/var/log/letsencrypt/letsencrypt.log` file for the failing challenge.
- Do not run `certbot` from cron every minute or with `--force-renewal` in a loop; that exhausts the duplicate limit.
- Mounting the Docker socket (even read-only) gives Traefik broad control over the host; consider a socket proxy for production.
- Install Certbot with the package manager or snap; do not pipe downloaded scripts into a shell.

Files in this skill

  • SKILL.md2 KB
  • _scores.json1.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…