使用Certbot管理Nginx免费SSL证书
Table of Contents
前几天在为家中部署的 Jellyfin 服务配置 SSL 证书时,顺手整理了一篇文档:单机nginx配置SSL证书和静态内容部署。该文档虽涵盖了 Nginx 的 SSL 配置与静态资源部署方法,但尚未包含 SSL 证书的申请流程。鉴于近期我正在使用 Certbot 工具,特此补充相关内容,以记录如何通过 Certbot 申请并管理免费 SSL 证书。
# 什么是certbot
经过近期的实际使用,我认为 Certbot 具备以下几个显著优势:
支持泛域名证书:在申请证书时指定通配符域名(如 *.example.com),即可覆盖所有二级子域名(例如 a.example.com、b.example.com 等),极大简化了多子域名场景下的证书管理。命令中的泛域名需要添加双引号,避免命令解析出错。
完全免费,有效期为 90 天:对于个人用户而言,这一特性无疑是其最大优势。
续期与更新对部署透明:首次部署需手动配置证书路径,但后续的自动续期或重新申请均可通过 Certbot 自动完成,无需修改服务器配置。
更多详细信息可参阅 Certbot 官方网站:https://certbot.eff.org/ 。
# 使用certbot申请证书
最初,我的目标仅是获取证书文件以供其他用途,因此倾向于使用 Certbot 最基础的证书申请功能。以下是目前采用的操作方式。
以下是申请证书的三种方式:
# 泛域名和主域名同时申请
certbot certonly -d "*.domain.com" -d domain.com --manual --preferred-challenges dns
# 指定二级域名:
certbot certonly -d a.domain.com --manual --preferred-challenges dns
申请过程需要提供邮箱,以及一些license和广告的政策步骤。由于我们加了--manual参数,所以域名所有权的验证需要通过域名解析进行验证,这一步可以到自己域名管理商平台操作,一般是添加TXT记录。
申请完证书后,可以到/etc/letsencrypt查看文件,部署时通常使用live目录下的文件或者软链接。
root@racknerd-715e59a:/etc/letsencrypt# tree
.
├── accounts
│ └── acme-v02.api.letsencrypt.org
│ └── directory
│ └── bf855ccd20087b82eb2b6168fba26d35
│ ├── meta.json
│ ├── private_key.json
│ └── regr.json
├── archive
│ └── ugla.cc
│ ├── cert1.pem
│ ├── cert2.pem
│ ├── chain1.pem
│ ├── chain2.pem
│ ├── fullchain1.pem
│ ├── fullchain2.pem
│ ├── privkey1.pem
│ └── privkey2.pem
├── cli.ini
├── live
│ ├── README
│ └── ugla.cc
│ ├── cert.pem -> ../../archive/ugla.cc/cert2.pem
│ ├── chain.pem -> ../../archive/ugla.cc/chain2.pem
│ ├── fullchain.pem -> ../../archive/ugla.cc/fullchain2.pem
│ ├── privkey.pem -> ../../archive/ugla.cc/privkey2.pem
│ └── README
├── renewal
│ └── ugla.cc.conf
└── renewal-hooks
├── deploy
├── post
└── pre
14 directories, 19 files
# 部署nginx
修改nginx配置,将live目录下的fullchain和privkey两个文件添加到server配置中。配置完证书后,重启nginx如果出现/etc/letsencrypt无权限问题,可以检查下nginx的user是否指定了www-data用户,可以修改成root或者其他有权限的用户解决。
server {
listen 443 ssl;
# 选择性开启http2。1.25.1版本以后要用下面这种方式开启。
http2 on;
# 原有 server_name,可继续新增更多当前证书支持的域名
server_name ugla.cc www.ugla.cc;
# ======================= 证书配置开始 =======================
# 指定证书文件(中间证书可以拼接至该pem文件中),请将 /etc/ssl/cert/ssl.pem 替换为您实际使用的证书文件的绝对路径
ssl_certificate /etc/letsencrypt/live/ugla.cc/fullchain.pem;
# 指定私钥文档,请将 /etc/ssl/cert/ssl.key 替换为您实际使用的私钥文件的绝对路径
ssl_certificate_key /etc/letsencrypt/live/ugla.cc/privkey.pem;
# 配置 SSL 会话缓存,提高性能
ssl_session_cache shared:SSL:1m;
# 设置 SSL 会话超时时间
ssl_session_timeout 5m;
# 自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 指定允许的 TLS 协议版本,TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差
ssl_protocols TLSv1.2 TLSv1.3;
# 优先使用服务端指定的加密套件
ssl_prefer_server_ciphers on;
# ======================= 证书配置结束 =======================
# 其它配置
root /var/www/html;
}
# 证书续期
后续更新时实测后再记录这块内容。
申请完证书时,工具会有如下提示:
This certificate will not be renewed automatically.
Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided.
To renew this certificate, repeat this same certbot command before the certificate's expiry date.
大概意思是 此证书不会自动续订。 手动颁发的证书(–manual)的自动续订需要使用身份验证钩子脚本(–manual-auth-hook),但您未提供该脚本。 要续订此证书,请在证书到期日期之前重复运行相同的 certbot 命令。