# 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 | 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` 不覆盖。