使用 Certbot --webroot 模式为 Nginx 配置 HTTPS

目录

之前我一直使用:

1
certbot --nginx

来自动申请和配置 HTTPS 证书。

这种方法虽然方便,但在实际使用中,我遇到了比较严重的问题:

  • certbot 会自动修改 nginx 配置
  • certbot 会自动 reload/restart nginx,导致systemd 状态与 nginx 实际状态脱节,出现“游离 nginx”,然后第一个证书成功、后面失败

最终决定迁移到:

1
certbot --webroot

这种模式下:

  • certbot 不再接管 nginx
  • 不再自动修改 nginx 配置
  • 不再 reload/restart nginx
  • nginx 完全手动管理

一、安装 certbot

Ubuntu:

1
2
sudo apt update
sudo apt install certbot

二、创建 challenge 目录

统一使用:

1
mkdir -p /var/www/.letsencrypt/.well-known/acme-challenge

说明:

  • certbot 以 root 身份运行,因此无需 www-data 写权限
  • nginx 只需要可读权限

三、配置 nginx challenge 路由

在所有 80 端口 server 中加入:

1
2
3
location /.well-known/acme-challenge/ {
    root /var/www/.letsencrypt;
}

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server {
    listen 80;
    server_name fupcode.com www.fupcode.com;

    location /.well-known/acme-challenge/ {
        root /var/www/.letsencrypt;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

四、申请证书

1
certbot certonly --webroot -w /var/www/.letsencrypt -d fupcode.com

说明:

参数含义
certonly只申请证书,不修改 nginx
–webroot使用 webroot challenge
–cert-name指定证书名称,可选,默认为域名
-wchallenge 根目录
-d域名,可多个

五、查看证书

1
certbot certificates

证书通常位于:

1
/etc/letsencrypt/live/fupcode.com/

例如:

1
2
/etc/letsencrypt/live/fupcode.com/fullchain.pem
/etc/letsencrypt/live/fupcode.com/privkey.pem

六、配置 nginx HTTPS

在 nginx 中手动配置:

1
2
ssl_certificate /etc/letsencrypt/live/fupcode.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fupcode.com/privkey.pem;

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
server {
    listen 443 ssl http2;
    server_name fupcode.com www.fupcode.com;

    ssl_certificate /etc/letsencrypt/live/fupcode.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/fupcode.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

七、nginx 重载

1
2
nginx -t
nginx -s reload

八、配置 deploy-hook

1
2
3
4
5
6
7
8
mkdir -p /etc/letsencrypt/renewal-hooks/deploy

cat >/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh <<'EOF'
#!/bin/sh
nginx -s reload
EOF

chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

九、测试续期

1
certbot renew --dry-run

如果成功,说明:

  • challenge 正常
  • 续期流程正常

发现新版本

当前站点有新版本可用。