TW●汤伟的数字生活NOTES ON A DIGITAL LIFE
个人数字生活文库始于 2026 · 持续修订总目录 ↗
全部文章

Linux 运维 / 实战手册

Linux 网络排错:按监听、DNS、HTTP、SSH 分层判断

通过有限查询区分地址绑定、名称解析、TLS 和应用错误,不把关闭验证或开放端口当作默认修复。

阅读设置字号仅保存在当前浏览器

先画出这一条请求真正经过的环境

本篇要完成的任务是解释一个个人页面为什么在某种访问方式下失败,并找到可验证的下一步。先写明发起请求的客户端、请求网址、协议和端口、是否经过代理,以及服务在宿主还是容器里。对于本地演示,把入口固定为回环端口;对于自己的域名,用 example.com 作为写作占位,实际操作时只换成你管理的地址。本文只给命令说明,没有连接任何个人服务器,也没有测得网络延迟。

同一个“本机”在不同终端里可能含义不同。笔记本终端的回环指向笔记本,远程终端的回环指向远程主机,容器内的回环又指向容器。首先在提供服务的正确环境确认监听,再从计划中的客户端发起请求。如果你在笔记本访问一个只发布到另一台主机回环的服务,失败并不证明应用坏了,可能只是入口设计与访问位置不一致。这时要先确定所需访问方式,再设计转发或监听配置,不能为了试通直接扩大所有地址的监听范围。

准备一张空记录,包含时间与时区、客户端环境、目标入口、工具版本、工具退出码、协议状态和下一步。每次只改变一个变量,例如只对比默认地址族与显式地址族,或者只比较是否使用既有代理。若同时换网络、换域名和换客户端,即使结果不同也无法知道由哪一项导致。少量受控请求足以定位常见问题,不需要连续高速探测,尤其不要把诊断变成对外部服务的负载测试。

记录诊断工具能力bash · GNU/Linux / macOS;DSM 先确认命令可用
查询 / 诊断
curl --version
ssh -V

read:核对 TLS 后端、协议和 OpenSSH 版本;不建立会话。

先确认应用是否真的在目标地址监听

前端开发最常见的网络误判,是本机能打开页面便认为其他设备也能访问。服务可能只绑定回环地址,或者只在容器网络命名空间中监听。先在正确环境查看端口,再把地址、协议族和进程身份对应起来。ss 显示的是当前命名空间的套接字,宿主输出不能完整代表容器内部,容器输出也不能证明宿主已经发布端口。

IPv4 全地址监听扩大了服务接收请求的地址范围,但不代表防火墙已经放行,也不代表允许把开发服务器暴露到互联网。进程列为空可能仅是当前用户看不到进程信息。不要为了看一个 PID 就批量提权;先通过自己应用的启动记录确认。文中公网 example.com 是示例占位,实际诊断只应针对自己的服务,本文没有向真实设备执行任何检查。

检查 TCP 监听地址与端口bash · Linux(iproute2 ss)
查询 / 诊断
ss -ltnp

-l 监听,-t TCP,-n 数字地址端口,-p 显示可见进程;只查询当前网络命名空间。 示意:127.0.0.1:3000 只绑定回环;0.0.0.0:3000 是 IPv4 全地址监听。 进程列缺失可能权限不足;监听不等于防火墙放行。容器与宿主需分别判断,不据此自动开放端口。

DNS 先看系统实际使用哪条解析链路

浏览器、命令行工具与 VPN 可能使用不同解析路径。Linux 使用 systemd-resolved 时,resolvectl status 能帮助观察各链路的 DNS 与域路由;但并不是所有发行版都启用该服务。没有命令或服务未运行时,应回到发行版自己的网络设置,不把网上某个 nameserver 直接写进 resolv.conf。符号链接或自动生成的配置文件尤其不适合盲改。

先记录问题是全部域名失败、某个域名失败,还是只在 VPN 开启时发生。查询内部名称不要发给公共 DNS 服务,这既可能得不到答案,也会泄露命名信息。界面中看到多个解析器不等于随机挑一个就可以;分流域规则可能决定哪条链路回答。排错记录分享时只保留是否命中预期链路,不公开实际内网地址。

查看系统解析链路bash · Linux(systemd-resolved、resolvectl)
查询 / 诊断
resolvectl status

显示全局与各网络链路的 DNS 配置及域路由,帮助辨认 VPN 分流;不更改 DNS。 示意:Link 下显示 DNS Servers 与 DNS Domain;真实地址不要公开。 服务未运行或命令不存在时应使用发行版网络界面,不修改 resolv.conf;浏览器 DoH 可能另走解析路径。

解析成功只是到达应用前的一步

执行名称查询后,检查返回的是 IPv4、IPv6 还是多个地址,并观察系统报告的解析途径。超时意味着没有及时得到回应,与明确报告名称不存在不同。对单域名失败先核对拼写与预期域名,全部失败再查链路与解析器状态。切换网络做对照也需要保持同一测试目标和时间窗口,否则很难判断变化来自哪一层。

解析得到地址并不能证明端口可达;HTTP 失败也未必是 DNS。浏览器启用安全 DNS、代理或缓存时,它与系统解析结果不一致可能是配置差异,不一定是污染。不要在缺乏证据时清掉所有缓存和网络配置。记录解析结果后继续检查协议响应,只有定位到某一层,修改配置才有可衡量的目标。

通过系统解析器查询名称bash · Linux(systemd-resolved、resolvectl)
查询 / 诊断
resolvectl query example.com

query 发起示例公网域名查询,显示地址及解析途径;使用时只替换为自己有权诊断的名称。 示意:返回一个或多个 IPv4/IPv6 地址;DNS 查询会产生网络流量。 超时先看链路 DNS 与路由;不存在名称和连接超时是不同分支,不用公共 DNS 测公司内部名称。

HTTP 状态、TLS 与退出码分别解释

curl 的连接超时和总超时可以避免一次诊断无限等待。先用 HEAD 获取响应头,观察是否确实到达服务器以及状态码;某些应用不支持 HEAD,会返回方法不允许,此时可对自己确认无副作用的地址做有限 GET。状态为重定向时,先看目标是否符合预期,不默认跟随未知地址。不要带真实 Cookie 或令牌把请求复制到公开讨论区。

TLS 证书校验失败应检查客户端时间、访问域名、证书链和信任配置,不能使用跳过验证选项当作修复。连接拒绝常提示端口没有监听或被明确拒绝,超时则还有丢包、防火墙和路由等可能。curl 默认收到某些 HTTP 错误仍可退出零,因此要同时看响应状态与工具错误;单独的“命令执行成功”不是应用验收。

分辨 HTTP 响应与连接失败bash · Linux/macOS(curl)
查询 / 诊断
curl --head --connect-timeout 5 --max-time 15 https://example.com/

--head 请求响应头,两个超时分别限制连接阶段与整个请求;保留默认 TLS 验证。 示意:HTTP/2 200 或 301;curl 退出 0 本身不保证 HTTP 状态成功。 405 可能服务器不支持 HEAD;证书错误检查时间、域名和证书链,不能用 -k 掩盖;会记录访问日志。

按不同层的症状决定下一次查询

第一层是名称解析。明确的名称不存在与等待超时应分开记录:前者先核对拼写、记录是否已配置和查询范围,后者再查链路解析器与路由。解析出地址后进入连接层,连接被拒绝常见于没有对应监听或路径上明确拒绝,等待超时则还可能涉及丢包、路由和过滤。仅有超时不能定位到某一台防火墙,更不能据此删除规则;下一步应结合服务端监听与客户端所在路径缩小范围。

第三层是加密连接。证书名称不匹配时核对请求域名与证书覆盖名称,证书不受信任时核对链和客户端信任来源,时间错误则先校正事实。通过裸地址请求可能改变服务器名称选择和证书匹配,因此不是普通域名请求的等价替代。第四层才是应用协议:收到不存在、无权限或服务端错误状态,说明至少某个服务器已经给出响应,接下来检查路由、认证设计或后端日志,而不是重新修改解析器。

示意案例是系统名称查询正常,网页请求返回不存在。此时用同一个主机名确认首页和目标路径的差异,再对应服务器访问日志;如果首页成功而深层路径失败,考虑静态站点路径或前端路由回退是否配置,而非判断整个网络中断。另一案例是入口只监听回环,本机请求成功、另一环境失败,这符合监听范围约束,应该调整访问方案而不是换镜像。案例只是推理模板,实际结论仍须由自己取得的输出支持。

查询指定个人回环端口的监听bash · GNU/Linux;macOS/BSD 与 DSM 不直接套用 GNU 长选项
查询 / 诊断
ss -ltnp "sport = :18080"

read:在服务所在 Linux 网络命名空间运行;macOS 无 ss,DSM 需核对 iproute2 工具。

绕开既有代理查询明确的本地静态入口bash · GNU/Linux;macOS/BSD 与 DSM 不直接套用 GNU 长选项
查询 / 诊断
curl --noproxy '*' --silent --show-error --output /dev/null --connect-timeout 3 --max-time 10 --write-out 'http=%{http_code} total=%{time_total}\n' http://127.0.0.1:18080/
request_status=$?
printf 'curl_exit=%s\n' "$request_status"

read:保存的是当前 shell 状态,不落盘;同时看协议状态和退出码。

用阶段计时缩小慢请求范围

总耗时只能说明用户等了多久,阶段计时能帮助判断延迟集中在哪。名称解析、建立连接、TLS、首字节与总时长通常是从请求开始累积到某节点的时间,不应相加。需要估算某阶段时,先理解连接复用、代理和协议行为,再考虑相邻节点差值。一次测量容易受缓存、首次连接和服务预热影响,不能拿它代表长期性能。

对照时保持网址、请求方式、网络与测试内容相同,做少量重复观察即可,不把诊断变成压力测试。首字节慢可能涉及服务端处理,也可能与链路有关,应与应用日志对应时间。响应体下载慢则继续检查体积和传输过程。示例中数字只演示格式,本手册没有声称某个网络或 NAS 达到了某个速度。

测量单次 HTTP 请求阶段bash · Linux/macOS(curl)
查询 / 诊断
curl --silent --show-error --output /dev/null --connect-timeout 5 --max-time 15 --write-out 'code=%{http_code} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}\n' https://example.com/

发送 GET 并丢弃响应体;计时单位秒,大多是从请求开始累计的节点时间,不能相加。 示意:code=200 dns=0.010 connect=0.030 tls=0.080 first=0.120 total=0.125;仅演示格式。 请求失败可能 code=000;连接复用、代理和缓存改变计时含义,先核对环境,再做有限次数对照。

用有限对照区分地址族、代理与应用耗时

如果自己的域名同时返回两种地址族,而只有部分客户端失败,可以分别限制地址族请求相同网址。某一族失败并不能单独说明域名记录错误,客户端连接能力、代理和服务监听也可能不同。命令若通过代理执行,地址族控制首先影响的可能是代理连接,远端解析又可能由代理完成;因此比较之前必须把代理条件写入记录,不把两个不同请求路径的结果当成直连网络事实。

阶段耗时使用同一请求方式、同一入口、接近的时间窗口。名称解析之后到连接建立的差值可以提供线索,但代理、连接复用和协议选择都会影响解释;多个累计字段不能直接相加。首字节等待较长时,结合应用日志看是否有相同时间的慢请求;总时间明显高于首字节时,再看响应体积与传输过程。本篇不给“正常必须小于某个数”的统一阈值,因为个人页面与大文件下载的预期不同。

如果 HEAD 返回方法不允许,改为确认无写副作用的静态路径 GET,并丢弃响应体。若返回重定向,先审查目标,再决定是否在后续命令中跟随;自动跟随可能把一次本机测试变成另一域名的外部请求。所有查询类网络请求按 read 分类,但远端可能记录访问;下载文件落盘、修改解析配置、建立转发或启动服务则改变本地状态,需要相应 write 或 danger 标注。

仅对自己的双栈入口比较地址族bash · GNU/Linux / macOS curl;DSM 先核对 IPv6 与 curl 能力
查询 / 诊断
curl -4 --head --connect-timeout 5 --max-time 15 https://example.com/
curl -6 --head --connect-timeout 5 --max-time 15 https://example.com/

read:example.com 为示例域名;真实对照仅换成自有入口。记录代理条件及两次错误,不直接修改配置。

SSH 先理解配置,再处理连接问题

SSH 错误至少可分为地址与端口、主机身份、用户认证和会话启动几层。先使用不连接的配置展开示例理解最终主机与端口;示例通过空配置文件避免读取个人配置中的执行钩子。若改成自己的配置,应先审阅 Match exec、代理命令等可能执行外部程序的设置,不能因为有 -G 就认定任何配置都无副作用。

实际连接遇到主机密钥变化时,需要通过自己掌握的可信渠道核对新指纹,不能删除 known_hosts 记录或禁用主机身份检查来“修好”。认证失败要核对账号、密钥选择和服务端许可,不在聊天中粘贴私钥。连接超时回到端口与网络层,认证成功但会话失败再查服务端受支持日志;不要混用不同层的修复操作。

不连接主机查看 SSH 有效配置bash · Linux/macOS(OpenSSH)
查询 / 诊断
ssh -G -F /dev/null -o HostName=example.com -o User=labuser -o Port=22 personal-lab

-G 展开配置后退出,-F /dev/null 避开个人配置和其中的 Match exec;显式给示例主机用户端口,不发起 SSH 登录。 示意:hostname example.com、user labuser、port 22;用于理解配置优先级。 不证明目标可连通或账号有效;若改为个人配置,先审阅 Match exec、ProxyCommand 等,不能盲目视作无副作用。

把 SSH 与网页验收分别结束

SSH 配置展开适合检查最终主机、账号、端口与配置优先级,却不会告诉你远端是否可达。实际登录还经过主机身份验证、账号认证和会话启动;网页已经可访问也不能保证 SSH 入口存在,两个协议可能监听不同地址和端口。若只是修复网页访问,本篇不要求顺便开放远程管理端口,诊断应停在已经定义的任务范围。

遇到主机身份提示变化时,先通过自己掌握的独立可信记录核对指纹,再决定是否更新本地信任记录。认证失败则检查选择的账号和身份是否符合服务端配置,而不是把连接超时的修复方案套过来。配置里包含代理命令或匹配执行条件时,读取配置本身也可能触发额外程序,所以前文用空配置文件演示。不能在未审阅个人配置的情况下,把任何带配置展开参数的命令都视为严格无副作用。

修复后的验收应回到最初那个失败客户端和原入口,重复相同请求并记录状态,再验证一个实际使用路径。只在服务端回环测试成功时,结论应写为“本机入口通过”,不能写成所有设备都能访问。如果修改了配置,保留原值和恢复方式,确认不需要的临时变更已按计划撤回;若并未修改任何设置,就记录证据与待处理层次,无需为了制造进展而增加动作。

最终记录包含已确认层次、仍不确定的分支与下一次要取得的证据。例如“名称查询返回,但连接超时;尚未取得服务端监听结果,下一步检查该入口监听”比“网络不好”更可操作。时间线与地址族、代理条件一并保存,下一次出现相同症状就能做可比对照。本轮没有实机验证的路由、厂商网络界面和真实 SSH 登录应明确列为未验证点,不由官方工具手册推断它们已经正常。

示意网络报告:客户端为服务宿主终端,入口为本机静态端口;监听检查有结果,单次首页请求返回成功,深层路径返回不存在。已确认连接和应用响应,待处理项为静态路由配置,下一步对照服务器请求日志和预期路径。该报告没有推断局域网或公网可用;若最初报错来自另一客户端,还必须回到那一处重测。这个例子展示了如何把模糊的网络故障收敛成一个具体配置问题。

已填写的示意材料text · GNU/Linux;macOS/BSD 与 DSM 不直接套用 GNU 长选项
查询 / 诊断
层次     症状示意                下一步证据
DNS      查询超时                链路解析器状态
TCP      连接拒绝                服务端对应地址和端口监听
TLS      名称不匹配              请求名称与证书覆盖范围
HTTP     首页成功、深层 404       路径及应用访问日志
SSH      认证失败                账号与所选身份,不修改 DNS

阅读用示意材料;不是命令输出或实测记录,复制保存为记录文件属于 write。

延伸阅读

iproute2 官方源码手册:ss systemd 官方源码手册:resolvectl curl 官方选项手册 OpenSSH ssh(1) 官方手册
同一专题 · 继续阅读Linux 文件与权限:从找到文件到安全归档Linux 进程、内存与日志:先建立证据链,再考虑重启Linux 磁盘与传输:分清容量、inode 和 rsync 复制语义查看整个专题 ↗