先说说我踩的第一个坑:证书类型选错了。我以为所有SSL证书都一样,直接买了个最便宜的域名验证(DV)证书,结果部署完发现公司官网的电商支付页面报错——DV证书不支持企业信息验证,浏览器直接显示”该网站未验证企业身份”。后来换成了OV证书才解决。
开篇展示:不同SSL证书类型(DV/OV/EV)对比图,标注适用场景和价格区间
第一步:生成证书签名请求(CSR)
这是整个流程的基础,很多人在这一步就搞错了。我见过有人直接在服务器上用OpenSSL生成私钥,结果私钥文件和CSR文件放在同一个目录下,权限设置成了777,这等于把家门钥匙挂在门上。
正确做法是这样的:
“bash
生成RSA私钥,推荐用4096位
openssl genrsa -out example.com.key 4096
设置文件权限,只有root可读
chmod 400 example.com.key
生成CSR
openssl req -new -key example.com.key -out example.com.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=example.com"
`
为什么要这么写?genrsa命令生成的是RSA私钥文件,-out指定输出文件名,位数4096比2048更安全但生成速度慢一些(大概慢0.2秒,可以忽略)。chmod 400这一步很多人会漏掉,但这是关键——私钥文件如果被其他用户读取,整个加密体系就崩了。
req -new是生成新的CSR请求,-subj参数里填的信息要特别注意:
- /CN=example.com
这里必须写你的域名全称 - 如果申请的是通配符证书,要写成/CN=*.example.com
- /O=MyCompany
如果是OV或EV证书,公司名称必须和营业执照完全一致(大小写、标点符号都不能错)
有个技巧:如果你有多个子域名,比如www.example.com、ode>mail.example.com、api.example.com,可以生成一个包含所有域名的CSR。在-subj后面加-addext “subjectAltName = DNS:www.ex
ample.com,DNS:mail.example.com,DNS:api.example.com”。这样一张证书就能覆盖所有子域名,省得每加一个子域名就重新申请一次。
踩坑记录:我第一次生成了2048位的私钥,后来发现某些老旧设备(比如安卓4.4以下的手机)不支持2048位以上的证书,但2048位本身也够用了。纠结这个的可以生成2048位,兼容性更好,安全性也不差。
第二步:选择证书颁发机构(CA)
市面上证书机构多如牛毛,从免费的Let's Encrypt到收费的Symantec,价格从0到几万不等。我建议按这个逻辑选:
- 个人博客/小站点:用Let's Encrypt或ZeroSSL,完全免费,90天有效期但可以自动续期
- 公司官网/电商:用DigiCert或GlobalSign的OV证书,1000-3000元/年
- 银行/金融:必须上EV证书,5000-20000元/年
另一个坑:别买便宜的三级代理商的证书。我同事贪便宜买了家小代理商的198元证书,结果部署后偶尔出现"证书链不完整"的错误,查了两天才发现是他们提供的中间证书版本太旧。后来换成正规渠道,问题消失。
核心内容展示:证书申请流程对比图(Let's Encrypt自动 vs 付费CA手动),标注各步骤耗时
第三步:提交CSR并完成验证
提交CSR后,CA会要求你验证域名所有权。常见验证方式有三种:
``
_record._example.com TXT "ca-verification-code-abc123"
。我强烈建议用DNS验证,因为:
- 不需要登录服务器
- 可以批量处理(比如一次性验证*.example.com)
- 续期时不用重新验证(大部分CA支持)
踩坑记录:有次我用邮箱验证,结果域名是在阿里云买的,邮箱是Gmail,但域名隐私保护把邮箱改成了阿里云的转发邮箱,CA的邮件被当垃圾邮件拦截了。折腾了3天才发现。从那以后,我用DNS验证从来没出过问题。
第四步:部署到Nginx服务器
拿到证书文件后(通常是.crt或.pem文件),部署到Nginx。这里要注意证书文件包含关系:
`nginx
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 证书文件路径
ssl_certificate /etc/nginx/ssl/example.com.crt;
# 私钥文件路径
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# HSTS配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 根目录和其他配置
root /var/www/html;
index index.html index.htm;
}
`
这段配置里,ssl_certificate指向的是CA发的证书文件,这个文件通常包含了你的站点证书和CA的中间证书。如果你收到的是分离的文件(比如example.com.crt和ca-bundle.crt),需要手动合并:
`bash`
cat example.com.crt ca-bundle.crt > combined.crt
为什么要合并? 因为Nginx的ssl_certificate指令只认一个文件,如果只放站点证书,浏览器会报"证书链不完整",因为缺少中间证书。这个错误很隐蔽,因为有些浏览器会自动下载中间证书,但大部分不会。
还有个技巧:用ssl_certificate配置时,可以用ssl_trusted_certificate指定一个独立的CA证书链文件,用于OCSP Stapling。但大多数人直接用合并文件就够了。
第五步:配置自动续期(针对Let's Encrypt)
如果你用的是Let's Encrypt免费证书,90天有效期意味着你每三个月就要手动续期一次。这谁能记得住?必须上自动续期。
用certbot工具,配置cron定时任务:
`bash
安装certbot
sudo apt-get install certbot python3-certbot-nginx
第一次申请(自动检测Nginx配置)
sudo certbot --nginx -d example.com -d www.example.com
测试续期
sudo certbot renew --dry-run
配置cron自动续期(每天检查两次)
echo "0 */12 * * * /usr/bin/certbot renew --quiet --no-self-upgrade" | sudo tee -a /etc/crontab
`
这里有个细节:–quiet参数让certbot不输出日志,但必要时会通过邮件通知你(如果配置了邮箱)。–no-self-upgrade防止certbot自动升级版本导致配置文件变化。
踩坑记录:有次certbot自动续期失败,原因是域名解析临时出问题,证书无法验证。结果网站证书过期,用户访问显示"不安全"。解决方案:在crontab里写个脚本,续期失败时发邮件告警。
`bash
#!/bin/bash
/usr/local/bin/certbot-renew.sh
/usr/bin/certbot renew --quiet --no-self-upgrade 2>&1 | grep -q "No renewals were attempted"
if [ $? -eq 0 ]; then
# 续期成功,重新加载Nginx
systemctl reload nginx
else
# 续期失败,发邮件
echo "SSL证书续期失败,请检查" | mail -s "SSL Renewal Failed" admin@example.com
fi
`
第六步:验证部署是否正确
部署完后,用工具验证一下:
,看地址栏是否显示绿色锁。,输入你的域名,等几分钟就能看到详细报告。我遇到过评级A+的配置,后来加了HTTP/2和OCSP Stapling,性能从3.2秒降到0.8秒。`bash
用openssl验证证书信息
openssl s_client -connect example.com:443 -servername example.com
验证证书是否过期
openssl x509 -in /etc/nginx/ssl/example.com.crt -noout -dates
`
最后一个坑:配置完发现浏览器访问正常,但微信小程序访问报错"SSL证书验证失败"。查了半天发现是小程序的某些版本不支持TLS 1.3,强制降级到TLS 1.2就好了。所以配置里ssl_protocols最好写成TLSv1.2 TLSv1.3,不要只写TLS 1.3。
总结前展示:常见SSL部署问题排查路线图,标注错误类型和解决步骤
总结一下,你可以立刻用的三个点
最后说一句:SSL证书配置这个事儿,看着简单,但细节太多了。上面这些坑我一个不落地都踩过,希望你能少走弯路。如果还有问题,欢迎在评论区讨论。