3. 客户端侧排查:本地防火墙、DNS与路由表

连接超时,很多时候问题出在客户端自己身上。我见过不少团队,一遇到超时就盯着服务器抓包,折腾半天才发现是本地防火墙把包给拦了。说实话,挺冤的。

这一节,我们聚焦客户端侧的三块硬骨头:本地防火墙、DNS解析、路由表与网关。这三样东西,任何一个出问题,都会让你连不上目标。

3.1 本地防火墙检查

防火墙这东西,说白了就是一把锁。它决定哪些流量能出去,哪些能进来。很多操作系统默认会开启防火墙,你装个安全软件,它也可能自己加规则。

怎么查?我习惯先看防火墙状态,再查具体规则。

3.1.1 检查防火墙是否拦截出站流量

在Linux上,我常用 iptables 或 firewalld。Windows的话,用 netsh advfirewall 或者图形界面。

先看一个Linux的例子:

# 查看防火墙默认策略和当前规则
iptables -L -n -v

# 如果规则太多,只看OUTPUT链(出站流量)
iptables -L OUTPUT -n -v

输出里,你会看到 Chain OUTPUT (policy ACCEPT) 或者 policy DROP。如果默认策略是DROP,那所有出站连接都会被拦,除非有显式放行规则。

注意: 有些云服务器的安全组规则也会影响客户端。如果你在云上做测试,记得同时检查云控制台的安全组出站规则。

Windows下,我一般这么查:

# 查看防火墙状态
netsh advfirewall show allprofiles

# 查看是否有阻止特定端口的规则
netsh advfirewall firewall show rule name=all dir=out | findstr "3389"

我记得有一次,一个同事反馈连不上某个数据库。我让他 telnet 测试端口,一直超时。查了半天,发现是他本机的防火墙阻止了所有出站TCP 3306端口。放行之后,秒连。

3.1.2 临时关闭防火墙做对比测试

如果你怀疑是防火墙的问题,可以临时关掉它做对比测试。注意,这只是为了定位问题,生产环境千万别这么干。

# Linux (CentOS/RHEL 7+)
systemctl stop firewalld
systemctl disable firewalld   # 谨慎使用

# Windows (管理员权限)
netsh advfirewall set allprofiles state off

关掉防火墙后,再试一次连接。如果通了,那基本确定是防火墙规则的问题。这时候再一条条排查规则,找到具体是哪条在拦。

小技巧: 我习惯用 tcpdump 在客户端抓包,同时看防火墙日志。两边对照,能快速定位是防火墙丢包,还是网络层面丢包。

3.2 DNS解析超时排查

连接超时,有时候不是连不上,而是找不到目标。DNS解析失败或超时,会让你根本拿不到IP地址,自然也就没法建立连接。

你想想看,你输入 www.example.com,系统得先去问DNS服务器:“这域名对应的IP是啥?”如果DNS服务器没响应,或者响应太慢,你的连接就会卡在解析阶段,最终超时。

3.2.1 检查DNS解析是否正常

最直接的办法,用 nslookup 或 dig 命令。

# 使用系统默认DNS
nslookup www.example.com

# 指定DNS服务器(比如用Google的8.8.8.8)
nslookup www.example.com 8.8.8.8

如果 nslookup 返回 Non-existent domain 或者超时,那问题就在DNS上。

用 dig 能看到更详细的信息:

dig www.example.com

# 只看响应时间
dig www.example.com | grep "Query time"

正常情况下,查询时间应该在几十毫秒以内。如果超过1秒甚至几秒,那DNS解析本身就是瓶颈。

3.2.2 排查DNS服务器配置

客户端用的DNS服务器是谁?这个很关键。我见过有人把DNS设成了一个内网地址,结果在外网环境根本解析不了。

查看当前DNS配置:

# Linux
cat /etc/resolv.conf

# Windows
ipconfig /all | findstr "DNS"

如果发现DNS服务器地址不对,或者指向了一个不可达的IP,那就改掉它。

实战经验: 有一次,客户反馈某个应用间歇性超时。我抓包发现,DNS查询请求发了三次,每次间隔5秒,最后超时。查下来,是客户内网的DNS服务器负载太高,响应慢。换成公共DNS(如114.114.114.114)后,问题解决。

3.2.3 检查本地hosts文件

有时候,问题出在本地 hosts 文件。这个文件可以手动指定域名和IP的映射关系。如果里面写了一个错误的IP,那DNS解析再快也没用。

# Linux / Mac
cat /etc/hosts

# Windows
type C:\Windows\System32\drivers\etc\hosts

看看有没有你要访问的域名。如果有,确认IP是否正确。我曾经遇到过,测试环境把线上域名指向了测试IP,结果连不上,还以为是网络问题。

3.3 本地路由表与网关检查

DNS解析拿到了IP,防火墙也放行了,但数据包怎么走?这就看路由表了。路由表决定了你的数据包下一跳该发给谁。

如果路由表配置错了,数据包可能被发到错误的网关,或者干脆找不到路,直接丢包。

3.3.1 查看本地路由表

Linux和Windows都能用 route 命令查看。

# Linux
route -n

# Windows
route print

输出里,重点关注三列:目标网络、网关、接口。

目标网络 网关 接口 说明
0.0.0.0/0 192.168.1.1 eth0 默认路由,所有未知流量走这个网关
10.0.0.0/8 10.0.0.1 eth1 特定网段走专用网关
192.168.1.0/24 0.0.0.0 eth0 直连网段,不需要网关

如果你的目标IP是 203.0.113.5,系统会先看有没有匹配的特定路由。没有的话,就走默认路由 0.0.0.0/0,发给网关 192.168.1.1。

3.3.2 检查默认网关是否可达

默认网关是数据包出站的最后一关。如果网关本身不可达,那所有外网连接都会超时。

怎么检查?用 ping 测试网关IP。

ping 192.168.1.1

如果ping不通,或者丢包严重,那问题就在网关这一层。可能是网关设备挂了,也可能是网线、交换机的问题。

注意: 有些网关设备会禁止ping。如果ping不通,不代表网关一定有问题。可以试试用 arping 或者检查ARP表。

3.3.3 检查ARP缓存

路由表告诉数据包下一跳的IP,但真正发送时,需要知道下一跳的MAC地址。这个映射关系存在ARP缓存里。

# Linux
arp -n

# Windows
arp -a

看看网关IP对应的MAC地址是否正确。如果ARP缓存里没有网关的记录,或者记录是错的,那数据包就发不出去。

我遇到过一种情况:网关设备做了主备切换,但客户端的ARP缓存还是旧的MAC地址,导致数据包发到了错误的设备上。清空ARP缓存后,问题解决。

# Linux 清空ARP缓存
ip neigh flush all

# Windows 清空ARP缓存
netsh interface ip delete arpcache

3.4 本章知识体系

下面这张图,帮你把客户端侧排查的三个维度串起来。你可以把它当作一个检查清单。

客户端侧排查知识体系 客户端侧排查:三大核心维度 客户端连接超时 本地防火墙 DNS解析 路由表与网关 检查规则 临时关闭测试 nslookup/dig 检查DNS配置 route -n ping网关 排查顺序建议 先查防火墙 → 再查DNS → 最后查路由表与网关 别忘了检查 hosts 文件和 ARP 缓存

嗯,这张图把三个维度的排查要点都列出来了。你按照这个顺序走一遍,大部分客户端侧的问题都能定位到。

3.5 避坑指南

最后,分享几个我踩过的坑:

  • 防火墙规则有优先级:不是所有规则都平等。有些防火墙会按顺序匹配,匹配到第一条就停止。你加了一条放行规则,但如果前面有一条拒绝规则匹配了,那还是会被拦。
  • DNS缓存会骗人:系统会缓存DNS解析结果。如果你改了DNS配置,但缓存没刷新,可能还是用旧IP。用 ipconfig /flushdns (Windows) 或 systemd-resolve --flush-caches (Linux) 清一下。
  • 多网卡环境要小心:如果你的机器有多个网卡(比如有线+无线),路由表可能同时有多个默认路由。系统会选优先级最高的那个。我曾经遇到过,无线网卡的默认路由优先级更高,导致流量走了无线,但无线网关配置错了,连不上外网。

这些细节,平时不注意,出问题的时候能折腾你半天。记住,客户端侧排查,耐心和细心比技术更重要。