📢 你是否遇到过这些问题?
- 接手一个老项目,只有服务器账号,没有架构图?
- 服务突然异常,但不知道它依赖哪些外部系统?
- 想画数据流向图,却找不到文档?
别担心!只要你有 shell 权限,就能用几个 Linux 命令,逆向还原出整个系统的通信拓扑。
本文将带你一步步:
- 查看谁在监听
- 分析谁在连接你
- 抓包看 UDP 数据来源
- 统计出站连接目标
- 最终拼出一张“事实上的架构图”
无需任何外部工具,全是系统自带命令(netstat
、ss
、lsof
、tcpdump
),拿来即用,实战有效!
💡 适用场景:运维排查、系统交接、安全审计、自研服务调试
本文帮你彻底搞懂:如何排查“谁在连我”、“我连了谁”,适用于 Java、Nginx、MySQL、自研服务等所有网络程序
一、核心概念:先搞懂这些术语
概念 | 说明 |
---|---|
监听端口(LISTEN) | 你的服务正在等待别人来连接(如 Web 服务监听 80) |
入站连接(Inbound) | 外部机器连接你的服务 → “谁在连我” |
出站连接(Outbound) | 你的程序主动连接外部服务 → “我连了谁” |
UDP 通信 | UDP 是无连接协议,没有“连接状态”,只能通过抓包看“谁发了包给我” |
📌 关键区别:
- TCP 有连接状态(
ESTABLISHED
,LISTEN
),可直接查 - UDP 无连接,必须用
tcpdump
抓包分析
二、常用命令速查表(建议收藏)
目的 | 命令 |
---|---|
查看所有监听端口 | ss -lntup 或 netstat -lntup |
查看某进程的连接 | lsof -p <PID> |
查看谁在连某个端口 | ss -tnp | grep :端口 |
抓包看 UDP 谁在发数据 | tcpdump -i any -n udp dst port <端口> |
统计连接来源 IP | ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c |
✅ 推荐使用
ss
替代老旧的netstat
(更快、更现代)
三、如何查看“我的程序被谁连接”(入站连接)
1. 查看本机监听了哪些端口
ss -lntup
# 或(旧系统)
netstat -lntup
输出示例:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program
tcp6 0 0 10.104.2.184:20007 :::* LISTEN 1182/java
udp6 0 0 10.104.2.184:20009 :::* 1182/java
👉 说明:
java
进程(PID 1182)在监听20007
(TCP)和20009
(UDP)10.104.2.184
是内网 IP,表示允许内网访问
2. 查看谁在连接 TCP 端口(如 20007)
ss -tnp | grep ':20007'
输出示例:
ESTAB 0 0 10.104.2.184:20007 10.104.11.178:51865 users:(("java",pid=1182,fd=12))
👉 说明:
10.104.11.178
正在连接你的20007
端口- 这是典型的“服务间调用”场景
3.ss
命令参数详解
ss
的参数是 单字母选项,可以组合使用。以下是常见参数说明:
参数 | 全称(含义) | 说明 |
---|---|---|
-l | --listening | 显示监听状态的端口(LISTEN) |
-n | --numeric | 显示数字形式的地址和端口,不解析成域名或服务名(如不把 80 解析为 http) |
-t | --tcp | 显示 TCP 协议的连接 |
-u | --udp | 显示 UDP 协议的连接 |
-p | --processes | 显示使用该连接的进程信息(PID 和程序名) |
3. 查看谁在向 UDP 端口发数据(如 20009)
UDP 没有“连接状态”,必须用 tcpdump
抓包:
tcpdump -i any -n -c 10 'udp and dst port 20009'
输出示例:
IP 10.104.11.178.51865 > 10.104.2.184.20009: UDP, length 1440
IP 10.104.33.6.59928 > 10.104.2.184.20009: UDP, length 144
👉 说明:
10.104.11.178
和10.104.33.6
正在向你发送数据- 你的服务是 UDP 服务端(如心跳、配置同步)
4. 抓多个 UDP 端口(批量监控)
tcpdump -i any -n -c 10 'udp and (port 20009 or port 20010 or port 20012 or port 20013)'
⚠️ 注意:不要写成
200010
(这是 20万10),正确是20010
(2万零10)
5. 只看“入站”流量(别人发给你)
# 只抓目标是你服务器的包
tcpdump -i any -n 'udp and (dst port 20009 or dst port 20010)'
6. 排除自己发出的包(避免干扰)
# 排除从本机发出的 UDP 包
tcpdump -i any -n 'udp and (port 20009 or port 20010) and not src host 10.104.2.184'
7. 统计 UDP 数据来源 IP(批量分析)
timeout 10 tcpdump -i any -n -nn -l udp 'dst port 20009' 2>/dev/null | \
awk '{print $3}' | cut -d'>' -f1 | sort | uniq -c | sort -nr
输出:
8 10.104.11.1785 10.104.33.63 10.104.5.35
👉 表示:
10.104.11.178
发了 8 次包,是主要客户端
四、如何查看“我的程序连接了谁”(出站连接)
1. 使用 lsof
查看某进程的连接
lsof -p 1182 | grep ESTABLISHED
输出示例:
java 1182 root 15u IPv6 123456 0t0 TCP 10.104.2.184:54220->10.104.7.2:20009 (ESTABLISHED)
👉 说明:
- 你的 Java 程序正在连接
10.104.7.2:20009
- 这可能是上报、转发或服务发现
2. 使用 ss
查看出站连接
ss -tnp | grep '1182'
或按目标 IP/端口过滤:
ss -tnp | grep '10.104.7.2:20009'
3. 使用 netstat
(旧系统)
netstat -tnp | grep 1182
五、tcpdump
实战:谁在连接我?我在连谁?
场景 1:抓“谁在连我”(入站)
# TCP:谁在连接我的 20007 端口(SYN 包)
tcpdump -i any -n 'tcp and dst port 20007 and (tcp[tcpflags] & tcp-syn) != 0'# UDP:谁在向 20009 发包
tcpdump -i any -n 'udp and dst port 20009'
场景 2:抓“我在连谁”(出站)
# 我的程序从本地 54220 端口发起连接
tcpdump -i any -n 'src port 54220'# 或看我连了哪个外部 IP
tcpdump -i any -n 'dst host 10.104.7.2'
场景 3:监控双向通信
# 监控与某个服务的全部通信
tcpdump -i any -n 'host 10.104.7.2 and port 20009'
六、一键诊断脚本:check_connections.sh
#!/bin/bash
echo "=== 当前时间 ==="
dateecho -e "\n=== 监听端口 ==="
ss -lntupecho -e "\n=== TCP 入站连接统计(来源 IP)==="
ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10echo -e "\n=== UDP 数据来源(最近10秒)==="
echo "抓包中...(请稍等)"
timeout 10 tcpdump -i any -n -nn -l udp 'dst port 20009 or dst port 20010' 2>/dev/null | \
awk '{print $3}' | cut -d'>' -f1 | sort | uniq -c | sort -nr || echo "无 UDP 流量"echo -e "\n=== 出站连接(ESTABLISHED)==="
ss -tn | grep ESTAB | awk '{print $5}' | sort | uniq -c | sort -nr | head -10echo -e "\n=== 本地监听服务 ==="
ss -lntup | grep -v '127.0.0.1' | grep -v '::1' || echo "无非本地监听"
使用方法:
chmod +x check_connections.sh
./check_connections.sh
七、附录:常见端口用途参考
端口 | 协议 | 常见用途 |
---|---|---|
22 | TCP | SSH |
80/443 | TCP | HTTP/HTTPS |
3306 | TCP | MySQL |
6379 | TCP | Redis |
9092 | TCP | Kafka |
20007~20013 | UDP/TCP | 自定义监控、游戏、配置服务 |
总结:一句话记住
你想知道 | 使用命令 |
---|---|
我监听了哪些端口? | ss -lntup |
谁在连我的 TCP 服务? | ss -tnp | grep :端口 |
谁在向我的 UDP 端口发数据? | tcpdump -i any -n udp dst port <端口> |
我的程序连接了谁? | lsof -p <PID> 或 ss -tnp |
统计连接来源? | ss / tcpdump + awk + sort + uniq |