ss 看不到 netstat 的 listen 端口,因 ss -l 默认不显示通配符地址监听项且过滤中间状态;应使用 ss -tula 并注意权限、内核接口差异及进程名获取机制。

netstat 显示的 LISTEN 端口为什么 ss 看不到
因为 netstat 默认显示所有监听套接字(包括未绑定具体地址的 0.0.0.0 和 ::),而 ss -l 默认只显示已建立监听状态的套接字,且对通配符地址(如 0.0.0.0:22)的呈现逻辑不同。
实操建议:
- 用
ss -tuln替代netstat -tuln——-t(TCP)、-u(UDP)、-l(listening)、-n(数字端口)是等效组合 - 若仍缺端口,加
-a:ss -tula,否则ss会跳过处于SYN-RECV或其他中间状态的监听项 -
netstat可能读取/proc/net/tcp等旧接口,而ss直接调用netlink,内核版本较新时后者更准,但某些容器或 chroot 环境下可能因权限缺失漏报
ss 输出里 State 列显示 weird 状态如 syn-recv、fin-wait-1
这些不是错误,而是 ss 比 netstat 更细粒度地暴露了 TCP 状态机细节。例如 syn-recv 表示服务端已发 SYN+ACK、正等待客户端 ACK(三次握手未完成),常见于被 SYN flood 攻击或客户端异常断连后。
实操建议:
- 排查连接堆积:用
ss -tan state syn-recv | wc -l统计数量,持续 >100 需查防火墙、SYN cookies 是否开启(cat /proc/sys/net/ipv4/tcp_syncookies) -
ss -tan state established才对应netstat的ESTABLISHED;ss不把CLOSE_WAIT归入listening,这点和netstat -an行为一致 - 避免误判:
ss的state过滤支持复合条件,比如ss -tan '( dport = :80 or dport = :443 )',括号和空格必须保留,否则语法报错
想看某个进程绑定了哪些端口,ps + netstat 组合为什么常失效
因为 netstat -tulpn 依赖 /proc/<pid>/fd/</pid> 符号链接解析,而容器、sudo 启动、seccomp 限制或非 root 用户运行的服务会导致该路径不可读,netstat 就显示 - 或直接跳过进程名。
韩顺平,毕业于清华大学,国内著名的软件培训高级讲师,先后在新浪、点击科技、用友就职。 主持或参与《新浪邮件系统》、《橙红sns(社会化网络)网站》、《点击科技协同软件群组服务器端(Linux/solaris平台)》、《国家总参语音监控系统》、《英语学习机系统》、《用友erp(u8产品)系统》等项目。实战经验丰富,授课耐心细致,通俗易懂,勇于实践,勤于创新,授课风格贴近生活,授课语言生动风趣,多年
实操建议:
- 优先用
ss -tulpn—— 它通过netlink获取进程 ID 更可靠,尤其在 systemd 管理的服务中 - 若仍无进程名,检查是否缺少
cap_net_admin或cap_net_raw能力(getpcaps <pid></pid>),或尝试sudo ss -tulpn - 替代方案:
lsof -i -P -n -sTCP:LISTEN,但开销大、默认不装、且在某些内核(如 Alpine 的 musl)上无法识别 socket 类型
ss 命令输出列太多记不住,怎么快速定位关键字段
ss 默认列顺序固定但冗长,实际只需关注 Recv-Q/Send-Q、State、Local Address:Port、Peer Address:Port、Process(如果可用)。其余如 Timer、UID、Inode 多数场景可忽略。
实操建议:
- 用
-o显示 timer 仅用于诊断重传问题,普通监控不用加;-e(扩展)会强制显示 UID 和 Inode,但需 root 权限,且容易让输出变宽难读 - 简化输出:用
ss -tunl | awk '{print $1,$4,$5}'提取协议、本地地址、进程(注意$5在无进程时为空) - 别依赖列号硬编码:不同版本
ss(如 iproute2 5.15 vs 6.1)可能微调列顺序,建议用ss -h确认当前字段含义,或改用--no-header+column -t对齐再切
真正麻烦的是 UDP 套接字的状态不可见——ss -uln 里所有 UDP 都标为 UNCONN,哪怕程序已经 bind() 并 recvfrom() 中。这时候不能靠 State 判断“是否活跃”,得结合 /proc/net/udp 的 st 字段或用 tcpdump 抓包验证。









