如何找出占用指定端口的应用程序及运行HTTP服务器的进程?常规排查工具失效时的处理方案
这确实是个挺让人头疼的场景——netstat、lsof这些常用工具都没给出有效结果,但curl明明能收到404响应,说明端口上确实有服务在运行。下面分两种场景给你具体的排查方法:
一、识别正在使用某一端口的应用程序(常规工具失效时)
当lsof/fuser都无法定位端口占用时,大概率是遇到了RAW套接字、socket激活服务、端口转发/重定向或者容器/虚拟机端口映射这类特殊情况,试试这些方法:
用BPF追踪工具抓连接事件
BPF类工具(比如bpftrace或bcc)能直接追踪内核级的网络系统调用,绕过常规工具的限制。比如用bpftrace监听accept系统调用:sudo bpftrace -e 'tracepoint:syscalls:sys_accept* { printf("PID %d accepted connection on fd %d\n", pid, args->fd); }'保持这个命令运行,然后另开终端执行
curl http://localhost:80,你就能看到处理连接的进程PID,接着用ps aux | grep <PID>就能找到对应的应用程序。检查iptables端口转发/重定向规则
有时候80端口的流量被iptables转发到了其他端口或进程,用下面的命令查看NAT表规则:sudo iptables -t nat -L -n -v重点看
PREROUTING和OUTPUT链,有没有把dport 80转发到其他端口(比如REDIRECT到本地其他端口)或者远程地址的规则。排查systemd socket激活服务
部分服务用systemd socket预先监听端口,只有当有连接进来时才启动主进程,常规工具在无连接时可能看不到进程。用下面的命令查看监听80端口的socket单元:sudo systemctl list-sockets | grep :80如果找到对应的socket单元,比如
http.socket,可以用systemctl status <socket-unit>查看关联的服务进程。检查容器/虚拟机的端口映射
如果你的机器上运行了Docker、KVM这类容器/虚拟化工具,80端口可能被容器内的服务占用并映射到主机。用docker ps查看容器的端口映射情况,或者检查虚拟网卡(比如docker0)的流量。
二、定位运行HTTP服务器的进程(针对你的curl 404场景)
从你提供的curl -vv输出来看,响应头里有X-Content-Type-Options: nosniff——这是Go语言标准库默认添加的响应头,大概率是一个Go语言编写的HTTP服务。结合这个特征,你可以:
根据技术栈特征排查进程
直接搜索系统中运行的Go进程:ps aux | grep go或者用
pgrep -f go列出相关PID,再逐个检查这些进程的监听情况(即使常规工具看不到,也可以用strace -p <PID> -e trace=network追踪它的网络操作)。用tcpdump抓包分析响应细节
抓取下完整的HTTP响应,看看有没有更多隐藏特征:sudo tcpdump -i lo port 80 -A -s 0执行后再用
curl访问,tcpdump会输出完整的请求和响应内容,可能会找到Server头、自定义响应字段等能定位程序的线索。追踪curl的连接交互
用strace追踪curl的整个连接过程,看它到底和哪个进程建立了通信:sudo strace -e trace=connect,read,write curl http://localhost:80从输出里可以看到连接的文件描述符,再结合
lsof -p $(pidof curl)(在curl连接未断开时快速执行),能找到对应的peer进程信息。
内容的提问来源于stack exchange,提问作者Vinay B




