04. DNS 与 Certbot 子域名证书
1. 本章目标
本章让 airport.cxhair.cn 指向云服务器,并让 HTTPS 证书覆盖这个子域名。你会理解为什么已有的 cxhair.cn 证书不一定能直接复用。
2. DNS、服务器和证书是三件事
- DNS 回答“
airport.cxhair.cn对应哪个 IP”; - 云服务器接收这个 IP 上的网络请求;
- TLS 证书证明服务器被授权代表某个域名,并加密连接。
拥有 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
关注:
Certificate Name:Certbot 管理证书时使用的名称;Domains:证书 SAN 覆盖的全部域名;Certificate Path和Private Key Path;- 到期日期。
若 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. 本章验收
airport.cxhair.cn解析到正确服务器;- HTTP 能从公网到达 Nginx;
- 证书 SAN 包含
airport.cxhair.cn; - 原
cxhair.cn站点仍正常; certbot renew --dry-run成功。