别被总分骗了:拆解一份网站诊断报告,从 DNS 到 SSL 逐项找证据
问题背景同事把一份内部巡检脚本生成的“网站综合诊断报告”甩过来总分41/100红的黄的一大片问一句“先修哪个”。第一反应通常是去看报错最多的那一栏然后开始改 Nginx 配置。改完重跑分数没动报错换了个位置。原因很简单综合诊断报告里的指标不是并列关系而是依赖关系。DNS 不通TCP 检测会失败TCP 不通TLS 肯定握手失败TLS 不通过HTTP 状态码那一栏根本不会执行。指标之间是串联的不是并联的。所以读报告的正确姿势不是“找红点”而是从最底层开始逐层核对证据DNS → TCP → TLS → HTTP → 应用层。上游没过下游的 FAIL 一律先当成“连带失败”不要浪费时间去修。下面用一份可复现的示例报告把每一项指标拆开讲。环境与版本本文所有命令都在以下环境验证过读者可以照着敲组件版本OSUbuntu 22.04.3 LTSdig (BIND utils)9.18.18OpenSSL3.0.2curl7.81.0报告由自建脚本diag.sh生成目标是一个演示域名portal.example.comIP 段使用 RFC 5737 文档地址203.0.113.0/24不指向任何真实服务。./diag.sh portal.example.com443现象复现脚本输出的报告片段如下 网站综合诊断报告 target : https://portal.example.com/ generated : 2025-01-15 10:22:31 08:00 score : 41 / 100 [1] DNS A : 203.0.113.8, 203.0.113.9 CNAME : not present TTL : 60 resolve_ms : 12 NS 一致性 : 2/2 一致 status : PASS [2] TCP 443 connect: PASS (203.0.113.8, 18ms) 80 connect: PASS [3] TLS protocol : TLSv1.2 cipher : ECDHE-RSA-AES128-GCM-SHA256 notBefore : 2024-01-01 00:00:00 UTC notAfter : 2024-04-01 00:00:00 UTC SAN : DNS:www.example.com chain : 2 (leaf intermediate) hostname : MISMATCH expire : EXPIRED (已过期 289 天) status : FAIL [4] HTTP status : 未执行上游 TLS 未通过 [5] 应用层 status : 未执行重点看两处[3]里同时出现了两个失败原因——hostname: MISMATCH和expire: EXPIRED[4]、[5]明确写了“未执行”。这就是依赖链的体现。原因分析为什么 DNS 显示 PASS 也不能跳过[1] DNS这一栏检查的是“能不能拿到解析结果”而不是“解析结果对不对”。它正确的部分是A记录存在返回了 2 个地址TTL 60说明这条记录变更生效很快适合做灰度切换NS 一致性 2/2表示两个权威 NS 给出的结果一致没有出现解析分裂但它没查的东西同样关键解析出的 IP 是否属于预期 CDN 段、CAA 记录是否允许当前 CA 签发、是否存在陈旧的 CNAME 残留。DNS PASS 只代表链路通不代表语义对。TLS 两个失败原因是独立的hostname: MISMATCH和expire: EXPIRED是两条互不影响的失败路径在 OpenSSL 里分别对应不同的校验环节expire由X509_V_ERR_CERT_HAS_EXPIRED触发和证书内容无关只看系统时钟与notAfter的大小关系hostname由X509_check_host()完成比对的是 SAN 列表跟有效期无关任何一条不通过curl都会以退出码60SSL certificate problem中断HTTP 层根本不会发出请求。所以报告里[4]不执行是正确行为不是脚本漏检。阅读顺序原则把上面这些串起来报告的正确阅读顺序是从[1]往下读遇到第一个 FAIL 就停下来先确认它是不是根因如果 FAIL 出现在[3]及之后回看上游指标是否都 PASS判断当前是根因还是连带每条 FAIL 都要能找到一条可复现的命令和它的原始输出不能只看脚本给的颜色解决方案不要急着改服务端配置先用三条命令把证据坐实。第一步DNS 证据核对digshort time3tries1A portal.example.comdignoall answer authority portal.example.comdigshort NS example.comtime3 tries1是必须的。默认dig会重试 3 次、单次超时 5 秒遇到挂掉的权威服务器会卡住十几秒巡检脚本里非常容易假死。第二步TLS 证书链与 SANecho|openssl s_client\-connectportal.example.com:443\-servernameportal.example.com\2/dev/null|openssl x509-noout-dates-extsubjectAltName-servername不能省。多证书站点SNI 分流的情况下不带 SNI 拿到的可能是默认证书跟浏览器看到的完全不是一张。第三步主机名与有效期校验echo|openssl s_client-connectportal.example.com:443\-servernameportal.example.com2/dev/null\|openssl x509-noout-checkhostportal.example.com不匹配时输出Hostname portal.example.com does NOT match certificate退出码非 0可以直接用于 CI 断言。有效期的判断用-checkend更方便# 检查证书在 0 秒后是否会过期退出码非 0 表示已过期echo|openssl s_client-connectportal.example.com:443-servernameportal.example.com2/dev/null\|openssl x509-noout-checkend0核心代码把上面的检查串成一个分层脚本上游失败就标记下游为SKIP避免把连带失败误判成独立问题#!/usr/bin/env bashset-uopipefailHOST${1:?usage:$0 host[port]}PORT${2:-443}say(){printf%-12s %s\n$1$2;}# ---------- [1] DNS ----------echo[1] DNSA_REC$(digshort time3tries1A$HOST2/dev/null|grep-E^[0-9]\.||true)if[-z$A_REC];thensaystatusFAIL: 无 A 记录sayevidencedig short time3 tries1 A$HOSTexit1fisayA$(echo$A_REC|tr\n )# ---------- [2] TCP ----------echo[2] TCPif!timeout5bash-c/dev/tcp/$(echo$A_REC|head-1)/$PORT2/dev/null;thensaystatusFAIL:$PORT不可达saynote下游 TLS/HTTP 均为连带失败跳过exit2fisaystatusPASS# ---------- [3] TLS ----------echo[3] TLSTLS_OUT$(echo|timeout10openssl s_client-connect$HOST:$PORT\-servername$HOST2/dev/null)if[-z$TLS_OUT];thensaystatusFAIL: 握手未建立exit3fisaynotAfter$(echo$TLS_OUT|openssl x509-noout-enddate|cut-d-f2)echo$TLS_OUT|openssl x509-noout-checkend0/dev/null21\sayexpireOK||sayexpireEXPIREDifecho$TLS_OUT|openssl x509-noout-checkhost$HOST/dev/null21;thensayhostnameMATCHelsesayhostnameMISMATCH$HOST不在 SAN 中exit3fi# ---------- [4] HTTP ----------echo[4] HTTPsaycode$(timeout10curl-s-o/dev/null-w%{http_code}https://$HOST:$PORT/||echoFAIL)关键设计是两个exitDNS 或 TCP 失败就直接终止不把下游噪声写进报告TLS 失败有效期或主机名也终止因为此时 HTTP 层的结果没有诊断价值。验证结果修完证书续期 把portal.example.com加进 SAN后重跑脚本[1] DNS A 203.0.113.8 203.0.113.9 [2] TCP status PASS [3] TLS notAfter Apr 1 23:59:59 2026 GMT expire OK hostname MATCH [4] HTTP code 200对应报告里原来的[3] TLS → FAIL、[4] HTTP → 未执行全部转绿。原来的score: 41回升到96扣分项只剩 TTL 偏短。整个修复过程中服务端 Nginx 配置一行没改——一开始如果顺着“HTTP 那一栏没结果”去查应用方向就完全错了。常见坑把连带失败当独立问题。报告里[4]不执行、[5]不执行是设计如此不是漏检。看到“未执行”要往上找不要往下找。dig不带超时参数。默认超时 重试叠加遇到挂掉的 NS 会让整个巡检脚本假死。巡检场景下time3 tries1是底线。openssl s_client不带-servername。SNI 分流站点上会拿到默认证书校验结果和浏览器不一致容易误判为“证书没问题”。只看notAfter不看notBefore。时钟漂移或者 CA 误签发时notBefore在未来同样会导致握手失败报错文案不一样但结果一样。用 IP 去连 TLS。证书 SAN 里不会有裸 IP除非站点特意签了 IP SAN这样校验必然失败属于自己造的错。本地 DNS 缓存干扰复现。验证解析改动时用dig 8.8.8.8或1.1.1.1指定解析器别信本机 systemd-resolved 的缓存。总结综合诊断报告的价值不在于总分而在于它把一条链路拆成了可核对的分层证据。阅读顺序固定为DNS → TCP → TLS → HTTP → 应用层三个执行要点遇到第一个 FAIL 就停先判断是根因还是连带失败每一条 FAIL 都要能落到一条可复现的命令上脚本输出的颜色不作为证据上游失败时下游标记SKIP而不是FAIL避免误导出错误的修复方向按这个顺序读一份 41 分的报告看完你会知道该改的是证书而不是 Nginx。

相关新闻

MCP 面试高频考点:把知识库 RAG 检索封装成 Tool,Java 落地要避哪些坑?

MCP 面试高频考点:把知识库 RAG 检索封装成 Tool,Java 落地要避哪些坑?

MCP 面试高频考点:把知识库 RAG 检索封装成 Tool,Java 落地要避哪些坑? 面试场景 面试官:我们先做一个贴近工程的题。假设团队已经有一套内部知识库 RAG 能力,包含文档解析、切块、向量索引、召回和重排,…

2026/10/7 8:12:03 阅读更多 →
科研绘图别再用PS抠图了,科迅捷AI帮你一键生成学术图表

科研绘图别再用PS抠图了,科迅捷AI帮你一键生成学术图表

为什么你画的科研图,导师总说不专业?写过学术论文的同学都懂,图做不好,整篇论文的档次就上不去。很多人画科研图还在用PPT拼、用PS抠,结果画出来的图要么分辨率不够,要么字体不对,要么配色丑得像…

2026/10/7 8:12:03 阅读更多 →
SRC漏洞挖掘实战:从资产收集到漏洞验证与提交完整流程

SRC漏洞挖掘实战:从资产收集到漏洞验证与提交完整流程

声明:本文所有技术手段仅适用于 SRC 平台明确授权范围内的目标,以及你拥有书面授权的资产。未经授权的扫描、探测、数据读取均可能触犯《刑法》第 285、286 条与《网络安全法》。请对数据保持最小化原则:只验证、不落地、不传播。 引言&#…

2026/10/7 8:12:03 阅读更多 →

最新新闻

用TensorFlow和CNN预测股票走势:从数据准备到回测的完整指南

用TensorFlow和CNN预测股票走势:从数据准备到回测的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 8:43:27 阅读更多 →
JSP+Servlet+MySQL 在线购书系统 MVC 期末大作业实战指南

JSP+Servlet+MySQL 在线购书系统 MVC 期末大作业实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 8:43:27 阅读更多 →
Python调用百度AI识别花卉,自动分类整理照片实战

Python调用百度AI识别花卉,自动分类整理照片实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 8:43:27 阅读更多 →
FOC电流环时序优化:SSSU/DSDU/SSDU/DSSU四大策略解析

FOC电流环时序优化:SSSU/DSDU/SSDU/DSSU四大策略解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 8:43:27 阅读更多 →
FPGA LVDS接收调试:可编程输入延迟IDELAYE3原理与实战

FPGA LVDS接收调试:可编程输入延迟IDELAYE3原理与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 8:43:27 阅读更多 →
Python笔记(二)--列表

Python笔记(二)--列表

这一节了解一下Python中的列表,列表是一种有序、可变、可重复的数据容器,用来把多个数据放在一个变量里管理。可以把它理解成一排“编号格子”,每个格子存一个数据,编号从0开始。简单总结如下:API:1 列表下标访问lst[index]:通过整…

2026/10/7 8:42:26 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 6:26:51 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 8:21:32 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 4:21:51 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 1:18:13 阅读更多 →