一台服务器上多个站点的证书管理

一台机器上跑着好几个站点,每个都要 HTTPS。记录一下 vhost 的组织方式、证书签发的正确顺序,以及自动续期里容易失效的环节。

多站点共用一台机器时,最容易出问题的不是证书怎么签,而是顺序和续期。下面这套流程在我手头的服务器上已经稳定跑了很久。

先 HTTP 再 HTTPS

新站上线的顺序应该是:先只配 80 端口的 vhost,让域名通过 HTTP 就能访问;确认解析生效之后,再签证书、加 443 配置,最后把 80 改成跳转。反过来的话,如果解析还没生效就去签证书,验证必然失败,还会把配置改乱。

# 1. 先让 80 能通
server {
    listen 80;
    server_name example.com;
    root /var/www/example.com/public;
    index index.php index.html;

    location / { try_files  / /index.php?; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    }
}

# 2. 再签证书
# certbot --nginx -d example.com

证书续期为什么会失效

certbot 装好之后通常会自动创建续期定时任务,但续期之后 nginx 并不会自动加载新证书,需要 reload。多站点环境下还要注意两点:一是续期验证走的是 80 端口,如果某个 vhost 把 80 全量跳转到 443,要确保验证路径不会被跳转吃掉;二是证书数量多了以后,单次续期失败不会影响其他站点,但需要有人看得到失败通知。

验证续期是否真的有效,不要等三个月。用 --dry-run 立刻跑一遍,这是成本最低的检查方式:

# 立刻验证续期流程,不产生真实的证书变更\ncertbot renew --dry-run

配置组织上的一个习惯

站点配置统一放 sites-available,用软链接在 sites-enabled 里启用同一份文件;不要直接编辑 enabled 目录下的真实文件,否则备份和回滚都会变得混乱。每个站点的 root 是独立的,证书路径写绝对路径,不依赖任何相对位置。