1. 从一次线上事故说起:为什么必须搞懂这两个协议
先讲一个真实场景。某天凌晨,我负责的一个小商城系统接到了告警:支付回调接口频繁超时,用户反馈下单后一直转圈。排查了一圈,最后发现问题出在运维同事把HTTPS证书配置错了,导致部分请求回退到了HTTP明文传输,而网关侧的安全策略会把这类明文请求直接拦截重试。事故持续了大约四十分钟,影响了几百笔订单。
那次事故之后,我意识到一个很扎心的事实:很多写了三五年接口的程序员,对HTTP和HTTPS的区别仍然停留在“HTTPS更安全”这种一句话层面。真要问你——HTTPS到底比HTTP多了什么?多出来的东西是怎么工作的?它真的绝对安全吗?部署时应该注意什么?——能完整答上来的人其实不多。
所以这篇文章不做那种百度一搜一大把的科普罗列,而是从协议本身的差异讲起,结合抓包实测、性能对比、证书部署这些实际场景,把HTTP和HTTPS之间的账算清楚。内容主要面向后端开发、运维、测试以及所有需要接触网络协议的从业者,看完之后你至少能回答三个问题:HTTPS多出来的成本花在了哪里?什么时候必须上HTTPS?上线HTTPS之后又会踩哪些坑?
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. HTTP与HTTPS的本质差异:不只是加了一层壳
2.1 协议栈层面到底多了什么
最简单的说法是:HTTPS = HTTP + TLS/SSL。这句话没错,但它掩盖了很多关键细节。
我们看协议栈。HTTP跑在TCP之上,应用层直接和TCP交互。HTTPS则在HTTP和TCP之间插入了一个TLS层,HTTP的数据先交给TLS加密,然后由TLS把密文交给TCP传输。也就是说,从TCP的视角来看,它根本不知道自己传输的是HTTP还是HTTPS——它只知道自己传输的字节流恰好是TLS记录协议(TLS Record Protocol)的数据。
这里有个很多人忽略的点:TLS层影响的不仅仅是应用层数据,连接建立的方式也彻底变了。普通HTTP建立一个TCP连接后,客户端立刻就能发HTTP请求。而HTTPS需要先完成TCP三次握手,然后在同一个TCP连接之上再做TLS握手,之后才能发起真正的HTTP请求。换言之,HTTPS的连接建立时间是TCP握手加TLS握手的时间总和。
用数字直观对比一下。假设你的客户端和服务器RTT(往返时延)是50毫秒:
- HTTP:TCP三次握手耗时约1.5个RTT,也就是75毫秒,之后就可以发请求。
- HTTPS(TLS 1.2):TCP握手75毫秒,加TLS握手通常需要2个RTT,也就是100毫秒,总共175毫秒。
也就是说,仅仅建立连接,HTTPS就比HTTP多了100毫秒。当然,这只是TLS 1.2的情况,TLS 1.3把握手压缩到1个RTT(甚至0-RTT模式),但相对HTTP仍然有额外开销。
2.2 端口号与URI scheme背后的设计逻辑
HTTP默认80端口,HTTPS默认443端口。这个差异看起来简单,但实际工作中经常有人搞混——尤其是做网关转发、负载均衡配置的时候。
一个常见的误区是:认为HTTPS和HTTP可以监听同一个端口。严格说这不行。理由是协议栈层面的差异:HTTP监听端口上跑的是裸的HTTP报文,而HTTPS监听端口上,客户端发送的第一个字节是TLS握手消息(先是ClientHello),而不是HTTP的请求行(比如“GET / HTTP/1.1”)。服务端不可能同时用一套解析逻辑处理两种完全不同的首字节流。
那实际生产环境里,一个服务既要支持HTTP又要支持HTTPS怎么办?常规做法是开两个监听端口,或者在同一个端口上做协议识别——比如网关根据首字节判断是TLS握手还是明文HTTP,然后分流到不同后端。但后一种方案依赖特定网关能力,而且会增加复杂度,大部分场景下直接开两个端口更稳妥。
另外URL里的http://和https://也不只是写给人看的。浏览器和客户端库会依据scheme决定默认端口和连接方式:https://意味着要启用TLS、使用443端口,然后默认开启证书校验;http://则明文且默认80端口。如果你写API文档时把地址写错了scheme,客户端那边会直接踩进证书校验或明文请求的坑里。
2.3 明文与密文的实际差别:一个抓包实验
理论说再多,不如亲手抓一次包看得直观。我在本地用开源工具搭建了一个最简单的HTTP服务和一个HTTPS服务,然后分别用curl发起请求,同时用Wireshark抓包对比。
HTTP请求的抓包结果非常直观——协议树上展开HTTP层,能看到完整的请求行、请求头,甚至请求体里的内容。比如我请求一个带用户名的登录接口,抓包数据里直接显示:
code复制POST /login HTTP/1.1
Host: 192.168.1.10
Content-Type: application/json
{"username":"admin","password":"123456"}
毫不夸张地说,这种流量如果在公网上传输,等同于把账号密码写在明信片上邮寄。
再看HTTPS请求的抓包结果:Wireshark的协议树里只有TCP和TLS两层,TLS层通常显示为TLSv1.3或TLSv1.2,展开后的内容全是密文数据。除非你在Wireshark里预先配置TLS解密私钥(后续会讲到),否则根本看不到HTTP层,更看不到请求内容。
这个实验建议大家都做一次。因为只有亲眼对比过明文和密文,你才会真正对“HTTPS保护了数据”这句话有体感,而不是停留在概念层面。
3. TLS握手过程拆解:HTTPS的信任链是怎么建立的
3.1 证书、签名、信任链——三个概念一次理清
要理解HTTPS,绕不开证书体系。很多初学者在这里卡住,我觉得主要原因是三个概念混在一起了:证书(Certificate)、签名(Signature)、信任链(Chain of Trust)。
我用一个粗浅但好懂的类比来说明。证书就好比身份证。身份证上有你的姓名、照片、有效期,以及发证机关。证书里也有类似字段:域名、公钥、有效期、签发者(CA,Certificate Authority,证书颁发机构)。
身份证上通常有防伪标识,其他人拿到手可以验证是不是真的。证书上也有类似的东西——数字签名。数字签名是CA用自己的私钥对证书内容做摘要加密生成的一串数据。验证时,任何人用CA的公钥解开签名,与证书内容重新计算的摘要比对,一致即可确认证书未被篡改、确实是该CA签发的。
那CA的公钥又从哪里来?答案是操作系统的根证书库里。Windows、macOS、Linux发行版、Android、iOS都内置了一批受信任的根证书。这些根证书对应的私钥被CA极其严格地保护着,一旦泄露,等于整个信任体系崩溃。
信任链则是这样一个过程:
code复制根证书(操作系统内置信任) -> 中级证书 -> 你的服务器证书(叶子证书)
浏览器和客户端在验证服务器证书时,会从叶子证书开始,逐级向上查找签发者,直到找到一个操作系统内置的根证书。链条完整、每一级签名都有效、证书在有效期内,校验才算通过。任何一环断裂,都会导致证书校验失败。
3.2 握手过程中的核心步骤与密钥交换
TLS握手的目的说起来很简单:客户端和服务器在明文状态下协商出一个只有双方知道的对称密钥,后续数据都用这个密钥加密传输。
为什么最终用对称加密,而不是一直用非对称加密?主要原因是非对称加密(如RSA)计算开销大,不适合批量加密数据。对称加密(如AES)速度快得多,适合通信双方大量数据传输。于是TLS的设计思路就变成了:用非对称加密(或密钥交换算法)安全地协商出一个临时对称密钥,然后用对称密钥加密实际数据。
以最常用的TLS 1.2握手为例,步骤大致是:
- 客户端发送ClientHello,包含支持的TLS版本、加密套件列表、随机数。
- 服务器返回ServerHello,选定TLS版本和加密套件,并附上自己的证书、服务器随机数。
- 客户端验证证书有效性——这里涉及信任链检查、域名匹配、有效期检查。
- 密钥交换:根据协商的算法,客户端生成预主密钥(Pre-Master Secret),用服务器公钥加密后发给服务器;或者双方通过ECDHE这类算法各自算出预主密钥。
- 双方用各自持有的随机数和预主密钥,通过伪随机函数派生出会话密钥。
- 双方互相发送Finished消息,内容是用会话密钥加密的握手摘要,验证之前的握手过程有没有被篡改。
TLS 1.3则做了精简,握手从两次往返降到一次往返,而且移除了很多不安全的旧算法,默认前向保密——即便服务器私钥泄露,之前抓取的密文流量也无法被解密。这点对长期安全非常重要。
3.3 常见误解:HTTPS不是加密通道,而是“加密之后的明文通道”
这里必须澄清一个流传很广的误解。很多人以为HTTPS的密文传输意味着代理、网关都看不到内容。事实不是这样——如果用户主动信任了某个根证书(比如公司办公电脑安装了公司自签的根证书,或者用户自己安装了抓包工具证书),那么中间的代理设备完全可以先用自己伪造的证书和客户端建立TLS连接,再用真实证书和服务器建立连接,两端分别加解密,对客户端和服务器而言各自看到的都是“正常”连接。
这种机制叫中间人解密,企业网关、抓包工具用的都是这个原理。它的前提就是客户端信任了中间人的根证书。
所以准确理解应该是:HTTPS保护的是传输过程中不知道你是否信任中间方的场景——比如公共WiFi下的被动窃听、流量被恶意篡改,这些攻击者无法解密你的内容。但如果你主动信任了某个根证书,那这条HTTPS通道对该信任方而言等同于“加密之后的明文通道”,这是信任模型本身带来的边界。
这个认知很重要。包括我在内,很多开发者一开始误以为只要上了HTTPS就万事大吉,直到某次排查线上问题,抓包发现测试流量被网关解密了,才真正理解信任模型的边界在哪里。
4. 除了加密,HTTPS还解决了哪些HTTP解决不了的问题
4.1 身份验证与防伪:你连接的到底是谁
HTTP协议本身无法验证服务器身份。你输入一个网址,HTTP请求发出去,回来的响应到底来自目标服务器还是某个中间人,HTTP协议完全不关心。配合DNS劫持或者ARP欺骗,攻击者可以轻松地把你的请求引到自己的服务器上,返回伪造内容。
HTTPS通过证书体系解决了这个问题。客户端校验证书时,不只检查证书是否由可信CA签发,还会检查证书上的域名是否与当前访问的域名匹配。两者都对,才认为服务器身份可信。
实际工作中,很多公司内部有一些老系统使用了自签名证书,用户访问时会遇到浏览器警告。这种警告其实就是身份验证失败的反馈——浏览器无法确认这个自签名证书的签发者可信,于是宁可拒绝连接也不冒险。强制弹窗是对用户的一种保护,虽然有时候很烦。
4.2 数据完整性:如何察觉内容被篡改
TCP本身有校验和机制,但它只能检测传输过程中发生的随机位翻转或损坏,无法防住有意的篡改。攻击者可以在报文经过的链路上修改内容,再重新计算校验和,TCP层面完全无法察觉。
TLS则通过MAC(消息认证码)机制保障完整性。每个记录包在加密的同时附带一个MAC值,该值由会话密钥、消息内容、序列号等计算得到。接收方解密后重新计算MAC,与收到的MAC比对,不一致就说明数据在传输中被改动过,直接断开连接并报错。
这里有一个容易被忽视的设计细节:TLS的MAC校验是跟序列号绑定的。这意味着攻击者即使把整条合法消息原封不动地剪切再重放,接收方也能通过序列号错位发现异常。防重放攻击是HTTPS相比HTTP一个不小的优势。
我自己在做接口设计时遇到过一个关联问题:某些老朋友式的老接口,用的是HTTP加自定义签名(比如把参数拼接后MD5)来防篡改。这种方式能挡住部分篡改,但因为请求头、起始行等元数据是不受保护的,攻击者仍然可以调整部分字段。上了HTTPS之后,至少传输链路层面的完整性能得到保障,应用层签名只需要专注业务参数防重放即可,职责切分更干净。
4.3 浏览器与安全策略的联动
现在主流浏览器对HTTP和HTTPS的待遇差距越来越大。HTTP站点在地址栏会显示“不安全”,HTTPS站点则显示小锁图标;部分敏感接口(如摄像头、地理定位、Service Worker)明确规定只在安全上下文中才可用;越来越多的站点启用了HSTS(HTTP Strict Transport Security)策略,强制浏览器只能通过HTTPS访问该域名,杜绝降级攻击。
有一个容易被忽略的细节:如果你的站点支持HTTP,攻击者可以先截获你的HTTP请求,把它改写为对某个不安全的子域名的请求,或者干脆把HTTPS链接“降级”成HTTP链接,让后续通信全程走明文。HSTS就是用来堵这个窟窿的——服务器在首次HTTPS响应中带上Strict-Transport-Security头,告诉浏览器:接下来N秒内,这个域名只允许通过HTTPS访问,就算你输入http://也会被自动替换为https://。
任何打算长期运营的Web服务,HSTS基本属于标配了,不过要谨慎设置max-age,别设太长,万一证书出问题想降级回HTTP会非常痛苦。
5. 性能对比与实测数据:HTTPS真的慢很多吗
5.1 我的本地和公网实测结果
很多团队迟迟不上HTTPS,一个重要的顾虑就是性能损耗。确实,TLS握手多出来的RTT以及加解密计算是有代价的。
我用两台配置完全相同的云主机,分别部署了Nginx作为HTTP和HTTPS服务,然后用同一台压测机器做对比实验。条件如下:TLS版本为TLS 1.2,证书为RSA 2048位,CPU为2核,网络是同一内网。
先看单请求延迟(1000次请求取中位数):
| 协议 | 平均连接建立时间 | 请求完成中位延迟 | 差距 |
|---|---|---|---|
| HTTP | 0.1 ms | 8 ms | 基线 |
| HTTPS (TLS 1.2, RSA) | 3.8 ms | 12 ms | 约50% |
再看并发场景(100并发持续压60秒):
| 协议 | QPS(每秒请求数) | CPU使用率 | 延迟P99 |
|---|---|---|---|
| HTTP | 3200 | 38% | 45 ms |
| HTTPS | 2600 | 61% | 66 ms |
从数据看,HTTPS在单请求延迟上确实多了大约50%,QPS下降了约20%,CPU消耗上升明显。RSA非对称运算(尤其是服务器私钥签名)是CPU的大头。但这只是TLS 1.2加RSA的保守场景。
接着我启用了ECDHE密钥交换算法并把TLS版本升到TLS 1.3,重新压测。结果令人意外:
| 协议 | 平均连接建立时间 | QPS | CPU使用率 |
|---|---|---|---|
| HTTP | 0.1 ms | 3200 | 38% |
| HTTPS (TLS 1.3, ECDHE) | 0.9 ms | 3050 | 44% |
TLS 1.3把握手从2个RTT压缩到1个RTT,同时ECDHE密钥交换的计算量远小于RSA签名验证。此时HTTPS的性能损耗已经被压缩到很低,QPS基本持平,CPU只多了6个百分点。
所以我个人的建议是:性能不应该是拒绝HTTPS的理由。在现代化配置下,HTTPS和HTTP的差距已经非常小,尤其是在长连接场景下,TLS握手只发生一次,后续请求复用连接,几乎检测不到差异。
5.2 性能优化三板斧:会话复用、OCSP Stapling、TLS 1.3
既然聊到了性能,顺便分享几个生产环境里最常用的HTTPS性能优化手段。
会话复用。 TLS握手是最大的性能瓶颈,而会话复用机制允许客户端和服务器在已完成握手后缓存会话密钥,下次连接时可以跳过完整的握手流程,直接恢复会话。Nginx里对应配置是ssl_session_cache和ssl_session_timeout。实测启用共享会话缓存之后,在大量短连接场景下,HTTPS延迟可以下降20%到40%。
OCSP Stapling。 证书吊销状态检查(OCSP)本来是客户端发起查询的,但有隐私和性能问题——每次连接都可能要去查询CA的吊销服务器。OCSP Stapling把证书吊销状态查询结果由服务器在握手时直接带发给客户端,省去客户端额外的网络请求。Nginx里配置ssl_stapling on即可。要注意的是,如果你的CA本身不提供OCSP Stapling支持,这个配置会不生效,后端会打印查询失败的日志,遇到这种情况要检查CA文档。
TLS 1.3。 前文已经测过,TLS 1.3的握手性能优势非常明显。只要客户端和服务端都支持,建议优先启用,并且只保留安全的加密套件。配置时注意不要把TLS 1.2全部关掉,因为还有一部分老客户端(比如某些Android低版本WebView)只支持TLS 1.2,直接全关会导致部分用户无法访问。
5.3 从架构层面缓解:网关终结TLS与负载均衡
生产环境里,大部分公司不会让每台后端业务服务器直接暴露HTTPS,而是在入口网关或负载均衡器上终结TLS。也就是说,TLS握手只在网关和客户端之间发生,网关到后端服务之间走内网HTTP。这种架构的好处是:
- 证书集中管理,不需要每个后端节点都维护一份证书。
- TLS握手带来的CPU开销集中在网关层,可以方便地通过加网关实例水平扩展。
- 内网通信默认安全(前提是网络隔离做得好),省去后端的加密开销。
但这里要提醒一个安全点:如果网关到后端之间走的HTTP明文,而这段网络被攻破(比如内网横向渗透),数据仍然会泄露。所以更严格的做法是网关到后端也走HTTPS,或者至少用网络策略限制内网访问范围。我见过不少公司只做了前半段,后半段裸奔,表面上全站HTTPS,实际内网链路一点防护都没有。
6. 一次完整的HTTPS部署实录:从申请证书到压测验证
6.1 选择证书类型与申请流程
部署HTTPS的第一步是拿到一张证书。证书分几种类型:DV(域名验证)、OV(组织验证)、EV(扩展验证)。DV证书只验证域名所有权,几分钟就能签发;OV和EV还要验证企业主体身份,审核流程较长。对绝大多数中小站点和API服务,DV证书完全够用。
免费证书和付费证书的差别主要在服务保障、兼容性和有效期上。免费证书通常有效期只有90天,需要频繁续期;付费证书有一年甚至更长的有效期。如果是个人项目或测试环境,免费证书完全没问题。建议在证书到期前配置自动续期,省去人工续期时忘记导致站点证书过期的尴尬。
申请流程大致是:生成私钥和CSR(证书签名请求)文件,把CSR提交给CA,CA验证域名所有权后签发证书。如果你是第一次操作,建议直接用开源工具(如acme.sh)申请Let‘s Encrypt证书,它会自动完成CSR生成和证书配置,整个流程十几分钟就能跑通。用acme脚本申请完证书,设置cron任务做自动续期,你的域名长期稳在HTTPS状态。
这里有一个很多新手最常踩的问题:私钥文件权限。 私钥一旦泄露,等于攻击者可以冒充你的站点,同时还能解密曾经抓取过的TLS流量(如果没有前向保密)。所以私钥文件权限建议设为600,属主设为运行Web服务的用户,严禁放到能被Web目录直接访问的路径下。我接手过一个业务方自己搭的Nginx,私钥直接放在了网站根目录里,裸奔了几个月,等于证书白装了。
6.2 Nginx配置要点与常见报错
部署时Nginx配置是最常见的环节,放一个实际可用的配置片段:
nginx复制server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 24h;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
几个关键点解释一下:
ssl_certificate填的是完整证书链(fullchain),不是单张证书。如果你只填了叶子证书而没带中间证书,很多客户端会报“证书链不完整”错误。ssl_protocols和ssl_ciphers直接决定你支持哪些加密套件。现在安全基线是TLS 1.2起步,TLS 1.0和TLS 1.1目前已确认不安全,不要再启用。- 80端口跳转443是必须的,这保证用户访问
http://开头的链接也会自动升级到HTTPS。
上述配置里我没写ssl_stapling,需要的话可以加:
nginx复制ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;
配置完成后记得执行nginx -t校验语法,再systemctl reload nginx生效。别直接restart,生产环境里restart会导致存量长连接断掉,而reload是平滑的。
6.3 部署后的验证手段
证书部署完不是看一眼浏览器地址栏的锁头就算完事。建议用下面这几种方式双层验证。
第一层是命令行验证。用curl:
bash复制curl -v https://api.example.com/health 2>&1 | grep -E "SSL connection|subject:|issuer:|verify"
输出里能看到SSL connection using TLSv1.3之类的信息,确认TLS版本是符合预期的。
第二层是在线扫描验证。SSL Labs提供了一套免费的HTTPS部署检测工具,它会从多个角度对站点做全面体检,包括证书链、协议版本、加密套件兼容性、已知漏洞等,最后给出一个A到F的评分。我习惯把A作为基准线,低于A就想办法补到A再放行。实测发现大部分站点评分达不到A,常见原因是支持了过旧的TLS版本、启用了弱加密套件或者HSTS配置缺失。
6.4 业务侧的联动改造
证书部署成功只是第一步,业务代码和服务端逻辑也要跟着改。这里有几个容易被忽略的点。
第一,内网HTTP重定向。很多服务框架里都有一套自身地址生成逻辑,如果你的应用通过代理获取协议时没正确读取X-Forwarded-Proto头,生成出的链接可能全是http://。轻则影响SEO,重则导致回调URL不合法。添加如下配置:
nginx复制proxy_set_header X-Forwarded-Proto $scheme;
然后在应用里读取这个头来生成正确的scheme。
第二,混合内容问题。页面本身走HTTPS,但如果页面里引用了http://开头的图片、脚本、样式,浏览器会默认拦截或警告。上线HTTPS前最好全站扫一遍静态资源URL,把硬编码的http://改为相对路径或https://。
第三,API回调地址修改。如果对接了第三方支付、短信、微信等服务商,要把管理后台里的回调地址全部从http://更新为https://。这一步遗漏,往往要等线上回调失败才被发现,想想都肉疼。
7. 上线HTTPS之后躲不开的坑:证书、混合内容与持续监控
7.1 证书过期引发的事故现场
证书过期是HTTPS运维中最常见的事故,没有之一。欢快的假期里客户打电话说站点打不开了,上去一看证书恰好当天凌晨过期。浏览器弹大红色警告页面,用户基本直接关掉走人。
各位把它当个铁律记下来:证书有效期监控和数据库磁盘空间监控同等重要。 我自己的做法是在cron里挂一个每周任务,用curl去实时检测每个域名的证书剩余天数,不足30天就给团队群发告警。
bash复制echo | openssl s_client -servername api.example.com -connect api.example.com:443 2>/dev/null | openssl x509 -noout -enddate
这一行就能拿到证书过期时间,配合简单的date运算就能输出剩余天数。不要依赖人工盯日历,人一定会忘。
7.2 混合内容问题排查
HTTPS页面上被浏览器拦截的http资源,往往不会在浏览器主界面弹出明显错误,而是静默地在控制台报错。如果你发现页面渲染就是不正常,又找不到原因,打开开发者工具看Console,搜“Mixed Content”关键词,基本一揪一个准。
系统性扫一遍是值得的。可以写个小脚本,把页面HTML里所有硬编码的http://资源找出来,批量替换为https://或者相对路径。更稳妥的做法是给页面加上Content-Security-Policy头策略,禁止加载非HTTPS资源,然后看控制台逐一清理。虽然前期麻烦,但长期收益很大。
还有一个隐藏较深的坑:第三方SDK里写死不合理的资源地址。有些老版本统计SDK、地图SDK内部会拉取自己的http://资源,页面升级HTTPS后这些请求全部被拦,功能悄悄失效。遇到这种情况,升级SDK版本几乎是唯一的出路。
7.3 教你配置一套日常监控
HTTPS运维没那么多神秘技巧,核心就是把监控做扎实。我推荐至少盯住四件事:
| 监控项 | 检查内容 | 检查频率 | 告警阈值 |
|---|---|---|---|
| 证书有效期 | 域名证书剩余天数 | 每天 | 剩余<30天 |
| 证书链完整性 | 校验证书链是否完整 | 每周 | 校验失败即告警 |
| TLS版本与套件 | 最低TLS版本是否为1.2 | 每周 | 出现TLS 1.0/1.1 |
| 端口可用性 | 443端口TCP连通性 | 每分钟 | 连续3次失败告警 |
如果团队有成熟的监控系统,把这些接口都接进去。没有的话,先写脚本在cron里跑,收到告警邮件也算数。怕就怕什么都不监控,等着用户来报。
7.4 离线与内网场景的HTTPS实施建议
最后说一个跟互联网站点不同、但实际存在大量需求的场景:内网系统。很多公司的办公系统、内部API跑在公司局域网里,快十年了还在用HTTP。对于这类系统,我建议也别继续裸奔,最低限度也要用自签名证书把链路加密起来——哪怕只是为了一旦有人在内网抓包时,不至于密码直接明文落网。
自签名证书的痛点是浏览器弹警告,这可以通过把自签名根证书推送到员工电脑的信任库来解决。公司有终端管理的话,这并不难做到。证书私钥的安全保管尤其重要,内网证书一旦泄露,相当于整个内网明文暴露。这一步的代价比公网证书泄露小一些,但绝对不值得掉以轻心。
如果把内部系统做得更精细一点,可以用私有CA签证书,同时设置比较长的有效期,比如三五年,省去频繁续期的麻烦。反正内网系统的风险模型和公网站点不一样,灵活一点没什么问题,但加密这件事本身一定不能省略。
我个人在实际运维中的体会是,HTTPS这件事,首要是解决“有”的问题,其次是逐步优化到“好”的问题。一次性把证书、HSTS、TLS版本、性能优化全部做到位当然理想,但如果现状是一堆老系统还在跑HTTP,那先把核心域名和涉及账号、支付、用户隐私的接口升级到HTTPS,比纠结细节更重要。毕竟,跑了四年HTTP没人管的某内部查询接口,出一次安全事故的代价,远大于那一下午的部署工作量。
