ngrep 是 Linux 中一个网络数据包抓取与分析 的命令行工具。它结合了 grep 的过滤功能和 tcpdump 的抓包能力,可以实时捕获并过滤网络流量,支持正则表达式匹配,是网络调试和安全分析的实用工具。
📦 安装方法
bash
# Debian/Ubuntu 系统
sudo apt update && sudo apt install ngrep
# RHEL/CentOS 系统
sudo yum install ngrep
# Arch Linux 系统
sudo pacman -S ngrep
# macOS (使用 Homebrew)
brew install ngrep
📖 基本语法
bash
ngrep [选项] [BPF过滤表达式] [匹配表达式]
核心功能:
- 实时捕获网络数据包
- 支持正则表达式过滤
- 显示数据包内容(十六进制和ASCII)
- 支持多种协议和端口过滤
- 保存捕获数据到文件
🎯 常用选项
| 选项 | 说明 |
|---|---|
-i |
忽略大小写。 |
-q |
安静模式,只显示匹配的数据包。 |
-v |
反转匹配,显示不匹配的数据包。 |
-W |
显示格式:byline(按行)、single(单行)、none(无格式)。 |
-t |
显示时间戳。 |
-T |
显示相对时间戳。 |
-c |
匹配指定次数的数据包后退出。 |
-n |
匹配指定数量的数据包后退出。 |
-l |
使用行缓冲输出。 |
-d |
指定网络接口。 |
-p |
不使用混杂模式。 |
-s |
设置抓取数据包的长度(snaplen)。 |
-S |
限制匹配字符串的长度。 |
-w |
匹配整个单词。 |
-x |
以十六进制和ASCII显示数据包内容。 |
-X |
以十六进制显示数据包内容。 |
-O |
将匹配的数据包保存到文件。 |
-I |
从文件读取数据包(离线分析)。 |
-N |
显示子协议信息(如HTTP方法)。 |
-P |
设置匹配模式:and(与)、or(或)。 |
-A |
显示匹配行后的行数。 |
-B |
显示匹配行前的行数。 |
🌐 协议和端口过滤
| 表达式 | 说明 |
|---|---|
port 80 |
过滤80端口。 |
host 192.168.1.1 |
过滤指定主机。 |
net 192.168.1.0/24 |
过滤指定网络。 |
tcp |
只捕获TCP流量。 |
udp |
只捕获UDP流量。 |
icmp |
只捕获ICMP流量。 |
src host 192.168.1.1 |
过滤源主机。 |
dst host 192.168.1.1 |
过滤目标主机。 |
src port 80 |
过滤源端口。 |
dst port 80 |
过滤目标端口。 |
💡 核心用法示例
1. 基本抓包
bash
# 捕获所有网络流量(按Ctrl+C停止)
ngrep
# 捕获所有流量,显示时间戳
ngrep -t
# 捕获所有流量,显示相对时间戳
ngrep -T
# 捕获所有流量,以十六进制和ASCII显示
ngrep -x
# 捕获所有流量,只显示匹配的数据包
ngrep -q
2. 端口过滤
bash
# 捕获80端口(HTTP)流量
ngrep port 80
# 捕获443端口(HTTPS)流量
ngrep port 443
# 捕获53端口(DNS)流量
ngrep port 53
# 捕获25端口(SMTP)流量
ngrep port 25
# 捕获21端口(FTP)流量
ngrep port 21
# 捕获22端口(SSH)流量
ngrep port 22
# 捕获3306端口(MySQL)流量
ngrep port 3306
# 捕获5432端口(PostgreSQL)流量
ngrep port 5432
# 捕获27017端口(MongoDB)流量
ngrep port 27017
# 捕获6379端口(Redis)流量
ngrep port 6379
3. 主机过滤
bash
# 捕获与指定主机的所有流量
ngrep host 192.168.1.100
# 捕获来自指定主机的流量
ngrep src host 192.168.1.100
# 捕获发往指定主机的流量
ngrep dst host 192.168.1.100
# 捕获两个主机间的流量
ngrep host 192.168.1.100 and host 192.168.1.200
4. 协议过滤
bash
# 捕获所有TCP流量
ngrep tcp
# 捕获所有UDP流量
ngrep udp
# 捕获所有ICMP流量
ngrep icmp
# 捕获TCP且端口80的流量
ngrep tcp and port 80
# 捕获UDP且端口53的流量
ngrep udp and port 53
5. 内容匹配
bash
# 捕获包含"password"的数据包
ngrep password
# 捕获包含"GET"或"POST"的数据包
ngrep "GET|POST"
# 捕获包含"error"的数据包,忽略大小写
ngrep -i error
# 捕获包含"admin"的整个单词
ngrep -w admin
# 捕获包含"user"但不包含"test"的数据包
ngrep user | grep -v test
# 使用正则表达式匹配邮箱
ngrep "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
# 匹配JSON格式的数据
ngrep "\{[^}]*\}"
# 匹配XML格式的数据
ngrep "<[^>]+>.*</[^>]+>"
6. 高级过滤组合
bash
# 捕获80端口且包含"login"的数据包
ngrep login port 80
# 捕获443端口且包含"cookie"的数据包
ngrep -i cookie port 443
# 捕获指定主机80端口的POST请求
ngrep "POST" host 192.168.1.100 and port 80
# 捕获DNS查询包含"google"的数据包
ngrep google port 53
# 捕获MySQL查询包含"SELECT"的数据包
ngrep SELECT port 3306
# 捕获Redis命令包含"GET"的数据包
ngrep GET port 6379
7. 输出控制
bash
# 捕获10个数据包后退出
ngrep -n 10
# 捕获5个匹配"error"的数据包后退出
ngrep -c 5 error
# 按行显示数据包内容
ngrep -W byline
# 单行显示数据包内容
ngrep -W single
# 显示匹配行前后的内容
ngrep -A 2 -B 2 password
# 限制匹配字符串长度为100
ngrep -S 100
# 设置抓取数据包长度为1024字节
ngrep -s 1024
8. 接口和文件操作
bash
# 指定网络接口(如eth0)
ngrep -d eth0
# 指定无线接口(如wlan0)
ngrep -d wlan0
# 指定回环接口
ngrep -d lo
# 从文件读取数据包进行分析
ngrep -I capture.pcap
# 将匹配的数据包保存到文件
ngrep -O output.pcap password
# 不使用混杂模式
ngrep -p
🔍 实用场景示例
场景1:HTTP流量监控
bash
# 监控所有HTTP请求
ngrep -q -W byline "^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH) " port 80
# 监控HTTP请求头中的User-Agent
ngrep -i "user-agent:" port 80
# 监控HTTP响应状态码
ngrep "HTTP/1.[01] (200|404|500|302)" port 80
# 监控HTTP请求中的敏感信息
ngrep -i "(password|token|auth|key|secret)" port 80
# 监控HTTP Cookie
ngrep -i "cookie:" port 80
# 监控HTTP Referer
ngrep -i "referer:" port 80
# 监控HTTP Content-Type
ngrep -i "content-type:" port 80
场景2:DNS查询监控
bash
# 监控所有DNS查询
ngrep -q port 53
# 监控包含特定域名的DNS查询
ngrep "google.com" port 53
# 监控DNS A记录查询
ngrep "IN.*A" port 53
# 监控DNS MX记录查询
ngrep "IN.*MX" port 53
# 监控DNS TXT记录查询
ngrep "IN.*TXT" port 53
场景3:数据库流量分析
bash
# 监控MySQL查询
ngrep -q -W byline port 3306
# 监控MySQL SELECT语句
ngrep -i "select" port 3306
# 监控MySQL INSERT语句
ngrep -i "insert" port 3306
# 监控MySQL UPDATE语句
ngrep -i "update" port 3306
# 监控MySQL DELETE语句
ngrep -i "delete" port 3306
# 监控PostgreSQL查询
ngrep -q -W byline port 5432
# 监控MongoDB查询
ngrep -q -W byline port 27017
# 监控Redis命令
ngrep -q -W byline port 6379
场景4:安全监控
bash
# 监控SSH连接尝试
ngrep "SSH-" port 22
# 监控FTP登录尝试
ngrep "USER|PASS" port 21
# 监控SMTP认证
ngrep "AUTH LOGIN" port 25
# 监控可疑SQL注入尝试
ngrep -i "(union|select|insert|update|delete|drop|exec|--|#|/\\*)" port 80
# 监控XSS攻击尝试
ngrep -i "(<script|javascript:|onerror=|onload=)" port 80
# 监控文件包含尝试
ngrep -i "(\.\./|\.\.\\|etc/passwd|windows/win.ini)" port 80
# 监控命令注入尝试
ngrep -i "(system\(|exec\(|popen\(|shell_exec\(|passthru\()" port 80
场景5:应用调试
bash
# 监控API请求
ngrep "/api/" port 80
# 监控特定API端点
ngrep "/api/v1/users" port 80
# 监控JSON格式的请求体
ngrep "\{.*\}" port 80
# 监控XML格式的请求体
ngrep "<.*>" port 80
# 监控错误响应
ngrep -i "\"error\"" port 80
# 监控特定用户会话
ngrep "session_id=abc123" port 80
# 监控文件上传
ngrep -i "multipart/form-data" port 80
📊 输出解读示例
示例输出:
T 192.168.1.100:54321 -> 192.168.1.1:80 [AP]
GET /index.html HTTP/1.1.
Host: example.com.
User-Agent: Mozilla/5.0.
Accept: text/html.
字段说明:
- T:TCP数据包(U表示UDP,I表示ICMP)
- 192.168.1.100:54321:源IP地址和端口
- 192.168.1.1:80:目标IP地址和端口
- [AP]:TCP标志(A=ACK,P=PSH,S=SYN,F=FIN,R=RST)
- 后续行:数据包内容(以点号.表示换行)
十六进制输出示例:
bash
ngrep -x port 80
输出:
T 192.168.1.100:54321 -> 192.168.1.1:80 [AP]
47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1..
48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 6f Host: example.co
6d 0d 0a 0d 0a m....
🔧 实用脚本示例
脚本1:HTTP请求监控脚本
bash
#!/bin/bash
# HTTP请求监控脚本
INTERFACE="eth0"
PORT="80"
LOG_FILE="http_requests_$(date +%Y%m%d_%H%M%S).log"
PATTERNS=("GET" "POST" "PUT" "DELETE" "HEAD" "OPTIONS" "PATCH")
echo "HTTP请求监控开始 $(date)" | tee "$LOG_FILE"
echo "接口: $INTERFACE, 端口: $PORT" | tee -a "$LOG_FILE"
echo "======================================" | tee -a "$LOG_FILE"
# 构建匹配模式
PATTERN=""
for method in "${PATTERNS[@]}"; do
if [ -z "$PATTERN" ]; then
PATTERN="$method"
else
PATTERN="$PATTERN|$method"
fi
done
echo "监控模式: $PATTERN" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# 开始监控
ngrep -d "$INTERFACE" -q -W byline -t "^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH) " port "$PORT" | while read -r line; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 提取请求信息
if echo "$line" | grep -q "^T.*->.*\[AP\]"; then
src=$(echo "$line" | awk '{print $2}')
dst=$(echo "$line" | awk '{print $4}')
echo "[$timestamp] $src -> $dst" | tee -a "$LOG_FILE"
elif echo "$line" | grep -q "^ [A-Z]"; then
echo " $line" | tee -a "$LOG_FILE"
fi
done
脚本2:敏感信息泄露检测
bash
#!/bin/bash
# 敏感信息泄露检测脚本
INTERFACE="eth0"
PORT="80"
SENSITIVE_PATTERNS=(
"password="
"token="
"auth="
"key="
"secret="
"api_key="
"access_token="
"refresh_token="
"credit_card="
"ssn="
"social_security="
"phone="
"email="
"address="
)
LOG_FILE="sensitive_leaks_$(date +%Y%m%d_%H%M%S).log"
ALERT_FILE="alerts_$(date +%Y%m%d_%H%M%S).log"
echo "敏感信息泄露检测开始 $(date)" | tee "$LOG_FILE"
echo "接口: $INTERFACE, 端口: $PORT" | tee -a "$LOG_FILE"
echo "======================================" | tee -a "$LOG_FILE"
# 构建匹配模式
PATTERN=""
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
if [ -z "$PATTERN" ]; then
PATTERN="$pattern"
else
PATTERN="$PATTERN|$pattern"
fi
done
echo "检测模式: $PATTERN" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# 开始检测
ngrep -d "$INTERFACE" -q -W byline -t -i "$PATTERN" port "$PORT" | while read -r line; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 检查是否为新数据包
if echo "$line" | grep -q "^T.*->.*\[AP\]"; then
src=$(echo "$line" | awk '{print $2}')
dst=$(echo "$line" | awk '{print $4}')
echo "[$timestamp] 检测到敏感信息传输" | tee -a "$LOG_FILE"
echo " 来源: $src" | tee -a "$LOG_FILE"
echo " 目标: $dst" | tee -a "$LOG_FILE"
# 记录警报
echo "[$timestamp] 警报: 敏感信息泄露" >> "$ALERT_FILE"
echo " 来源: $src" >> "$ALERT_FILE"
echo " 目标: $dst" >> "$ALERT_FILE"
elif echo "$line" | grep -q " .*="; then
echo " 内容: $line" | tee -a "$LOG_FILE"
echo " 内容: $line" >> "$ALERT_FILE"
# 提取可能的敏感值
sensitive_line=$(echo "$line" | grep -o "[^ ]*=[^ ]*")
echo " 提取: $sensitive_line" | tee -a "$LOG_FILE"
echo " 提取: $sensitive_line" >> "$ALERT_FILE"
fi
echo "" | tee -a "$LOG_FILE"
done
脚本3:网络流量统计分析
bash
#!/bin/bash
# 网络流量统计分析脚本
INTERFACE="eth0"
DURATION=60 # 监控时长(秒)
LOG_FILE="traffic_analysis_$(date +%Y%m%d_%H%M%S).log"
# 协议统计数组
declare -A protocol_count
declare -A port_count
declare -A host_count
echo "网络流量统计分析开始 $(date)" | tee "$LOG_FILE"
echo "接口: $INTERFACE, 时长: ${DURATION}秒" | tee -a "$LOG_FILE"
echo "======================================" | tee -a "$LOG_FILE"
# 临时文件
TEMP_FILE="/tmp/ngrep_output_$$.log"
# 启动ngrep后台进程
ngrep -d "$INTERFACE" -q -t -n 1000 "" > "$TEMP_FILE" 2>&1 &
NGRERP_PID=$!
# 等待指定时长
echo "正在捕获流量,请等待 ${DURATION}秒..." | tee -a "$LOG_FILE"
sleep "$DURATION"
# 停止ngrep
kill -INT "$NGRERP_PID" 2>/dev/null
wait "$NGRERP_PID" 2>/dev/null
echo "流量捕获完成,开始分析..." | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# 分析协议分布
echo "1. 协议分布统计:" | tee -a "$LOG_FILE"
tcp_count=$(grep -c "^T" "$TEMP_FILE")
udp_count=$(grep -c "^U" "$TEMP_FILE")
icmp_count=$(grep -c "^I" "$TEMP_FILE")
total_count=$((tcp_count + udp_count + icmp_count))
if [ "$total_count" -gt 0 ]; then
tcp_percent=$(echo "scale=2; $tcp_count * 100 / $total_count" | bc)
udp_percent=$(echo "scale=2; $udp_count * 100 / $total_count" | bc)
icmp_percent=$(echo "scale=2; $icmp_count * 100 / $total_count" | bc)
echo " TCP: $tcp_count ($tcp_percent%)" | tee -a "$LOG_FILE"
echo " UDP: $udp_count ($udp_percent%)" | tee -a "$LOG_FILE"
echo " ICMP: $icmp_count ($icmp_percent%)" | tee -a "$LOG_FILE"
echo " 总计: $total_count 个数据包" | tee -a "$LOG_FILE"
else
echo " 未捕获到数据包" | tee -a "$LOG_FILE"
fi
echo "" | tee -a "$LOG_FILE"
# 分析端口分布
echo "2. 常用端口流量统计:" | tee -a "$LOG_FILE"
common_ports=("80:HTTP" "443:HTTPS" "53:DNS" "22:SSH" "25:SMTP" "21:FTP" "3306:MySQL" "5432:PostgreSQL" "27017:MongoDB" "6379:Redis")
for port_info in "${common_ports[@]}"; do
port=$(echo "$port_info" | cut -d: -f1)
service=$(echo "$port_info" | cut -d: -f2)
port_traffic=$(grep -c ":$port\]" "$TEMP_FILE")
if [ "$port_traffic" -gt 0 ]; then
echo " 端口 $port ($service): $port_traffic 个数据包" | tee -a "$LOG_FILE"
fi
done
echo "" | tee -a "$LOG_FILE"
# 分析主机通信
echo "3. 主机通信统计:" | tee -a "$LOG_FILE"
echo " 通信最多的源主机:" | tee -a "$LOG_FILE"
grep "^[TUI]" "$TEMP_FILE" | awk '{print $2}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -5 | while read count host; do
echo " $host: $count 个数据包" | tee -a "$LOG_FILE"
done
echo "" | tee -a "$LOG_FILE"
echo " 通信最多的目标主机:" | tee -a "$LOG_FILE"
grep "^[TUI]" "$TEMP_FILE" | awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -5 | while read count host; do
echo " $host: $count 个数据包" | tee -a "$LOG_FILE"
done
echo "" | tee -a "$LOG_FILE"
# 分析内容特征
echo "4. 内容特征分析:" | tee -a "$LOG_FILE"
echo " HTTP请求方法分布:" | tee -a "$LOG_FILE"
http_methods=("GET" "POST" "PUT" "DELETE" "HEAD" "OPTIONS" "PATCH")
for method in "${http_methods[@]}"; do
count=$(grep -c " $method " "$TEMP_FILE")
if [ "$count" -gt 0 ]; then
echo " $method: $count 次" | tee -a "$LOG_FILE"
fi
done
echo "" | tee -a "$LOG_FILE"
# 清理临时文件
rm -f "$TEMP_FILE"
echo "======================================" | tee -a "$LOG_FILE"
echo "分析完成 $(date)" | tee -a "$LOG_FILE"
echo "详细日志已保存到: $LOG_FILE" | tee -a "$LOG_FILE"
⚠️ 重要注意事项
- 权限要求 :需要 root 权限或
CAP_NET_RAW能力来捕获网络数据包。 - 性能影响:在高流量网络中使用可能影响系统性能。
- 隐私问题:可能捕获敏感信息,需遵守法律法规。
- 加密流量:无法解密 HTTPS 等加密流量内容。
- 网络模式:默认使用混杂模式,可能捕获所有网络流量。
- 输出格式 :
-W byline选项使输出更易读,但可能影响性能。
🔄 相关命令对比
| 命令 | 用途 | 特点 |
|---|---|---|
ngrep |
网络数据包抓取与过滤 | 支持正则表达式,类似 grep |
tcpdump |
网络数据包抓取 | 功能强大,支持复杂过滤 |
wireshark |
图形化数据包分析 | 功能全面,支持深度分析 |
tshark |
命令行版 Wireshark | 功能强大,输出格式丰富 |
netcat |
网络调试工具 | 简单网络连接测试 |
🎯 最佳实践
- 精确过滤:使用具体的 BPF 表达式减少不必要的数据包捕获。
- 输出重定向:将输出保存到文件以便后续分析。
- 正则优化:使用高效的正则表达式减少性能开销。
- 权限管理:在生产环境中谨慎使用,避免隐私泄露。
- 实时监控 :结合
watch命令进行实时监控。 - 组合使用 :与其他工具如
grep、awk、sed结合进行深度分析。
ngrep 是网络调试和安全分析的强大工具,特别适合需要快速过滤和分析网络流量的场景。通过灵活使用过滤表达式和正则匹配,可以高效地监控特定类型的网络通信。