Linux端口与连接排查:ss、lsof、nc、telnet、curl

「端口被占用了」「服务起不来报地址已被使用」「防火墙开了但连不上」------端口问题几乎每个部署日都会遇到。排查端口,需要回答四个问题:谁在监听、端口通不通、谁占用了、连接状态如何 。这一篇用 ss、lsof、nc、telnet、curl 五把工具,串成一套端口排查的完整流水线,并讲清端口占用、连接拒绝、超时这几类问题的处理套路。

一、端口排查的四个问题

拿到一个端口号,先想清楚要查什么:

问题 工具
谁在监听这个端口? ss -lntp / lsof -i
端口从外面能连吗? nc / telnet
端口被谁占用了(起不来服务)? lsof -i / fuser
应用层返回什么? curl

思路:先看本机有没有监听 → 再看对方能不能连 → 再看应用是否正常。 逐层排除。

二、ss:端口与连接的首选工具

ss(socket statistics)是现代 Linux 看端口和连接的首选,比 netstat 快得多(第 67 篇已介绍),这里聚焦「端口排查」的用法。

查看监听端口

bash 复制代码
sudo ss -tlnp
text 复制代码
State   Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:22           0.0.0.0:*          users:(("sshd",pid=980))
LISTEN  0       511     0.0.0.0:80           0.0.0.0:*          users:(("nginx",pid=1234))
LISTEN  0       128     127.0.0.1:3306       0.0.0.0:*          users:(("mysqld",pid=2345))
  • -t TCP,-l 监听,-n 数字,-p 显示进程
  • 0.0.0.0:80 监听所有网卡;127.0.0.1:3306 只监听本地(外部连不上!)

⚠️ 监听地址决定能否被外部访问

这是「端口开着却连不上」的头号原因:

监听地址 含义
0.0.0.0:80 或 *:80 所有网卡,外部可连
127.0.0.1:3306 仅本机回环,外部连不上
192.168.1.10:80 仅该网卡

看到服务只监听 127.0.0.1,那不管防火墙怎么放行,外部都连不上------要改服务的绑定配置(如 MySQL 的 bind-address、Redis 的 bind)。

精简输出

bash 复制代码
# 只看监听端口,不显示进程
ss -tln

# 简洁格式
ss -tln | awk '{print $4}' | sort -t: -k2 -n

三、lsof:从进程反查端口

ss 是从「端口」找进程,lsof 反过来:从「进程」找它打开的端口和文件。

查看端口被谁占用

bash 复制代码
sudo lsof -i :8080
text 复制代码
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java     12345 app    42u  IPv6 1234567      0t0  TCP *:8080 (LISTEN)

一眼看出 PID 12345 的 java 占了 8080。

常用查询

bash 复制代码
# 所有网络连接
sudo lsof -i

# 所有 TCP
sudo lsof -i TCP

# 某进程打开的所有文件/端口
sudo lsof -p 12345

# 某用户打开的网络连接
sudo lsof -i -u app

# 某状态
sudo lsof -i -sTCP:LISTEN

fuser:更快的端口占用查询

bash 复制代码
sudo fuser 8080/tcp
text 复制代码
8080/tcp:            12345

fuser 只输出 PID,速度更快,适合脚本。

四、nc / telnet:测试端口连通性

本机监听正常,还得测「从外部/另一端能不能连」。这是区分「服务问题」和「网络/防火墙问题」的关键。

nc(netcat)

bash 复制代码
# 测单端口
nc -zv 192.168.1.100 80

# 测一组端口
nc -zv 192.168.1.100 20-80

# 带超时(避免长时间卡住)
nc -zv -w 3 192.168.1.100 80

# 从本机某个源端口测(排查源端口限制)
nc -zv -s 192.168.1.50 192.168.1.100 80
text 复制代码
Connection to 192.168.1.100 80 port [tcp/http] succeeded!

telnet

bash 复制代码
telnet 192.168.1.100 80
  • Connected to ... → 端口开放
  • Connection refused → 端口没监听或被 REJECT
  • 长时间无响应 → 防火墙 DROP 或网络不通

⚠️ 三种结果对应三类问题

结果 含义 排查方向
succeeded / Connected 端口可连 网络和端口都 OK,查应用
Connection refused 端口没监听 服务没起 / 监听地址错 / 被 REJECT
超时无响应 包被丢弃 防火墙 DROP / 网络不通 / 路由问题

refused 和超时的区别至关重要:refused 说明包到了目标、只是没人接;超时说明包根本没到。后者才是网络/防火墙问题。

用 nc 模拟服务端(测反向)

bash 复制代码
# 在 A 机监听
nc -l 9999

# 在 B 机连接
nc 192.168.1.10 9999
# 直接打字,A 机能收到,说明双向通畅

五、curl:HTTP 层诊断

端口通了,还要确认 HTTP 应用正常。curl 是最实用的 HTTP 测试工具。

基础测试

bash 复制代码
# 请求并显示响应头
curl -I http://192.168.1.100/

# 显示详细过程
curl -v http://192.168.1.100/

# 跟随重定向
curl -L http://example.com/

# 指定方法
curl -X POST -d '{"key":"value"}' -H "Content-Type: application/json" http://host/api

# 只看 HTTP 状态码
curl -o /dev/null -s -w "%{http_code}\n" http://host/

用 -w 拆解各阶段耗时

bash 复制代码
curl -o /dev/null -s -w "dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com/
text 复制代码
dns:0.011 connect:0.032 tls:0.098 ttfb:0.145 total:0.156

各阶段含义:

指标 含义
time_namelookup DNS 解析耗时
time_connect TCP 连接耗时
time_appconnect TLS 握手完成耗时
time_starttransfer 首字节时间(TTFB)
time_total 总耗时

哪个阶段大,问题就在哪:DNS 慢查 DNS,connect 慢查网络,ttfb 慢查应用。

常用诊断选项

bash 复制代码
# 忽略证书(测试自签名)
curl -k https://host/

# 指定 Host 头(测虚拟主机)
curl -H "Host: example.com" http://1.2.3.4/

# 指定网卡/源 IP
curl --interface eth0 http://host/

# 显示响应时间
curl -w "@curlformat.txt" -o /dev/null -s http://host/

六、端口被占用怎么处理

服务起不来报 Address already in use,处理步骤:

bash 复制代码
# 1. 找到占用端口的进程
sudo lsof -i :8080
# 或
sudo ss -lntp | grep :8080
# 或
sudo fuser 8080/tcp

# 2. 确认是不是僵尸进程或重复启动
ps -fp <PID>

# 3. 决定杀掉还是换端口
sudo kill <PID>          # 优雅终止
sudo kill -9 <PID>       # 强杀(谨慎)

# 4. 确认端口释放
sudo ss -lntp | grep :8080

⚠️ TIME_WAIT 导致端口"被占用"

服务重启后立刻报端口占用,可能是上一个连接处于 TIME_WAIT:

bash 复制代码
ss -tan | grep :8080 | grep TIME-WAIT

处理:服务端应设 SO_REUSEADDR(大多数框架默认开启),或等待 60 秒(2MSL)自然释放。

七、⚠️ 常见错误

  1. 只看本机监听说"端口开了" 。还要从对端 nc/telnet 测,本机监听的 127.0.0.1 外部连不上。
  2. refused 和超时不分。refused 是服务没起(本地问题),超时是网络/防火墙(链路问题),方向完全不同。
  3. 忽略了监听地址 。服务绑在 127.0.0.1,却一直查防火墙。
  4. lsof 看不到进程。需要 root,普通用户看不到别人的进程。
  5. curl 不指定 Host 测虚拟主机失败。多站点服务器要根据 Host 头路由,直接 IP 访问可能返回默认站或 404。
  6. 测端口不带超时 。nc/telnet 遇 DROP 会卡很久,加 -w 3。
  7. 防火墙和安全组只看一个。云服务器有安全组 + 本机防火墙两层,都要放行。
  8. curl 正常但浏览器不行。可能是代理、证书、DNS 缓存等客户端侧问题。

八、原理探究:端口、套接字与四元组

端口是什么

IP 地址定位「哪台机器」,端口定位「机器上的哪个进程」。端口是 16 位,范围 0~65535:

范围 用途
0~1023 众所周知端口(需 root 绑定)
1024~49151 注册端口
49152~65535 动态/临时端口(客户端出站用)

套接字与四元组

一条 TCP 连接由四元组唯一标识:

复制代码
(源IP, 源端口, 目标IP, 目标端口)

ss 里每一个连接就是一条四元组。这也是为什么服务端 0.0.0.0:80 能同时接受成千上万个连接------每个客户端的四元组不同,内核靠四元组区分它们。

客户端临时端口

客户端发起连接时,内核从「临时端口范围」里分配一个源端口:

bash 复制代码
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768    60999

高并发短连接场景下,这不到 3 万个端口可能被耗尽 (大量 TIME_WAIT 占着),表现为「Cannot assign requested address」。解法:开启 net.ipv4.tcp_tw_reuse(客户端侧)、用长连接、或调大端口范围。

监听套接字 vs 连接套接字

  • 监听套接字 :ss -l 看到的 LISTEN,服务端 listen() 创建的,负责接受新连接。
  • 连接套接字:三次握手完成后,内核为每条连接创建一个新的套接字,由四元组标识。

同一个服务端端口(如 80)对应一个监听套接字 + N 个连接套接字 ,这就是 ss -tln 只有一条 80、而 ss -tan 有大量 80 连接的原因。

理解了模型,排查就清晰了

  • 服务起不来 → 看监听套接字能否创建(端口被占、权限不足)
  • 外部连不上 → 看监听地址 + 防火墙 + 安全组
  • 连上没响应 → 看连接套接字状态(SYN_RECV 卡住 = 网络问题)
  • 连接太多 → 看四元组数量、临时端口、TIME_WAIT

九、端口排查速查表

bash 复制代码
# 1. 谁在监听端口
sudo ss -tlnp | grep :80
sudo lsof -i :80

# 2. 端口被谁占用
sudo lsof -i :8080
sudo fuser 8080/tcp

# 3. 从外面测端口
nc -zv -w3 host 80
telnet host 80

# 4. HTTP 层测试
curl -I http://host/
curl -o /dev/null -s -w "%{http_code}\n" http://host/
curl -w "dns:%{time_namelookup} connect:%{time_connect} total:%{time_total}\n" -s -o /dev/null http://host/

# 5. 看连接状态汇总
ss -tan | awk 'NR>1{print $1}' | sort | uniq -c | sort -rn

# 6. 杀占用端口的进程
sudo kill $(sudo lsof -t -i :8080)

端口排查的主线记住:ss 看谁在听 → lsof 看谁占了 → nc/telnet 测通不通 → curl 测应用 。而绝大多数「端口问题」,根因就三个:服务没起、监听地址错、防火墙没放行------对照结果类型(refused vs 超时)就能快速定位。

相关推荐
看浪的路人42 分钟前
第8讲:记忆系统的监控与运维——Prometheus 指标、Grafana 面板与告警体系
运维·grafana·prometheus
java_logo1 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
运维·docker·容器·定时任务·青龙面板·轩辕镜像·qinglong
时间售卖铺1 小时前
MySQL 安装部署
运维·数据库·mysql·云原生
亚川楼宇自控系统数据中心厂家1 小时前
消防风机一体化监控系统结合楼宇自控 协同管控原理科普
运维
邪修king1 小时前
Re:Linux系统篇(三十七):进程间通信Chapter4:System V 共享内存深度解析:为什么它是最快的 IPC?
android·linux·运维
桌管小李1 小时前
终端安全一体化实战:AI 审计、行为分析、零信任、防拍照与远程运维全解析
运维·服务器·网络·人工智能·windows·安全·macos
流星白龙2 小时前
【Docker】14.存储卷与管理卷Volume
运维·docker·容器
迪康Defender2 小时前
端点安全选型观察:一体化平台与传统 EDR 的场景差异
运维·经验分享·安全·自动化·学习方法·远程工作·安全架构