如果你维护的服务器突然出现线上访问超时,第一反应会用什么工具?我以前带过的新人,上来就打开抓包工具,准备分析一整晚的数据。我说你先别急,先跑三条命令:ifconfig 看一眼本机网卡,ping 探一下网关,netstat 看一看有没有端口卡住。十分钟内,问题基本能定位到七八成。
这不是古板。Linux 的网络管理从来不是靠一套图形界面撑起来的,真正能在一线救命的,往往是命令行里那几个基础工具。ifconfig、ping、netstat、nslookup、finger 这五个命令,年龄比不少读者都大,但直到今天,它们依然是排查网络故障时最高频的入口。这篇文章就从头到尾把它们捋一遍,不光是背参数,而是告诉你每个命令在真实故障里到底该怎么用、输出该怎么看、哪些坑我踩过。
1. 先回答一个问题:为什么还要翻这几条命令
1.1 一套故障现场,三个排查阶段
有一次,某应用反馈访问慢,监控面板上一片红,看起来像是全面故障。当时的处理过程我印象很深:先在自己的终端上执行ifconfig,发现本机网卡 RX errors 一直在涨,丢包计数明显异常;接着ping网关,果然延迟忽高忽低;再netstat -tlnp一看,数据库监听地址没对外,只有本地回环。三条命令下来,问题范围就从“整个系统”缩小到“网卡到网关这一段链路”上。
这类场景我经历过很多次,所以总结出一个习惯:网络故障排查有三个阶段,而这三个阶段恰好对应这几条命令。
第一阶段看“自己”:本机网卡通不通、有没有错包、IP 配置对不对,这是ifconfig的活。第二阶段看“链路”:报文能不能到网关、到对端,延迟和丢包如何,这是ping的活。第三阶段看“服务”:端口有没有在听、连接状态健不健康,这是netstat的活。等前三层都正常,才轮到应用层的问题,比如域名解析对不对,这时候用nslookup;如果还涉及到用户在服务器上的登录状态,finger能补充一点信息。
我粗略统计过,内部日常告警里,大约六到七成的问题能在这一步收口。剩下的才需要动抓包工具或者流量分析系统。很多人把排查想复杂了,一上来就上重型工具,反而丢了基本功。
1.2 这些工具共同的使用逻辑
这五个命令并不处在同一个网络层级,理解它们的分工比死记参数更重要。
ifconfig工作在第二、三层之间,管的是网卡和 IP 地址;ping依赖 ICMP 协议,工作在第三层;netstat看的是 TCP/UDP 的连接状态和端口,工作在传输层;nslookup是应用层的 DNS 查询客户端;finger则更“偏门”,它查的是远程主机上的用户信息,本质是一个轻量的应用层信息协议。
我常用的排查顺序是从低到高:先确认物理和链路层,再确认网络层,再确认传输层,最后再去看应用层和用户层。这就像家里网络出问题,你不会先换电脑,而是先看楼道里的光猫亮不亮、网线插没插好。底层通了再往上看,每一步都有证据,排查起来就不会乱。
所以,真正值钱的不是记住五条命令的语法,而是知道在哪个环节该掏出哪条命令,并且能读懂它的输出。
2. ifconfig:老牌网卡信息的排版师
2.1 输出字段的逐行拆解
很多现代发行版已经不预装 ifconfig 了,但你仍然会在老系统、嵌入式设备、网络设备的运维文档里反复看到它。它的输出非常直观,经典的一段长这样:
$ ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255 ether 00:16:3e:0a:1b:2c txqueuelen 1000 (Ethernet) RX packets 15220 bytes 1892340 (1.8 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8321 bytes 1045677 (1018.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0第一行flags是关键。UP表示网卡已启用,RUNNING表示物理链路有载波,说白了就是网线或者光纤有信号;BROADCAST和MULTICAST表示支持广播和组播。如果只看到 UP 而没有 RUNNING,通常意味着物理层没通,网线、模块、对端设备都要查。
第二行inet是 IPv4 地址,netmask是子网掩码,broadcast是广播地址。这里最常见的错误是在小型局域网里配错了掩码,导致两个“看起来在同一网段”的机器互相不通。你在终端前一筹莫展时,先看这里往往就有答案。
第三行ether是 MAC 地址,也就是物理地址。后面 RX 和 TX 两组数据更值得关注:errors是错误包,dropped是被内核丢弃的包,overruns是缓冲区溢出,carrier是载波错误。我在实际中见过一种典型情况:网卡跑着跑着断流,ifconfig一看 RX errors 非零且持续增长,十有八九是网线老化或接口松动,重新插拔后计数不再增长,问题就解决了。
2.2 临时改IP、掩码以及虚拟接口
ifconfig 不仅能看,还能临时改。注意“临时”两个字,重启网络服务或重启机器后一切恢复原状,所以它适合调试和测试环境,不适合做永久配置。
# 临时指定IP和掩码,并启用网卡 ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up # 关闭网卡 ifconfig eth0 down # 创建虚拟接口,绑定额外IP ifconfig eth0:1 192.168.1.101 netmask 255.255.255.0 up这里我想特别强调虚拟接口。老派配置里经常用eth0:1这种方式给一张网卡绑多个 IP,在服务器上做测试分流、模拟多环境时非常方便。用法很简单,冒号后面的数字可以自己起名字,比如eth0:test也行。
但有一个坑必须要提:ifconfig eth0 down会直接断掉这张网卡上的所有通信,如果你正通过 SSH 远程连接这台服务器,网卡一关,连接立刻断开。我早年就在生产机器上干过这种事,手一抖连自己都连不回去了,最后只能让机房同事帮忙。用这命令前,心里一定要过一遍:我到底连的是哪张网卡,断了之后还能不能恢复。
另外,ifconfig临时改地址后,默认路由一般不会自动更新。你可能发现 IP 改好了,但ping不通外网,那是因为route表里的默认网关还是老地址。这时候要用route add default gw 192.168.1.1或者直接改用ip命令重新配置。
2.3 现在已经不推荐,但你必须能读懂
如果你用的是较新的发行版,系统会提示你用ip addr替代ifconfig。ip命令来自 iproute2 工具包,功能更强大,输出也更结构化。两者的对应关系大致是这样的:
| 用途 | ifconfig 写法 | ip 命令等价写法 |
|---|---|---|
| 查看所有网卡 | ifconfig -a | ip addr show |
| 查看指定网卡 | ifconfig eth0 | ip addr show dev eth0 |
| 启用网卡 | ifconfig eth0 up | ip link set eth0 up |
| 关闭网卡 | ifconfig eth0 down | ip link set eth0 down |
| 添加临时IP | ifconfig eth0:1 192.168.1.101 netmask 255.255.255.0 | ip addr add 192.168.1.101/24 dev eth0 |
| 删除临时IP | ifconfig eth0:1 down | ip addr del 192.168.1.101/24 dev eth0 |
既然有了更好的替代品,为什么还要学 ifconfig?因为存量系统太多。我现在维护的机器里,有好几台跑的还是老系统,工具链完全没有升级。你翻历史文档、查供应商手册、读自动化脚本,满屏都是 ifconfig。可以不用它配置,但不能看不懂它说什么。能读输出,是底线。
我的建议是,新环境尽量用ip命令,但在老环境里能和 ifconfig 顺畅交流,是一个运维必备的生存技能。
3. ping:不是简单的“通或不通”
3.1 ICMP协议在大楼里的角色
ping 是大家最早接触的网络命令,但很多人只把它当成“通不通”的开关。实际上,它背后是 ICMP 协议,全称是 Internet Control Message Protocol,互联网控制报文协议。它和 TCP、UDP 不一样,不承载业务数据,只负责传递控制信息和错误报告。
你可以把 ICMP 想象成大楼物业的巡检员。他不帮你搬家具,也不帮你送快递,但他能告诉你电梯有没有停运、走廊灯是不是灭了、哪一户门敲不开。ping 就是敲门的动作,发一个 ICMP 回显请求,对方回一个回显应答,一来一回就知道这条路通不通、走一趟要多久。
这个校验码在底层有两个关键信息:ttl和time。ttl是生存时间,每经过一个路由器减一,减到零报文就被丢弃。time是往返时间,也就是从发出到收到响应的总耗时。一个常见的ping输出如下:
$ ping -c 4 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.042 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.038 ms 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.041 ms 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.047 ms --- 192.168.1.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.036/0.042/0.047/0.006 ms注意我加了-c 4,只发四个包。不少人在服务器上直接敲ping不加任何参数,结果命令永远不会自己停,只能Ctrl+C中断。这种习惯在故障处理时非常不好,一旦网络不通,命令就一直挂在那,你以为是卡死了,其实是在等超时。默认情况下,建议所有 ping 测试都带上次数限制。
3.2 高频参数及一次丢包分析
除了-c,有几个参数在排障里出场率很高:
-i 0.2:调整发送间隔,默认是一秒,排查抖动时可以改成 0.2 秒,多打几个包看得更细。-s 1400:指定数据包大小。有些网络设备对分片有特殊处理,标准小包能通,大包可能不通。复制粘贴场景里,用-s 1400模拟大包传输很有价值。-W 3:设置等待超时时间为 3 秒。内网设备如果超过 3 秒还没响应,基本可以认为是异常。-I 192.168.1.10:指定发起 ping 的源地址。当服务器有多个 IP 时很有用,可以判断是不是某个出口或路由策略有问题。-f:泛洪模式,快速发包测试极限丢包率,这个在生产环境慎用,很容易把对端设备打满。
我举一个真实的丢包分析例子。某次排查内网慢的问题,ping -c 100 -i 0.2 网关地址,结果丢包率达到 3%,平均延迟 20 多毫秒,最差的一跳甚至到 300 毫秒。这种少量但持续的丢包,在业务上表现为偶尔卡顿、下载速度不稳。后来检查发现是交换机端口协商成了半双工,改成强制千兆全双工后,同样的测试丢包率降到 0%。所以丢包出来之后,不要急着下结论,先记录以下三个维度:丢包率、平均延迟、最大延迟。结合这三组数据,基本能区分是链路拥塞、设备损坏还是配置协商问题。
3.3 防火墙回显策略对结论的干扰
使用 ping 时最大的误判来源是防火墙策略。很多设备默认拒绝 ICMP,或者只允许特定网段的 ping。这时候你ping不通,但业务端口其实完全正常。我就踩过这样的坑:某台外部系统的 IP 连续ping不通,我以为网络断了,结果用端口连通性工具去测,应用服务一切正常,问题只是对方安全策略禁了 ICMP。
所以,ping的结果永远要和其他证据交叉验证。我自己的习惯是:ping 不通的时候,顺手测一下业务端口;ping 得通但业务不通,那就要考虑服务的监听地址、权限和防火墙规则。总之,别把 ping 当成唯一真理,它只是链路层和网络层的探针。
4. netstat:一眼看穿端口和连接状态
4.1 五个最常用的组合
netstat 是 network statistics 的缩写,读起来像“网络状态”。它的最大价值是告诉你“此刻这台机器上发生了什么”,我先列出几个几乎天天在用的组合:
netstat -tlnp:查看正在监听的 TCP 端口以及对应进程,排查端口占用首选。netstat -anp:查看所有连接,不解析域名,直接显示数字地址。netstat -tunap:TCP 和 UDP 都看,同时跳过主机名解析,速度更快。netstat -r:查看路由表,相当于route -n。netstat -i:查看网卡接口收发统计,和 ifconfig 数据类似,但格式更紧凑。
举个例子,你想知道 8080 端口被谁占了:
$ netstat -tlnp | grep 8080 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 2333/java这里的 PID/Program name 是 2333 和 java,一眼就知道是 Java 服务。需要注意,非 root 用户经常看不到 PID 那一列,会显示成-,这时需要用sudo重新执行。这是我在新手阶段经常遇到的情况,还以为命令出了问题,其实是权限不够。
另一个非常实用的场景是确认服务监听范围。同样一条 8080 端口,如果 Local Address 是127.0.0.1:8080,说明只监听本地,外部机器访问不到;如果是0.0.0.0:8080,说明监听所有网卡,外部可以访问。很多服务“起了但连不上”的问题,就是监听地址配错了。
4.2 TCP状态族的观察方法
netstat 的-anp输出里,最常出现的几个 TCP 状态是有明确含义的:
LISTEN:服务正在监听,等待连接。ESTABLISHED:已建立连接,正在通信。TIME_WAIT:主动关闭方在等待足够时间,确保对端收到最后的确认报文。CLOSE_WAIT:被动关闭方收到对端关闭请求,但本端尚未主动关闭连接。SYN_SENT:发出了连接请求,但没有收到对端响应。
我在排障时最关注两个状态。第一个是大量TIME_WAIT,这在短连接服务里很常见,本身不一定是坏事;但如果数量过多,占满端口,就会导致新连接无法建立。通常调整内核参数net.ipv4.tcp_tw_reuse和应用连接复用机制能缓解。第二个是不断增长的CLOSE_WAIT,这几乎可以断定是应用层 bug:代码收到关闭信号后没有正确调用 close 或释放连接。排查的时候直接用netstat -tanp | grep CLOSE_WAIT看是哪个进程积累了一堆半关闭连接,然后去盯它的线程栈和连接管理代码。
有一次我接到告警,说某个服务连不上数据库。我先在数据库服务器上netstat -tlnp,看到 MySQL 监听地址是127.0.0.1:3306,而不是0.0.0.0或者业务网段的地址。整个问题在十秒内定位:数据库只允许本机访问,业务服务器当然连不上。这个结论不是靠猜,而是 netstat 的一行输出直接给出的。
4.3 和ss的衔接准备
现代系统里,我更推荐用ss命令替代 netstat 做日常查看。原因是 netstat 需要遍历/proc下的网络文件,当连接数达到几万甚至几十万时,性能和实时性都不好。ss直接使用内核的 socket 诊断接口,数据来自内核内部,速度快得多,输出也更详细。
对比一下最常用的等价关系:
netstat -tlnp→ss -tlnpnetstat -anp→ss -anpnetstat -i→ip -s link
不过,老系统、自动化脚本、历史文档里仍然大量存在 netstat,所以我没有直接把它扔掉。我的策略是:新写脚本用 ss,遇到老环境仍然熟练使用 netstat。两个工具都掌握,切换起来没有任何心理负担。
5. nslookup:把DNS从黑盒变成透明盒子
5.1 一次查询经历的完整流程
域名解析出问题的时间通常很隐蔽:网站偶尔打不开,但过一会儿又自动恢复;或者客户反馈访问慢,但服务器负载很低。这种“看起来都正常但又不对劲”的场景,我会先怀疑 DNS,然后执行nslookup。
$ nslookup www.example.test Server: 192.0.2.53 Address: 192.0.2.53#53 Non-authoritative answer: Name: www.example.test Address: 203.0.113.20输出第一行Server告诉你是哪台 DNS 服务器给出的回答。如果你系统里配置的 nameserver 并不是预期的服务器,那问题就从这里开始。注意Non-authoritative answer这个提示,它表示这条记录不是源权威服务器直接回答的,而是缓存里的结果。缓存本身是正常的,但如果缓存过期机制出问题,或者某个中间缓存服务器返回了陈旧记录,就会导致解析地址异常。
我遇到过一个典型案例:域名在权威服务器上已经改了 IP,但客户端仍然解析到旧地址。排查方法很简单,就是用 nslookup 把查询发到不同位置的 DNS 服务器,对比结果是否一致。如果有的服务器返回新地址,有的返回旧地址,说明问题出在缓存层的同步或 TTL 配置上。
5.2 常见记录类型与排查手段
nslookup 默认查询 A 记录,也就是 IPv4 地址。但它也能查其他记录,你只需要在交互模式里用set type切换:
> set type=mx > example.test ...常见类型有:
A:IPv4 地址记录。AAAA:IPv6 地址记录。CNAME:别名记录,指向另一个域名。MX:邮件交换记录,指定邮件服务器。NS:域名服务器记录,指定权威 DNS 服务器。TXT:文本记录,常用来做域名验证或 SPF 配置。
排查思路通常是这样:先A记录确认解析到哪个 IP,再NS记录确认权威服务器,再MX记录确认邮件链路。如果A记录解析正常,但服务依旧不可用,就把目光转向应用层;如果A记录本身就解析错误,再往下查你使用的 DNS 服务器是否继承了错误的上游数据。
还要注意/etc/resolv.conf的配置格式:
nameserver 192.0.2.53 nameserver 192.0.2.54 search example.test多个nameserver表示备选服务器,查询超时后才会切换。不少人改了这个文件后忘记重启相关服务,其实多数程序是每次解析都重新读取这个文件的,但如果有进程在启动时缓存了配置,就需要重启。优先用 systemd 相关方式管理网络时,还需要确认配置是否被覆盖。
5.3 为什么建议再备一个dig
很多发行版默认不装 dig,但我会在要长期排查的机器上主动补装,因为它给的信息比 nslookup 完整得多。dig 会显示响应时间、查询所用的服务器、TTL 值,以及权威答案和附加答案的完整结构。对比来看,nslookup 适合快速看结果,dig 适合深挖细节。
我的工作习惯是:日常验证解析用nslookup,因为它简洁,几乎所有 Linux 环境都有;一旦需要确认 TTL、权威性和多级缓存链路,就用 dig 去拿详细信息。两个工具配合,DNS 的排查基本不会卡住。
6. finger:被遗忘的轻量用户情报工具
6.1 finger到底能输出什么
很多人看到 finger 会愣一下,因为它确实不在日常故障排查的必备清单里。但在很久以前,它是系统管理员查看“谁在机器上、在干什么”的常用工具。后来慢慢被who、w、last这些命令取代,不过它仍然值得认识。
执行finger不带参数,会列出当前登录到系统的所有用户:
$ finger Login Name Tty Idle Login Time Office Office Phone auser A User pts/0 5 Sep 2 09:12 buser B User pts/1 12 Sep 2 10:30执行finger 用户名,可以查看单个用户的更详细信息,包括主目录、Shell、最近登录时间、邮件读取状态,以及用户目录下的计划文件内容:
$ finger auser Login: auser Name: A User Directory: /home/auser Shell: /bin/bash Last login ... (online) Mail last read ... No Plan.这里有个有趣的细节:finger 会读取用户主目录下的.plan、.project、.forward文件并显示出来。以前 UNIX 用户习惯用.plan发布“我今天在做什么”的状态,类似今天社交软件的签名档。在内部系统中,如果大家愿意维护这些文件,finger 可以快速展示团队成员的日程和联系方式。
6.2 限制与安全争议
finger 能展示这么多用户信息,本身就是一把双刃剑。远程 finger 服务通常跑在 79 端口,如果面向公网开放,就等于把系统用户列表、登录时间、姓名、终端位置等敏感信息直接暴露给陌生人。这种信息泄露在过去引发过不少安全讨论,所以现代系统基本默认不安装或禁用 finger,很多版本里连命令都没有了。
因此我的建议是:如果你只是自己用,直接装客户端工具做本机查询并无不可;但不要在公网环境开启 finger 服务。在需要批量查看登录用户的场景,优先用who和w,后者还能显示每个终端当前执行的命令和负载,信息更实时、更安全。
如果确实要在隔离的内网环境里用 finger,也要控制访问来源,只允许信任网段访问 79 端口,并关闭用户目录下计划文件的自动读取。安全底线是:任何能暴露系统内部结构的服务,默认都应该关闭,除非有明确且必要的业务理由。
6.3 从命令行习惯看整个排障逻辑
回到开头的问题:为什么老命令至今不过时?因为排查从来不是靠某一条命令“一招制敌”,而是靠一组命令组合成一套方法。ifconfig 看本机,ping 看链路,netstat 看端口和连接,nslookup 看解析,finger 看用户状态,各有分工又彼此衔接。
我自己有一个实操习惯,在接手一台不熟悉的服务器时,会按固定的顺序把这些命令各跑一遍,把输出存成一份“系统快照”。等故障真的发生时,拿快照和当前状态对比,能非常快地找出变化。比如netstat -tlnp的输出里少了一个关键监听端口,或者ifconfig里 RX errors 突然暴涨,这些变化本身就是诊断线索。
最后分享一个小技巧:这些命令的输出字符比较多,不要用肉眼硬看。如果你经常需要在几十台机器上重复同样的排查,不妨把常用的组合写成一个简单脚本,只过滤你关心的字段。比如我常跑的:
netstat -tlnp | awk '{print $4, $6, $7}' | sort -u这样输出的就是监听地址、状态和进程的对应关系,一眼扫过去就能发现哪个端口挂在哪张网卡上。命令行工具看似基础,组合起来就是一套非常顺手的排查语言。能用好它们,比装一堆监控面板更管用。