一、为什么要用Snort的嗅探器模式
搞网络运维和问题排查的时候,大家手里最常用的可能就是ping和telnet,但这两个命令只能告诉你通不通,不能告诉你数据包里到底放了什么。真正想弄清一台服务器为什么响应慢,某个内网主机是不是在偷偷往外传数据,还是得回到最原始的方法:把经过网卡的数据包抓下来,一个一个拆开看。Snort作为一个老牌的入侵检测系统,很多人都知道它能根据规则报警,却很少用它的嗅探器模式。其实这个模式非常轻量,不需要写任何规则,几个参数就能把网络中的原始流量在终端上展示出来,用来做临场分析特别顺手。
1.1 嗅探器模式到底能干什么
Snort有三种经典运行方式:嗅探器、包记录、网络入侵检测。嗅探器模式说简单点,就是把网卡上收到的数据包直接打印出来,让你看着屏幕就能知道谁在和谁通信、用了什么协议、端口是多少、流量长什么样。比如你想知道某台开发机在启动时是不是偷偷联网,用这个模式就能一清二楚。
1.2 和普通抓包工具的区别
可能你会说,抓包不是还有别的工具吗?tcpdump确实也很好用,但Snort在输出格式上做了优化,它能以相对容易阅读的方式展示网络层和传输层的头信息,还能把应用层的内容一起列出来。对于已经熟悉Snort的人来说,多一个工具就多一种解决问题的角度,而且Snort的规则语法里有很多和BPF相关的写法,学会了嗅探器模式,也为以后写检测规则打下基础。
二、准备一个最简单的Snort环境
2.1 安装Snort
在Ubuntu上安装Snort非常快,只需一条命令。需要注意的是,Snort需要以root权限运行,因为它要打开原始套接字读取网卡数据。
# 技术栈:Snort + Shell
# 更新软件包索引
sudo apt update
# 安装Snort
sudo apt install -y snort
# 验证安装是否成功
snort -V
安装过程中,安装程序可能会让你选择网卡,没有特别需求的话按默认走就行。装好之后,可以用snort -V看看版本,确认命令已经可以用了。
2.2 让网卡进入混杂模式
普通网卡在默认情况下只会把目的地址是它自己的报文交给系统处理,但做流量分析往往需要看到整个局域网里的包,这时候就要打开混杂模式。Snort在嗅探器模式下会自动把指定的网卡切换成混杂模式,所以你不必手动操作。但如果想验证当前网卡状态,可以用下面的命令:
# 技术栈:Snort + Shell
# 查看eth0网卡状态,UP表示已启用
ip link show eth0
# 手动打开混杂模式(一般用不到,Snort会自动做)
sudo ip link set eth0 promisc on
注意:在公共网络或者没有授权的网络上进行抓包,可能涉及隐私和法律问题,最好只在你自己管理的网络或试验环境里操作。
三、Snort嗅探器模式的核心命令参数
3.1 从终端打印包头信息
最简单的命令就是在指定网卡上开启监听,然后用v参数打印TCP/IP头的摘要信息。我们来看一个最基本的例子:
# 技术栈:Snort + Shell
# -i指定网卡,-v表示把包头信息打印到终端
sudo snort -i eth0 -v
运行后,终端会不停滚出类似下面的内容(这里以一段HTTP访问流量为例):
# 技术栈:Snort + Shell
# 终端输出示例,注意这只是一个片段
10/10-15:24:11.842530 192.168.1.10:54321 -> 192.168.1.20:80
TCP TTL:64 TOS:0x0 ID:1234 IpLen:20 DgmLen:60 DF
***A**** Seq: 0xA1B2C3D4 Ack: 0x11223344 Win: 0x2000
这里每一行都包含时间戳、源IP和端口、目的IP和端口,然后是TCP的详细字段。如果只是确认网络通不通、端口有没有在听,这个输出已经足够了。
3.2 把应用层数据也显示出来
只看包头抓不到细节,比如HTTP请求的网址、POST的参数、桌面协议发出来的一大串字符串。只要加上d参数,Snort就会把包的应用层载荷一起打印出来。组合使用vd效果更好,一行命令既看头又看数据:
# 技术栈:Snort + Shell
# -v显示包头,-d显示应用层数据
sudo snort -i eth0 -vd
这个命令在排查“某个程序往服务器发了什么内容”时特别有用。比如你能直接在输出里看到GET /api/login HTTP/1.1这样的字符串,立刻明白客户端在请求什么。
3.3 显示链路层头信息
如果连MAC地址、以太网类型这些二层信息也需要看,可以再加上e参数。三层组合vde是嗅探器模式下最完整的输出形式,适合排查交换网络里的ARP欺骗或原始以太网帧异常。
# 技术栈:Snort + Shell
# -e表示打印数据链路层信息,加上vd后看到的内容非常全
sudo snort -i eth0 -vde
不过输出全也意味着信息量很大,屏幕滚动快,这个时候我们可以配合后面的BPF过滤器来精确定位。
四、用BPF过滤器精确定位你关心的流量
4.1 BPF是什么
BPF全称是Berkeley Packet Filter,它是一套用来过滤数据包的规则表达式。Snort的命令行直接支持在末尾写BPF表达式,而且不用引号也可以,但为了避免Shell把特殊字符解释掉,建议用单引号包起来。这个过滤器本质上就是一组布尔条件,只有满足条件的包才会被打印或记录。
4.2 按IP和端口过滤
比如我只关心来自某个IP的流量,就可以在命令后面写host关键字。也可以组合多个条件,比如只看某个网段的流量访问指定端口。
# 技术栈:Snort + Shell
# 只看192.168.1.100发起的流量
sudo snort -i eth0 -v 'host 192.168.1.100'
# 只看访问22端口且来自内网网段的TCP包
sudo snort -i eth0 -vd 'tcp and dst port 22 and src net 192.168.1.0/24'
这里要注意,BPF表达式中条件之间默认是“与”的关系,想表达“或者”的时候要显式写or。实际使用中,把host、net、port、tcp、udp这些关键字组合起来,就能覆盖绝大多数过滤需求。
4.3 按TCP标志位过滤
TCP协议里有很多标志位,比如SYN、ACK、FIN。想要过滤出连接建立时的SYN包,可以直接操作TCP头里的偏移量。下面的表达式表示“TCP头的第13个字节和0x02做按位与,结果不为0”,也就是SYN位被置1的包。
# 技术栈:Snort + Shell
# 只看SYN包,tcp[13]取的是TCP头第13个字节(从0开始编号)
sudo snort -i eth0 -v 'tcp and tcp[13] & 0x02 != 0'
如果你对TCP头结构不熟悉,这个看着有点唬人,但其实原理很简单:TCP标志位都集中在一个字节的各个位上,0x02对应的二进制是00000010,正好是SYN位的位置。把那个字节和0x02做按位与,如果结果不等于0,说明SYN位被置位了。
五、把抓到的包保存成pcap文件
5.1 保存到磁盘
终端输出虽然直观,但流量一大就会疯狂滚动,根本来不及看。更靠谱的做法是把数据包保存下来,再用Snort读取它慢慢分析。Snort用l参数指定保存目录,用b参数表示以二进制pcap格式写文件。如果只用l目录而不加b,Snort会生成ASCII日志,但不利于后续用r参数精确分析,所以保存原始包时一定要记得加b。
# 技术栈:Snort + Shell
# 创建目录用来存放抓包文件
sudo mkdir -p /tmp/snortcap
# -l指定输出目录,-b表示二进制模式
# 这里的BPF条件只抓取80端口且包含SYN标志的包
sudo snort -i eth0 -l /tmp/snortcap -b 'tcp and dst port 80 and tcp[13] & 0x02 != 0'
运行一段时间后按Ctrl+C停止,Snort会在/tmp/snortcap目录下生成一个名为snort.log.一串数字的文件。文件名里的数字是Unix时间戳。
5.2 回放pcap文件
抓到文件之后,可以用r参数读取,并再次用v等方式输出到终端。这样即使流量包已经抓完,你也可以反复研究,不用担心线上流量干扰。
# 技术栈:Snort + Shell
# 先看一下生成了什么文件
ls -l /tmp/snortcap
# 读取刚才保存的pcap文件,并打印包头和应用层数据
sudo snort -r /tmp/snortcap/snort.log.1700000000 -vd
# 如果只想从pcap中再看某个IP的包,也可以叠加BPF过滤
sudo snort -r /tmp/snortcap/snort.log.1700000000 -v 'host 192.168.1.20'
这里r参数后面要写真实的文件名,先用ls看一眼目录里的文件再执行,不要照抄。
六、一个实际问题:内网主机大量外联的定位过程
下面用一个非常常见的例子把前面的命令串起来。某天公司内网突然很卡,防火墙日志显示来自192.168.1.50这台主机有大量出站连接,怀疑它中了木马或者有后台程序在扫描外网。我们要用Snort的嗅探器模式来抓包确认。
6.1 第一步:确认流量方向
先看来自这台主机、主动向外发出的流量。注意我们要看的是源地址,所以过滤器写成src host,如果写成host就会把双向流量都包含进来,不好分辨是谁先发的。
# 技术栈:Snort + Shell
# 抓取192.168.1.50发起的所有TCP连接
sudo snort -i eth0 -v 'src host 192.168.1.50 and tcp'
这时屏幕上会快速刷出大量记录。如果一个包被重复打印且带有SYN、ACK等标志,说明连接建立过程有重传,很可能是对端网络不可达或主动丢弃了连接。
6.2 第二步:过滤出SYN连接包
为了更清楚地看到它到底想连哪些地址,我们进一步过滤,只保留SYN包。SYN是TCP连接建立的第一个包,代表一种“想连你”的意图。
# 技术栈:Snort + Shell
# 过滤SYN包,看看这台机器正在主动连接哪些地址
sudo snort -i eth0 -vd 'src host 192.168.1.50 and tcp and tcp[13] & 0x02 != 0'
抓一段时间后按Ctrl+C,然后看终端记录的源IP和目的IP。如果你的终端已经打印了很多信息,可以把输出重定向到文件再慢慢看,但注意重定向命令要用sudo,否则写文件会报权限问题。
# 技术栈:Snort + Shell
# 把输出保存到文本文件,避免刷屏
sudo snort -i eth0 -v 'src host 192.168.1.50 and tcp' > /tmp/snort_output.txt 2>&1
这里使用2>&1把错误也一并写入,方便排查。
6.3 第三步:观察端口变化
看了一会儿之后,你可能会发现192.168.1.50在短时间内连续访问了不同IP的同一端口,比如目标端口都是3389或445。这是一种典型的扫描行为。如果目标端口是80和443,也可能是正常上网,但大量短连接同时出现就不太正常了。通过Snort打印出来的TCP窗口、序列号,还能进一步判断是不是工具在自动发送。
这里再补充一个技巧:如果想确认这台机器和某个固定目标之间是否有大量重传,可以用下面的过滤器把源和目的都固定下来,然后加上vd观看。
# 技术栈:Snort + Shell
# 只看192.168.1.50与流量中一个可疑地址之间的双向包
sudo snort -i eth0 -vd 'host 192.168.1.50 and host 203.0.113.7'
如果刷出来的包中反复出现相同的TCP序列号,说明对端没有正确回复,这是网络故障或对方防火墙丢包的一个强信号。到这里,我们基本上就能给网络管理员一个可靠的判断:这台机器确实在主动向外发起异常连接,需要进一步查杀或断网隔离。
七、应用场景、优点缺点与注意事项
7.1 典型的应用场景
Snort嗅探器模式适合用在:线上服务出问题时快速抓包确认;在无法安装图形界面的服务器上直接查看流量;对某个IP进行短时间监控;把可疑流量保存成pcap文件留作证据;以及学习TCP/IP协议时自己抓包试验。很多运维事故的根因,都是靠这种“什么也不管,先抓下来看五分钟”的方式找到的。
7.2 优点和局限
优点很明显:命令简单、上手快;不需要写规则文件;输出格式中头部信息非常齐全;支持BPF,过滤灵活;还能保存成标准pcap格式。局限也很明显:它只能抓包和显示,没有流重组和统计分析能力,数据量一大,人眼根本看不过来。所以它适合作为临场分析工具,而不是长期监控方案。长期监控还是需要把包保存下来或者用NIDS模式配合规则去报警。
7.3 注意事项
第一,抓包必须获得网络管理者的授权,不要在自己不拥有的网络上乱抓。第二,i参数指定的网卡必须真实存在,可以用ip link查。第三,b参数保存的文件是二进制pcap,不要用cat直接看。第四,Ctrl+C停止时,Snort会输出一段统计信息,比如接收了多少包、分析了多少包,统计信息对判断丢包率很有用。第五,如果在虚拟机的网卡上抓包,可能看到VXLAN或vSwitch的封装流量,这是正常现象,不要当作异常。
八、总结
Snort的嗅探器模式看起来简单,实际用好了能解决很多棘手问题。从最基础的vd,到组合BPF过滤,再到保存pcap回放,其实只需要掌握几个核心参数。遇到网络慢、连接异常、有机器偷偷外联,不妨打开终端,用Snort看一眼真实的流量。很多时候,问题的答案就藏在一个个数据包里。真正动手抓一次,你就会发现网络分析没有想象中那么神秘,Snort这个老工具也依然能在关键时刻派上大用场。
评论
围绕“Snort嗅探器模式下的网络流量分析实战与问题定位技巧”参与讨论