lvv.me 是单域名,*.lvv.me 是泛域名。如果自己的网站除了主域名外还有类似与 img.lvv.me、 file.lvv.me 之类的子域名,使用泛域名证书是比较好的选择。
LetsEncrypt 也支持泛域名证书了,申请和配置都比较简单。
提示:LetsEncrypt 的泛域名不支持匹配多级域名的,比如申请 *.lvv.me
的证书,只能匹配 img.lvv.me
或者 file.lvv.me
,而不能匹配 cdn.img.lvv.me
域名。
获取证书
sudo apt-get install certbot
Tips: 在 FreeBSD 上包名有 py{ver}-
前缀,比如叫 py39-certbot
,需要先通过 pkg search certbot
确定当前最新的包名。
命令比较长,用脚本辅助一下 get-cert.sh
#!/bin/sh
set -e
sudo certbot --duplicate certonly -d "*.$1" -d "$1" --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
get-cert.sh lvv.me
根据提示配置好域名的 DNS,需要配置两个 TEXT 类型的记录。
提示:一定要确认 TXT 记录已经生效了再继续下一步,否则会失败,一个简单的方法是添加了 TXT 记录以后使用 dig
命令查询:
dig txt _acme-challenge.lvv.me
查询结果可以找到 TXT 区段就说明生效了:
; <<>> DiG 9.10.6 <<>> txt _acme-challenge.lvv.me
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25452
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 19
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_acme-challenge.lvv.me. IN TXT
;; ANSWER SECTION:
_acme-challenge.lvv.me. 600 IN TXT "rlCEXLl8gTyv3OjV2oSm7C0A8yeAJF7RkBkbUBo2oJM"
_acme-challenge.lvv.me. 600 IN TXT "tQk-UWAb6rtbFp8YxCgdWcBBcqRPj5GAhzhL9oxjA00"
都完成以后,证书就保存在 /etc/letsencrypt/live/lvv.me
里了:
cert.pem chain.pem fullchain.pem privkey.pem README
fullchain.pem
和 privkey.pem
就是 Nginx 需要的公钥和私钥。
配置 Nginx
如果 Nginx 是运行在 Docker 里的话,需要注意 live/lvv.me 目录里的文件是符号链接,实际文件保存在 archive
目录里:
cert.pem -> ../../archive/lvv.me/cert1.pem
chain.pem -> ../../archive/lvv.me/chain1.pem
fullchain.pem -> ../../archive/lvv.me/fullchain1.pem
privkey.pem -> ../../archive/lvv.me/privkey1.pem
README
nginx.conf 的配置要这么写:
http {
...
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/lvv.me/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lvv.me/privkey.pem;
...
}
docker 需要做 /etc/letsencrypt
的目录映射,才能正确的找到证书:
docker run -v /etc/letsencrypt:/etc/letsencrypt ...
管理自动生成的证书
列出所有证书:
sudo certbot certificates
删除证书:
sudo certbot delete
命令会列出所有的证书名称和序号,按序号删除对应的证书即可。
自动更新证书
通过以下命令添加自动更新证书计划:
SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}'); echo "0 0,12 * * * root sleep $SLEEPTIME && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
然后重启 cron
服务。
参考:https://eff-certbot.readthedocs.io/en/latest/using.html#setting-up-automated-renewal