Skip to content

入侵检测系统 (IDS/IPS) 部署与规则编写 — Snort/Suricata

Published:
11 min read

在网络安全防御体系中,防火墙负责对流量进行访问控制,而入侵检测系统(IDS)和入侵防御系统(IPS)则承担着更深层次的职责——检测并识别网络中的恶意行为和攻击流量。本文将详细介绍 IDS/IPS 的核心概念,并以 Snort 和 Suricata 两款主流开源工具为例,讲解部署方法、规则编写和告警分析实战。

IDS 与 IPS 的概念区别

入侵检测系统(IDS)

IDS(Intrusion Detection System)以旁路(被动)模式部署,通过镜像端口或 TAP 设备获取网络流量的副本进行分析。当检测到可疑活动时,IDS 会产生告警通知管理员,但不会主动阻断流量。优点是不影响网络性能,缺点是响应滞后。

入侵防御系统(IPS)

IPS(Intrusion Prevention System)以串联(主动)模式部署在网络路径中,所有流量都必须经过 IPS。当检测到攻击流量时,IPS 能够实时阻断恶意数据包。防护更主动,但如果规则配置不当可能造成误杀合法流量。

部署模式选择

模式部署位置特点适用场景
IDS(旁路)交换机镜像端口不影响流量,只告警监控分析、合规审计
IPS(串联)网络出入口串联实时阻断,有延迟影响边界主动防御
混合模式同时部署兼顾监控和防御大型网络环境

Snort 安装与基本配置

Snort 是由 Martin Roesch 于 1998 年创建的老牌开源 IDS/IPS,目前由 Cisco Talos 团队维护。它支持实时流量分析、协议解析和内容匹配。

安装 Snort 3

# Ubuntu/Debian 环境安装依赖
sudo apt update
sudo apt install -y build-essential libpcap-dev libpcre3-dev \
    libnet1-dev zlib1g-dev luajit hwloc libdnet-dev \
    libdumbnet-dev bison flex cmake libhwloc-dev

# 安装 DAQ(数据采集库)
git clone https://github.com/snort3/libdaq.git
cd libdaq
./bootstrap
./configure
make && sudo make install

# 编译安装 Snort 3
git clone https://github.com/snort3/snort3.git
cd snort3
./configure_cmake.sh --prefix=/usr/local
cd build
make -j$(nproc) && sudo make install
sudo ldconfig

# 验证安装
snort -V

snort.lua 核心配置

Snort 3 使用 Lua 格式的配置文件(Snort 2 使用 snort.conf):

-- /usr/local/etc/snort/snort.lua

-- 网络变量定义
HOME_NET = '192.168.1.0/24'
EXTERNAL_NET = '!$HOME_NET'

-- DAQ 配置(IDS 模式使用 pcap)
daq = {
    module_dirs = { '/usr/local/lib/daq' },
    modules = {
        {
            name = 'pcap',
            mode = 'passive',    -- IDS模式
            variables = { 'buffer_size=4194304' }
        }
    }
}

-- 检测引擎配置
detection = {
    hyperscan = true,
    search_method = 'hyperscan'
}

-- 输出配置:统一日志
alert_json = {
    file = true,
    limit = 100,
    fields = 'timestamp msg src_addr src_port dst_addr dst_port proto action'
}

-- 引用规则文件
ips = {
    enable_builtin_rules = true,
    include = '/usr/local/etc/snort/rules/local.rules',
    variables = {
        nets = {
            HOME_NET = HOME_NET,
            EXTERNAL_NET = EXTERNAL_NET
        },
        ports = {
            HTTP_PORTS = '80 8080 443',
            SSH_PORTS = '22'
        }
    }
}

启动 Snort

# IDS 模式:监听 eth0 接口
sudo snort -c /usr/local/etc/snort/snort.lua -i eth0 -l /var/log/snort/ -A alert_json

# 测试配置文件是否正确
sudo snort -c /usr/local/etc/snort/snort.lua --warn-all -T

# 读取 pcap 文件进行离线分析
sudo snort -c /usr/local/etc/snort/snort.lua -r capture.pcap -l /var/log/snort/

Snort 规则语法详解

Snort 规则是其核心,每条规则由规则头规则选项两部分组成。

规则基本结构

动作 协议 源IP 源端口 方向 目的IP 目的端口 (选项)

规则示例详解

# 检测外部对内网的 SSH 暴力破解
alert tcp $EXTERNAL_NET any -> $HOME_NET 22 (
    msg:"SSH Brute Force Attempt";
    flow:to_server,established;
    content:"SSH-";
    detection_filter:track by_src, count 5, seconds 60;
    classtype:attempted-admin;
    sid:1000001;
    rev:1;
)

# 检测 SQL 注入尝试
alert http $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (
    msg:"SQL Injection - UNION SELECT detected";
    flow:to_server,established;
    http_uri;
    content:"UNION"; nocase;
    content:"SELECT"; nocase; distance:0;
    classtype:web-application-attack;
    sid:1000002;
    rev:1;
)

# 检测 Nmap SYN 扫描
alert tcp $EXTERNAL_NET any -> $HOME_NET any (
    msg:"Nmap SYN Scan Detected";
    flags:S;
    flow:stateless;
    threshold:type both, track by_src, count 20, seconds 5;
    classtype:attempted-recon;
    sid:1000003;
    rev:1;
)

# 检测可疑的反弹 Shell
alert tcp $HOME_NET any -> $EXTERNAL_NET any (
    msg:"Possible Reverse Shell - /bin/bash";
    flow:established;
    content:"/bin/bash"; nocase;
    content:"-i"; distance:0; within:10;
    classtype:trojan-activity;
    sid:1000004;
    rev:1;
)

# 检测 ICMP 隧道(大尺寸 Ping 包)
alert icmp $EXTERNAL_NET any -> $HOME_NET any (
    msg:"Large ICMP Packet - Possible ICMP Tunnel";
    dsize:>800;
    itype:8;
    classtype:misc-activity;
    sid:1000005;
    rev:1;
)

关键规则选项说明

选项作用
msg告警消息文本
flow流方向(to_server/to_client, established/stateless)
content内容匹配(支持文本和十六进制)
nocase内容匹配忽略大小写
depth从起始位置搜索的字节范围
offset开始搜索的偏移量
distance上一个 content 匹配后的间隔
within限制搜索窗口
pcre使用正则表达式匹配
threshold阈值控制(限制告警频率)
sid规则唯一标识符(自定义规则建议 >= 1000000)
rev规则修订版本号
classtype攻击分类

Suricata:高性能多线程 IDS/IPS

Suricata 由 OISF(Open Information Security Foundation)开发,最大优势是原生多线程架构,能充分利用多核 CPU,在高流量环境下性能远超单线程的 Snort 2。

Suricata 安装

# Ubuntu/Debian
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update
sudo apt install -y suricata suricata-update

# CentOS/RHEL
sudo yum install -y epel-release
sudo yum install -y suricata

# 验证
suricata --build-info

suricata.yaml 关键配置

# /etc/suricata/suricata.yaml

vars:
  address-groups:
    HOME_NET: "[192.168.1.0/24, 10.0.0.0/8]"
    EXTERNAL_NET: "!$HOME_NET"
  port-groups:
    HTTP_PORTS: "80"
    SSH_PORTS: "22"

# 多线程配置
threading:
  set-cpu-affinity: yes
  cpu-affinity:
    - management-cpu-set:
        cpu: [0]
    - receive-cpu-set:
        cpu: [1]
    - worker-cpu-set:
        cpu: [2, 3, 4, 5]
        mode: "exclusive"

# 运行模式:workers 模式最适合多核
runmode: workers

# 网络接口
af-packet:
  - interface: eth0
    threads: 4
    cluster-type: cluster_flow
    defrag: yes
    use-mmap: yes

# EVE JSON 日志输出
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: eve.json
      types:
        - alert:
            metadata: yes
        - http:
            extended: yes
        - dns
        - tls:
            extended: yes
        - flow

启动 Suricata

# IDS 模式
sudo suricata -c /etc/suricata/suricata.yaml -i eth0

# IPS 模式(需要 NFQ 或 AF_PACKET inline)
sudo suricata -c /etc/suricata/suricata.yaml --af-packet=eth0 -D

# 测试配置
sudo suricata -T -c /etc/suricata/suricata.yaml

规则管理工具

suricata-update

# 更新规则集
sudo suricata-update

# 列出可用规则源
sudo suricata-update list-sources

# 启用 ET Open 规则集
sudo suricata-update enable-source et/open

# 禁用特定规则(减少误报)
echo "2100498" >> /etc/suricata/disable.conf
sudo suricata-update

PulledPork(Snort 规则管理)

# 安装 PulledPork
git clone https://github.com/shirkdog/pulledpork3.git
cd pulledpork3

# 配置 pulledpork.conf 中的 Oinkcode
# oinkcode = your_oink_code_here

# 运行规则更新
sudo python3 pulledpork.py -c /etc/pulledpork/pulledpork.conf

# 设置 cron 定时更新
echo "30 2 * * * root /usr/local/bin/pulledpork.py -c /etc/pulledpork/pulledpork.conf" >> /etc/crontab

告警分析与日志查看

# 查看 Snort 告警日志
tail -f /var/log/snort/alert_json.txt | python3 -m json.tool

# 查看 Suricata EVE JSON 日志
tail -f /var/log/suricata/eve.json | jq 'select(.event_type == "alert")'

# 统计告警来源 Top 10
cat /var/log/suricata/eve.json | jq -r 'select(.event_type == "alert") | .src_ip' | sort | uniq -c | sort -rn | head -10

# 统计告警类型分布
cat /var/log/suricata/eve.json | jq -r 'select(.event_type == "alert") | .alert.signature' | sort | uniq -c | sort -rn | head -20

# 查看特定 SID 的详细告警
cat /var/log/suricata/eve.json | jq 'select(.alert.signature_id == 2024897)'

# 使用 fast.log 快速查看
tail -f /var/log/suricata/fast.log

安全建议与防御措施

  1. 分层部署:在网络边界部署 IPS 进行主动防御,在内网关键节点部署 IDS 进行监控分析,形成纵深防御。
  2. 规则精细化:不要盲目启用所有规则。根据实际业务环境选择相关规则集,禁用无关规则以降低误报率和性能消耗。
  3. 定期更新规则:攻击手法不断演进,规则库需要保持定期更新。建议通过自动化工具每日更新一次。
  4. 白名单管理:对已知安全的流量添加 pass 规则(白名单),放在规则链最前面以避免误报。
  5. 性能调优:高流量环境优先选择 Suricata 多线程方案,合理分配 CPU 核心,启用 AF_PACKET 或 DPDK 加速。
  6. 日志集中管理:将告警日志接入 ELK Stack 或 Splunk 等 SIEM 平台,实现统一分析和关联告警。
  7. 定期审计告警:关注高频告警和新出现的告警类型,及时排查是否为真实攻击。
  8. 规则测试:新规则上线前先在 IDS 模式下运行一段时间,确认无大量误报后再切换为 IPS 阻断模式。

总结

IDS/IPS 是网络安全监控和防御的重要手段,Snort 和 Suricata 作为两款最成熟的开源方案各有优势。Snort 规则生态丰富、社区活跃,Suricata 凭借多线程架构在高速网络中表现出色,并且完全兼容 Snort 规则格式。在实际部署中,建议根据网络规模和性能需求选择合适的引擎,精细化配置规则集,并结合 SIEM 平台实现从检测到响应的闭环安全运营。