ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kali Linux 上 Snort 安装配置与规则编写实战:从告警到排查

Kali Linux 上 Snort 安装配置与规则编写实战:从告警到排查 1. 先把方案定下来装 Snort 之前必须想明白的四件事在 Kali 上把 Snort 跑起来属于那种看教程十分钟、自己动手三小时的事情。Snort 是一款开源的网络入侵检测系统工作在被动监听的位置上把经过网卡的流量按规则一条条比对命中了就产生告警。它不主动发包、不修改数据、不干预通信本质上是给网络装了一双盯着异常的眼睛。放在 Kali 上用它最常见的场景就是你已经有了一台 Kali 虚拟机或者物理机想给自己搭的实验网段加一层流量审计能力看看有没有扫描、异常连接、可疑的探测行为顺便练一练规则编写。这篇内容适合三类人刚接触网络安全、想找一个能立刻看到效果的实战项目练手的新手已经会用抓包工具、但没系统写过检测规则的中级玩家以及需要在实验环境里做流量审计、但又不想上重型平台的人。下面所有操作我都默认你是在自己拥有完全控制权的实验网络里做别往生产网或者别人的网络里套。1.1 Snort 解决的是什么问题为什么要在 Kali 上跑很多人第一次接触 Snort 会有个误解觉得它是抓包工具跟 Wireshark 差不多。这两者的区别其实很大。Wireshark 是给人看的你要点开每一个包、一层层展开协议树靠眼睛去发现问题Snort 是给规则看的它在你睡觉的时候也能一条条比对流量特征命中就落一条告警日志。前者是显微镜后者是报警器。抓包工具解决我要看清楚这个包长什么样Snort 解决我要在没人盯着的时候也能知道网络里发生了什么值得注意的事。那为什么偏偏放在 Kali 上因为 Kali 本身已经预置了大量网络分析相关的库和工具链libpcap、tcpdump、抓包权限、网卡配置这些东西基本是开箱即用的状态你不需要再从零搭一套分析环境。而且 Kali 通常以虚拟机形式存在你可以随手把网络模式在 NAT、桥接、Host-Only 之间切换造出各种不同形态的流量来测试自己的规则是否生效这个便利程度是普通 Linux 桌面比不了的。我用得最多的组合就是Kali 一张网卡桥接到实验网段Snort 挂在这张网卡上做检测然后从另一台机器发起各种正常和不正常的访问看 Snort 的告警日志里到底吐出什么。需要提前说清楚一点Snort 的规则匹配是基于特征的。它不会理解这个行为是不是恶意的它只会说这条流量匹配了我写的第 1000001 条规则。所以规则的写法、规则集的取舍直接决定了你看到的是有用信息还是一屏噪声。这也是为什么后面我会花很大篇幅在规则语法和误报调优上而不是只给你一条apt install命令就完事。1.2 Snort 2 和 Snort 3版本差异必须先确认这是新手最容易踩的第一个坑。Snort 目前两条主线并存2.9.x 系列和 3.x 系列。它们的配置文件格式完全不一样——2.9 用/etc/snort/snort.conf这种文本配置规则语法是经典的alert tcp ...风格3.x 换成了 Lua 配置/etc/snort/snort.lua规则虽然尽量兼容旧语法但配置结构、插件加载方式、告警输出都变了。Debian 及其衍生发行版的软件源里snort这个包通常对应的是 2.9 系Debian 打包维护的版本而 Snort 3 在很多源里并不直接提供或者以单独的包名提供。所以在动手之前先做一件事装完之后立刻执行snort -V看版本号再去看/etc/snort/目录下到底有什么文件。snort -V ls -l /etc/snort/如果看到的是snort.conf那你走的是 2.9 路线后面所有配置文件相关的操作都按 2.9 来如果看到的是snort.lua说明你装到了 3.x配置思路要换成 Lua 那一套。我个人的建议是入门阶段优先把 2.9 系玩明白因为它的配置是所见即所得的文本结构变量、预处理、输出插件、规则包含四段式排列逻辑非常直观网上的资料也最厚。等你把规则语法吃透了再迁到 3.x那时候你关注的只是配置语法怎么写而不是检测逻辑是怎么回事学习曲线会平缓很多。1.3 安装方式apt 一把梭还是源码编译两种方式我都用过各有各的适用场景别听人说源码编译才专业就一头扎进去。apt安装的优点是快、依赖自动处理、有 systemd 服务单元、升级方便缺点是版本被锁死在源里提供的那个版本编译选项也是打包者定的比如你可能想要--enable-sourcefire启用一些额外的检测能力apt 装出来的不一定带。源码编译的优点是版本和编译选项完全可控缺点是依赖得一层层手动装DAQ数据采集库还得先编一遍中间任何一步报错都要自己啃。我的实际建议是这样如果你只是想在实验环境里跑起来、写规则、看告警apt 足够十分钟能搞定把精力花在规则上更划算。如果你明确需要某个特定版本、或者需要自定义编译选项、或者 apt 装出来的版本跟你的规则集不兼容再走源码那条路。下面两条路线我都会给完整命令你可以按需选。1.4 目录规划与数据流开工前先画清楚在 Linux 里装这类工具最忌讳的就是装完了不知道文件散落在哪。我习惯在动手前先把目录职责理一遍这样后面排查问题的时候能直接定位到位置不用满硬盘find。路径职责备注/etc/snort/snort.conf主配置文件2.9 系核心所有变量和 include 都在这里/etc/snort/rules/规则文件存放目录手写规则建议放local.rules/etc/snort/so_rules/共享对象规则需要额外下载入门可先不用/etc/snort/preproc_rules/预处理器规则部分预处理模块依赖/var/log/snort/告警与抓包落盘目录默认权限是 root 可写/etc/default/snort服务启动参数Debian 系特有控制 systemd 拉起时带什么参数/etc/snort/snort.debian.conf发行版封装的接口配置安装时的交互选择会写到这里数据流是这样的网卡收到流量 → Snort 通过 libpcap 抓取 → 解码器按协议拆包 → 预处理器做重组和规范化 → 规则引擎逐条匹配 → 命中后交给输出插件 → 写进/var/log/snort/下的告警文件。理解这条链路很重要因为后面规则不报警告警文件是空的这类问题几乎都能对应到链路中的某一段抓取段网卡/权限、解码段校验和/分片、预处理段流重组、规则段语法/方向、输出段插件配置。2. Kali 环境准备与 Snort 安装实操2.1 系统更新与源的处理Kali 的源配置是新手第一个容易翻车的地方。默认源在国外下载速度慢的时候apt install会卡在某个包上半天下不来最后超时。换源这件事本身没有技术含量但要注意两点一是改之前先备份原文件二是别在网上随便抄一个来路不明的源地址用官方列出的镜像源就行。sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo apt update sudo apt full-upgrade -yfull-upgrade在 Kali 上是常规操作因为它滚动更新的特性比较强包之间的依赖经常需要整体协调。升级过程可能会提示重启如果内核更新了建议重启一次再继续避免后面装驱动类依赖时出现版本对不上的情况。升级完之后顺手确认一下自己的网卡名字和 IP 段后面配置 HOME_NET 要用ip -4 addr show ip route show这两条命令的输出你要记住三个信息网卡名比如eth0、ens33、本机 IP、所在网段比如192.168.152.0/24。这三个值后面会在配置文件里反复出现。2.2 apt 安装路线一条命令加一次交互正式开始安装sudo apt install -y snort大部分时候这一步会弹出交互式配置界面问两件事一是请指定要监听的网络接口二是HOME_NET 网段是什么。这里别慌按你刚才ip addr看到的结果填就行接口填eth0之类的实际网卡名HOME_NET 填网段比如192.168.152.0/24。如果你不小心填错了也不用重装答案会被写进/etc/snort/snort.debian.conf直接编辑那个文件就能改。装完之后立刻做三件事snort -V # 确认版本 ls /etc/snort/ # 确认配置文件形态 dpkg -L snort | head -50 # 看清这个包到底装了哪些文件dpkg -L这个技巧特别好用它能直接列出某个包放的所有文件路径比到处翻目录靠谱得多。我第一次装完 Snort 就是靠它才发现主配置文件和规则目录的真实位置。2.3 源码编译路线从 DAQ 到 Snort 的完整依赖链如果你决定走源码顺序不能乱先装编译依赖再编 DAQ最后编 Snort因为 Snort 编译时要链接 DAQ 的库。第一步把依赖一次性装上sudo apt install -y build-essential libpcap-dev libpcre3-dev libpcre2-dev \ libdumbnet-dev bison flex zlib1g-dev liblzma-dev openssl libssl-dev \ libnghttp2-dev libluajit-5.1-dev pkg-config libhwloc-dev libdaq-dev这里面几个依赖值得解释一下为什么必须装libpcap-dev是抓包的基础不装 Snort 根本没法和网卡对话libpcre3-dev或者libpcre2-dev是正则表达式引擎规则里用pcre选项时就靠它libdumbnet-dev提供了一层更安全的网络接口封装编译时报 dumbnet 相关的错基本都是缺它bison和flex是语法分析工具编译规则解析器要用。第二步如果源里没有现成的 DAQ 开发包就手动编一个wget https://www.snort.org/downloads/snort/daq-2.0.7.tar.gz tar -xvzf daq-2.0.7.tar.gz cd daq-2.0.7 ./configure make sudo make install sudo ldconfigsudo ldconfig这一步千万别漏它的作用是刷新动态链接库缓存。我见过太多人编译装完之后运行报error while loading shared libraries: libdaq.so.2就是因为没执行它系统找不到新装的库。第三步编 Snort 本体wget https://www.snort.org/downloads/snort/snort-2.9.20.tar.gz tar -xvzf snort-2.9.20.tar.gz cd snort-2.9.20 ./configure --enable-sourcefire --disable-open-appid make sudo make install sudo ldconfig--enable-sourcefire会开启一些额外的检测能力也是源码编译相比 apt 最大的价值所在。--disable-open-appid用来跳过应用识别模块这个模块在实验环境里用处不大跳过能少装一堆依赖、编译也快不少。配置检查通过后编译大概几分钟取决于你的虚拟机 CPU 核数。2.4 安装完的自检清单不管走哪条路线装完都要过一遍这个清单任何一项不通过都不要往下走snort -V能打印出版本号和编译时间说明二进制可执行snort -T -c /etc/snort/snort.conf能跑完并输出 Snort successfully validated the configuration说明配置文件语法没问题ls /var/log/snort/目录存在且 root 可写ip addr里的网卡名和配置文件里写的接口名一致。-T这个参数我要单独强调它是改配置和改规则之后必须执行的校验动作相当于编译器的语法检查。它只解析配置、不抓包、不常驻几秒钟就返回结果。养成改一次校验一次的习惯能省掉大量启动到一半崩了不知道哪错了的时间。3. 三种运行模式与网卡、核心变量的配置Snort 有三种基本运行模式这不是可选的功能而是你排查问题的阶梯先用最简单的方式确认能看到流量再逐步加上检测逻辑。很多人的问题是直接跳到检测模式一启动没输出就完全不知道该从哪查起。3.1 嗅探模式先确认能看见包这是最原始的模式等于一个简化版抓包工具不做任何规则匹配sudo snort -v -i eth0-v表示把包头信息打印到终端-i指定网卡。执行之后你在另一台机器上 ping 一下这台 Kali终端应该刷刷地往外吐 ICMP 报文信息。如果一条都没有问题一定出在抓取这一段跟规则一点关系都没有先解决网卡和权限。这里有个虚拟机的经典坑如果你用的是 NAT 模式虚拟机和宿主机之间的流量走的是虚拟网卡你能抓到但实验网段里其他机器的流量可能完全绕开了这张卡。想抓全通常要切到桥接模式或者用 Host-Only 组一个独立网段让所有待检测的机器都在同一个二层广播域里。这个问题我在搭环境阶段浪费过一个下午后来才明白不是 Snort 的问题是虚拟网络拓扑的问题。3.2 包记录模式把流量落成文件确认能看到包之后下一步是把流量存下来方便事后分析sudo snort -dev -i eth0 -l /var/log/snort-d打印应用层数据-e打印链路层头-l指定日志目录。执行一段时间后按CtrlC你会看到/var/log/snort/下出现了抓包文件通常是以源 IP 和目的 IP 命名的目录结构里面是 pcap 文件。这些文件可以直接用抓包工具打开回看。这个模式在实际工作中的价值是留存证据。检测模式只能告诉你发生了什么事包记录模式能让你事后把原始流量翻出来逐字节确认到底传了什么。做规则调试的时候我经常两个模式配合检测模式报警了我就去翻对应时间点的 pcap看看到底是哪个字段命中了规则。3.3 检测模式-c 加 -A 的正确组合真正干活的模式sudo snort -A console -q -c /etc/snort/snort.conf -i eth0参数逐个解释-A console表示把告警直接打到终端方便实时观察正式跑的时候通常换成-A fast让它写文件-q是安静模式不打印那些启动时的模块加载信息让终端只显示告警-c指定主配置文件-i指定网卡。如果配置里已经写好了output段-A命令行参数可能会覆盖配置文件里的设置这点要注意。我习惯的做法是调试阶段用-A console -q能立刻看到效果稳定运行阶段把输出写进配置文件然后用-A fast配合-D让它在后台跑。还有一个参数值得单独说-k none。它的作用是关闭 TCP/UDP 校验和检查。在虚拟机环境下网卡卸载功能checksum offload会导致抓到的包校验和字段是未计算状态Snort 会把它们全部丢掉表现就是明明有流量但一条告警都没有。这个坑非常隐蔽因为日志里往往只是轻描淡写地提一句丢弃了多少个包不仔细看根本注意不到。在虚拟环境里调试我基本都会加上-k none能省掉一大类莫名其妙的排查。3.4 HOME_NET 这些东西到底怎么填打开/etc/snort/snort.conf最前面几十行都是变量定义。新手看这段容易晕其实只要理解一件事这些变量的作用是让规则能相对地描述方向而不是写死 IP。举个最直观的例子ipvar HOME_NET 192.168.152.0/24 ipvar EXTERNAL_NET !$HOME_NET规则里写$EXTERNAL_NET any - $HOME_NET 80意思就是从外部发往我内部 Web 服务的流量。你换了网段只改这一行所有规则自动适配不用一条条去改 IP。!$HOME_NET这个写法是集合取反表示除了 HOME_NET 之外的所有地址。其他几个常用的变量ipvar HTTP_SERVERS $HOME_NET ipvar SMTP_SERVERS $HOME_NET ipvar DNS_SERVERS $HOME_NET ipvar SQL_SERVERS $HOME_NET var RULE_PATH /etc/snort/rules var SO_RULE_PATH /etc/snort/so_rules var PREPROC_RULE_PATH /etc/snort/preproc_rules var WHITE_LIST_PATH /etc/snort/rules var BLACK_LIST_PATH /etc/snort/rulesRULE_PATH这一类是路径变量供后面include用。如果你把规则文件放在了别的地方改这里就行。我踩过的一个坑是路径末尾的斜杠——include $RULE_PATH/local.rules这种写法如果RULE_PATH末尾已经带了斜杠拼出来就变成双斜杠虽然大多数情况能正常解析但偶尔会报文件找不到。所以路径变量统一不加尾斜杠比较稳妥。注意var和ipvar的区别在于ipvar会按 IP 地址或网段解析支持取反和列表var只做纯字符串替换。写网段和地址一律用ipvar写路径和端口一律用var混用了虽然不一定立刻报错但行为可能跟你预期的不一样。4. 逐段拆解 snort.conf把配置变成自己能改的东西4.1 配置文件的四段式骨架和执行顺序2.9 系的配置文件结构非常规整从头到尾基本是四块变量定义、预处理器配置、输出插件配置、规则文件包含。顺序很重要因为后面会引用前面定义的东西你把include挪到变量定义之前就会报变量未定义。我通常会在改配置前做一次缩略版梳理把每一段的起止行号记下来grep -n ^#\|^ipvar\|^var\|^preprocessor\|^output\|^include /etc/snort/snort.conf | head -80这条命令能把所有关键行的行号列出来改的时候直接跳行效率高很多。如果你觉得原配置太乱也可以自己写一份精简版只保留你真正需要的模块这样启动更快、报错更少。我现在的习惯就是维护一份自己的精简配置遇到问题一眼就能定位。4.2 预处理器的取舍思路预处理器是 Snort 在规则匹配之前对流量做的预处理主要干三件事IP 分片重组、TCP 流重组、协议规范化。这三件事不做好规则会大量漏报因为攻击者可以用分片或者分段的方式把特征拆开让你匹配不到。preprocessor frag3_global: max_frags 65536 preprocessor frag3_engine: policy first detect_anomalies preprocessor stream5_global: track_tcp yes, track_udp yes, track_icmp no, max_tcp 262144, memcap 64MB preprocessor stream5_tcp: policy first, use_static_footprint_sizesstream5的max_tcp 262144表示同时跟踪的 TCP 会话数上限memcap 64MB是内存上限。这两个值要根据你的流量规模调实验环境几十个会话默认值绰绰有余如果你拿它盯一个繁忙的网段就得往上加否则会看到 Stream5: TCP session limit reached 这类提示超出的会话就不再做重组检测质量直接下降。协议规范化相关的预处理器要不要开取决于你检测什么。如果你主要盯 HTTP那http_inspect就值得配它能把 URI 编码、大小写变形、多余空格这些规避手法规范化掉让规则更容易命中。但它需要unicode.map这类映射文件位置不对就会报错preprocessor http_inspect: global iis_unicode_map /etc/snort/unicode.map 1252 compress_depth 65535 decompress_depth 655351252是代码页编号对应西欧字符集。如果你的文件不在这个路径改成实际路径即可。我见过最常见的现象就是启动时报 iis_unicode_map 找不到其实文件就在那儿只是路径写错了。4.3 输出插件告警到底写到哪个文件输出这一段的配置直接决定你能不能看到结果所以别照抄按需要选output alert_fast: alert.fast output log_tcpdump: tcpdump.logalert_fast是最常用的告警输出格式是一行一条可读性好适合tail -f实时看。文件名是相对路径基准目录由-l参数决定默认是/var/log/snort/。log_tcpdump会把触发告警的原始报文另存成 pcap非常方便事后取证但会明显增加磁盘占用长期跑的话要留意空间。如果你需要和别的系统对接还可以考虑alert_syslog把告警丢给系统日志或者用alert_unified2生成二进制格式给分析平台消费。入门阶段不必上这么多先把alert_fast跑通能稳定看到告警再考虑扩展。一次只加一个输出插件加完就验证这样出问题的时候能立刻知道是哪个插件引起的。4.4 用自己的规则文件替换掉那一堆 includeDebian 打包的配置里通常有几十行include $RULE_PATH/xxx.rules指向一堆你可能根本没有的规则文件启动时会刷出一堆 Cant find file 的警告。处理方式有两种一是把用不到的注释掉二是把规则集下载齐。我建议入门阶段用第一种只保留自定义规则文件include $RULE_PATH/local.rules然后在/etc/snort/rules/local.rules里写自己的规则。这样做的好处非常明确你写的每一条规则引发的每一条告警你都知道是为什么不会在一堆来自规则集的告警里迷失。等你摸清了规则语法再引入官方规则集那时你已经有能力区分哪条告警有意义、哪条是噪声了。创建目录和空规则文件的命令sudo mkdir -p /etc/snort/rules /etc/snort/so_rules /etc/snort/preproc_rules sudo touch /etc/snort/rules/local.rules sudo chown -R root:root /etc/snort5. 从零写一条自己的规则5.1 规则头五个字段一句话讲透Snort 规则的骨架长这样动作 协议 源地址 源端口 方向 目的地址 目的端口 (选项; 选项; ...)用一条具体规则对着看alert tcp $EXTERNAL_NET any - $HOME_NET 22 (msg:SSH connection attempt; sid:1000010; rev:1;)alert是动作表示命中后产生告警除此之外还有log只记录不告警、pass放行优先级最高用来做白名单、drop/reject仅在内联模式下有效Kali 上默认的被动模式用不了。tcp是协议可以是 tcp、udp、icmp、ip。源和目的地址可以是具体 IP、网段变量、any。方向有两个-单向、双向。端口的写法很灵活any表示任意80表示单个[80,443]表示列表!22表示排除。这里有个新手极易混淆的点和这种写法在 2.9 里是小于等于端口号的意思跟比较运算无关别当成数学符号理解。我第一次看到的时候困惑了很久。5.2 规则体的常用选项括号里的选项决定规则的精确定义常用的有这么几个选项作用举例msg告警时显示的文字msg:ICMP ping from outside;sid规则唯一编号自定义规则建议从 1000000 起rev规则修订号改一次加一rev:2;content匹配报文里的字节内容content:/test;nocase匹配时忽略大小写常跟在 content 后pcre用正则表达式匹配pcre:/admin\/login/i;flow限定流的方向和状态flow:to_server,established;itypeicode限定 ICMP 类型和代码itype:8; icode:0;http_uri把 content 限定在 URI 部分匹配需配合 http_inspectsid的编号规则要说一下1 到 999999 是官方保留段你自定义的规则从 1000000 开始避免将来升级规则集时和官方编号撞车。rev是给规则做版本管理的你改了规则内容就把rev加一这样从日志里能看出命中的是哪一版规则。flow这个选项值得多解释一句它是靠stream5预处理器的流跟踪能力工作的。flow:to_server,established的意思是只匹配已经建立连接、且方向是从客户端到服务端的报文。加上它有个很实际的好处TCP 三次握手产生的 SYN 包会被排除掉能大幅减少重复告警。如果你写了一堆 TCP 规则但没加 flow会发现同一次连接触发好几条告警看着很乱。5.3 三条可以立刻上手的规则实例实例一检测外部发来的 ICMP 回显请求。这条规则最简单用来验证整套流程是否通畅最合适alert icmp $EXTERNAL_NET any - $HOME_NET any (msg:ICMP echo request from external; itype:8; icode:0; sid:1000001; rev:1;)实例二检测 HTTP 请求里包含特定关键词的访问。这条演示 content 和 http_uri 配合alert tcp $EXTERNAL_NET any - $HOME_NET $HTTP_PORTS (msg:HTTP URI contains test keyword; flow:to_server,established; content:/test; http_uri; nocase; sid:1000002; rev:1;)实际使用时把/test换成你想盯的路径模式。http_uri限定只在 URI 部分匹配避免在响应体里误命中这个限定条件能显著降低误报。实例三检测短时间内来自同一源的多次 SSH 连接尝试。这条用到了频次控制alert tcp $EXTERNAL_NET any - $HOME_NET 22 (msg:Possible SSH brute force attempt; flow:to_server,established; detection_filter:track by_src, count 10, seconds 60; sid:1000010; rev:1;)detection_filter的语义是同一个源地址在 60 秒内触发本规则达到 10 次之后才真正产生告警。注意它不是每 10 次报一次而是过了阈值之后每次都报所以你会看到告警集中爆发。如果不想被刷屏可以配合threshold或event_filter做抑制这个后面调优那节再说。这类规则在实验环境里用来观察扫描行为很直观但同样的道理它只能用在你自己拥有管理权限的网段里做审计。5.4 规则写完必须做的两步验证规则写完不是保存就完事必须做两步第一步语法校验。sudo snort -T -c /etc/snort/snort.conf输出里如果出现ERROR一定要处理不能放过。常见的错误包括括号不匹配、选项之间漏了分号、sid重复、用了当前版本不支持的选项。特别提醒一句同一个sid在多个文件里出现会直接报错退出所以自定义规则的编号最好自己维护一张表别随手乱起。第二步实际流量验证。sudo snort -A console -q -c /etc/snort/snort.conf -i eth0保持这个终端开着然后从另一台机器发起对应行为。如果告警出现了说明规则生效如果没有就按顺序排查流量有没有经过这张网卡、方向写对没有、EXTERNAL_NET和HOME_NET的划分是否把测试流量排除在外了。这里我要重点讲一个几乎每个人都踩过的坑你从同网段的另一台机器发起的测试流量源地址和目的地址都在 HOME_NET 里而你的规则写的是$EXTERNAL_NET any - $HOME_NET any源地址不满足!$HOME_NET的条件所以规则永远不命中。解决办法有两个测试期间临时把规则源地址写成any或者把测试机挪到一个不在 HOME_NET 范围内的网段。我一开始死活想不通为什么规则明明写对了却没反应最后发现就是这个问题。6. 规则集的引入、更新与性能取舍6.1 为什么迟早要引入现成规则集手写规则的好处是可控坏处是覆盖面窄。你不可能凭自己把几千种常见异常流量的特征都写一遍所以到了一定阶段引入维护良好的公开规则集是必然选择。但引入的方式要讲究不要一次性全量导入然后看着满屏告警发呆那等于把信噪比直接拉到最低。我的做法是分层local.rules放自己写的、调试过的高置信规则引入的规则集先只开几个和你实验环境相关的类别观察一两天看告警量是否可接受再逐步放开。这样每一步的影响都是可控的出了问题也知道是哪一批规则引入的。6.2 规则更新工具的配置要点手工下载规则文件再替换的方式太原始实践中通常用一个规则管理工具来做这件事它会帮你下载、按需裁剪、生成配置文件、并自动做语法校验。配置上有几个关键点值得说第一规则集的启用清单要显式写出来别用全开的默认值。第二输出目录要和snort.conf里的RULE_PATH对上否则下载完了主配置根本没引用。第三它一般会在生成配置后调用一次校验如果校验不通过会保留上一次的可用版本这个回滚机制千万别关掉否则一次失败的更新就可能让整个检测停摆。更新完成后的验证流程和手写规则一样先-T校验再用-A console观察一段时间确认启动正常、告警量在预期范围内。更新规则这件事我从来不和改配置文件同时做一次只改一个变量出问题时才能快速定位。6.3 规则越多越慢怎么按需裁剪规则数量直接影响两个东西内存占用和匹配速度。每条规则在启动时会编译成内部的匹配结构几千条规则占几百 MB 内存是很正常的事。规则数上万之后低配虚拟机上启动慢到几十秒也不奇怪。裁剪的思路有三条一是按协议裁如果你的实验环境里根本没有某些协议的流量相关规则整批关掉二是按服务裁只保留你网段里实际存在的服务对应规则三是按置信度裁那些告警量巨大但几乎没有真实价值的类别直接不启用。判断标准很简单一条规则如果一周触发几百次而你没有一次需要去处理它那它在你的环境里就是噪声。另外规则顺序也有讲究。Snort 是按顺序匹配的pass规则优先级最高可以用来给已知的、完全信任的流量开绿灯让它们不进入后续匹配。把高频的、确定无害的流量用pass提前放行能省下不少匹配开销。这个技巧在处理某台机器持续产生大量正常流量导致告警刷屏的场景时特别管用。7. 常见问题与排查技巧实录7.1 启动阶段报错速查表下面这张表是我这些年实际遇到过的按错误信息类型整理报错信息关键词原因处理方式Cant find fileinclude 的规则文件不存在注释掉对应 include或补上文件Unknown rule type规则语法错误或版本不匹配检查括号和分号确认版本ERROR: Duplicate sid规则编号重复换一个 1000000 以上的编号error while loading shared libraries动态库路径未刷新执行sudo ldconfigERROR: Unable to open address file白/黑名单文件缺失建立空文件或注释相关行Cannot open /etc/snort/snort.conf权限不足加sudo执行FATAL: Could not open /var/log/snort日志目录不存在或无权限建目录并确认属主排查这类问题的通用心法就一句看报错里给出的行号直接跳过去。Snort 的报错通常格式是文件名(行号) 具体原因这就是最精确的定位信息比任何猜测都管用。我见过很多人拿着报错去网上搜结果搜到一堆不相关的答案实际只要看那个行号两秒钟就找到了。7.2 抓不到包的五种原因这一类问题占了我排查时间的大头按出现频率排序第一没加-i或者网卡名写错。表现是启动没报错但什么都没有。解决办法是明确指定网卡并和ip addr的输出核对一遍。第二虚拟机网络模式不合适。NAT 模式下你只能看到本机和宿主之间的流量其他机器的流量可能完全不经过这张卡。换成桥接或者用 Host-Only 组独立网段。第三校验和问题。前面说过的-k none虚拟网卡卸载导致的伪校验和。表现是日志里悄悄提到丢弃了大量包。第四网卡没进入混杂模式。Snort 需要 root 权限才能把网卡设成混杂模式否则只能收到发给自己的单播。用sudo运行是最省事的办法。第五防火墙或者网络策略把流量拦在了到达网卡之前。这种情况下 Snort 根本看不到包因为它压根没到。可以从目标机器上直接抓包对比确认。7.3 告警不落盘、日志文件是空的这个问题分两种情况。一种是你用了-A console却去找文件那当然找不到console输出是打到终端的不写文件。想让告警落盘要么在配置文件里配output alert_fast: alert.fast要么用-A fast并确认日志目录参数-l指向正确。另一种是配置里配了输出但文件是 0 字节。这时候先确认到底有没有产生告警在终端用-A console同时跑一遍如果终端有输出而文件没有那就是输出路径或者权限的问题如果终端也没有那问题不在输出段而在更前面的抓取或规则段回到上一节去查。这个双通道对比的排查方法特别好用能一刀把问题范围切开。还有一个容易被忽略的点Debian 打包的 Snort 服务单元启动时用的是/etc/default/snort里的参数跟你手动在命令行敲的那条命令可能不是一回事。所以我命令行跑有告警、systemd 跑没告警这种情况一定要去翻/etc/default/snort看看里面配的接口和参数是什么。7.4 误报太多时的调优思路误报的处理不是简单删规则而是分层次降噪。第一层是加约束条件比如给 content 加上http_uri限定位置、给 TCP 规则加上flow:to_server,established、用nocase避免大小写绕过。约束越精确误报越少但要小心约束太严导致漏报。第二层是频次抑制。对扫描类尝试类这种天然会高频触发的规则用detection_filter或者event_filter限制告警频率。这类规则的特点是单次触发没有价值成批触发才有意义所以抑制掉零星的告警是合理的。第三层是白名单。对于那些你完全清楚、频繁出现在日志里的合法流量用pass规则或者白名单文件把它们提前排除。这层处理务必谨慎白名单一旦写宽了就等于给攻击者开了一扇门所以每一条白名单我都要写注释说明为什么加、什么时候加的、什么条件下可以删。第四层才是考虑放弃某条规则。这一步我一般放到最后而且会先把规则注释掉观察一周确认真的没有价值再彻底删除。8. 把它挂进日常工作流里的几个做法8.1 用 systemd 托管与开机自启的坑apt 装的 Snort 通常会带一个 systemd 服务单元理论上sudo systemctl enable --now snort就能跑起来。但实际用的时候要留意几点一是/etc/default/snort里的参数决定了实际启动的行为改配置文件之后记得同步检查这里二是服务单元的日志走的是系统日志不再往终端输出所以观察告警要去看/var/log/snort/下的文件或者用journalctl -u snort -f看服务本身的运行状态。我个人不太推荐把调试中的配置直接设成开机自启。原因是配置有问题的状态下自启系统每次启动都会卡在一个报错的服务上时间久了容易忽视。更稳妥的做法是手动调试到稳定运行一段时间确认告警质量可接受再设成自启。8.2 实时盯盘和一个简单的自动化处理告警文件是纯文本一行一条实时观察用tail就够了sudo tail -f /var/log/snort/alert.fast如果想做点自动化比如把告警按源 IP 统计出 Top 10一条命令能搞定sudo awk -F[][] {print $2} /var/log/snort/alert.fast | sort | uniq -c | sort -rn | head -10这个统计在分析扫描行为的时候特别有用你会很直观地看到哪个来源地址的告警数量异常突出。至于自动化响应比如发现某类告警后自动发通知或者临时阻断这属于更高阶的做法需要非常谨慎地设计因为误判导致的自动阻断可能比告警本身造成的麻烦更大。入门阶段我建议只做发现和记录不做自动处置。8.3 和看包工具配合先报警再定性Snort 和抓包工具是互补关系不是替代关系。我的固定流程是Snort 负责 7×24 小时盯着、发现异常并落一条告警告警里通常包含时间戳、源目地址、端口、规则编号和 msg 文字。然后我拿着这条告警的时间点去对应的 pcap 文件里定位那一段流量用抓包工具逐字节确认到底发生了什么。这个流程的关键在于抓包数据要留够。如果只跑检测模式不记录原始流量事后就只能看着一行告警文字猜。所以我在实验环境里一般会同时开alert_fast和log_tcpdump两个输出让告警和原始包都有留存事后分析的时候就不缺材料了。磁盘空间是要留意一下但实验环境的流量规模通常不至于撑爆盘。我自己在实际搭这套东西的过程中感受最深的一点是Snort 的难点从来不在安装而在知道自己看到的每一条告警是怎么来的。安装命令就那么几行但如果你不清楚变量定义怎么影响规则方向、预处理怎么影响流重组、输出插件怎么影响你看到的日志遇到问题时就会陷入改一个参数试一下不行再改回来的随机试错。反过来只要你把规则的骨架理解透了遇到任何一条告警你都能顺着方向—协议—端口—content—选项这条线一路追下去定位速度会快得超出你的预期。还有一个经验是别急着把手里的规则数量堆起来。我有一段时间开了大批现成规则结果每天几百条告警最后一条都没认真看等于白装。后来砍到只剩十几条自己写的规则每条告警我都能说出它为什么触发、值不值得处理反而真正抓到了几次有价值的扫描行为。工具的价值不在于它报了多少而在于你报出来的每一条都能用得上。
返回列表