0aa8fe6
这次没有正文改动。
这是 tls/SSL 证书申请、部署与续期.md 的改动记录。后台每次保存都会留一份快照,
这里显示的是快照之间的差异,不会混入其他文章的改动。
还没有后台修改记录。
下面是 Git 里的提交,可能包含其他文章的改动(因为一次提交会带上工作区所有变化)。
0aa8fe6
这次没有正文改动。
e4d2cd0
@@ -0,0 +1,86 @@ +--- +tags: [SSL, 证书, nginx] +order: 10 +--- + +# SSL 证书申请、部署与续期 + +## 场景 + +给站点上 HTTPS,或者证书快到期要换。 + +## 前置条件 + +- 域名已经能解析到这台机器 +- 80 端口可访问(HTTP 验证需要) +- 知道证书放哪,权限怎么设 + +## 配置 + +### 自签(内网够用) + +```bash +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ + -keyout /etc/nginx/ssl/kb.key \ + -out /etc/nginx/ssl/kb.crt \ + -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Corp/CN=kb.corp.local" +``` + +### 免费证书(Let's Encrypt) + +```bash +dnf install -y certbot python3-certbot-nginx +certbot --nginx -d kb.example.com --non-interactive --agree-tos -m ops@example.com + +# 自动续期 +systemctl enable --now certbot-renew.timer +certbot renew --dry-run +``` + +### nginx 配置 + +```nginx +server { + listen 443 ssl http2; + server_name kb.example.com; + + ssl_certificate /etc/nginx/ssl/kb.crt; + ssl_certificate_key /etc/nginx/ssl/kb.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + location / { proxy_pass http://127.0.0.1:8080; } +} + +server { + listen 80; + server_name kb.example.com; + return 301 https://$host$request_uri; +} +``` + +## 验证 + +```bash +openssl s_client -connect kb.example.com:443 -servername kb.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subject +curl -I https://kb.example.com +``` + +看有效期、域名是否匹配、链是否完整(`s_client` 输出里 `Verify return code: 0`)。 + +## 回滚 + +```bash +# 换回旧证书 +cp /etc/nginx/ssl/kb.crt.bak /etc/nginx/ssl/kb.crt +nginx -t && systemctl reload nginx +``` + +## 坑 + +- **证书链不全**,浏览器报错但 `curl` 能通(因为 curl 用的是系统信任库)。 +- 证书和私钥不匹配,nginx 起不来,`nginx -t` 会报错。 +- 私钥权限 `0644`,任何用户都能读。 +- 续期后没 reload,nginx 还在用旧证书。 +- 只配了 443 没配 80 跳转,用户还是走 HTTP。 +- 通配符证书只匹配一级子域,`a.b.example.com` 不覆盖。