aitarurachel/splunk-siem-and-log-Analysis
GitHub: aitarurachel/splunk-siem-and-log-Analysis
基于 Azure 免费层搭建 Splunk SIEM 系统,实现 Windows AD 日志采集、威胁狩猎与自动告警的动手实验。
Stars: 0 | Forks: 0
# 实验 3 — 基于 Azure 的 Splunk SIEM 与日志分析
## 概述
本实验将使用 Azure 上的免费工具,从零开始构建一个可运行的 SIEM(安全信息与事件管理)流水线。完成后,你将拥有:
- 一台在 Azure Ubuntu 虚拟机上运行的 **Splunk Enterprise** 实例,用于接收并对实时 Windows 事件日志建立索引
- 安装在 Windows Server 虚拟机(来自[实验 1](https://github.com/aitarurachel/active-directory-azure-lab))上的 **通用转发器**,通过加密通道自动将日志发送至 Splunk
- 可运行的 **SPL(Splunk 处理语言)** 搜索,用于检测登录失败、帐户锁定以及非工作时间访问
- 一个**安全仪表板**,显示登录活动、失败趋势以及最受攻击的帐户
- 一个**自动告警**,当检测到暴力破解迹象时触发,无需人工轮询
同样的架构模式——端点上的转发器、集中式索引器、分析师通过 Web UI 访问——正是企业级 Splunk 部署在规模化时所使用的。
## 本实验解决的问题
一个中型组织每天会产生数百万条日志事件:工作站的 Windows 事件日志、Active Directory 的身份验证日志、防火墙日志、Web 服务器访问日志以及云资源日志。如果没有 SIEM,这些日志就散落在各个系统中,没有人能跨系统搜索、关联事件或识别指示攻击的模式。
**没有 SIEM:** 分析师调查潜在入侵时,必须逐个登录每个系统,手动对文本文件进行 grep,并在不同来源之间进行时间戳的心算关联。一个跨越 50 台工作站的暴力破解攻击几乎不可见。
**有 SIEM:** 一位分析师可以在两分钟内,通过一条 SPL 查询同时扫描所有端点,识别攻击源 IP,查看哪些帐户被针对,并判断是否有登录成功。
本实验教授的就是这套核心技能:获取数据、有效搜索,以及将搜索转化为自动检测。
## 架构概览
```
┌─────────────────────────────────────────────────────────────────┐
│ Microsoft Azure — Free Account │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Azure Virtual Network — 10.0.0.0/16 │ │
│ │ │ │
│ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │
│ │ │ DC01 — Windows │ │ Splunk Enterprise │ │ │
│ │ │ Server VM (Lab 1) │──────▶│ Ubuntu 22.04 LTS │ │ │
│ │ │ │ :9997 │ Standard_B2s │ │ │
│ │ │ Universal Forwarder│ TLS │ │ │ │
│ │ │ inputs.conf │ │ Index: windows_logs│ │ │
│ │ │ EventLog: Security │ │ Web UI: port 8000 │ │ │
│ │ │ EventLog: System │ │ SPL · Dashboards │ │ │
│ │ │ EventLog: Applic. │ │ Alerts │ │ │
│ │ └─────────────────────┘ └──────────┬──────────┘ │ │
│ │ │ HTTPS │ │
│ │ ┌────────────────────────────────────────┼──────────┐ │ │
│ │ │ NSG Rules │ │ │ │
│ │ │ Port 22 → your IP only │ │ │ │
│ │ │ Port 8000→ your IP only │ │ │ │
│ │ │ Port 9997→ VNet only (10.0.0.0/16) │ │ │ │
│ │ └────────────────────────────────────────┼──────────┘ │ │
│ └───────────────────────────────────────────┼──────────-──┘ │
└──────────────────────────────────────────────┼─────-──────────-─┘
│
┌───────────▼──────────┐
│ SOC Analyst │
│ Browser · port 8000 │
│ Search · Dashboards │
│ Alert investigation │
└──────────────────────┘
```
**数据流总结:**
1. Windows Server 虚拟机通过正常的 AD 操作和模拟攻击流量生成事件日志条目(4624、4625、4740)
2. 通用转发器读取 `inputs.conf`,压缩并加密日志批次,通过端口 9997 发送至 Splunk 索引器
3. Splunk 解析所有事件并将其索引到 `windows_logs` 索引中
4. SOC 分析师打开浏览器,连接到端口 8000,并对已索引的数据运行 SPL 搜索
5. 计划告警搜索每 15 分钟在后台运行一次,当阈值被超过时触发
## 技术栈与工具
| 组件 | 工具/服务 | 选择理由 |
|---|---|---|
| **SIEM 平台** | Splunk Enterprise(免费许可) | 行业标准。出现在职位描述中的频率高于任何其他 SIEM。每天 500 MB 的免费许可对于家庭实验室完全足够。 |
| **日志转运器** | Splunk 通用转发器 | 专为此任务设计。轻量级、加密、原生支持 Windows 事件日志,无需自定义脚本。 |
| **SIEM 主机操作系统** | Ubuntu 22.04 LTS | Splunk 的原生 Linux 支持。稳定的 LTS 版本。`dpkg` 安装非常直接。 |
| **日志源** | Windows Server 2022 虚拟机(实验 1) | 生成真实的 Active Directory 身份验证事件 |
| **云平台** | Microsoft Azure | 免费层虚拟机足以使用。Azure 的内部 VNet 允许转发器到索引器的流量不经过公共互联网。 |
| **虚拟机大小(Splunk)** | Standard\_B2s(2 vCPU,4 GB RAM) | Splunk 文档要求的最低 RAM 是 4 GB。B2s 是满足此要求且符合免费层资格的最小 Azure 虚拟机尺寸。 |
| **查询语言** | SPL(Splunk 处理语言) | Splunk 的原生语言。管道风格的语法直接对应分析师的工作流程:查找事件,然后塑造结果。 |
| **网络安全** | Azure NSG(网络安全组) | 在 NIC 级别应用的有状态防火墙规则。将端口 9997 限制为内部 VNet 流量,将端口 22/8000 限制为单个受信任 IP。 |
## 分步操作说明
### 步骤 1:下载 Splunk Enterprise
Splunk Enterprise 对家庭实验室免费。在 60 天全功能试用后,它会自动转换为永久免费许可(每天 500 MB 的索引限制,对本实验完全足够)。
**隐私说明:** Splunk 要求注册帐户才能下载。使用 [temp-mail.org](https://temp-mail.org/en/) 获取一次性的电子邮件地址。其余字段填写虚拟信息,这些信息不会被验证。
1. 导航到 `splunk.com/en_us/download/splunk-enterprise.html`
2. 使用临时电子邮件地址创建一个免费的 Splunk 帐户
3. 选择 **Splunk Enterprise**,而不是 Splunk Cloud 或 Splunk SOAR
4. 选择 **Linux (.deb)** 包(用于你接下来要创建的 Ubuntu 虚拟机)
5. 复制下载页面上显示的 `wget` 下载命令
### 步骤 2:在 Azure 中部署 Ubuntu 虚拟机 Splunk 将在一台专用的 Ubuntu 虚拟机上运行。这样可以将其与你的 Windows Server 日志源隔离,并模拟真实的企业部署模式。 | 设置 | 值 | |---|---| | 操作系统 | Ubuntu 22.04 LTS | | 尺寸 | Standard_B2s(2 vCPU,4 GB RAM),Splunk 的最低要求 | | 磁盘 | 至少 30 GB | | 入站端口 | 22 (SSH) · 8000 (Web UI) · 9997 (转发器输入) | **需要配置的 NSG 规则:** | 端口 | 源 | 原因 | |---|---|---| | 22 | 仅你的公共 IP | SSH 访问——不要开放到 0.0.0.0/0 | | 8000 | 仅你的公共 IP | Splunk Web UI——分析师访问 | | 9997 | VNet CIDR(例如 10.0.0.0/16) | 转发器输入,仅内部使用,绝不面向公共互联网 | ### 步骤 3:在 Ubuntu 虚拟机上安装 Splunk SSH 进入你新的 Ubuntu 虚拟机,然后运行以下命令: **macOS / Linux:** ``` ssh yourusername@YOUR_VM_PUBLIC_IP ``` **Windows (PuTTY):** 打开 PuTTY → 输入虚拟机的公共 IP → 端口 22 → SSH → 打开 → 接受主机密钥 → 输入凭据。 **注意:** 在 Linux 终端输入密码时,屏幕上不会有任何显示——没有点号,没有星号。这是正常的。输入密码后按回车键即可。 连接后,安装 Splunk: ``` # 下载 Splunk Enterprise(截至2026年4月的当前版本) wget -O splunk-10.2.2-linux-amd64.deb \ "https://download.splunk.com/products/splunk/releases/10.2.2/linux/splunk-10.2.2-80b90d638de6-linux-amd64.deb" # 注意:Splunk 在每个新版本发布时都会更新下载 URL。 # 如果 wget 返回 404,请登录 splunk.com → Free Trials & Downloads → Linux .deb # 并从该页面复制更新后的 wget 命令。 # 安装包 sudo dpkg -i splunk-10.2.2-linux-amd64.deb # 启动 Splunk 并接受许可协议 # 系统将提示您创建管理员用户名和密码 sudo /opt/splunk/bin/splunk start --accept-license # 配置 Splunk 在 VM 重启时自动启动 sudo /opt/splunk/bin/splunk enable boot-start ``` 打开浏览器,导航到 `http://YOUR_VM_PUBLIC_IP:8000`——Splunk 登录屏幕确认安装成功。
###步骤 4:配置 Splunk 以接收日志 需要告诉 Splunk 监听哪个端口,通用转发器才能发送数据。 **4a — 在端口 9997 上启用接收:** 1. 登录 Splunk Web UI,地址为 `http://YOUR_VM_PUBLIC_IP:8000` 2. 点击 **设置** → **转发和接收** 3. 点击 **配置接收** → **新建接收端口** → 输入 `9997` → **保存** **4b — 创建 `windows_logs` 索引:** 1. 点击 **设置** → **索引** 2. 点击 **创建新索引** 3. 名称:`windows_logs` → **保存** ### 步骤 5:在 Windows Server 上安装通用转发器 1. 在 DC01 上,打开浏览器,导航到 `splunk.com/en_us/download/universal-forwarder.html` 2. 下载 **Windows 64-bit** 安装程序 3. 运行安装程序: - 当提示 **部署服务器** 时:输入你的 Splunk 虚拟机的 **私有** IP 和端口 `8089` - 当提示 **接收索引器** 时:输入你的 Splunk 虚拟机的 **私有** IP 和端口 `9997` - 完成安装,其他所有设置保持默认 **使用私有 IP(例如 10.0.x.x),而不是公共 IP。** 转发器流量保持在 Azure VNet 内部。这样做更快、更安全,并且符合步骤 2 中配置的 NSG 规则。 ### 步骤 6:配置 `inputs.conf` `inputs.conf` 文件告诉通用转发器要收集哪些日志通道。在你的 **Windows Server 虚拟机** 上创建此文件。 **文件位置(必须准确):** ``` C:\Program Files\SplunkUniversalForwarder\etc\system\local\inputs.conf ``` 以 **管理员身份** 打开记事本,然后将文件保存到上述路径。如果 `local` 文件夹不存在,请在 Windows 资源管理器中手动创建。 ``` [WinEventLog://Security] # 安全日志:所有身份验证事件 — 登录、失败、锁定 disabled = 0 # disabled=0 表示启用;disabled=1 将关闭此源 start_from = oldest # 收集历史事件,而不仅仅是未来的新事件 current_only = 0 evt_resolve_ad_obj = 1 # 解析 AD 对象名称,以便显示用户名而不是 SID [WinEventLog://System] # 系统日志:操作系统级别事件 — 服务启动/停止、驱动程序故障 disabled = 0 [WinEventLog://Application] # 应用程序日志:来自已安装应用程序的事件 disabled = 0 ``` 保存后,重新启动转发器以应用新配置。在 **管理员 PowerShell** 中运行以下命令: ``` Restart-Service SplunkForwarder ``` ### 步骤 7:基本的 SPL 搜索 所有搜索均在 **搜索与报告** 应用的搜索栏中输入。调整右侧的时间选取器,选择要分析的时间窗口。 **确认数据正在流入:** ``` index=windows_logs | head 100 ``` 返回最近的 100 条事件。如果没有返回结果,请确认 DC01 上的 `SplunkForwarder` 服务正在运行(在 PowerShell 中运行 `Get-Service SplunkForwarder`)。
**查找失败的登录尝试(EventCode 4625):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 | stats count by Account_Name, Workstation_Name | sort -count ``` 按用户名和源机器对所有失败的登录事件进行分组,并按数量排序。在短时间内一个帐户出现五次或更多失败,是潜在的暴力破解迹象。 **查找成功登录(EventCode 4624):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4624 | stats count by Account_Name, Logon_Type | sort -count ```
**查找帐户锁定事件(EventCode 4740):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4740 | table _time, Account_Name, Caller_Computer_Name | sort -_time ``` 同一个帐户从同一台机器出发出现多次锁定,是强烈的暴力破解信号。 **过去 24 小时内失败登录最多的 10 个用户名:** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 earliest=-24h | stats count as failures by Account_Name | sort -failures | head 10 ``` 在 Active Directory 中不存在的用户名表示帐户枚举攻击。失败次数超过 20 次的帐户需要立即调查。 **检测非工作时间登录(在 08:00–19:00 之外):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4624 | eval hour=strftime(_time, "%H") | where hour < 8 OR hour > 19 | table _time, Account_Name, Workstation_Name, Logon_Type | sort -_time ```
服务帐户在非工作时间登录(类型 5)是预期的。普通用户帐户在非工作时间进行交互式或 RDP 登录(类型 2 或 10)需要审查。 ### 步骤 8:构建安全仪表板 1. 在 Splunk 中,点击 **仪表板** → **创建新仪表板** 2. 命名为 `Windows 安全概览` → **创建仪表板** 3. 使用 **添加面板 → 新建搜索** 添加以下面板: | 面板名称 | 搜索 | 可视化 | |---|---|---| | 失败的登录 — 过去 24 小时 | EventCode=4625 配合 `stats count by Account_Name` | 条形图 | | 帐户锁定 — 过去 7 天 | EventCode=4740 配合 `table` 输出 | 事件列表 | | 随时间变化的登录活动 | EventCode=4624 配合 `timechart count` | 线图 | | 主要源 IP 地址 — 非工作时间 | 非工作时间搜索配合 `stats count by Workstation_Name` | 柱状图 |
### 步骤 9:创建自动告警 告警取代了手动仪表板监控。Splunk 按计划运行搜索,并在条件满足时通知你——这是自动化 SOC 检测的基础。 首先,手动验证搜索是否有效: ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 | stats count as failures by Account_Name | where failures > 10 ``` 然后将其保存为告警: 1. 点击 **另存为 → 告警** 2. **名称:** `潜在暴力破解 — 高失败计数` 3. **告警类型:** 计划 4. **运行间隔:** 15 分钟 5. **触发条件:** 结果数量大于 0 6. **触发操作:** 添加到已触发告警 7. 点击 **保存**
**阈值调整注意事项:** 10 次失败的阈值是一个起点。在实际环境中,你需要观察 2-4 周的基线活动,然后进行调整,以最大限度地减少误报而不遗漏真正的攻击。告警疲劳——太多低质量的告警——是 SOC 分析师职业倦怠的主要原因之一。 ## 验证检查清单 | 检查项 | 如何验证 | 预期结果 | |---|---|---| | Splunk 正在运行 | 浏览到 `http://YOUR_VM_IP:8000` | 登录页面加载 | | 数据正在流入 | 运行 `index=windows_logs \| head 10` | 返回最近的事件 | | 安全事件存在 | 运行 EventCode=4625 搜索 | 返回失败的登录事件 | | 仪表板已填充 | 打开 Windows 安全概览 | 所有面板显示数据 | | 告警已激活 | 设置 → 搜索、报告和告警 | 告警列表显示为已启用 | | NSG 规则正确 | Azure 门户 → 虚拟机 → 网络 | 端口 22/8000 限定到你的 IP;端口 9997 限定到 VNet CIDR | **生成测试数据:** 如果 4625 搜索没有返回结果,请在 Windows Server 虚拟机上故意输入几次错误的密码,然后再次运行搜索。事件通常会在 60 秒内出现在 Splunk 中。 ## 架构决策与权衡 ### 决策 1:使用两个独立的虚拟机,而不是将 Splunk 和 AD 放在同一台机器上 **我的做法:** Splunk 运行在专用的 Ubuntu 虚拟机上。Windows Server(实验 1)仅作为日志源。 **原因:** 在生产环境中,你绝不会将日志收集器与被监控的端点放在一起。如果那台机器被攻破,攻击者就同时控制了证据和调查工具。将它们分开既能模拟真实世界的架构,也能避免 Splunk 和 Active Directory 服务之间的内存争用。 **权衡:** 你需要为两台虚拟机付费,而不是一台。在本实验中,由于两者都属于 Azure 免费层预算(除非被弃用),成本为零。出于成本考虑,单虚拟机设置可能很有吸引力;但从安全角度来看,这是错误的决定。 ### 决策 2:使用通用转发器而非 Syslog 或 WinRM **我的做法:** 在 Windows Server 上安装unk 自己的通用转发器代理来发送日志。 **原因:** 通用转发器专为此任务设计。它原生处理 Windows 事件日志格式(无需解析),在发送前压缩数据,加密到 Splunk 的传输流,并内置缓冲,因此即使网络暂时断开,日志也不会丢失。Syslog 是常见的替代方案,但需要一个 Syslog 到 Splunk 的中继,并且在转换过程中会丢失一些 Windows 事件字段的保真度。 **权衡:** 通用转发器是专有代理。每个你想监控的端点都需要安装它。在规模化场景下,假设有 10,000 个端点,代理管理本身就成了一项运营负担。这就是为什么大型企业通常将 Splunk 与部署服务器(也是 Splunk 的)或端点管理工具(如 SCCM 或 Ansible)结合起来使用。在本实验中,手动安装一次是完全合理的。 ### 决策 3:将所有事件源使用单一索引(`windows_logs`) **我的做法:** 所有三个 Windows 事件日志通道(安全、系统、应用程序)都写入名为 `windows_logs` 的同一个索引。 **原因:** 简单。对于单一源的实验室,一个索引更容易管理、更容易搜索,并且避免了索引级访问控制策略的复杂性。 **权衡:** 在生产环境中,将安全、系统和应用程序日志混合到同一个索引中,会使得为不同的日志类型应用不同的保留策略、为不同的团队分配不同的 RBAC 权限以及精细控制存储成本变得更加困难。生产部署通常会有单独的索引:至少 `win_security`、`win_system`、`win_app`,并根据合规要求调整保留窗口(安全日志通常需要保留 12 个月;应用程序日志可能只需要 30 天)。 ## 在生产环境中我会做得不同的地方 本实验特意限定在学习的范围内。即使对于一个小型组织,生产级的 Splunk 部署也应该解决以下差距: **Web UI 的 TLS(端口 8000)** 本实验中的 Splunk Web UI 通过纯 HTTP 运行。在生产环境中,你会将 Splunk 放在反向代理(nginx 或 HAProxy)后面,并配备有效的 TLS 证书,或者直接配置 Splunk 原生的 SSL 设置。通过纯 HTTP 传输的分析师凭据在任何不完全受信任的网络上都容易被截获。 **用于转发器管理的 Splunk 部署服务器** 在一台机器上手动安装通用转发器对于实验室来说没问题。当端点数量达到 50 个以上时,你需要一个 Splunk 部署服务器来集中推送 `inputs.conf`、`outputs.conf` 和应用程序配置。当达到 500 个以上端点时,你需要将转发器部署与端点管理平台(SCCM、Ansible、Chef 或 Puppet)集成。 **索引级保留策略和分层存储** 本实验使用一个具有默认保留(无限,直到磁盘满)的单一索引。在生产环境中,你需要根据合规要求为每个索引定义保留窗口,通常安全日志的热/暖存储保留 90 天,冷存储保留 12 个月。Azure Blob 存储(Splunk SmartStore)以远低于虚拟机磁盘的成本处理冷层。 **基于角色的访问控制 (RBAC)** 本实验使用单一管理员帐户。生产环境中的 Splunk 应映射到你的身份提供商(通过 SAML 映射到 Azure AD / Entra ID),并强制执行索引级读取权限。1 级分析师不应该能够修改告警配置;3 级分析师不应该看到恰好流经 SIEM 的 HR 数据。 **高可用性和索引器集群** 单索引器设置没有冗余。如果虚拟机宕机,你将同时失去搜索能力和在宕机期间到达的任何事件(转发器会在本地排队,但队列存在限制)。生产环境中的 Splunk 使用索引器集群(至少 3 个节点),复制因子为 2,外加一个用于查询端高可用性的搜索头集群。 **更广泛的数据源** 本实验只摄入了 Windows 事件日志。生产环境的 SIEM 至少应摄入防火墙日志(Palo Alto、Fortinet)、云审计日志(Azure Monitor、AWS CloudTrail)、身份提供商日志(Entra ID 登录日志)、EDR 遥测(Defender for Endpoint)、电子邮件安全日志和 DNS 查询日志。跨这些来源的关联才是真正威胁检测所在。 ## 关键要点 - **SIEM 的好坏取决于其数据。** 只有一个日志源的 Splunk 比没有好,但检测覆盖率与你能从多少系统摄入数据直接相关。获取数据是第一个也是最重要的技能。 - **SPL 是力量倍增器。** 能够高效编写 SPL 搜索的分析师可以在几分钟内完成调查,否则需要数小时的手动日志审查。 - **阈值调整是一项持续的操作,而不是一次性任务。** 告警需要根据观察到的行为不断优化。在部署时设置的静态阈值很少能保持正确。 - **仪表板告诉你状态;搜索告诉你故事。** 使用仪表板进行持续的态势感知;在需要调查特定事件时,使用临时的 SPL 搜索。 - **这种架构模式是通用的。** Microsoft Sentinel、AWS Security Hub、Elastic SIEM 和 Chronicle 都遵循相同的概念模型:代理将日志转发到集中式平台,分析师在此平台上进行搜索、关联和告警。工具在变,但思维模型不变。
### 步骤 2:在 Azure 中部署 Ubuntu 虚拟机 Splunk 将在一台专用的 Ubuntu 虚拟机上运行。这样可以将其与你的 Windows Server 日志源隔离,并模拟真实的企业部署模式。 | 设置 | 值 | |---|---| | 操作系统 | Ubuntu 22.04 LTS | | 尺寸 | Standard_B2s(2 vCPU,4 GB RAM),Splunk 的最低要求 | | 磁盘 | 至少 30 GB | | 入站端口 | 22 (SSH) · 8000 (Web UI) · 9997 (转发器输入) | **需要配置的 NSG 规则:** | 端口 | 源 | 原因 | |---|---|---| | 22 | 仅你的公共 IP | SSH 访问——不要开放到 0.0.0.0/0 | | 8000 | 仅你的公共 IP | Splunk Web UI——分析师访问 | | 9997 | VNet CIDR(例如 10.0.0.0/16) | 转发器输入,仅内部使用,绝不面向公共互联网 | ### 步骤 3:在 Ubuntu 虚拟机上安装 Splunk SSH 进入你新的 Ubuntu 虚拟机,然后运行以下命令: **macOS / Linux:** ``` ssh yourusername@YOUR_VM_PUBLIC_IP ``` **Windows (PuTTY):** 打开 PuTTY → 输入虚拟机的公共 IP → 端口 22 → SSH → 打开 → 接受主机密钥 → 输入凭据。 **注意:** 在 Linux 终端输入密码时,屏幕上不会有任何显示——没有点号,没有星号。这是正常的。输入密码后按回车键即可。 连接后,安装 Splunk: ``` # 下载 Splunk Enterprise(截至2026年4月的当前版本) wget -O splunk-10.2.2-linux-amd64.deb \ "https://download.splunk.com/products/splunk/releases/10.2.2/linux/splunk-10.2.2-80b90d638de6-linux-amd64.deb" # 注意:Splunk 在每个新版本发布时都会更新下载 URL。 # 如果 wget 返回 404,请登录 splunk.com → Free Trials & Downloads → Linux .deb # 并从该页面复制更新后的 wget 命令。 # 安装包 sudo dpkg -i splunk-10.2.2-linux-amd64.deb # 启动 Splunk 并接受许可协议 # 系统将提示您创建管理员用户名和密码 sudo /opt/splunk/bin/splunk start --accept-license # 配置 Splunk 在 VM 重启时自动启动 sudo /opt/splunk/bin/splunk enable boot-start ``` 打开浏览器,导航到 `http://YOUR_VM_PUBLIC_IP:8000`——Splunk 登录屏幕确认安装成功。
###步骤 4:配置 Splunk 以接收日志 需要告诉 Splunk 监听哪个端口,通用转发器才能发送数据。 **4a — 在端口 9997 上启用接收:** 1. 登录 Splunk Web UI,地址为 `http://YOUR_VM_PUBLIC_IP:8000` 2. 点击 **设置** → **转发和接收** 3. 点击 **配置接收** → **新建接收端口** → 输入 `9997` → **保存** **4b — 创建 `windows_logs` 索引:** 1. 点击 **设置** → **索引** 2. 点击 **创建新索引** 3. 名称:`windows_logs` → **保存** ### 步骤 5:在 Windows Server 上安装通用转发器 1. 在 DC01 上,打开浏览器,导航到 `splunk.com/en_us/download/universal-forwarder.html` 2. 下载 **Windows 64-bit** 安装程序 3. 运行安装程序: - 当提示 **部署服务器** 时:输入你的 Splunk 虚拟机的 **私有** IP 和端口 `8089` - 当提示 **接收索引器** 时:输入你的 Splunk 虚拟机的 **私有** IP 和端口 `9997` - 完成安装,其他所有设置保持默认 **使用私有 IP(例如 10.0.x.x),而不是公共 IP。** 转发器流量保持在 Azure VNet 内部。这样做更快、更安全,并且符合步骤 2 中配置的 NSG 规则。 ### 步骤 6:配置 `inputs.conf` `inputs.conf` 文件告诉通用转发器要收集哪些日志通道。在你的 **Windows Server 虚拟机** 上创建此文件。 **文件位置(必须准确):** ``` C:\Program Files\SplunkUniversalForwarder\etc\system\local\inputs.conf ``` 以 **管理员身份** 打开记事本,然后将文件保存到上述路径。如果 `local` 文件夹不存在,请在 Windows 资源管理器中手动创建。 ``` [WinEventLog://Security] # 安全日志:所有身份验证事件 — 登录、失败、锁定 disabled = 0 # disabled=0 表示启用;disabled=1 将关闭此源 start_from = oldest # 收集历史事件,而不仅仅是未来的新事件 current_only = 0 evt_resolve_ad_obj = 1 # 解析 AD 对象名称,以便显示用户名而不是 SID [WinEventLog://System] # 系统日志:操作系统级别事件 — 服务启动/停止、驱动程序故障 disabled = 0 [WinEventLog://Application] # 应用程序日志:来自已安装应用程序的事件 disabled = 0 ``` 保存后,重新启动转发器以应用新配置。在 **管理员 PowerShell** 中运行以下命令: ``` Restart-Service SplunkForwarder ``` ### 步骤 7:基本的 SPL 搜索 所有搜索均在 **搜索与报告** 应用的搜索栏中输入。调整右侧的时间选取器,选择要分析的时间窗口。 **确认数据正在流入:** ``` index=windows_logs | head 100 ``` 返回最近的 100 条事件。如果没有返回结果,请确认 DC01 上的 `SplunkForwarder` 服务正在运行(在 PowerShell 中运行 `Get-Service SplunkForwarder`)。
**查找失败的登录尝试(EventCode 4625):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 | stats count by Account_Name, Workstation_Name | sort -count ``` 按用户名和源机器对所有失败的登录事件进行分组,并按数量排序。在短时间内一个帐户出现五次或更多失败,是潜在的暴力破解迹象。 **查找成功登录(EventCode 4624):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4624 | stats count by Account_Name, Logon_Type | sort -count ```
**查找帐户锁定事件(EventCode 4740):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4740 | table _time, Account_Name, Caller_Computer_Name | sort -_time ``` 同一个帐户从同一台机器出发出现多次锁定,是强烈的暴力破解信号。 **过去 24 小时内失败登录最多的 10 个用户名:** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 earliest=-24h | stats count as failures by Account_Name | sort -failures | head 10 ``` 在 Active Directory 中不存在的用户名表示帐户枚举攻击。失败次数超过 20 次的帐户需要立即调查。 **检测非工作时间登录(在 08:00–19:00 之外):** ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4624 | eval hour=strftime(_time, "%H") | where hour < 8 OR hour > 19 | table _time, Account_Name, Workstation_Name, Logon_Type | sort -_time ```
服务帐户在非工作时间登录(类型 5)是预期的。普通用户帐户在非工作时间进行交互式或 RDP 登录(类型 2 或 10)需要审查。 ### 步骤 8:构建安全仪表板 1. 在 Splunk 中,点击 **仪表板** → **创建新仪表板** 2. 命名为 `Windows 安全概览` → **创建仪表板** 3. 使用 **添加面板 → 新建搜索** 添加以下面板: | 面板名称 | 搜索 | 可视化 | |---|---|---| | 失败的登录 — 过去 24 小时 | EventCode=4625 配合 `stats count by Account_Name` | 条形图 | | 帐户锁定 — 过去 7 天 | EventCode=4740 配合 `table` 输出 | 事件列表 | | 随时间变化的登录活动 | EventCode=4624 配合 `timechart count` | 线图 | | 主要源 IP 地址 — 非工作时间 | 非工作时间搜索配合 `stats count by Workstation_Name` | 柱状图 |
### 步骤 9:创建自动告警 告警取代了手动仪表板监控。Splunk 按计划运行搜索,并在条件满足时通知你——这是自动化 SOC 检测的基础。 首先,手动验证搜索是否有效: ``` index=windows_logs sourcetype=WinEventLog:Security EventCode=4625 | stats count as failures by Account_Name | where failures > 10 ``` 然后将其保存为告警: 1. 点击 **另存为 → 告警** 2. **名称:** `潜在暴力破解 — 高失败计数` 3. **告警类型:** 计划 4. **运行间隔:** 15 分钟 5. **触发条件:** 结果数量大于 0 6. **触发操作:** 添加到已触发告警 7. 点击 **保存**
**阈值调整注意事项:** 10 次失败的阈值是一个起点。在实际环境中,你需要观察 2-4 周的基线活动,然后进行调整,以最大限度地减少误报而不遗漏真正的攻击。告警疲劳——太多低质量的告警——是 SOC 分析师职业倦怠的主要原因之一。 ## 验证检查清单 | 检查项 | 如何验证 | 预期结果 | |---|---|---| | Splunk 正在运行 | 浏览到 `http://YOUR_VM_IP:8000` | 登录页面加载 | | 数据正在流入 | 运行 `index=windows_logs \| head 10` | 返回最近的事件 | | 安全事件存在 | 运行 EventCode=4625 搜索 | 返回失败的登录事件 | | 仪表板已填充 | 打开 Windows 安全概览 | 所有面板显示数据 | | 告警已激活 | 设置 → 搜索、报告和告警 | 告警列表显示为已启用 | | NSG 规则正确 | Azure 门户 → 虚拟机 → 网络 | 端口 22/8000 限定到你的 IP;端口 9997 限定到 VNet CIDR | **生成测试数据:** 如果 4625 搜索没有返回结果,请在 Windows Server 虚拟机上故意输入几次错误的密码,然后再次运行搜索。事件通常会在 60 秒内出现在 Splunk 中。 ## 架构决策与权衡 ### 决策 1:使用两个独立的虚拟机,而不是将 Splunk 和 AD 放在同一台机器上 **我的做法:** Splunk 运行在专用的 Ubuntu 虚拟机上。Windows Server(实验 1)仅作为日志源。 **原因:** 在生产环境中,你绝不会将日志收集器与被监控的端点放在一起。如果那台机器被攻破,攻击者就同时控制了证据和调查工具。将它们分开既能模拟真实世界的架构,也能避免 Splunk 和 Active Directory 服务之间的内存争用。 **权衡:** 你需要为两台虚拟机付费,而不是一台。在本实验中,由于两者都属于 Azure 免费层预算(除非被弃用),成本为零。出于成本考虑,单虚拟机设置可能很有吸引力;但从安全角度来看,这是错误的决定。 ### 决策 2:使用通用转发器而非 Syslog 或 WinRM **我的做法:** 在 Windows Server 上安装unk 自己的通用转发器代理来发送日志。 **原因:** 通用转发器专为此任务设计。它原生处理 Windows 事件日志格式(无需解析),在发送前压缩数据,加密到 Splunk 的传输流,并内置缓冲,因此即使网络暂时断开,日志也不会丢失。Syslog 是常见的替代方案,但需要一个 Syslog 到 Splunk 的中继,并且在转换过程中会丢失一些 Windows 事件字段的保真度。 **权衡:** 通用转发器是专有代理。每个你想监控的端点都需要安装它。在规模化场景下,假设有 10,000 个端点,代理管理本身就成了一项运营负担。这就是为什么大型企业通常将 Splunk 与部署服务器(也是 Splunk 的)或端点管理工具(如 SCCM 或 Ansible)结合起来使用。在本实验中,手动安装一次是完全合理的。 ### 决策 3:将所有事件源使用单一索引(`windows_logs`) **我的做法:** 所有三个 Windows 事件日志通道(安全、系统、应用程序)都写入名为 `windows_logs` 的同一个索引。 **原因:** 简单。对于单一源的实验室,一个索引更容易管理、更容易搜索,并且避免了索引级访问控制策略的复杂性。 **权衡:** 在生产环境中,将安全、系统和应用程序日志混合到同一个索引中,会使得为不同的日志类型应用不同的保留策略、为不同的团队分配不同的 RBAC 权限以及精细控制存储成本变得更加困难。生产部署通常会有单独的索引:至少 `win_security`、`win_system`、`win_app`,并根据合规要求调整保留窗口(安全日志通常需要保留 12 个月;应用程序日志可能只需要 30 天)。 ## 在生产环境中我会做得不同的地方 本实验特意限定在学习的范围内。即使对于一个小型组织,生产级的 Splunk 部署也应该解决以下差距: **Web UI 的 TLS(端口 8000)** 本实验中的 Splunk Web UI 通过纯 HTTP 运行。在生产环境中,你会将 Splunk 放在反向代理(nginx 或 HAProxy)后面,并配备有效的 TLS 证书,或者直接配置 Splunk 原生的 SSL 设置。通过纯 HTTP 传输的分析师凭据在任何不完全受信任的网络上都容易被截获。 **用于转发器管理的 Splunk 部署服务器** 在一台机器上手动安装通用转发器对于实验室来说没问题。当端点数量达到 50 个以上时,你需要一个 Splunk 部署服务器来集中推送 `inputs.conf`、`outputs.conf` 和应用程序配置。当达到 500 个以上端点时,你需要将转发器部署与端点管理平台(SCCM、Ansible、Chef 或 Puppet)集成。 **索引级保留策略和分层存储** 本实验使用一个具有默认保留(无限,直到磁盘满)的单一索引。在生产环境中,你需要根据合规要求为每个索引定义保留窗口,通常安全日志的热/暖存储保留 90 天,冷存储保留 12 个月。Azure Blob 存储(Splunk SmartStore)以远低于虚拟机磁盘的成本处理冷层。 **基于角色的访问控制 (RBAC)** 本实验使用单一管理员帐户。生产环境中的 Splunk 应映射到你的身份提供商(通过 SAML 映射到 Azure AD / Entra ID),并强制执行索引级读取权限。1 级分析师不应该能够修改告警配置;3 级分析师不应该看到恰好流经 SIEM 的 HR 数据。 **高可用性和索引器集群** 单索引器设置没有冗余。如果虚拟机宕机,你将同时失去搜索能力和在宕机期间到达的任何事件(转发器会在本地排队,但队列存在限制)。生产环境中的 Splunk 使用索引器集群(至少 3 个节点),复制因子为 2,外加一个用于查询端高可用性的搜索头集群。 **更广泛的数据源** 本实验只摄入了 Windows 事件日志。生产环境的 SIEM 至少应摄入防火墙日志(Palo Alto、Fortinet)、云审计日志(Azure Monitor、AWS CloudTrail)、身份提供商日志(Entra ID 登录日志)、EDR 遥测(Defender for Endpoint)、电子邮件安全日志和 DNS 查询日志。跨这些来源的关联才是真正威胁检测所在。 ## 关键要点 - **SIEM 的好坏取决于其数据。** 只有一个日志源的 Splunk 比没有好,但检测覆盖率与你能从多少系统摄入数据直接相关。获取数据是第一个也是最重要的技能。 - **SPL 是力量倍增器。** 能够高效编写 SPL 搜索的分析师可以在几分钟内完成调查,否则需要数小时的手动日志审查。 - **阈值调整是一项持续的操作,而不是一次性任务。** 告警需要根据观察到的行为不断优化。在部署时设置的静态阈值很少能保持正确。 - **仪表板告诉你状态;搜索告诉你故事。** 使用仪表板进行持续的态势感知;在需要调查特定事件时,使用临时的 SPL 搜索。 - **这种架构模式是通用的。** Microsoft Sentinel、AWS Security Hub、Elastic SIEM 和 Chronicle 都遵循相同的概念模型:代理将日志转发到集中式平台,分析师在此平台上进行搜索、关联和告警。工具在变,但思维模型不变。
标签:Active Directory, AMSI绕过, Azure, Plaso, SPL, Universal Forwarder, Windows Server, Windows安全审计, 事件日志, 免杀技术, 威胁检测, 安全仪表板, 安全信息事件管理, 安全运营, 扫描框架, 搜索处理语言, 暴力破解检测, 登录事件, 自动化告警, 账户锁定