真正可靠的判断是端口被监听、进程存活、可建立连接三者同时满足;用ss -tulnp查监听,nc -zv实测连通性,结合监听地址与进程路径识别高危暴露。

怎么看端口是不是真在监听?别被 netstat 假象骗了
很多运维一看到 netstat -tuln | grep :80 有输出,就认为 Nginx 肯定跑着——但其实可能只是进程残留、socket 未释放,或服务已崩溃但内核还挂着 LISTEN 状态。真正可靠的判断是:**端口被监听 + 进程存活 + 可建立连接**三者同时满足。
-
ss -tulnp比netstat更准,它直读内核 socket 表,不依赖 /proc 下的进程状态快照;旧系统若没装iproute2,netstat -tulnp仍可用,但需 root 权限才显示PID/Program name - 仅看 LISTEN 不够:比如
127.0.0.1:3306是安全的,但0.0.0.0:3306就意味着 MySQL 对全网开放,必须结合监听地址判断暴露面 - 用
nc -zv 127.0.0.1 80实测连通性,如果返回succeeded!才算服务真活;失败则可能是防火墙(iptables/firewalld)、SELinux 或服务本身卡死
哪些监听端口该立刻警惕?重点查这三类
不是所有 LISTEN 都危险,但以下三类必须人工确认:
-
非常规高危端口:如
:6379(Redis)、:6379(未授权访问常见入口)、:27017(MongoDB),尤其当进程路径含/tmp、/dev/shm或名字可疑(如sh、bash、python3.9无明确业务名) -
监听地址为
0.0.0.0却无业务需求:比如后台管理服务本该只绑127.0.0.1,却对外暴露,极可能是配置错误或后门植入 -
端口与进程明显不匹配:例如
ss -tulnp | grep :443显示是java进程,但你系统里根本没部署 Java Web 服务——就得查ps -p PID -o cmd=看真实启动命令
lsof -i 和 ss -tulnp 到底选哪个?
二者目标一致,但行为逻辑不同:lsof 从进程视角出发,列出“哪些进程打开了哪些网络文件”;ss 从内核 socket 视角出发,回答“当前有哪些监听 socket”。实际中建议分层使用:
- 快速筛查:用
ss -tuln(无需权限,速度快),过滤出所有监听端口 - 精准溯源:对可疑端口补查
sudo lsof -iTCP:,-Pn -P防止把:80解析成:http,-n跳过 DNS 查询,避免卡顿 - 注意兼容性:
lsof默认不安装,CentOS/RHEL 需yum install lsof,Ubuntu/Debian 是apt install lsof;而ss属于iproute2,现代发行版基本都预装
如何建立可持续的端口监控习惯?
手动查一次没用,关键是要形成基线和告警闭环。最轻量的做法是:
- 首次运行
ss -tuln | awk '{print $5}' | sort | uniq > /etc/port-baseline.txt,存一份可信端口清单 - 定期执行对比:
diff /etc/port-baseline.txt ,有差异就人工介入 - 别只盯端口数——
ss -s输出的 summary 里,tcp:行的listen数值突增,可能预示连接队列堆积或 SYN Flood 攻击
最容易被忽略的是 IPv6 监听(如 :::22),很多脚本只 grep :22,漏掉 :::22;检查时务必加 -6 或用 ss -tuln(默认包含 IPv4/IPv6)。










