地址栏里“不安全”三个字,比任何流量数据都更能说明一个网站的现状。我第一次帮朋友调试一个商城项目时,输入后台地址就直接看到红色警告,那一刻我就知道,这个站点缺的不是功能,而是最基础的HTTPS保护。后来我把腾讯云免费SSL证书的申请与配置流程完整走了一遍,从注册到配置、从验证到强制跳转,每个环节都踩过或深或浅的坑。这篇教程就是把这些经验按顺序整理出来:如何申请腾讯云的免费SSL证书,如何通过DNS验证,如何在Nginx上启用HTTPS,以及后续续期监控怎么做。
1. HTTPS与SSL证书:这事为什么躲不掉
1.1 HTTPS到底解决什么问题
HTTP协议设计之初的前提是所有参与者都在可信网络内。放在今天这个环境里,咖啡厅WiFi、运营商链路、CDN节点,任何一个环节都能看到明文报文。登录密码、登录Cookie、小程序的access_token,一旦被截获,几乎等于把账号权限交了出去。HTTPS做的事情,简单说是三件:加密传输、身份验证、完整性校验。
再把话说白一点,HTTP内容像是一张明信片,任何人都能翻看;HTTPS像是把明信片塞进带锁的保险箱,接收方要有密码才能打开。浏览器和服务器在TLS握手中先确认双方身份,再协商出一个临时会话密钥,后续内容全部用该密钥加密。证书在这里面扮演的角色是“身份证”,它证明申领这个域名的组织确实控制着对应的域名,同时提供公钥用于加密协商。
说了这么多,其实对普通网站所有者来说,最直接的结论只有一句话:没有HTTPS,浏览器会不断警告访问者;有HTTPS,地址栏恢复正常,小程序后台、支付回调、第三方接口才愿意对接你的域名。
1.2 DV、OV、EV:证书类型怎么选
现在证书类型搞得人眼花缭乱,但本质上按验证深度分成三档。
| 证书类型 | 验证内容 | 申请要求 | 典型场景 |
|---|---|---|---|
| DV | 域名所有权 | 证明能控制该域名 | 个人博客、企业展示站、API接口 |
| OV | 域名+组织信息 | 提交营业执照等材料 | 企业官网、电商类站点 |
| EV | 域名+组织+法律实体 | 严格审查,材料更多 | 银行、政务、高信任平台 |
很多刚接触证书的朋友容易误以为免费证书加密不够强。实际上DV、OV、EV在加密强度上没有本质差别,区别在于证书背书方对申请者身份的审查程度。DV证书签发快,但CA无法确认这张证书背后是企业还是个人;OV和EV能够建立更强的信任链。如果你的站点只是要“启用HTTPS”,DV足够用。
1.3 腾讯云免费证书的真实定位
腾讯云免费SSL证书本质上是与TrustAsia等CA合作的DV单域名证书。优势很明显:操作入口在云控制台内,注册完账号就能申请,签发速度通常很快,而且能与CDN、负载均衡等腾讯云产品一键绑定。对于服务器在腾讯云上的用户,申请完证书可以直接在控制台部署到对应的云资源,比自己手动下载再回源方便很多。
但也有两个限制需要提前了解。第一,免费证书通常只支持单个域名,不支持 *.example.com 通配符;如果你的业务有大量子域名,要么申请多张免费证书,要么购买商业通配符证书。第二,免费证书有效期目前为3个月左右,这意味着每年都要处理几次续期问题,所以文章后面会详细写续期监控和自动部署的方法。
2. 申请前准备与关键参数
2.1 账号、域名与网络环境
申请前需要三个基本前提:完成实名认证的腾讯云账号、一个自己可以修改DNS解析记录的域名、以及能访问腾讯云控制台的浏览器环境。域名不一定非要用腾讯云DNSPod解析,其他服务商也一样能验证,只是腾讯云解析在验证时会更顺滑。网络环境没什么特别要求,只要能打开控制台就行。
如果你是全新的服务器,还要想清楚证书准备放哪。最常见的场景是Nginx,也可能是Apache、宝塔面板、腾讯云CDN、API网关。本文以Nginx为准,因为它的配置方式最通用,其他面板或网关本质上只是把同一套证书文件换个位置存放。
2.2 密钥算法和CSR生成方式
申请时有一段表单是关于密钥算法的。腾讯云通常提供RSA和ECC两种选择,大多数场景直接用RSA 2048即可,兼容性最好。ECC生成的密钥更短、握手性能更好,但部分老版本操作系统和服务器软件不认,对于初期项目,不值得为了那一点性能提升引入不确定性。
CSR那一栏通常有两种方式:在线生成,或者自己生成CSR上传。默认选在线生成即可,平台会帮你生成私钥和证书签名请求,下载证书包里会一并提供私钥文件。如果公司安全策略要求私钥不能出现在第三方平台,那就用openssl本地生成私钥和CSR,只把CSR内容粘贴到申请单里。对于绝大多数个人站,在线生成最省事,但要注意保存好下载的私钥文件,丢了就只能重新签发。
2.3 免费证书的有效期与续期预期
在提交申请之前,建议先做好心理预期:免费证书不是一劳永逸的。过去行业里还有1年有效期的免免费证书,现在主流CA和云厂商都在缩短有效期,腾讯云免费证书目前基本是3个月左右。这意味着每年至少要和证书续期打四次交道。好在腾讯云控制台提供自动续期能力,并且很多云资源支持自动更新,只要你提前把自动续期打开,证书到期前平台会重新签发并部署;非云资源、自己管理的服务器则要依靠提醒脚本,这点第6节会详细展开。
3. 申请流程与域名验证
3.1 在腾讯云控制台发起申请
登录腾讯云控制台,在顶部搜索框输入“SSL证书”,进入证书管理页面。找到“申请免费证书”按钮,点击后会进入一个证书申请单。填写信息时,域名一栏填你真正需要保护的主域名,比如 example.com;如果你确实需要 www.example.com,要看平台是否支持同时绑定主域和www。如果不支持,就单独再为 www.example.com 申请一张同名DV证书,或者把两个域名都解析到同一台服务器后分别部署。字段里还有证书备注、联系人邮箱等,邮箱建议填写你长期在用的,后续到期提醒、验证通知都会发到这里。
验证方式一般有DNS验证和文件验证两种,我会直接推荐DNS验证。原因后面细说。如果你在腾讯云提交订单后没有立刻看到“验证”按钮,可能是订单还在生成状态,刷新页面即可。
3.2 DNS验证操作与检查方法
选择DNS验证后,控制台会给出三条信息:主机记录、记录类型、记录值。主机记录通常类似_dnsauth或_dnsauth.example.com,记录类型是TXT,记录值是一长串随机字符串。你需要登录域名的DNS服务商控制台,进入该域名的解析设置,添加一条TXT记录。
这里经常出现的问题是把主机记录填错。比如提示要填_dnsauth,你偏要填www或者完整域名,提交后一直无法验证。以阿里云、DNSPod、Cloudflare等平台为例,添加记录时主机记录字段只填相对域名前缀,不要带上主域名。记录类型选TXT,记录值完整复制,不要漏字符。
加完后不要急着疯狂点击“验证”。可以先用命令行检查是否生效。Windows和Linux都可以用nslookup:
nslookup -type=TXT _dnsauth.example.com如果返回的记录值和控制台一致,再回到腾讯云页面点击“验证”。正常情况下从添加记录到验证通过只需要几分钟,个别情况因为地域节点缓存不同会慢一些,等十几分钟再验证也不迟。验证通过后,CA会自动签发证书,状态从“待验证”变成“已签发”,这个过程通常也在几分钟至一小时内完成。
顺带说一个经验:如果你是腾讯云的DNSPod解析用户,TXT记录可以在DNSPod控制台直接添加,腾讯云SSL控制台和DNSPod的验证数据通常是打通的,有时候添加完直接在证书页面刷新即可看到通过。
3.3 文件验证操作与适用场景
文件验证适合那些不想动DNS解析记录,或者域名被托管在一个操作不便的平台上的人。控制台会给出一个需要上传的验证文件路径,比如在域名的根目录下创建.well-known/pki-validation/xxx.txt,文件内容是指定的验证字符串。创建完成后,让这个文件可以通过http://example.com/.well-known/pki-validation/xxx.txt直接访问,再回控制台点验证。
这个方案最大的坑在于目录拼写。.well-known前面有英文点,如果服务器系统是Linux,注意不能把这个目录放在public_html里错误的位置。有些面板软件默认会隐藏文件名带点的文件,传输时要开启显示隐藏文件。另外,文件验证要求站点已经能通过HTTP对外访问,如果你的网站还没上线,只想先把证书弄好,建议还是优先做DNS验证。证书签发后,这个验证文件就可以删除,不影响线上。
4. Nginx服务器配置实战
4.1 证书下载与文件权限
证书状态变成“已签发”之后,在证书列表右侧点击“下载”。下载类型选择Nginx,压缩包里一般有两个关键文件:example.com_bundle.crt(证书链)和example.com.key(私钥)。.crt文件名里的bundle表示内含域名证书和中间CA证书,这正是服务器需要完整证书链的原因。
把这两个文件上传到服务器,建议统一放在/etc/nginx/ssl/目录下。注意私钥文件权限一定要收紧:
sudo mkdir -p /etc/nginx/ssl sudo cp example.com_bundle.crt example.com.key /etc/nginx/ssl/ sudo chown root:root /etc/nginx/ssl/* sudo chmod 644 /etc/nginx/ssl/example.com_bundle.crt sudo chmod 600 /etc/nginx/ssl/example.com.key私钥一旦泄露,你的证书就失去了保密意义。把它放在虚拟主机Web目录之外,权限设置成仅root可读,是一个三分钱成本就能做好的安全习惯。
4.2 配置HTTPS监听与HTTP跳转
在Nginx配置目录下新增一个站点配置文件,或者修改现有 server 块。以Ubuntu/Debian示例,配置文件通常在/etc/nginx/sites-available/example.com.conf,CentOS可能在/etc/nginx/conf.d/example.com.conf。写入以下核心配置:
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name example.com www.example.com; ssl_certificate /etc/nginx/ssl/example.com_bundle.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/example.com; index index.html index.htm; }第一段server块负责把所有HTTP请求301重定向到HTTPS,第二段是真正的HTTPS站点。注意 301 是永久重定向,浏览器和搜索引擎会记住这个跳转;如果你在调试阶段想随时回到HTTP,临时用302会更方便,但上线环境最终要用301。
配置完成后执行检查和重载:
sudo nginx -t sudo systemctl reload nginx如果 nginx -t 报错,多半是路径写错、文件不存在或者证书密钥不匹配,先检查路径再继续。重载后访问https://example.com,看到站点内容且地址栏出现小锁,核心目标已经达成。
4.3 配置跳转后端口和防火墙问题
实际部署中一大类“不生效”案件并非证书配置问题,而是443端口没有放通。腾讯云服务器默认安全组可能只放行了80、22等端口,需要在腾讯云控制台的安全组规则中,添加“TCP:443”的入站规则,来源地址按需选择,对外服务的网站通常设为0.0.0.0/0。如果是轻量应用服务器,则在防火墙页面放行443。
Linux服务器自身的防火墙也要检查。如果你的系统是CentOS7+,常用firewalld;Ubuntu则常用ufw。放行方式:
sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload或者:
sudo ufw allow 443/tcp配置完成后,可以在本机用curl -k https://example.com -I测试响应,如果返回HTTP状态码正常,说明端口和TLS握手都已通。
4.4 TLS版本、会话缓存和OCSP优化
证书能用之后,我建议顺手把TLS相关参数调优。一个基础但健康的配置如下:
ssl_protocols TLSv1.2 TLSv1.3; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_stapling on; ssl_stapling_verify on; resolver 119.29.29.29 valid=300s; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;逐条解释一下。ssl_protocols只保留 TLSv1.2 和 TLSv1.3,把 TLSv1.0、TLSv1.1 这些老协议关掉,它们已经有已知漏洞,浏览器基本也不会再用了。ssl_session_cache和ssl_session_timeout用于复用TLS会话,减少重复握手的开销,对高并发站点效果明显。OCSP Stapling的意思是服务器在握手时直接附带证书吊销状态,浏览器不用再额外访问CA的吊销接口,能提高握手速度和稳定性,这里需要指定一个可公网访问的DNS resolver,腾讯云自己的119.29.29.29就行。
HSTS这一项要特别谨慎。它告诉浏览器:未来一段时间内,本域名只能走HTTPS,连301都不用了,浏览器强行把HTTP转换成HTTPS。如果配置有严重问题,用户可能在一段时间内无法访问站点。所以建议先把HSTS注释掉,等站点稳定确认无误再打开,或者先不加preload参数。
4.5 反向代理场景的额外细节
如果你的Nginx不只是托管静态页面,而是把请求反代到后端服务,比如Node.js、Java、PHP-FPM,有三件事要处理。第一,proxy_pass写http://127.0.0.1:8080这类内部地址没问题,因为TLS在Nginx这一层已经终止。第二,要把真实协议传给后端:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme;很多框架生成页面链接时会根据请求协议判断,拿不到X-Forwarded-Proto就会一直生成http开头的链接,导致静态资源被浏览器混合内容策略拦截。第三,后端应用如果读到的还是http,要检查框架自身的“trusted proxies”配置,否则即使Nginx传了头,框架也可能不认。
5. 常见问题与排查技巧
5.1 证书文件与生效异常
证书和私钥不匹配。Nginx启动时报错,说证书的key和证书不匹配,通常是下载了其他域名的证书或私钥文件放错了位置。排查方式是用openssl比对两个文件的公钥哈希:
openssl x509 -in example.com_bundle.crt -noout -pubkey | openssl sha256 openssl pkey -in example.com.key -pubout | openssl sha256两条命令的输出一致,说明证书和密钥配对;不一致就重新下载对应域名的证书包。
证书链不完整。有些环境下浏览器提示“证书链不完整”,是因为服务器只贴了域名证书,而没把中间CA证书一起贴上去。腾讯云下载包里.bundle文件就是完整链,直接使用它而不是只取第一段证书。
浏览器显示旧证书。部署新证书后仍然看到旧证书,先清浏览器缓存和无痕模式测试,再用curl -v看服务器实际返回的证书时间。如果服务器确实返回新证书,基本就是浏览器或CDN缓存问题。
5.2 重定向与混合内容
HTTPS重定向循环。表现是浏览器一直在域名之间来回跳,停不下来。要排查三层:源站Nginx是否有HTTP到HTTPS的301;CDN是否开启了HTTP强制跳转;后端代码或框架是否又在302跳转。我见过太多案例是CDN强制跳转和源站301同时打开,两层叠加导致死循环。解决方案是保留一层跳转逻辑,比如CDN跳HTTPS时,源站直接把HTTP也返回HTTPS内容,不作二次302。
混合内容拦截。页面已经走了HTTPS,但地址栏的小锁变成感叹号,甚至部分JS、图片加载失败。打开浏览器开发者工具的Console,一般会看到类似“Mixed Content”的提示,标记出哪个URL还是http。解决方式是把站内资源地址统一改成相对路径或完整https链接,比如把代码里的http://example.com/wp-content/uploads/...改成https://example.com/...或直接/wp-content/...。系统性查一遍全站配置里的硬编码地址,比一个个改前端文件更省时间。
5.3 验证失败、续期不成功
DNS验证一直失败。最常见的三个原因:TXT记录值复制不全、主机记录前缀填错、域名本身还没在公网正常解析。在命令行用nslookup确认记录已经能查到后,再回控制台点击验证。如果记录值里带引号或特殊符号,粘贴时不要自己加空格。
续期后新证书没自动部署到自己服务器。腾讯云的自动续期和自动部署只对云产品、云资源生效;你自己管理的Nginx、Apache不在此列。它不会把你的免费证书自动推到一台普通CVM的/etc/nginx目录里。所以如果部署在自管服务器上,续期后要手动下载并替换证书文件,或者用脚本调用证书服务API去处理。这也是我坚持要写第6节监控脚本的原因。
6. 到期监控与长期维护
6.1 用openssl查看证书过期时间
证书一旦不在云服务商的控制范围内,就要靠服务器命令自行掌握时间。查看本地证书文件有效期,一行命令即可:
openssl x509 -noout -dates -in /etc/nginx/ssl/example.com_bundle.crt输出里的notAfter就是过期时间。如果想快速看还剩多少天,可以用日期计算把它转换成秒再除以86400。这个命令值得放在服务器备忘录里,每次去服务器排查证书问题都会用到。
6.2 写一个简单的到期提醒脚本
在Nginx所在服务器上,可以放一个脚本定期检查证书剩余天数,剩余时间不足30天就往自己的工作群或邮箱发提醒。脚本逻辑不复杂,我直接用最朴素的写法:
#!/bin/bash CERT="/etc/nginx/ssl/example.com_bundle.crt" EXP=$(openssl x509 -enddate -noout -in "$CERT" | cut -d= -f2) EXP_EPOCH=$(date -d "$EXP" +%s) NOW_EPOCH=$(date +%s) DAYS=$(( (EXP_EPOCH - NOW_EPOCH) / 86400 )) if [ "$DAYS" -lt 30 ]; then echo "证书剩余 $DAYS 天过期: $EXP" # 这里接入你常用的通知方式,比如企业微信机器人: # curl -s 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx' -H 'Content-Type: application/json' -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"证书剩余 $DAYS 天过期\"}}" fi然后通过crontab设置每周一早上执行一次:
0 9 * * 1 /usr/local/bin/check_ssl_expiry.sh脚本输出可以直接通过系统邮件、企业微信机器人、钉钉群机器人等方式推送。我习惯只提醒到还剩30天,留足处理时间,不至于等到过期当天手忙脚乱。
6.3 自动部署与手动部署的取舍
免费证书有效期变短后,腾讯云控制台为了减轻续期压力,对CDN、负载均衡等云资源提供了“自动续期+自动更新”的体验:只要证书来源是腾讯云签发,并部署在这些云资源上,到期前平台会重新签发并替换旧证书。这是最省心的方案。
但自己管理的服务器,本质上仍是“下载证书→覆盖旧文件→reload Nginx”这个流程。想全自动化,可以用acme.sh或certbot替换腾讯云免费证书,让脚本自动申请Let's Encrypt证书并hook到reload Nginx;也可以等腾讯云证书签发后通过API拉取证书再部署。这两种自动化的复杂度都不低,刚上手的站点先不用急着做。更稳妥的策略是:控制台开启自动续期,服务器上挂一个到期提醒脚本,剩30天提醒一次,剩7天再提醒一次,手动替换也只需要2分钟。
我个人在实际操作中的体会是,SSL证书这件事,本质上是“一次性配置,持续性维护”。第一次申请和配置花的时间不超过半小时,难点从来都不在于步骤本身,而在于链路长——从云控制台一路走到浏览器地址栏,中间跨越了DNS、防火墙、Nginx、CDN、后端框架好几个层级,任何一层有问题,表现都是“HTTPS用不了”。把你自己的流程固定下来,配上到期提醒和监控脚本,剩下的就是每次到期前花两分钟换文件、reload一次。等到用户访问时看到角落里那把小锁,一切值得。