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不通,或者丢包严重,那问题就在网关这一层。可能是网关设备挂了,也可能是网线、交换机的问题。
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 本章知识体系
下面这张图,帮你把客户端侧排查的三个维度串起来。你可以把它当作一个检查清单。
嗯,这张图把三个维度的排查要点都列出来了。你按照这个顺序走一遍,大部分客户端侧的问题都能定位到。
3.5 避坑指南
最后,分享几个我踩过的坑:
- 防火墙规则有优先级:不是所有规则都平等。有些防火墙会按顺序匹配,匹配到第一条就停止。你加了一条放行规则,但如果前面有一条拒绝规则匹配了,那还是会被拦。
- DNS缓存会骗人:系统会缓存DNS解析结果。如果你改了DNS配置,但缓存没刷新,可能还是用旧IP。用
ipconfig /flushdns(Windows) 或systemd-resolve --flush-caches(Linux) 清一下。 - 多网卡环境要小心:如果你的机器有多个网卡(比如有线+无线),路由表可能同时有多个默认路由。系统会选优先级最高的那个。我曾经遇到过,无线网卡的默认路由优先级更高,导致流量走了无线,但无线网关配置错了,连不上外网。
这些细节,平时不注意,出问题的时候能折腾你半天。记住,客户端侧排查,耐心和细心比技术更重要。