04. DNS 与 Certbot 子域名证书

1. 本章目标

本章让 airport.cxhair.cn 指向云服务器,并让 HTTPS 证书覆盖这个子域名。你会理解为什么已有的 cxhair.cn 证书不一定能直接复用。

2. DNS、服务器和证书是三件事

拥有 cxhair.cn 证书不等于自动拥有所有子域名证书。一张证书只有在 Subject Alternative Name(SAN)中包含 airport.cxhair.cn,浏览器才会接受它用于该子域名。

3. 添加 DNS 记录

进入 cxhair.cn 当前使用的 DNS 服务控制台,添加:

字段 值
类型 A
主机记录 airport
记录值 京东云服务器公网 IPv4
TTL 使用默认值或 600 秒

如果域名 DNS 不在京东云管理,就在实际的权威 DNS 服务商处修改。域名注册商和 DNS 托管商可能不是同一家。

验证解析:

dig +short airport.cxhair.cn A

Windows PowerShell 可以执行:

Resolve-DnsName airport.cxhair.cn

输出 IP 必须是目标服务器公网 IP。DNS 尚未生效时不要开始 HTTP-01 证书申请。

4. 先提供一个 HTTP 站点

Certbot 的 Nginx 插件需要能够识别站点。创建 /etc/nginx/sites-available/airport.cxhair.cn:

server {
    listen 80;
    listen [::]:80;
    server_name airport.cxhair.cn;

    root /var/www/airport-operations-explorer/client/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

启用站点:

sudo ln -s /etc/nginx/sites-available/airport.cxhair.cn \
  /etc/nginx/sites-enabled/airport.cxhair.cn
sudo nginx -t
sudo systemctl reload nginx

如果软链接已存在,ln 会报错。先用 ls -l /etc/nginx/sites-enabled/ 检查,不要重复创建。

从公网验证:

curl -I http://airport.cxhair.cn

5. 检查现有证书

sudo certbot certificates

关注:

若 Domains 已经包含 airport.cxhair.cn,无需重新签发,只要让该 Nginx 站点引用对应证书路径。

还可以检查线上证书:

openssl s_client -connect cxhair.cn:443 -servername cxhair.cn </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -ext subjectAltName

6. 方案 A:扩展现有证书

若希望 cxhair.cn 和 airport.cxhair.cn 使用同一个证书,先备份 Nginx 配置:

sudo cp -a /etc/nginx /etc/nginx.backup-before-airport-cert
sudo nginx -t

假设 certbot certificates 显示证书名称为 cxhair.cn,并且原证书只包含 cxhair.cn,执行:

sudo certbot --nginx \
  --cert-name cxhair.cn \
  -d cxhair.cn \
  -d airport.cxhair.cn

关键点:必须列出这张证书应继续覆盖的全部域名。若原证书还包含 www.cxhair.cn,命令也要保留它:

sudo certbot --nginx \
  --cert-name cxhair.cn \
  -d cxhair.cn \
  -d www.cxhair.cn \
  -d airport.cxhair.cn

--cert-name 选择要修改的证书。-d 列表定义新证书包含的域名集合,遗漏旧域名可能使其不再被覆盖。

多域名证书的优点是只维护一张证书;缺点是续期时所有域名都必须继续能完成验证,一个站点迁移时耦合更强。

7. 方案 B:为子域名单独签发

对两个独立站点,单独证书通常更容易维护:

sudo certbot --nginx -d airport.cxhair.cn

它通常创建 /etc/letsencrypt/live/airport.cxhair.cn/。独立证书不会改变 cxhair.cn 的现有证书,续期和迁移互不影响。

教程后续配置以“检查实际证书路径”为准,不强制选择同一张证书。你的要求是共享证书时,使用方案 A。

8. 为什么当前不首选通配符证书

*.cxhair.cn 能覆盖 airport.cxhair.cn 等一级子域名,但不能覆盖根域 cxhair.cn。通配符证书通常需要 DNS-01 challenge,并配置 DNS API 凭据。只有子域名数量较多时才值得承担额外复杂度。

9. 验证证书和续期

sudo nginx -t
sudo systemctl reload nginx
sudo certbot certificates
curl -I https://airport.cxhair.cn

检查子域名 SAN:

openssl s_client \
  -connect airport.cxhair.cn:443 \
  -servername airport.cxhair.cn </dev/null 2>/dev/null \
  | openssl x509 -noout -dates -ext subjectAltName

模拟续期:

sudo certbot renew --dry-run
systemctl list-timers | grep certbot

--dry-run 使用 Let’s Encrypt 测试环境,不会替换当前有效证书。若模拟失败,自动续期也可能失败,应立即查看 Certbot 输出、DNS 和 80 端口。

证书更新后 Nginx 需要 reload 才能读取新文件。Certbot 的 Nginx 安装通常会管理相应部署动作,但仍应通过线上检查确认。

10. 常见错误

浏览器提示名称不匹配

实际证书 SAN 没有 airport.cxhair.cn,或 Nginx 命中了错误的默认站点。检查:

sudo nginx -T | grep -n "server_name\|ssl_certificate"

Certbot 验证超时

依次检查 DNS、京东云安全组、UFW、Nginx 80 端口和 server_name。HTTP-01 验证需要 Let’s Encrypt 从公网访问 80 端口。

申请次数过多

Let’s Encrypt 有速率限制。先修复配置,再使用测试环境或 certbot renew --dry-run 验证,不要反复申请正式证书。

原主域名证书丢失某个域名

扩展证书时 -d 列表不完整。重新查看原需求,用 --cert-name 和完整域名集合修正,并同时验证所有站点。

11. 本章验收

下一章:使用 PM2 管理 Node.js 后端

12. 参考资料