
最近折腾 AWS(亚马逊云服务)安全告警时,我踩过几个坑:CloudTrail 明明记下了所有操作,却没人盯着日志;等发现异常时,往往已经过去了好几天。这篇把整件事说清楚:如何用 CloudTrail 和 Lambda(无服务器计算服务)筛选高风险事件,再把告警实时推到 Slack,顺便算清楚这套方案到底要花多少钱。
你是否想知道,有人通过访问密钥(access key)越权访问,或者擅自扮演某个角色?又或者离职员工还在使用克隆到自己笔记本上的凭证,准备把生产环境全部毁掉?
好消息是,AWS 已经记录了这些操作。坏消息是,大多数团队并不会实时查看这些日志,通常要等到几天后服务异常才发现问题。这里要讨论的,不是具体的命令和配置,而是一套补上监控缺口的基本思路:它如何工作、能告警什么、能带来什么收益,以及实际成本是多少。
如果准备落地,后面这个 AWS Builder Center 技术版文章会给出关键代码、命令,以及每个组件的完整配置。
AWS 账户里的所有活动都有日志记录。我们的做法是,在日志上增加一个过滤器,只放行危险事件;再用一个函数判断每个事件有多严重,最后把告警发到团队的 Slack 频道,让值班人员几分钟内就能看到。
完整的数据流大致如下:

一切从 CloudTrail 开始,它是 AWS 的审计日志。每当有人或某个程序调用 API(应用程序接口)时,CloudTrail 都会记录:具体做了什么、涉及哪个服务、发生时间、来源 IP(互联网协议地址)、所属账户,以及操作最终成功还是失败。
但真正让整套方案成为可能的是另一个字段:userIdentity.type。它表示每次调用使用的是哪种类型的凭证。
| 类型 | 含义 |
|---|---|
Root |
有人使用了账户的 root 权限 |
IAMUser |
长期凭证,例如 IAM(身份与访问管理)用户的访问密钥或密码 |
AssumedRole |
扮演角色后获得的临时凭证 |
AWSAccount |
另一个 AWS 账户扮演了你的角色 |
AWSService |
某个 AWS 服务代表你执行了操作 |
有了这张表,文章开头提到的每种场景都有可识别的特征。遗留在笔记本上的访问密钥会显示为 IAMUser;第三方从自己的账户扮演你的角色,会显示为 AWSAccount;使用 root 登录,则会直接标记为 Root。
既然已经明确能拿到哪些信息,接下来看看这些工作分别由谁负责:
组件已经齐了,接下来跟踪一个具体案例:有人使用访问密钥删除生产环境中的数据库。
IAMUser)比临时凭证更值得警惕。如果函数执行失败呢?AWS 会额外重试两次。仍然失败时,事件会保存在备用队列中,同时告警通知团队,避免任何告警悄无声息地丢失。
到这里,看起来都很直接。但有一个设计决策决定了系统究竟能不能真正保护你:究竟让哪些事件通过过滤器。
最自然的做法是,只关注团队成员的操作,例如通过 SSO(单点登录)登录的用户,避免流水线和 Kubernetes 控制器把频道刷爆。但问题是,使用访问密钥的 IAM 用户不会通过 SSO 登录。这样的过滤器,恰好会漏掉员工离职后仍然存活的凭证。
解决办法是把问题拆成两部分。CloudWatch Logs 刚好支持这种设计,因为每个日志组最多可以配置两个订阅过滤器:
这些模式也不需要完全从零编写。AWS 在 Security Hub 的 CloudWatch.1 到 CloudWatch.14 安全控制项中,提供了覆盖 root、MFA、IAM 变更、CloudTrail、KMS、S3 和网络配置的官方模式。这些模式基于 CIS(互联网安全中心)AWS Foundations Benchmark,是非常合适的起点。
两个过滤器运行后,以下几类情况会出现在 Slack 中:
除了处理具体事件,这套系统还会改变团队看待基础设施的方式:
系统跑起来以后,最值得结合自身业务调整的是“正在破坏什么”这个过滤器。下面这些操作建议纳入考虑:
有个细节需要注意:DynamoDB 默认会记录删除表的操作,但逐条删除数据项不会记录。后者属于数据事件(data events),需要在 trail 中单独启用,并会产生额外费用。
大多数情况下,这套方案花不了多少钱。核心取决于一个问题:你的 trail 是否已经把事件发送到 CloudWatch Logs?
| 组件 | 计费方式 | 预期费用 |
|---|---|---|
| CloudTrail,第一份管理事件副本 | 投递到 S3 时免费 | 没有新增成本 |
| CloudTrail 投递到 CloudWatch Logs | 每 GB 投递费用 USD 0.25,另加 CloudWatch Logs 摄取费用 | 如果还没有配置,这通常是主要成本;使用 Control Tower 时已经存在 |
| Lambda | 每百万次调用 USD 0.20,每 GB-s USD 0.0000166667(x86);免费额度为每月 100 万次调用和 400,000 GB-s | 基本可以视为零成本:只会处理过滤后的事件 |
| SNS | 按发布次数计费 | 每条告警发布一条消息 |
| Amazon Q Developer,自定义通知 | 没有额外费用 | 零 |
可以看一组实际数据:一个包含 7 个账户的组织原本已经把 trail 发送到 CloudWatch Logs,连续统计了 16 天。期间函数执行了 19 次,共发布 103 条消息,折算下来,每月成本不到 1 美分。
如果你的 trail 还没有把事件发送到 CloudWatch Logs,真正需要关注的是组织每月产生的事件量,以 GB 为单位,因为交付和摄取费用都由它决定。
想正确使用它,也需要明确能力边界:
只按谁来过滤,看起来似乎已经够了,直到真正值得警惕的执行者恰恰不像日常用户。再按什么正在被破坏增加一层过滤,才能补上这个缺口。而且整套方案都由原生云服务组成,长期运行成本几乎可以忽略。
AWS Builder Center 的技术版文章里,包含了函数的关键代码、连接各组件所需的命令、两个过滤器的设计、需要留意的边界,以及常见问题的处理方法。
换句话说,如果明天有人使用了一直没人撤销的访问密钥,你们会从哪里发现问题?
这个主题还整理成了 YouTube Shorts、TikTok、Instagram Reels 短视频,LinkedIn 轮播图,Medium 文章,以及 AWS Builder Center 技术版文章。
━━━━━━━━━━━━━━━━━━━━
🟧 dev.luchops
Cloud & DevOps, explicado sin vueltas.
━━━━━━━━━━━━━━━━━━━━