4. Linux 端口排查:四把利刃在手

端口排查这事儿,说白了就是「谁在哪个口上蹲着」。QUIC 跑在 UDP 上,跟 TCP 的排查思路不太一样。我这些年踩过的坑,十有八九都是端口没查清楚。今天把这四把刀磨利了,以后遇到端口问题,你心里就有底了。

核心思路:先看端口有没有在监听,再看哪个进程占着,最后确认能不能连上。QUIC 用的是 UDP,别光盯着 TCP 看。

4.1 netstat:老牌工具,依然能打

netstat 是我刚入行时用的第一个网络排查工具。虽然现在有了 ss,但很多老系统上还得靠它。

常用参数组合:

# 查看所有 UDP 监听端口(QUIC 重点关注)
netstat -uan

# 查看所有 TCP 监听端口
netstat -tan

# 显示进程信息(sudo 才能看到别人的进程)
sudo netstat -tunlp

# 只看 QUIC 常用的 443 端口
sudo netstat -unlp | grep 443

参数说明:

参数 含义 我的习惯
-u 显示 UDP 查 QUIC 必加
-t 显示 TCP 顺便看看有没有冲突
-n 不解析域名 加这个快很多
-l 只显示监听状态 排查服务端够用了
-p 显示进程 PID/名称 定位问题必备

我的经验:有一次线上 QUIC 服务连不上,我 netstat -tunlp 一看,443 端口确实在监听。但仔细一看,是 TCP 的 443,UDP 的 443 根本没起来。嗯,QUIC 用的是 UDP,这个坑我替你们踩过了。

4.2 ss:现代 Linux 的标配

ss 是 netstat 的替代品,性能更好,信息更全。我个人习惯,新系统上直接用 ss。

常用命令:

# 查看所有 UDP socket
ss -uan

# 查看所有 TCP socket
ss -tan

# 显示进程信息
sudo ss -tunlp

# 只看特定端口
sudo ss -unlp 'sport = :443'

# 查看 socket 详细信息(缓冲区大小等)
sudo ss -unlp -o

ss 和 netstat 的对比:

对比项 netstat ss
性能 读取 /proc 文件系统,慢 直接读取内核信息,快
信息量 基础信息 更详细,支持过滤
UDP 支持 支持 支持,且更准确
适用场景 老系统、临时排查 日常排查、性能调优

注意:ss 的输出里,UDP 的 State 列通常是 UNCONN(未连接),这是正常的。UDP 是无连接的,不像 TCP 有 LISTEN、ESTAB 这些状态。我第一次看到 UNCONN 时还以为服务没起来,白忙活半天。

4.3 lsof:谁动了我的端口

lsof 是「List Open Files」的缩写。在 Linux 里,一切皆文件,socket 也是文件。lsof 能告诉你哪个进程打开了哪个端口。

实战命令:

# 查看 443 端口被谁占着
sudo lsof -i :443

# 只看 UDP 的 443
sudo lsof -i UDP:443

# 查看某个进程打开了哪些端口
sudo lsof -p 12345

# 查看所有 UDP 监听端口
sudo lsof -i UDP -s UDP:LISTEN

输出解读:

COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
quic-server 12345 root 3u IPv4 123456 0t0 UDP *:443
  • COMMAND:进程名,一眼看出是谁
  • PID:进程 ID,杀进程时用
  • FD:文件描述符,3u 表示第 3 个文件描述符,u 表示可读写
  • TYPE:IPv4 或 IPv6
  • NAME:UDP *:443,表示监听所有网卡的 443 端口

避坑指南:我曾经遇到一个情况,lsof -i :443 什么都没输出,但服务就是连不上。后来发现 QUIC 服务监听的是 UDP 443,而 lsof 默认只看 TCP。加上 UDP 参数就好了。记住:QUIC 是 UDP,查的时候别漏了。

4.4 /proc 文件系统:底层真相

/proc 是 Linux 内核暴露给用户的信息窗口。虽然平时用 netstat、ss 就够了,但有些极端情况,比如工具坏了、权限不够,就得直接翻 /proc。

核心文件:

# 查看所有 TCP/UDP socket 信息
cat /proc/net/tcp
cat /proc/net/udp

# 查看某个进程的 socket 信息
ls -la /proc/12345/fd/ | grep socket

# 查看 socket 的详细状态
cat /proc/net/udp | grep 443

/proc/net/udp 输出解读:

sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
0: 00000000:01BB 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 123456 1 0000000000000000 100 0 0 10 0
  • local_address:本地地址和端口,00000000:01BB 表示 0.0.0.0:443(01BB 是 443 的十六进制)
  • rem_address:远程地址,全 0 表示监听状态
  • st:状态,07 表示 UDP 监听(UNCONN)
  • uid:运行该 socket 的用户 ID
  • inode:inode 号,可以用来关联进程

实用技巧:用 inode 号反查进程:

# 找到 inode 为 123456 的进程
find /proc -name "fd" -exec ls -l {} \; 2>/dev/null | grep "socket:\[123456\]"

这招在工具全挂的时候特别好用。我有一回在生产环境上,ss 和 lsof 都报错,就是靠这招找到的罪魁祸首。

4.5 知识体系总览

下面这张图,把四把利刃的关系和适用场景串起来了。建议你保存下来,排查问题时对照着看。

Linux 端口排查四把利刃 端口占用排查 netstat ss lsof /proc 文件系统 netstat 特点 老牌工具,兼容性好 性能一般,信息基础 适合老系统排查 ss 特点 现代标配,性能强劲 信息详细,支持过滤 日常排查首选 lsof 特点 进程视角,精准定位 支持 UDP/TCP 过滤 查谁占端口必备 /proc 文件系统 底层真相,直接读内核 工具失效时的救命稻草 inode 反查进程

4.6 实战排查流程

遇到 QUIC 端口问题,我一般按这个顺序来:

  1. 先用 ss 扫一眼:sudo ss -unlp | grep 443,看端口有没有在监听
  2. 再用 lsof 确认进程:sudo lsof -i UDP:443,看是哪个程序占着
  3. 如果 ss 和 lsof 都挂了:直接翻 /proc/net/udp,用 inode 反查
  4. 最后用 netstat 兜底:老系统上可能只有 netstat

重要提醒:QUIC 用的是 UDP,不是 TCP。很多新手查端口时只查 TCP,结果服务明明在跑,却以为没起来。我见过不止一次这种 case。记住:查 QUIC,加 -u 参数。

这四把刀,你平时用 ss 和 lsof 就够了。但 /proc 和 netstat 也得会,万一哪天工具出问题,它们能救命。嗯,今天就到这儿,下节课我们讲怎么抓包分析 QUIC 流量。