准备
通过 sudo nginx -V 发现 debian apt 安装的 nginx 已经有 ssl 模块,可以支持 https。
开放 443 端口
sudo ufw allow 443
letsencrypt 提供免费 3 个月期证书https://letsencrypt.org/zh-cn/getting-started/
获取安装证书
使用 Certbot ACME 客户端既可以为你获取证书,也可以帮助你安装证书(如果您需要的话)。在 https://certbot.eff.org/instructions 上选择自己的 web 服务器和系统,可以看到适合自己的安装方法
sudo apt install certbot python-certbot-nginx
然后
sudo certbot --nginx
或
sudo certbot certonly --nginx
这里要输入一些信息。。
然后 certbot 将通过 cron 任务或 systemd 定时器自动更新证书。
泛域名
不幸的是这是单域名的搞法,泛域名不能这样搞。
由于 certbot 不支持阿里云的域名接口,需要手工配置证书。这里有 http 和 dns 两种选择。
http challenge 挑战将要求你在 web 服务器顶级目录(“web根目录”)中的 /.well-known/acme-challenge/ 中放置具有特定名称和特定内容的文件。本质上它和 webroot 插件是一样的,但不是自动的。
sudo certbot certonly --manual --preferred-challenges http -d *.pran.top
在使用 dns challenge 时,certbot 将要求你将包含特定内容的 TXT dns 记录放在域名下,该域名由你希望颁发证书的主机名组成,前缀为 _acme-challenge。
sudo certbot certonly --manual --preferred-challenges dns -d *.pran.top
因为前者比较麻烦,选择后者。。
需要添加 TXT 域名记录 _acme-challenge.pran.top,值为 Lf7G0NGzGu77ij417Jwdj9iI82CCvjozcde_LLk-TFY 。验证下
dig -t txt _acme-challenge.pran.top @8.8.8.8
然后回来,确定。成功后,证书保存在
/etc/letsencrypt/live/pran.top/fullchain.pem/etc/letsencrypt/live/pran.top/
通过
sudo certbot renew
即可更新
nginx配置
nginx 配置可以通过
sudo certbot --nginx
来自动生成,然后再改。。这里又生成的证书可以通过
sudo certbot delete
来删除。。
这是全部通过 https 的配置,以后可以参考这个进行手工配置了
server {
server_name www.pran.top;
location / {
proxy_pass http://127.0.0.1:8000/;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/pran.top/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/pran.top/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 = www.pran.top) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.pran.top;
return 404; # managed by Certbot
}
sudo nginx -t 查看配置文件位置
sudo nginx -s reload
证书定时更新
Let’s Encrypt 的证书使用期限只有三个月,在证书到期前的一个月可以使用 certbot 来更新。Linux 的定时任务有两种方法:cron 和 systemd/timers,任何一种都能实现定时的更新任务,Certbot 两种都设置了。
sudo vi /etc/cron.d/certbot
可以看到 Certbot 设定的任务记录
0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
由于我们选择 timers 来自动更新,所以把 cron 任务注释掉:
0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
Certbot 在 /lib/systemd/system/ 下生成了两个文件:certbot.service 和 certbot.timer,一个是服务,一个是定时器。
certbot.service:
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshotExecStart=/usr/bin/certbot -q renew
PrivateTmp=true
可以看到也是运行 certbot -q renew 命令。
certbot.timer:
[Unit]
Description=Run certbot twice daily
[Timer]
OnCalendar=--* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true
[Install]
WantedBy=timers.target
每天 0 点和 12 点激活 certbot.service。其实不需要这么频繁的更新证书,而且在更新证书的时候我们加了钩子来关闭和开启 Nginx 服务,所以最好是在凌晨没人访问网站的时候更新证书,我们稍微修改一下:
[Unit]
Description=Run certbot every 05:00
[Timer]
OnCalendar=--* 05:00:00
Persistent=true
[Install]
WantedBy=timers.target
每天凌晨 5 点更新一次证书。因为只有过期前 30 天才会申请更新,所以前 60 天这个任务什么都没干。
保存修改以后需要重启定时器:
sudo systemctl daemon-reload
sudo systemctl restart certbot.timer
貌似没什么用,还是不能自动更新。脚本有问题