阿里云服务器Nginx配置HTTPS测试证书全流程详解

阿里云服务器Nginx配置HTTPS测试证书全流程详解 在测试环境里折腾HTTPS最怕什么就是本地自签名证书一把梭结果小程序或者App客户端根本不认联调时各种请求失败证书无效你连服务端到底有没有问题都判断不了。我前阵子帮一个项目组排查微信小程序的回调接口超时查到最后发现是阿里云服务器上压根没配正式证书443端口一直空着第三方回调自然进不来。其实这种场景用阿里云的免费测试证书就能解决不用花一分钱申请流程也就十几分钟。这篇文章就以阿里云服务器配置测试证书为线索把从控制台申请、文件下载、Nginx部署到验证和续期的全过程完整写一遍适合刚接触服务器运维、正在做开发联调或者想把HTTP升级成HTTPS的同学直接参考。1. 先搞清楚测试证书解决了什么问题1.1 开发联调场景下自签名证书是真不行有同学可能觉得测试环境而已用openssl生成个自签名证书不就行了这个想法我一开始也这么干过直到对接第三方服务时连续踩坑才放弃。自签名证书最大的问题是“客户端不信任”。当你用iOS的URLSession、微信小程序的request、或者安卓的OkHttp去访问一个自签名证书的HTTPS接口时系统底层证书校验直接就失败了表现就是一堆奇怪的异常比如TLS certificate verification failedSSL handshake aborted。你当然可以在客户端代码里临时关闭校验但那只是本地自欺欺人一旦要跟真实环境联调对方根本不会为你的自签名证书去做这种配置。而且很多云函数、回调接口、WebSocket服务在反向代理层就掐掉了未受信任的证书你连请求都发不进去。阿里云提供的免费测试证书则不一样它是由正规CA签发的DV单域名证书系统级信任所有客户端和设备都能正常完成TLS握手。换句话说它在能不能建立安全连接这个问题上跟付费证书没有本质区别。1.2 测试证书和付费证书的差别在哪用一个表格说清楚比较直观对比维度免费测试证书付费证书签发时长一般几分钟到几小时DV类型也很快OV/EV需要更久有效期较短通常按季度计以控制台实际显示为准一年或更长支持域名类型单域名不支持通配符可以买通配符、多域名兼容性主流设备和浏览器都没问题部分品牌有更老版本设备的兼容适配售后保障基本没有人工服务有厂商支持兜底适合场景开发联调、测试环境、个人项目生产环境、商业站点很多人担心免费测试证书加密强度不够其实这是个误解。TLS加密强度取决于协议版本和加密套件跟证书免费还是付费没有关系。同样的ECDHE密钥交换、TLS 1.3协议免费证书一样能提供足够的加密能力。它真正的问题是有效期短需要反复续期这个后面再说。1.3 申请前必须满足的前置条件在动手申请之前先确认这几项否则后面会卡住有一台阿里云服务器不管是ECS还是轻量应用服务器都可以。域名已经解析到这台服务器。最简单的验证方法是直接ping域名看返回的IP是不是服务器公网IP。这一步一定要确认因为证书验证要证明“你拥有这个域名”。服务器上已经安装好Nginx并且能用 systemctl status nginx 看到运行状态。你拥有域名管理控制台的权限因为免费测试证书通常需要通过添加DNS的TXT记录来完成域名所有权验证。需要特别提醒的是域名解析如果刚改过TTL或者用了CDN代理验证时可能出现记录已经添加但CA那边查不到的情况可以先等一两分钟再点验证不要急着重试。2. 阿里云控制台申请测试证书的完整流程2.1 找到数字证书管理服务入口登录阿里云控制台后直接在顶部搜索框搜数字证书管理服务就能进入。注意老控制台里叫SSL证书现在统一到数字证书管理服务了别找错。第一次使用的话控制台首页会让你理解免费证书测试这个概念。免费测试证书通常有数量限制具体数量以当前控制台页面提示为准。免费证书签发后会有有效期倒计时所以不要一口气把额度都用光按需申请就行。2.2 申请并完成DNS验证的分步操作我按自己实际操作过的路径来写你照着点就行在数字证书管理服务控制台左侧菜单选证书管理在免费证书页签下点击创建证书。这里会有一个说明提示你免费证书的规格和数量上限先读一遍再继续。填写要保护的域名。比如你的接口域名是 api.example.com就填这个全域名。申请时需要注意免费测试证书一般不支持通配符像 *.example.com 这种是没法申请的只能补一张证书或换付费方案。选择验证方式推荐选DNS验证。阿里云会给你生成一条TXT记录记录类型是TXT主机记录一般是_dnsauth开头记录值是类似一段随机字符串。复制这条记录。打开你的域名管理控制台在对应域名下添加这条TXT解析记录。如果你不清楚域名是不是在阿里云也没关系只要你能操作域名的解析就行不一定非要在阿里云解析。添加完DNS记录后回到证书管理控制台点击验证。CA机构会去查询这条TXT记录查到了就进入签发流程。整个过程我实测下来快的时候几十秒慢的时候接近二十分钟跟CA那边的队列有关系不用反复刷新。证书状态变为已签发后就可以下载使用了。2.3 下载证书并理解zip包里的文件在证书列表里找到已签发的证书点下载服务器类型选NGINX/Tengine这是Nginx最常用的格式。下载下来是个压缩包解压后通常包含域名.key私钥文件对应Nginx配置里的 ssl_certificate_key。域名.pem站点证书文件对应 ssl_certificate。域名_chain.pem部分包有证书链文件如果你的站点证书没有包含中间证书就需要在Nginx配置里单独指定证书链。这里有个特别重要的提醒key文件是私钥泄露了等于这张证书白签而且可能被别人冒用你的域名做HTTPS服务。不要把它提交到Git仓库不要在聊天工具里转发。我见过不止一次有人把key文件传到一个公共代码库里最后只能紧急吊销重签。证书文件可以公开私钥绝对不行。3. Nginx部署HTTPS从上传到验证的完整过程3.1 先确认Nginx支持SSL模块拿到证书文件后SSH登录服务器。第一步是确认Nginx有没有SSL支持nginx -V 21 | grep ssl如果输出里有 --with-http_ssl_module就说明支持。现在通过yum或apt安装的Nginx基本都带这个模块这个检查主要是排查那些从源码编译的老环境。如果不支持就得重新编译Nginx相对麻烦建议直接从官方源重新安装一个支持SSL的版本。3.2 上传证书文件并设置目录权限我习惯把证书统一放在 /etc/nginx/ssl/ 目录下按域名分子目录方便以后管理。假设你已经把证书文件从本地下载到了当前目录上传命令用scp就行scp example.com.key example.com.pem root你的服务器IP:/etc/nginx/ssl/上传后需要修改权限chmod 600 /etc/nginx/ssl/example.com.key chmod 644 /etc/nginx/ssl/example.com.pemkey文件权限设为600是必须的因为Nginx master进程通常以root启动worker进程读取证书时需要有足够权限但如果权限太宽其他用户也能读存在安全隐患。如果服务器开了SELinux还要注意文件上下文否则Nginx会提示Permission denied这时可以用 ls -Z 查看上下文用 restorecon 或 semanage 修正。3.3 编写Nginx的SSL server块打开Nginx配置一般路径是 /etc/nginx/nginx.conf或者 /etc/nginx/conf.d/ 下新建一个example.com.conf。我用一个典型的反向代理配置示例来说明server { listen 80; server_name example.com www.example.com; # HTTP 自动跳转 HTTPS接口场景建议用 308 return 308 https://$host$request_uri; } server { listen 443 ssl; http2 on; server_name example.com www.example.com; ssl_certificate /etc/nginx/ssl/example.com.pem; ssl_certificate_key /etc/nginx/ssl/example.com.key; # 如果 zip 包里有独立证书链文件或者你确认 pem 只含站点证书就加上下一行 # ssl_trusted_certificate /etc/nginx/ssl/example.com_chain.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off; root /var/www/html; index index.html index.htm; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }需要注意Nginx 1.25 版本以后语法改为 listen 443 ssl; 配合 http2 on; 单独一行。老版本则是 listen 443 ssl http2; 写在一行。如果你用的是 yum 默认源装的比较老的版本看到 http2 directive is not allowed here 的报错就把 http2 on; 改成 listen 443 ssl http2; 这种写法。3.4 安全组和防火墙最容易卡住的一步配置写完后先测试配置文件再重载Nginxnginx -t systemctl reload nginx然后你以为就能访问了结果浏览器打开一片空白或者提示无法访问。这时候九成是端口没放行。阿里云服务器有内外两层网络过滤缺一不可第一层是云控制台的安全组。进入ECS实例详情页找到安全组标签点击配置规则在入方向手动添加一条规则协议选TCP端口填443源设为0.0.0.0/0授权策略选允许。如果是轻量应用服务器入口在防火墙页签操作逻辑类似。第二层是服务器内部防火墙。CentOS带firewalld的话执行firewall-cmd --permanent --add-servicehttps firewall-cmd --reload或者直接按端口放行firewall-cmd --permanent --add-port443/tcp firewall-cmd --reloadUbuntu系统用ufw的话ufw allow 443/tcp这两层都放行后443端口才算真正通了。我之前有次排查了半小时最后发现是安全组只放行了80443忘了加这类低级错误占了配置失败原因的一半以上。3.5 用命令行和浏览器双重验证端口通了之后先别急着开心用命令行验证一下证书状态。最直接的命令是curl -vI https://example.com 21 | grep -E SSL connection|subject|issuer|HTTP/如果看到类似 SSL connection using TLSv1.3 以及证书的subject和issuer字段说明TLS握手已经成功。如果证书链不完整curl可能会提示 unable to get local issuer certificate。遇到这种情况确认pem文件是否包含了完整证书链。你可以用openssl查看证书内容openssl x509 -in /etc/nginx/ssl/example.com.pem -noout -text查看里面的证书签发者信息是否只有站点证书没有中间证书。如果有单独的chain文件在Nginx配置里加上 ssl_trusted_certificate 并指向它。浏览器层面直接访问 https://example.com看地址栏是否出现小锁。然后F12打开开发者工具切到Security面板点View Certificate可以看到证书的有效期、签发机构以及域名匹配情况。这个面板在排查问题时非常直观能一眼看出证书是否被信任、有没有过期。3.6 HTTP强制跳转HTTPS的细节在第一个server块里用 return 301 还是 return 308这个细节很多人不注意。301会把POST请求也重定向而且某些客户端在重定向后会把POST改成GET导致接口报Method Not Allowed。对于API接口和回调地址建议用308永久重定向它保留请求方法和请求体。页面跳转用301问题不大因为本来就是GET。这个坑我在实际联调中遇到过非常隐蔽当时客户端一直发POST服务端一直报错抓包才发现重定向后方法变了。4. 测试证书的坑位清单与续期方案4.1 常见配完不能访问问题汇总把实际过程中最常踩的坑列成一个清单遇到问题可以直接对照现象可能原因排查/解决办法curl 提示 SSL_ERROR_SYSCALL安全组或防火墙没放行443检查云控制台安全组和服务器内部防火墙浏览器显示证书无效证书链不完整用完整链pem或加 ssl_trusted_certificatenginx -t 报证书文件打不开权限不对或路径错误确认key为600权限、pem为644权限路径无拼写错误网站能访问但地址栏不安全页面引用了http资源全局替换资源为https或者配置CSP升级请求手机访问时好时坏证书链缺中间证书补全证书链用SSL检测工具验证访问时提示日期问题服务器系统时间不对同步系统时间date命令确认4.2 测试证书为什么容易突然不可用免费测试证书的一个显著特点是有效期短通常以季度为单位并且不支持纯自动续期。这意味着你必须在证书过期前重新申请并替换。很多人测试环境部署完证书就不管了两周后突然发现接口连不上一查证书过期了还在那里排查半天网络问题。这是很低级的浪费。我的建议是给证书做成自动化的生命周期管理在服务器上配置一个cron定时任务每天执行一次证书到期检查。使用 openssl s_client 从本地或远程读取证书的到期时间。如果剩余天数低于阈值比如30天就发告警到邮件或钉钉。一条很好用的远程查询命令echo | openssl s_client -connect example.com:443 -servername example.com 2/dev/null | openssl x509 -noout -enddate输出示例是 notAfterApr 20 12:00:00 2025 GMT。拿这个日期跟当前时间比较就能清楚知道还剩多少天。这条命令在生产环境排查突然断连时非常有用几秒钟就能判断是不是证书过期。4.3 续期实操手动申请替换当证书临近过期你需要做的流程是登录数字证书管理服务控制台在免费证书页签下申请一张新证书。完成同样的DNS验证等待签发。下载新证书文件覆盖服务器 /etc/nginx/ssl/ 下的旧文件。执行 nginx -t然后 systemctl reload nginx。再用 curl -vI 验证新证书的到期时间。这个过程的手动步骤比较多所以如果你在长期运行的测试环境里我更建议调研一下替代方案。比如用ACME协议自动续期的证书像Lets Encrypt配置一次后可以每60到90天自动续期彻底解决忘了续期这种问题。它跟阿里云测试证书的区别是阿里云证书是CA签发目前需要手动续期ACME证书是自动化流程更适合追求零运维的环境。4.4 测试证书到底能不能上生产环境直接说结论在涉及真实用户数据和交易的生产环境不建议长期使用免费测试证书。不是因为它不安全而是因为有效期短导致运维风险高。你可以想象一下某天早上用户打开你的站点浏览器弹出证书过期信任度瞬间清零这种事故多半只是因为忘了续期。免费测试证书最合适的场景是开发环境、测试环境、联调环境临时演示、比赛项目、课程作业个人博客、内部系统等对可用性要求不高的服务如果是一个中低流量且没有敏感业务的个人站点想长期免费使用HTTPS我更推荐用支持自动续期的ACME证书方案这样既免费又不需要频繁人工干预。如果你对证书管理有明确要求或者需要通配符证书、更高等级的OV/EV证书再考虑购买付费产品。5. 配置测试证书后的最后几步习惯配置完证书我自己习惯再做三件事推荐你也养成这几个习惯先是在本地浏览器和手机4G网络下分别访问一次HTTPS站点确认不是只有服务器本机可以访问。很多人配置完只在服务器上curl没想过手机走运营商网络访问时可能因为安全组或者证书链问题访问不了提前暴露问题比用户帮你发现要好得多。然后是把证书到期时间写入日历或监控脚本。这里可以很朴素不用上什么复杂系统直接在crontab里加一条每天运行的脚本0 9 * * * /home/ops/check_cert.sh脚本内容就是上面那条openssl命令加一个日期比较逻辑剩余天数小于30就输出告警。这样至少不会半夜被测试同事一个电话叫起来说环境又挂了。最后是记录好这次申请的域名、证书文件路径、到期时间以及服务器上对应的配置。因为免费测试证书的有效期短三个月就要来一轮如果每次都要靠回忆去捡起之前的操作会非常痛苦。写个简单的文档或者README放在服务器配置目录里下次续期直接照着做十分钟就能搞定。阿里云服务器配置测试证书这件事技术门槛真的不高卡住的往往是安全组放行、证书链完整、权限设置这些细节。如果你正好要配按这篇文章的流程走一遍应该能一路顺到底。如果中途遇到问题优先排查443端口是否通、证书链是否完整这两个环节解决了大部分排障时间。