Certbot 和 Let’s Encrypt 的关系
Let’s Encrypt
- 一个免费、自动化、开放的公共证书颁发机构(CA)。
- 通过 ACME(Automatic Certificate Management Environment)协议向域名所有者颁发 DV(Domain Validation)TLS/SSL 证书。
Certbot
- 由 Electronic Frontier Foundation (EFF) 维护的开源 ACME 客户端。
- 主要目标是简化与 Let’s Encrypt 之间的交互:
- 自动化域名验证(HTTP-01、DNS-01、TLS-ALPN-01 等)
- 安装并续期证书
- 更新 Web 服务器配置(Apache、Nginx、Lighttpd 等)
- Certbot 也能与任何兼容 ACME 的 CA 通信,不限于 Let’s Encrypt。
典型工作流程
- 解析参数并检测服务器类型。
- 选择并执行挑战(例如在 /.well-known/acme-challenge/ 下写入 token)。
- Let’s Encrypt 回访验证域名归属。
- 验证通过后签发证书;Certbot 下载并安装到本地。
- 创建定时任务 certbot renew 自动续期。
开始实验
实验环境:Amazon Linux 2023 (AL2023)
知识补充
dnf(Dandified YUM)
是 RPM-系 Linux 发行版的下一代包管理器。它在功能上取代了传统的yum
,两者命令参数几乎保持兼容。RPM
一开始叫 Red Hat Package Manager,后来改名为递归含义的 RPM Package Manager。RPM-系发行版
是把 RPM 作为原生软件包格式与核心包管理工具链的那一族 Linux 发行版。常听到的 Fedora / RHEL / CentOS / AlmaLinux / Rocky Linux / openSUSE / SUSE Linux Enterprise / Amazon Linux 2023 等。dnf
不是对rpm
CLI 的简单封装,而是调用librpm
完成最终操作。
包管理器 | 代表发行版 | 归属 |
---|---|---|
dnf / yum | Fedora, RHEL, CentOS | RPM |
zypper | openSUSE, SLE | RPM |
apt / apt-get | Debian, Ubuntu | DEB |
pacman | Arch Linux | tar.xz |
apk | Alpine | .apk |
snap
是一种由 Canonical(Ubuntu 的开发公司)推出的跨发行版应用打包和分发格式,也指围绕它的一整套生态系统。- 跨发行版。同一个 snap 包可以在几十种发行版上直接安装运行,不依赖各自的 RPM/Deb 系统仓库。
- 自包含(bundled)依赖。snap 包内部包含所有依赖,无需外部安装。
- https://snapcraft.io/
Launch an AWS EC2 instance
- Instance type: t2.nano
- Username: ec2-user
- Security Groups: Allow HTTP and HTTPS
- Public IPv4: 35.86.90.4
配置 nginx
sudo dnf update -y
sudo dnf install -y nginx
nginx -v
# nginx version: nginx/1.28.0
sudo systemctl start nginx
sudo systemctl enable nginx
systemctl status nginx
# Started nginx.service - The nginx HTTP and reverse proxy server.
直接通过 http://35.86.90.4,会看到默认的 nginx 欢迎页面。
sudo vi /etc/nginx/conf.d/default.conf
#
server {
listen 80;
listen [::]:80;
server_name tmp.yifans.net;
root /usr/share/nginx/html;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
sudo nginx -t
sudo systemctl reload nginx
将自己的域名(tmp.yifans.net
)解析到 35.86.90.4
,然后访问 http://tmp.yifans.net 同样看到 nginx 欢迎页面,游览器显示 Not Secure。
配置 certbot
# 暂无官方支持 AL2023
sudo wget -O /etc/yum.repos.d/snapd.repo \
https://bboozzoo.github.io/snapd-amazon-linux/al2023/snapd.repo
sudo dnf install -y snapd
sudo systemctl enable --now snapd.socket
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version
# certbot 4.1.1
# 前置 nginx 配置中要有 server_name tmp.yifans.net;
sudo certbot --nginx -d tmp.yifans.net
# 全自动完成
访问 http://tmp.yifans.net 会自动跳转 https。
# 看看被 certbot 自动修改的 nginx 配置
cat /etc/nginx/conf.d/default.conf
server {
server_name tmp.yifans.net;
root /usr/share/nginx/html;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/tmp.yifans.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/tmp.yifans.net/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = tmp.yifans.net) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name tmp.yifans.net;
return 404; # managed by Certbot
}
# 看看 certbot 预置的参数
# include /etc/letsencrypt/options-ssl-nginx.conf;
cat /etc/letsencrypt/options-ssl-nginx.conf
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org
ssl_session_cache shared:le_nginx_SSL:10m;
# 在内存里创建名为 le_nginx_SSL 的共享会话缓存区域,大小 10 MiB。
# 能加速后续同客户端的 TLS 握手(避免完整密钥交换)。
# 10 MiB 足够保存约 40 000 个会话条目。
ssl_session_timeout 1440m;
# 单位是分钟(1440 m = 24 h)。
# 表示缓存的会话条目过期时间;设为一天可在常见浏览器会话周期内复用。
ssl_session_tickets off;
# 关闭 TLS Session Tickets。
# 原因:早期实现无法便捷轮换 ticket 加密密钥,导致前向安全受损。
ssl_protocols TLSv1.2 TLSv1.3;
# 明确只允许 1.2 / 1.3。
# 关闭已不安全的 SSLv3、TLS 1.0、TLS 1.1。
ssl_prefer_server_ciphers off;
# 让客户端来决定从交集里选哪一组加密套件(服务器不强制优先级)。
# 在只开放现代安全套件的前提下,这样做兼容性好且简化维护。
# 如果你想严格控制,可改为 on 并自行调整 ssl_ciphers 顺序。
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
# 仅保留 GCM / ChaCha20-Poly1305 这一代 AEAD 套件;弃用 CBC、RC4、3DES 等。
# ECDHE-ECDSA(椭圆曲线 DH,证书是 ECDSA)
# ECDHE-RSA(证书是 RSA)
# DHE-RSA(传统 DH,给极旧设备兜底)
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
`ssl_dhparam` 告诉 Nginx 在使用 DHE(Diffie-Hellman Ephemeral)握手方式时,不用默认的 1024 位弱参数,而改用一份 自定义、更安全的 DH 参数文件。
DHE 是 TLS/SSL 协议中的一种「密钥交换算法」。它的核心作用只有两点:
- 让客户端与服务器在 公网信道 上安全地“协商出”一个对称加密用的随机密钥。
- 提供 前向安全(Forward Secrecy):哪怕以后服务器的长期私钥被泄露,过去抓到的加密数据也无法解密。
# 看看证书
sudo openssl x509 -in /etc/letsencrypt/live/tmp.yifans.net/fullchain.pem -noout -text | grep yifans.net
Subject: CN=tmp.yifans.net
DNS:tmp.yifans.net
只获取证书
首先需要将 tmp-certonly.yifans.net
解析到 35.86.90.4
,为了自动完成 acme challenge。
sudo vi /etc/nginx/conf.d/certonly.conf
server {
listen 80;
listen [::]:80;
server_name tmp-certonly.yifans.net;
root /usr/share/nginx/html;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
sudo nginx -t
sudo systemctl reload nginx
sudo certbot certonly --nginx
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: tmp.yifans.net
2: tmp-certonly.yifans.net
# 选择 2
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/tmp-certonly.yifans.net/fullchain.pem
Key is saved at: /etc/letsencrypt/live/tmp-certonly.yifans.net/privkey.pem
This certificate expires on 2025-10-01.
# /etc/nginx/conf.d/certonly.conf 没有被自动修改,需要手动添加证书
Wildcard Certificate
- 需要 DNS Credentials。
*.example.com
不覆盖example.com
,hello.goodbye.example.com
。*.goodbye.example.com
可覆盖hello.goodbye.example.com
。- 不可以申请
*.*.example.com
只能一个*
asterisk。
可以通过 DNS Plugins 插件申请 Wildcard Certificate,但是我觉得 manual 更简单。
sudo certbot certonly --manual -d '*.tmp.yifans.net' --preferred-challenges dns
Please deploy a DNS TXT record under the name:
_acme-challenge.tmp.yifans.net.
with the following value:
...
# 访问 https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.tmp.yifans.net. 预测试配置结果。
# 如果看到对应的值,按 Enter 继续。
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/tmp.yifans.net-0001/fullchain.pem
Key is saved at: /etc/letsencrypt/live/tmp.yifans.net-0001/privkey.pem
# 看看证书
sudo openssl x509 -in /etc/letsencrypt/live/tmp.yifans.net-0001/fullchain.pem -noout -text | grep yifans.net
Subject: CN=*.tmp.yifans.net
DNS:*.tmp.yifans.net
sudo vi /etc/nginx/conf.d/wildcard.conf
server {
server_name *.tmp.yifans.net;
root /usr/share/nginx/html;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/tmp.yifans.net-0001/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tmp.yifans.net-0001/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80;
server_name *.tmp.yifans.net;
return 301 https://$host$request_uri;
}
sudo nginx -t
sudo systemctl reload nginx
将 1.tmp.yifans.net
解析到 35.86.90.4
,然后访问 https://1.tmp.yifans.net,在 Chrome 的证书信息里可以看到 Common Name (CN) *.tmp.yifans.net
。
证书续期
sudo certbot renew --dry-run
References
– EOF –