Wazuh AWS CloudTrail 集成指南:从 S3 采集到规则引擎告警的完整实践
【免费下载链接】wazuhWazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.项目地址: https://gitcode.com/GitHub_Trending/wa/wazuh
导读
本文基于 Wazuh 开源安全平台的 AWS 集成模块,系统讲解如何采集并分析 AWS CloudTrail 日志。AWS CloudTrail 会记录 AWS 基础设施中的每一次 API 调用与账户活动,为治理、合规与安全监控提供审计日志;Wazuh 通过内置的aws-s3wodle 从 S3 存储桶拉取 CloudTrail 日志,交给规则引擎分析,并对未授权 API 调用、IAM 变更、安全组修改等可疑活动实时生成告警。读完本文,你将掌握 CloudTrail 在 Wazuh 中的完整配置流程、IAM 最小权限方案、底层处理链路与验证方法,可直接照搬落地。
CloudTrail 日志与 Wazuh 的对接方式
AWS CloudTrail 会在您启用后持续记录账户内发生的管理事件与数据事件,并默认以JSON文件形式投递到指定的 S3 存储桶。Wazuh 的 AWS 模块(位于仓库 wodles/aws)负责完成"拉取—解析—告警"整条链路:
- 按周期扫描 S3 存储桶,找出新产生的 CloudTrail 日志对象;
- 下载并解压
*.json.gz文件,读取其中的Records字段(每条记录即一个 CloudTrail 事件); - 将事件转换为 Wazuh 告警消息(
aws数据字段携带原始事件信息); - 交由 Wazuh 规则引擎匹配,产生告警。
在源码层面,这一逻辑由 wodles/aws/buckets_s3/cloudtrail.py 中的AWSCloudTrailBucket类实现:它继承自 wodles/aws/buckets_s3/aws_bucket.py 中的AWSLogsBucket,并在初始化时指定service = 'CloudTrail'、field_to_load = 'Records',即从日志 JSON 中加载Records数组作为事件列表。入口脚本 wodles/aws/aws_s3.py 会根据命令行参数--type cloudtrail(默认值即为cloudtrail)实例化该处理类。
提示:仓库中另有一份同主题文档 docs/ref/modules/integrations/aws-cloudtrail.md,本文在此基础上结合源码与测试做了纵深扩充。
前置条件
开始配置前,请确认以下三项均已就绪:
- 一个已启用 CloudTrail 并配置将日志投递到 S3 存储桶的 AWS 账户;
- AWS 凭证(Access Key 与 Secret Key),或一个具备读取该 S3 存储桶权限的 IAM 角色;
- Wazuh 代理端已安装 Python 3 与
boto3库(AWS SDK for Python,模块运行时的依赖)。
在 ossec.conf 中配置 aws-s3 wodle
Wazuh 代理的 AWS 模块通过代理配置文件ossec.conf中的<wodle name="aws-s3">块启用。以下是一个针对 CloudTrail 的最小可用配置:
<wodle name="aws-s3"> <disabled>no</disabled> <interval>10m</interval> <run_on_start>yes</run_on_start> <skip_on_error>yes</skip_on_error> <bucket type="cloudtrail"> <name>my-cloudtrail-bucket</name> <access_key>YOUR_ACCESS_KEY</access_key> <secret_key>YOUR_SECRET_KEY</secret_key> <regions>us-east-1</regions> <path>AWSLogs/</path> <only_logs_after>2024-01-01</only_logs_after> <remove_from_bucket>no</remove_from_bucket> </bucket> </wodle>上述配置的语义是:每 10 分钟扫描一次my-cloudtrail-bucket存储桶,解析us-east-1区域、AWSLogs/路径前缀下 2024-01-01 之后产生的 CloudTrail 日志;模块启动时立即处理一次,处理出错时跳过该文件继续运行,且不删除桶内已处理文件。
配置选项详解
| 选项 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
disabled | 否 | no | 设为yes时禁用整个 AWS 模块。 |
interval | 否 | 5s | 两次 S3 存储桶扫描之间的时间间隔。 |
run_on_start | 否 | yes | 模块启动时立即处理一次日志,而不是等到第一个周期结束。 |
skip_on_error | 否 | yes | 处理出错时跳过该文件继续,而不是终止模块。 |
bucket | 是 | — | 定义要监控的 S3 存储桶;对 CloudTrail 日志必须设为type="cloudtrail"。 |
name | 是 | — | S3 存储桶名称。 |
access_key | 否 | — | AWS 访问密钥 ID;使用 IAM 角色认证时无需填写。 |
secret_key | 否 | — | AWS 秘密访问密钥;使用 IAM 角色认证时无需填写。 |
aws_profile | 否 | — | AWS CLI 配置文件(profile)名称,用于替代密钥认证。 |
iam_role_arn | 否 | — | 要代入的 IAM 角色 ARN,用于跨账户访问。 |
iam_role_duration | 否 | — | 代入 IAM 角色会话的持续时间(秒)。 |
aws_organization_id | 否 | — | AWS 组织 ID,用于过滤该组织下的日志。 |
aws_account_id | 否 | — | 指定要过滤日志的 AWS 账户 ID。 |
aws_account_alias | 否 | — | AWS 账户别名,用于告警信息富化。 |
regions | 否 | — | 逗号分隔的 AWS 区域列表。 |
path | 否 | — | CloudTrail 日志文件的 S3 Key 前缀过滤器。 |
path_suffix | 否 | — | S3 Key 后缀过滤器。 |
only_logs_after | 否 | — | 仅处理此日期(YYYY-MM-DD)之后产生的日志。 |
remove_from_bucket | 否 | no | 处理完成后是否从存储桶删除日志文件。 |
discard_regex | 否 | — | 过滤掉匹配事件的正则表达式,需配合field属性指定 JSON 字段名,格式为<discard_regex field="fieldName">regex</discard_regex>。 |
sts_endpoint | 否 | — | 自定义 AWS STS 终端节点 URL(如 VPC Endpoint)。 |
service_endpoint | 否 | — | 自定义 AWS S3 终端节点 URL(如 VPC Endpoint)。 |
关键选项的源码级说明
- 认证方式:虽然
ossec.conf中仍支持access_key/secret_key,但在 wodles/aws/aws_tools.py 的参数定义中,这两个参数已标注为 4.4 版本起弃用(DEPRECATED_MESSAGE),官方推荐改用 IAM 角色或 AWS Profile 认证。iam_role_duration在 wodles/aws/aws_tools.py 的arg_valid_iam_role_duration中校验为 900~3600 秒,且必须与iam_role_arn同时使用,否则会直接报错。 path前缀:CloudTrail 默认的 S3 目录结构为AWSLogs/<account-id>/CloudTrail/<region>/<YYYY/MM/DD>/...。源码 wodles/aws/buckets_s3/aws_bucket.py 中的AWSLogsBucket会据此拼接get_base_prefix()、get_service_prefix()与get_full_prefix()来定位各账户、各区域的日志目录。remove_from_bucket:为yes时,模块在成功处理文件后调用delete_object从存储桶删除对象(见 wodles/aws/buckets_s3/aws_bucket.py 的iter_files_in_bucket方法)。删除操作不可恢复,生产环境务必谨慎。- 去重机制:模块使用 SQLite 数据库记录已处理文件的
bucket_path、aws_account_id、aws_region与log_key(默认库名s3_cloudtrail,表名cloudtrail),重复扫描时跳过已处理文件,并对每个账户/区域最多保留 500 条记录做 DB 维护(MAX_RECORD_RETENTION = 500)。 - 迟到日志处理:CloudTrail 等日志类型允许对象延迟到达,因此模块在 wodles/aws/buckets_s3/aws_bucket.py 中通过
rewind_marker_to_day_folder将 S3 扫描游标回退到前一天,避免漏掉乱序到达的日志文件(LATE_ARRIVAL_LOG_TABLES中包含cloudtrail)。
使用 IAM 角色认证
相比在配置中明文写入密钥,更推荐使用 IAM 角色(也支持跨账户)或 AWS Profile 认证:
<bucket type="cloudtrail"> <name>my-cloudtrail-bucket</name> <aws_profile>default</aws_profile> <iam_role_arn>arn:aws:iam::123456789012:role/WazuhRole</iam_role_arn> <regions>us-east-1,eu-west-1</regions> </bucket>该示例同时监控us-east-1与eu-west-1两个区域。从源码看,aws_profile、iam_role_arn等参数最终会被 src/wazuh_modules/src/wm_aws.c 中的 wodle 执行逻辑转换为aws_s3.py脚本的命令行参数(如--iam_role_arn、--only_logs_after、--trail_prefix),再由脚本完成实际的 S3 访问,因此 ossec.conf 中的标签与命令行选项一一对应。
AWS 侧配置
启用 CloudTrail
- 登录 AWS Management Console,进入CloudTrail服务;
- 创建一条 Trail(追踪),并配置将日志投递到 S3 存储桶;
- 如需多区域监控,请确保 Trail 对所有区域启用("Apply to all regions"),否则只有 Trail 所在区域的事件会被记录。
IAM 最小权限
Wazuh 所使用的 IAM 用户或角色,需要具备对目标 S3 存储桶的读取权限。最小权限策略如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-cloudtrail-bucket", "arn:aws:s3:::my-cloudtrail-bucket/*" ] } ] }其中s3:ListBucket用于列举桶内对象(扫描日志),s3:GetObject用于下载并读取日志文件。如果配置中开启了remove_from_bucket,还需额外追加s3:DeleteObject权限,否则删除对象会因权限不足而失败。
验证集成
修改配置后,重启 Wazuh 代理使配置生效:
systemctl restart wazuh-agent随后检查模块运行日志:
grep "aws-s3" /var/ossec/logs/ossec.log正常运行时,日志中会出现模块扫描存储桶、发现新日志、处理文件等调试信息(调试级别通过-d参数控制)。CloudTrail 事件被处理后,会生成携带aws数据字段的告警,其中包含原始事件信息;您可以在 Wazuh 仪表盘中按data.aws相关字段检索,例如data.aws.eventName、data.aws.sourceIPAddress等。
告警消息的字段富化细节
为了让 ES 索引映射保持稳定,模块在发送前会对事件做格式化(见 wodles/aws/buckets_s3/cloudtrail.py 的reformat_msg方法与 wodles/aws/buckets_s3/aws_bucket.py 的reformat_msg/get_alert_msg):
additionalEventData、responseElements、requestParameters等动态字段,若其值不是字典类型(如字符串、列表),会被统一转换为字典({'string': str(value)}),以规避 ES mapping 冲突;requestParameters.disableApiTermination若为布尔值,会转换为{'value': bool};既非布尔也非字典的异常类型会打印 WARNING 日志(对应测试 wodles/aws/tests/test_cloudtrail.py 中的test_aws_cloudtrail_bucket_reformat_msg_disable_api_termination_unexpected_type_prints_warning);sourceIPAddress若为 IPv4 地址,会额外生成source_ip_address字段以兼容新旧索引模式;- 事件中的
None值会在构造告警消息时被递归剔除(remove_none_fields); - 告警消息附带
log_info(含aws_account_alias、log_file、s3bucket)与aws_account_id等富化字段。
常见问题与排查思路
- 凭据错误:若配置了
access_key/secret_key但无法读取桶,模块在check_bucket阶段会因SignatureDoesNotMatch(错误码 3)或RequestTimeTooSkewed(错误码 19)退出,后者表示本机时间与 AWS 环境时间偏差过大,请先同步系统时钟。 - 区域或前缀不匹配:CloudTrail 日志存放路径不符合
AWSLogs/<account-id>/CloudTrail/<region>/...结构时,find_account_ids/find_regions可能找不到任何账户或区域(错误码 18),请核对path前缀与桶内实际目录。 - 文件解析失败:
get_log_file捕获解压失败(错误码 8)、解析失败(错误码 9)等异常;skip_on_error=yes时会跳过该文件并生成一条带error_msg的告警,便于追溯。 - 限流(Throttling):S3/STS 请求被限流时(
ThrottlingException,错误码 16),模块会提示检查重试配置;可适当调大interval或降低扫描频率。 - 告警缺失:先确认
only_logs_after的日期是否晚于最早日志时间、regions是否覆盖 Trail 启用的全部区域,再结合 ossec.log 中的aws-s3日志定位是"未扫描到文件"还是"规则未命中"。
小结
Wazuh 通过aws-s3wodle 将 AWS CloudTrail 审计日志接入统一的安全监控体系:配置上只需在ossec.conf声明存储桶、区域与认证方式,配合最小权限的 IAM 策略即可;处理层面由 wodles/aws/buckets_s3/cloudtrail.py 驱动的"扫描—去重—下载解压—字段格式化—告警上报"链路保证事件完整入库,最终由规则引擎对未授权 API 调用、IAM 变更等敏感操作产生告警。若要深入了解规则编写与告警分析,可继续阅读仓库 docs/ref/modules 下的相关模块文档。
【免费下载链接】wazuhWazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.项目地址: https://gitcode.com/GitHub_Trending/wa/wazuh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考