# Configuring Snort Ids For Intrusion Detection

> 安装、配置和调优 Snort 3 入侵检测系统（intrusion detection system），使用自定义和社区规则集、 预处理器和告警输出插件，在授权网络分段上监控网络流量中的恶意活动。

- Skill: `killvxk/configuring-snort-ids-for-intrusion-detection` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/configuring-snort-ids-for-intrusion-detection`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/configuring-snort-ids-for-intrusion-detection/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/configuring-snort-ids-for-intrusion-detection

---

# 配置 Snort IDS 进行入侵检测

## 适用场景

- 在关键网络边界部署基于网络的入侵检测系统（IDS），监控流量
- 编写自定义 Snort 规则，检测特定于组织的威胁、攻击模式或策略违规
- 调优现有规则集以减少误报，同时保持检测覆盖率
- 将 Snort 告警与 SIEM 平台集成，进行集中化安全监控
- 通过生成测试流量并确认检测，验证网络安全控制措施

**不适用于**：替代终端检测、在没有 TLS 检测的情况下监控加密流量，或作为不配合其他防御措施的唯一安全控制。

## 前置条件

- 通过源码或包管理器安装 Snort 3.x（`snort --version` 验证）
- 在 SPAN 端口或网络分路器上配置混杂模式的网络接口
- 安装 DAQ（数据采集库）进行数据包捕获集成
- 注册 Snort 账户，从 snort.org 下载 Snort 订阅者（付费）或社区规则集
- 安装 PulledPork 3 或类似规则管理工具进行自动化规则集更新
- 充足的 CPU 和内存，用于线速内联流量检测

## 工作流程

### 步骤 1：安装并验证 Snort 3

```bash
# 安装依赖项（Ubuntu/Debian）
sudo apt install -y build-essential libpcap-dev libpcre3-dev libnet1-dev \
  zlib1g-dev luajit hwloc libdumbnet-dev bison flex libcmocka-dev \
  libnetfilter-queue-dev libmnl-dev autotools-dev libluajit-5.1-dev \
  pkg-config cmake libhwloc-dev liblzma-dev openssl libssl-dev cpputest \
  libsqlite3-dev uuid-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
```

### 步骤 2：配置网络接口

```bash
# 禁用干扰数据包检测的卸载功能
sudo ethtool -K eth1 gro off lro off tso off gso off rx off tx off

# 启用混杂模式
sudo ip link set eth1 promisc on

# 创建 systemd 服务用于持久化接口配置
sudo tee /etc/systemd/system/snort-iface.service << 'EOF'
[Unit]
Description=Configure Snort capture interface
Before=snort.service

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -K eth1 gro off lro off tso off gso off rx off tx off
ExecStart=/sbin/ip link set eth1 promisc on
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable snort-iface.service
```

### 步骤 3：使用 Lua 配置文件配置 Snort 3

```bash
# 创建 Snort 目录结构
sudo mkdir -p /usr/local/etc/snort/{rules,builtin_rules,lists,appid}
sudo mkdir -p /var/log/snort

# 编辑主 Snort 配置文件
sudo tee /usr/local/etc/snort/snort.lua << 'LUAEOF'
-- Snort 3 配置

-- 网络变量
HOME_NET = '10.10.0.0/16'
EXTERNAL_NET = '!$HOME_NET'

-- 路径变量
RULE_PATH = '/usr/local/etc/snort/rules'
BUILTIN_RULE_PATH = '/usr/local/etc/snort/builtin_rules'

-- 配置 DAQ
daq = {
    module_dirs = { '/usr/local/lib/daq' },
    modules = { { name = 'afpacket', variables = { 'buffer_size_mb=256' } } }
}

-- 解码器配置
normalizer = { tcp = { ips = true } }

-- 流检测
stream = { }
stream_tcp = { policy = 'linux', session_timeout = 180 }
stream_udp = { session_timeout = 30 }
stream_icmp = { }

-- HTTP 检测
http_inspect = { }

-- DNS 检测
dns = { }

-- SSL/TLS 检测
ssl = { }

-- SMB 检测
dce_smb = { }

-- 文件识别和处理
file_id = { rules_file = '/usr/local/etc/snort/file_magic.rules' }

-- 端口扫描检测
port_scan = {
    protos = 'all',
    scan_types = 'all',
    memcap = 10000000
}

-- 基于信誉的过滤
-- reputation = {
--     blacklist = RULE_PATH .. '/blocklist.rules'
-- }

-- IPS 规则
ips = {
    enable_builtin_rules = true,
    include = RULE_PATH .. '/snort3-community.rules',
    variables = {
        nets = { HOME_NET = HOME_NET, EXTERNAL_NET = EXTERNAL_NET },
        ports = {
            HTTP_PORTS = '80 8080 8443',
            SSH_PORTS = '22',
            DNS_PORTS = '53'
        }
    }
}

-- 告警输出
alert_fast = {
    file = true,
    packet = false,
    limit = 100
}

-- 用于 Barnyard2/SIEM 集成的 Unified2 输出
-- alert_unified2 = { limit = 128 }

-- JSON 告警输出
alert_json = {
    file = true,
    limit = 100,
    fields = 'timestamp pkt_num proto pkt_gen pkt_len dir src_addr src_port dst_addr dst_port service rule action'
}

-- Syslog 输出
-- alert_syslog = { level = 'info', facility = 'local1' }

LUAEOF
```

### 步骤 4：下载并配置规则集

```bash
# 下载 Snort 3 社区规则
wget https://www.snort.org/downloads/community/snort3-community-rules.tar.gz
tar xzf snort3-community-rules.tar.gz
sudo cp snort3-community-rules/snort3-community.rules /usr/local/etc/snort/rules/

# 安装 PulledPork 3 进行自动化规则管理
git clone https://github.com/shirkdog/pulledpork3.git
cd pulledpork3
sudo python3 setup.py install

# 配置 PulledPork
sudo tee /usr/local/etc/pulledpork3/pulledpork.conf << 'EOF'
registered_ruleset = true
oinkcode = <YOUR_OINK_CODE>
snort_path = /usr/local/bin/snort
local_rules = /usr/local/etc/snort/rules/local.rules
sorule_path = /usr/local/etc/snort/so_rules/
snort_version = 3.0.0.0
blocklist_path = /usr/local/etc/snort/lists/
pid_path = /var/run/snort.pid
ips_policy = balanced
EOF

# 运行 PulledPork 获取并处理规则
sudo pulledpork3 -c /usr/local/etc/pulledpork3/pulledpork.conf
```

### 步骤 5：编写自定义检测规则

```bash
# 创建本地规则文件
sudo tee /usr/local/etc/snort/rules/local.rules << 'EOF'
# 检测常见端口上的反向 Shell
alert tcp $HOME_NET any -> $EXTERNAL_NET 4444 (
    msg:"LOCAL 疑似反向 Shell（端口 4444）";
    flow:established,to_server;
    content:"/bin/sh"; nocase;
    sid:1000001; rev:1;
    classtype:trojan-activity;
    priority:1;
)

# 通过 SMB 检测 Mimikatz 执行指标
alert tcp any any -> $HOME_NET 445 (
    msg:"LOCAL 通过 SMB 的 Mimikatz 横向移动";
    flow:established,to_server;
    content:"|FF|SMB";
    content:"mimikatz"; nocase; distance:0;
    sid:1000002; rev:1;
    classtype:trojan-activity;
    priority:1;
)

# 检测 DNS 隧道（高熵长子域名查询）
alert udp $HOME_NET any -> any 53 (
    msg:"LOCAL 疑似 DNS 隧道 - 查询名称过长";
    content:"|01 00|"; offset:2; depth:2;
    byte_test:1,>,50,12;
    sid:1000003; rev:1;
    classtype:policy-violation;
    priority:2;
)

# 检测 FTP 明文密码传输
alert tcp $HOME_NET any -> any 21 (
    msg:"LOCAL 检测到 FTP 明文密码";
    flow:established,to_server;
    content:"PASS "; depth:5;
    sid:1000004; rev:1;
    classtype:policy-violation;
    priority:2;
)

# 检测潜在端口扫描（SYN 洪水模式）
alert tcp $EXTERNAL_NET any -> $HOME_NET any (
    msg:"LOCAL 疑似端口扫描 SYN 洪水";
    flow:stateless;
    flags:S,12;
    threshold:type both, track by_src, count 100, seconds 10;
    sid:1000005; rev:1;
    classtype:attempted-recon;
    priority:2;
)
EOF
```

### 步骤 6：验证配置并运行

```bash
# 验证配置
snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq -T

# 在捕获接口上以 IDS 模式运行 Snort
sudo snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq \
  -i eth1 -l /var/log/snort -D

# 针对 PCAP 文件测试规则
snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq \
  -r test_traffic.pcap -l /var/log/snort/test/ -A fast

# 创建 systemd 服务用于生产部署
sudo tee /etc/systemd/system/snort.service << 'EOF'
[Unit]
Description=Snort 3 IDS
After=network.target snort-iface.service

[Service]
Type=simple
ExecStart=/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq -i eth1 -l /var/log/snort -D
ExecReload=/bin/kill -SIGHUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now snort.service
```

### 步骤 7：监控告警并调优规则

```bash
# 查看实时告警
tail -f /var/log/snort/alert_fast.txt

# 解析 JSON 告警进行分析
cat /var/log/snort/alert_json.txt | python3 -m json.tool

# 识别触发最多的规则用于调优
grep -oP 'sid:\d+' /var/log/snort/alert_fast.txt | sort | uniq -c | sort -rn | head -20

# 抑制嘈杂的误报规则
sudo tee -a /usr/local/etc/snort/rules/suppress.rules << 'EOF'
suppress gen_id 1, sig_id 2100498, track by_src, ip 10.10.1.100
suppress gen_id 1, sig_id 2100366, track by_dst, ip 10.10.5.0/24
EOF

# 验证规则数量和性能
snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq -T 2>&1 | grep -i "rules loaded"
```

## 核心概念

| 术语 | 定义 |
|------|------------|
| **IDS 与 IPS** | IDS 被动监控流量并生成告警；IPS 内联部署，可主动实时阻断或丢弃恶意数据包 |
| **Snort 规则** | 由头部（动作、协议、源/目标、端口）和选项（内容匹配、流方向、元数据）组成的检测签名，触发于匹配的流量 |
| **预处理器（Preprocessor）** | Snort 组件，在规则检测前对特定协议流量进行规范化和重组，处理分片、流重组和协议异常 |
| **DAQ（数据采集层）** | Snort 3 中的抽象层，与数据包捕获机制（AF_PACKET、PCAP、NFQ）接口以接收网络数据 |
| **Oink Code** | 从 snort.org 下载 Snort 订阅者或注册规则集所需的个人注册码 |
| **阈值/抑制** | 控制告警频率（阈值）或完全静默来自特定源/目标告警（抑制）的调优机制 |

## 工具与系统

- **Snort 3**：开源网络入侵检测和防御系统，采用基于 Lua 的配置和多线程架构
- **PulledPork 3**：自动化 Snort 规则管理工具，下载、处理和部署带策略过滤的规则集
- **Barnyard2**：专用的 Snort unified2 二进制输出读取工具，写入数据库（MySQL、PostgreSQL）进行 SIEM 集成
- **Snorby**：基于 Web 的 Snort 告警管理控制台，提供仪表板、事件分类和报告
- **tcpreplay**：通过 Snort 重放 PCAP 文件以验证规则和测试检测能力的工具

## 常见场景

### 场景：在网络边界部署 Snort IDS 满足合规要求

**场景背景**：一家医疗机构需要部署网络 IDS 以满足 HIPAA 技术保障要求。IDS 必须监控 DMZ 和内部网络之间的流量，检测常见攻击模式，并将告警转发到现有的 Splunk SIEM。峰值时期网络流量约为 500 Mbps。

**方法**：
1. 在配备双网卡的专用传感器上安装 Snort 3——一个用于监控（核心交换机的 SPAN 端口），一个用于管理
2. 使用 512 MB 环形缓冲区配置 AF_PACKET DAQ，在不丢包的情况下处理峰值吞吐量
3. 部署 Snort 社区规则加 Emerging Threats Open 规则集作为基础检测
4. 为特定于组织的威胁编写自定义规则：检测离开网络的 PHI 数据模式（社会安全号、医疗记录号格式）、未授权访问 DICOM/HL7 端口，以及连接到已知恶意 IP 列表
5. 配置 JSON 告警输出，通过 rsyslog 使用 syslog 转发到 Splunk
6. 针对 24 小时捕获的基线流量运行 Snort 以识别误报，然后为合法流量模式创建抑制规则
7. 将 Snort 作为 systemd 服务启用，配置自动重启和日志轮转

**常见陷阱**：
- 在不调优的情况下部署所有可用规则，使传感器和安全运营中心（SOC）每天被数千个误报淹没
- 忘记禁用网卡卸载功能，导致 Snort 因校验和错误或巨型帧而丢包
- 未针对峰值流量配置适当的传感器硬件，导致大流量期间丢包
- 仅依赖社区规则，没有针对组织特定威胁和合规要求的自定义规则

## 输出格式

```
## Snort IDS 部署报告

**传感器**: snort-sensor-01 (10.10.1.250)
**接口**: eth1（Core-SW1 gi0/24 的 SPAN 端口）
**配置**: /usr/local/etc/snort/snort.lua
**规则集**: Snort Community 3.0 + 本地规则（1,247 条活跃规则）
**HOME_NET**: 10.10.0.0/16

### 检测摘要（24 小时基线）

| 类别 | 告警数 | 最多触发规则 SID |
|----------|-------------|--------------|
| 侦察尝试 | 342 | 1:2100498（ICMP ping） |
| 木马活动 | 12 | 1:1000001（反向 Shell） |
| 策略违规 | 87 | 1:1000004（FTP 明文） |
| Web 应用攻击 | 23 | 1:2100654（SQL 注入） |

### 已执行调优操作
- 对 10.10.1.100 抑制 SID 2100498（监控服务器合法 ICMP）
- 对 SID 1000004 设置阈值：每源每小时最多 5 个告警
- 添加 3 条 PHI 外泄检测自定义规则
```

