📢 你是否遇到過這些問題?
- 接手一個老項目,只有服務器賬號,沒有架構圖?
- 服務突然異常,但不知道它依賴哪些外部系統?
- 想畫數據流向圖,卻找不到文檔?
別擔心!只要你有 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 |