在 Kali Linux 上的三虚拟机网络中,对 Snort 3 进行了全流程部署,既作为入侵检测系统(被动监控),也作为入侵防御系统(通过 iptables 主动阻断),并针对四种攻击向量完成了验证。
本实验通过将同一套四向量攻击链运行两次,证明了检测与防护之间的运维性区别——第一次针对只能记录日志但无法阻断的 IDS,第二次针对 IDS + iptables IPS 层,后者有选择地丢弃攻击流量,同时保留合法流量。
| 组件 | 详情 |
|---|---|
| 分析机 / 路由器 | Kali Linux — 3 个适配器:eth0 WAN(192.168.10.143,NAT),eth1 LAN1(10.10.10.1,仅主机模式),eth2 LAN2(192.168.50.1,仅主机模式) |
| 攻击机 | Kali Linux — eth0 接入 VMnet9(10.10.10.10)— 默认网关 10.10.10.1 |
| 目标机 | Metasploitable 2 — eth0 接入 VMnet10(192.168.50.10)— 默认网关 192.168.50.1 |
| Snort 版本 | Snort++ 3.12.1.0-0kali1(安装在分析机上) |
| 攻击工具 | Nmap 7.99、Hydra v9.6、Metasploit Framework(msfconsole) |
| 虚拟化平台 | VMware — VMnet9 = 10.10.10.0/24,VMnet10 = 192.168.50.0/24(均为仅主机模式) |
攻击机与 Metasploitable 之间的所有流量都会被强制经过分析机,使其成为监控与执行管控两方面的天然咽喉点。
┌─────────────────────────┐
│ Analyzer / Router │
│ Kali + Snort 3 │
│ │
Attacker Kali ──VMnet9──┤ eth1: 10.10.10.1 │
10.10.10.10 │ │
│ eth0: 192.168.10.143 ───┼──> WAN (NAT)
│ │
Metasploitable 2 ─VMnet10┤ eth2: 192.168.50.1 │
192.168.50.10 │ │
└─────────────────────────┘
图片就位后,请用
screenshots/01-network-topology.png替换此 ASCII 示意图:Topology
本实验分两个阶段执行,每个阶段使用相同的四向量攻击链:
ping 进行主机发现nmap -sS 进行端口枚举(1000 个端口)阶段 1(IDS) 在分析机上以被动模式运行 Snort,并加载五条自定义规则——实时观察告警,确认漏洞利用仍会照常进行。
阶段 2(IPS) 将 Snort 与 iptables 执行层配合,使用精准的丢弃规则——确认攻击被阻断,同时 ICMP ping 和合法 FTP 登录仍然可用。
MASQUERADE 和 FORWARD 规则,使分析机能够在子网间路由并访问 WAN——参见 scripts/router_config.sh。scripts/ping_check.sh 验证各虚拟机之间的端到端连通性。Snort 通过 Kali 包管理器安装(sudo apt install snort -y),并在 /etc/snort/snort.conf 中配置:
HOME_NET = "10.10.10.0/24,192.168.50.0/24"
EXTERNAL_NET = "any"
ips = {
enable_builtin_rules = true,
include = "/etc/snort/rules/local.rules",
variables = default_variables
}
alert_fast = { file = true, packet = false }
HOME_NET 覆盖两个内部子网,使 Snort 将分析机上所有子网间流量都视为值得检查的对象。alert_fast 生成紧凑的单行告警(逐包记录会产生过大的数据量)。
配置验证:
sudo snort -T -c /etc/snort/snort.conf
# Result: 652 rules loaded (5 custom text + 647 built-in), 0 warnings
/etc/snort/rules/local.rules 中的五条规则(完整文件见 scripts/local.rules):
Snort 以被动模式运行在两个内部接口上:
sudo snort -c /etc/snort/snort.conf -i eth1 -i eth2 \
-A alert_fast -l /var/log/snort/
# Watch alerts in a second terminal:
sudo tail -f /var/log/snort/alert_fast.txt
启动输出确认 pcap DAQ configured to passive——Snort 能看到每个数据包,但无法丢弃或修改其中任何一个。
从攻击机执行 scripts/attack_simulator.sh 后:
IDS 检测到了一切,却未能阻断任何东西。 这是阶段 1 的核心教训:一个没有执行能力的 IDS 只是警报系统,而不是锁。等到人工分析师读取告警时,攻击者早已是 root 权限。
另一个观察点:Snort 的内置规则(116:408、116:414)会在 DHCP 广播流量上触发——这并非恶意行为,但在生产部署中需要加入抑制规则,才能保持告警日志的可操作性。
IPS 层通过 scripts/ips_setup.sh 部署,该脚本会:
-D)启动 Snort,确保持续记录日志从攻击机重新运行同一攻击脚本:
两项手动检查确认了选择性执行:
ping -c 4 192.168.50.10 → 发送 4 个数据包,接收 4 个,0% 丢失msfadmin:msfadmin 执行 ftp 192.168.50.10 → 220 (vsFTPd 2.3.4) … 230 Login successful运行期间 iptables 数据包计数器的定量证明:2051 个数据包被接受,12 个数据包被 FTP connlimit 规则丢弃,808 个 ICMP 数据包被接受——选择性执行的具体数字。
即使在 IPS 模式下,Snort 仍会在 iptables 丢弃后续数据包之前,对到达其被动检测点的数据包持续触发 SID 1000002 / 1000003 告警——这意味着 iptables 负责执行阻断,而 Snort 负责审计日志,两者协同工作。
是的——SID 1000001 至 1000004 中的每一条都在攻击模拟期间正确触发:
:) 内容匹配精确捕获了漏洞利用字节序列。但检测不等于防护。 在每条告警持续触发的同时,vsftpd 漏洞利用打开了 root Meterpreter shell。SOC 分析师若实时盯着 IDS,会看到入侵发生——但攻击者在几秒内就已获得 root 权限,仅靠告警远远不够。这正是 IPS 存在的运维层面的核心原因。
该实现实现了完整的攻击缓解,同时可观察的正常流量影响为零。效果来自精准的规则设计——每条 iptables 规则针对一种行为特征,而非宽泛的协议:
connlimit 阻断暴力破解工具的并行性,但不破坏单会话 FTP。STRING 匹配 丢弃确切的漏洞利用载荷,但不过滤合法的 FTP 登录流量。一个已承认的局限:ICMP 被完全放行,这意味着攻击者仍然可以通过 ping 确认 Metasploitable 是否在线。在安全要求更高的环境中,这应该被限速或限制为仅允许可信来源。在本实验中,ICMP 是主要的连通性验证机制,因此保持开放。
本实验使用专用 Snort 机器。与在 pfSense 或 OPNsense 等防火墙设备中以插件方式运行 Snort 相比:
专用方案的优点:
权衡取舍:
对于需要性能、位置灵活性和定制能力的企业环境,专用 Snort 是正确的选择。pfSense/OPNsense 插件方案则更适合以易用性为优先的中小企业或家庭实验室环境。
阶段 2 在技术上属于被动 Snort + iptables 执行,而非 Snort 真正运行在 inline 模式——Snort 本身只负责记录日志(pcap DAQ configured to passive),而由 iptables 根据速率限制、字符串匹配和连接计数执行丢包。
这是一种合法且常见的部署模式(许多现实世界中的 Linux 系 IDS/IPS 架构正是如此运作)。一个自然的后续改进是将阶段 2 迁移到真正的 inline 配置,使用 snort --daq nfq(或 inline 模式下的 afpacket),并配合 Snort 的 reject / drop 规则动作,让 Snort 本身基于完整的特征匹配执行丢包,而不是交给 iptables。
snort-ids-ips-lab/
├── README.md ← this file
├── report/
│ ├── Snort-IDS-IPS-Report.pdf ← full lab report
│ └── Snort-IDS-IPS-Report.docx ← editable source
├── scripts/
│ ├── router_config.sh ← IP forwarding + iptables routing
│ ├── ping_check.sh ← connectivity verification
│ ├── attack_simulator.sh ← 4-vector attack chain
│ ├── ips_setup.sh ← IPS iptables rules + Snort daemon
│ └── local.rules ← 5 custom Snort rules (SID 1000001-1000005)
├── screenshots/ ← report figures
├── .gitignore
└── LICENSE
⚠️ 仅供实验使用。 这些脚本会对一个故意存在漏洞的目标运行真实漏洞利用和暴力破解工具。请勿对任何你不拥有、且未获得明确书面授权进行测试的系统运行这些脚本。
scripts/router_config.sh,然后运行 scripts/ping_check.sh 确认全面连通。sudo apt update && sudo apt install snort -y
scripts/local.rules 放到 /etc/snort/rules/local.rules,并在 /etc/snort/snort.conf 中设置 HOME_NET = "10.10.10.0/24,192.168.50.0/24"。sudo snort -T -c /etc/snort/snort.conf — 预期加载 652 条规则,0 警告。sudo snort -c /etc/snort/snort.conf -i eth1 -i eth2 -A alert_fast -l /var/log/snort/
# In another terminal:
sudo tail -f /var/log/snort/alert_fast.txt
sudo ./scripts/attack_simulator.sh — 观察告警触发并获取 Meterpreter shell。本仓库记录的所有活动均仅在自包含的 VMware 虚拟实验室环境中进行,用于有监督的学术学习目的。未以任何方式针对、扫描或影响任何外部、生产或真实世界的系统。Metasploitable 2 是一台故意存在漏洞的虚拟机,专门为安全培训而设计。
不得利用本材料对任何真实系统复现这些活动,除非获得系统所有者的明确书面授权。 未经授权的端口扫描、口令攻击或利用网络服务,在大多数司法管辖区均属违法行为。
MIT — 参见 LICENSE。实验报告本身仅用于教学参考。
| SID | 规则名 | 触发条件 |
|---|
| 1000001 | 检测到 ICMP Ping | 任意方向的 ICMP 流量 — 捕获侦察性 ping |
| 1000002 | FTP 连接尝试 | 到端口 21 的任何 TCP 连接 — 同时捕获合法流量和暴力破解流量 |
| 1000003 | 疑似 Nmap SYN 扫描 | 仅设置了 SYN 标志的 TCP 数据包(flags:S)— 半开扫描的特征 |
| 1000004 | VSFTPD 2.3.4 后门尝试 | FTP 端口 21 上的 content:":)" — 正是 CVE-2011-2523 的触发字符串 |
| 1000005 | 疑似 Metasploit Shellcode | `content:" |
| 攻击 | 检测情况 | 结果 |
|---|
| ICMP 侦察 | ✅ SID 1000001 — 双向告警 | Ping 完成 |
| Nmap SYN 扫描 | ✅ SID 1000003 — 不到 1 秒内产生数千条告警 | 枚举出 23 个开放端口 |
| Hydra FTP 暴力破解 | ✅ SID 1000002 — 反复产生 FTP 连接告警 | msfadmin:msfadmin 口令被破解 |
| vsftpd 2.3.4 后门 | ✅ SID 1000004 — :) 内容匹配触发 | 获得 Root Meterpreter Shell |
| 规则 | 作用 |
|---|
ACCEPT icmp | 显式放行所有 ICMP — 保留连通性检查能力 |
DROP tcp dpt:21 STRING ":)" | 丢弃端口 21 上包含 vsftpd 2.3.4 后门触发字符串的数据包 |
ACCEPT tcp --syn -m limit --limit 10/s --limit-burst 20 | 在速率限制范围内允许正常 TCP 握手 |
DROP tcp --syn(limit 之后) | 丢弃超过 10/s 的 SYN 洪水 — 阻断 Nmap SYN 扫描 |
DROP tcp dpt:21 -m connlimit --connlimit-above 5 --connlimit-mask 32 | 阻止每个来源超过 5 个并发 FTP 连接 — 瓦解 Hydra 的并行攻击 |
ACCEPT eth1→eth0、ACCEPT eth2→eth0 | 正常出站路由 |
ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED | 有状态 — 保留已建立的会话 |
| 攻击 | 阶段 2 结果 |
|---|
| ICMP 侦察 | ✅ 放行(有意为之) |
| Nmap SYN 扫描 | ❌ 已阻断 — 1000 filtered tcp ports (no-response),扫描耗时 21.71 秒,而非 <1 秒 |
| Hydra FTP 暴力破解 | ❌ 已阻断 — all children were disabled due too many connection errors — 0 valid password found |
| vsftpd 后门 | ❌ 已阻断 — Rex::ConnectionTimeout — Exploit completed, but no session was created |
| 攻击 / 流量 | 阶段 1(仅 IDS) | 阶段 2(IDS + iptables IPS) |
|---|
| ICMP ping | 已检测 ✅ | 放行 ✅(有意为之) |
| Nmap SYN 扫描 | 已检测 — 发现 23 个开放端口 | 已阻断 — 1000 个 filtered |
| Hydra FTP 暴力破解 | 已检测 — msfadmin:msfadmin 被破解 | 已阻断 — 未发现任何口令 |
| vsftpd 2.3.4 漏洞利用 | 已检测 — 获得 Root Meterpreter Shell | 已阻断 — 连接超时 |
| 合法 FTP 登录 | 不适用 | 保留(230 Login successful) |
sudo ./scripts/ips_setup.shping -c 4 192.168.50.10 # should succeed
ftp 192.168.50.10 # msfadmin / msfadmin — should succeed