aws-samples/sample-aws-security-incident-response-email-integration
GitHub: aws-samples/sample-aws-security-incident-response-email-integration
为 AWS Security Incident Response 提供无服务器邮件集成,使无控制台权限的利益相关方能通过发送邮件参与安全事件案例的更新与管理。
Stars: 0 | Forks: 0
# AWS Security Incident Response — 邮件集成
本项目为 [AWS Security Incident Response](https://aws.amazon.com/security-incident-response/) 提供了邮件集成,
使客户能够通过发送邮件而非登录 AWS 控制台来更新案例。它扩展了
[sample-aws-security-incident-response-integrations](https://github.com/aws-samples/sample-aws-security-incident-response-integrations)
项目的功能,该项目提供了针对 Jira、ServiceNow 和 Slack 的集成。
AWS Security Incident Response 帮助您为安全事件做准备、做出响应并从中
恢复。在活跃的安全事件期间,减少利益相关者提供更新的阻力非常重要。邮件是
最通用的方式——每个人都有,无需引导入门,并且它提供了天然的审计追踪。此
集成允许高管、法务、合规部门以及外部各方(外部顾问、取证供应商)参与
案例管理,而无需 AWS 控制台访问权限。
## 概述
该解决方案部署了一个无服务器管道,通过 Amazon SES 接收入站邮件,
将其存储在 Amazon S3 中,并使用 AWS Lambda 函数进行处理,
该函数会调用 AWS Security Incident Response API。利益相关者
在邮件主题中包含 SIR 案例 ID,Lambda 函数会自动添加评论、
更新案例详情或更改案例状态。
主要功能:
- 通过发送普通邮件为 SIR 案例添加评论
- 通过结构化关键字更新案例状态、描述或受影响的账户
- 根据案例的观察者列表对发件人进行验证,有助于防止未经授权的发件人进行更新
- 基于 S3 的邮件存储,可处理任意大小的邮件
- 带有 CloudWatch 告警的死信队列,用于失败事件监控
- 对所有入站邮件强制执行 TLS
## 架构

1. 利益相关者发送主题行中包含 `[SIR-]` 的邮件
2. Amazon SES 接收邮件并将原始内容存储在 Amazon S3 中
3. SES 向 Amazon SNS 主题发送轻量级通知
4. SNS 触发 AWS Lambda 函数
5. Lambda 从 S3 获取完整的邮件,对其进行解析并验证发件人
6. Lambda 调用相应的 SIR API(`CreateCaseComment`、`UpdateCase` 或 `UpdateCaseStatus`)
邮件将在 7 天后自动从 S3 中删除。
## 核心 AWS 服务
| 服务 | 用途 |
|---------|---------|
| Amazon SES | 通过接收规则接收入站邮件 |
| Amazon S3 | 存储原始邮件内容(避免触发 SNS 大小限制) |
| Amazon SNS | 将 SES 的通知传递给 Lambda |
| AWS Lambda | 解析邮件、验证发件人、调用 SIR API |
| Amazon SQS | 用于失败事件处理的死信队列 |
| Amazon CloudWatch | 用于监控的日志和告警 |
| AWS IAM | 为 Lambda 执行角色提供最低权限 |
| AWS CloudFormation (SAM) | 整个堆栈的基础设施即代码 |
## 域名设置指南
### 使用子域,而不是您的主域
不要将您公司主域的 MX 记录指向 SES —— 这会将
所有企业邮件重定向,使其脱离您现有的邮件提供商(Microsoft 365、Google Workspace 等)。
相反,请使用专用的子域:
- 使用 `sir.acme.com` 或 `security-ir.acme.com` 而不是 `acme.com`
- 子域的 MX 记录指向 SES
- 父域的邮件路由不受影响
- 利益相关者将更新发送至 `sir-cases@sir.acme.com`
### 邮件身份验证(DMARC、DKIM、SPF)
DKIM 作为步骤 1(域名验证)的一部分进行配置,并且是
所有部署所必需的。SPF、DMARC 和自定义 MAIL FROM 子域仅在
您还计划从该域发送邮件(例如,确认回复)时才需要。对于仅接收的部署,
DKIM + MX 记录就足够了。
如果您确实计划从子域发送邮件:
- 在自定义 MAIL FROM 子域(例如,`mail.sir.acme.com`)上添加 SPF 记录。
- 在 `_dmarc.sir.acme.com` 处添加一条 `p=reject` 的 DMARC 记录。
- 如果您的父域具有严格的 DMARC 策略(`p=reject`),则子域
将继承该策略。如果子域上没有正确的 DKIM/SPF,来自
`sir.acme.com` 的出站邮件可能会被收件人拒绝。
有关详细的设置说明,请参阅 [AWS SES DMARC 合规性文档](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-authentication-dmarc.html)。
### DNS 委派
子域记录可以直接在父域的托管区域中创建,
或者可以将子域委派给单独的托管区域(在相同或不同的 AWS 账户中)。
在大型企业中,DNS 更改可能需要中央 IT 或网络团队的批准——请为此预留好时间。
### 接收规则范围
此解决方案中的 SES 接收规则限定为单个收件人地址
(例如,`sir-cases@sir.acme.com`)。不要修改该规则以接受子域上的所有收件人
——这可能会使 SES 变成一个意外的开放邮件端点。
始终将接收规则限制为您打算处理的具体地址。
## 开始使用
### 前置条件
- [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)
- Python 3.12+
- 拥有 DNS 访问权限的域名(用于 SES 邮件接收)
- 已在目标账户中启用 AWS Security Incident Response
- 部署在 SIR 处于活跃状态的账户中(委托管理员账户或管理账户)
### 步骤 1:在 SES 中验证您的域名
SES 邮件接收仅在 `us-east-1`、`us-west-2` 和 `eu-west-1` 中可用。
1. 在 SES 控制台(在目标区域中),转到 **Identities → Create identity**
2. 选择 **Domain** 并输入您的域名
3. 在 DKIM 下,选择带有 2048 位签名密钥的 **Easy DKIM**
4. 点击 **Create identity**
SES 将提供 3 条用于 DKIM 的 CNAME 记录。请将这些记录添加到您的 DNS 托管区域:
```
._domainkey. CNAME .dkim.amazonses.com
._domainkey. CNAME .dkim.amazonses.com
._domainkey. CNAME .dkim.amazonses.com
```
然后添加一条 MX 记录以将入站邮件路由到 SES:
```
MX 10 inbound-smtp..amazonaws.com
```
等待身份状态在 SES 控制台中显示为 **Verified**:
```
aws sesv2 get-email-identity \
--email-identity \
--region
```
### 步骤 2:部署堆栈
```
cd sir-email-integration
./deploy.sh
```
示例:
```
# 使用默认 AWS credentials
./deploy.sh example.com sir-cases@example.com
# 使用 named profile
./deploy.sh example.com sir-cases@example.com --profile my-profile
# 使用特定 region
AWS_REGION=us-west-2 ./deploy.sh example.com sir-cases@example.com
```
### 步骤 3:激活 SES 接收规则集
每个账户的每个区域只能激活一个接收规则集。
```
aws ses set-active-receipt-rule-set \
--rule-set-name sir-email-integration-rules \
--region
```
## 使用方法
### 邮件格式
使用 `[SIR-]` 格式在主题行中包含 SIR 案例 ID。
邮件正文决定了要执行的操作。
#### 添加评论(默认)
```
Subject: [SIR-1234567890] Any subject text here
Body: Your comment text goes here. This will be added as a case comment.
```
#### 更新案例状态
```
Subject: [SIR-1234567890] Status update
Body:
ACTION: UPDATE_STATUS
STATUS: Detection and Analysis
```
有效状态:`Submitted`、`Detection and Analysis`、
`Containment, Eradication and Recovery`、`Post-incident Activities`
#### 更新案例描述
```
Subject: [SIR-1234567890] Description update
Body:
ACTION: UPDATE_DESCRIPTION
DESCRIPTION: Updated description of the incident...
```
#### 添加受影响的账户
```
Subject: [SIR-1234567890] Add accounts
Body:
ACTION: ADD_ACCOUNTS
ACCOUNTS: 123456789012, 234567890123
```
如果在正文中未找到 `ACTION` 关键字,则整个邮件正文将作为
评论发布到案例上。
## 测试
### 单元测试
```
pip install -r requirements.txt
python -m pytest tests/ -v
```
### 端到端测试(带域名)
如果仍处于沙箱模式,请在 SES 中验证您的发件人邮件:
```
aws sesv2 create-email-identity \
--email-identity \
--region
```
发送测试邮件:
```
python tests/send_test_email.py \
--case-id \
--to \
--from \
--comment "Testing email integration" \
--region
```
### 端到端测试(不带域名)
直接调用 Lambda 以测试完整的处理管道,无需
设置 SES 邮件接收:
```
aws lambda invoke \
--function-name sir-email-handler \
--region \
--cli-binary-format raw-in-base64-out \
--payload '{
"Records": [{
"Sns": {
"Message": "{\"content\": \"From: \\r\\nTo: test@test.com\\r\\nSubject: [SIR-] Test\\r\\nContent-Type: text/plain\\r\\n\\r\\nTest comment from email integration.\"}"
}
}]
}' \
/dev/stdout
```
### 验证结果
检查 Lambda 日志:
```
aws logs tail /aws/lambda/sir-email-handler --follow --region
```
然后在 AWS 控制台中检查 SIR 案例,以确认评论或更新
已出现。
## 故障排除
### 邮件未到达 Lambda
- 使用 `dig +short -t mx ` 验证 MX 记录是否指向 `inbound-smtp..amazonaws.com`
- 确认 SES 接收规则集是否处于活跃状态:
`aws ses describe-active-receipt-rule-set --region `
- 检查接收规则中的收件人地址是否与您发送到的地址完全匹配(包括大小写)
- SES 邮件接收仅在 `us-east-1`、`us-west-2` 和 `eu-west-1` 中可用。请验证您是否部署在受支持的区域中。
### Lambda 调用错误
- 检查 CloudWatch Logs:`aws logs tail /aws/lambda/sir-email-handler --region `
- "No SIR case ID found in subject" —— 邮件主题必须包含带有有效数字案例 ID 的 `[SIR-]`
- "Sender is not a watcher on case" —— `From` 地址必须与 SIR 案例上的观察者邮件匹配。请通过 SIR 控制台或 `UpdateCase` API 将发件人添加为观察者。
- "Case not found or not accessible" —— 验证案例 ID 存在,并且 SIR 已在部署 Lambda 的账户中启用
### 消息大小错误
此解决方案将邮件存储在 S3 中以避免 SNS 消息大小限制。如果您
看到与大小相关的错误,请验证 S3 存储桶是否存在,以及 Lambda 是否对其具有
`s3:GetObject` 权限。
### DLQ 中的失败事件
处理失败的事件将被发送到 SQS 死信队列。当 DLQ 中出现消息时,
将触发 CloudWatch 告警。
要检查失败的事件:
1. 导航到 SQS 控制台并找到 `sir-email-integration-dlq` 队列
2. 选择 "Send and receive messages" → "Poll for messages"
3. 检查消息内容以了解失败原因
4. 手动重新处理,或修复根本原因后重新发送邮件
### SES 域名验证未完成
- 确认 DKIM CNAME 记录是否已发布:
`dig +short -t cname ._domainkey.`
- DNS 传播可能需要长达 72 小时,尽管通常会在几分钟内完成
- 如果使用子域,请确保记录位于正确的托管区域中
## 安全
### 发件人验证
Lambda 函数在处理任何更新之前,会验证发件人的邮件地址是否与
SIR 案例上的观察者相匹配。来自不在观察者列表中的发件人的
邮件将被记录并丢弃。这有助于防止未经授权的各方
修改案例数据,但不能替代发送域上更广泛的邮件身份验证
控制(DKIM、DMARC)。
为了获得更强的发件人保证,客户应在其发送域上配置 DMARC。
如果没有 DMARC 强制执行,`From` 头部可能会被伪造以冒充合法的观察者。
### 传输加密
SES 接收规则强制执行 TLS(`TlsPolicy: Require`),确保入站邮件在传输过程中被加密。未使用 TLS 发送的邮件将被 SES 拒绝。
### 最低权限 IAM
Lambda 执行角色仅限定为所需的 SIR API 操作:
`security-ir:GetCase`、`security-ir:CreateCaseComment`、
`security-ir:UpdateCase`、`security-ir:UpdateCaseStatus`,以及对邮件存储桶的 `s3:GetObject`。除 SIR 资源范围外,未使用任何通配符权限。
### 静态加密
SNS 主题和 SQS 死信队列使用堆栈创建的客户托管 KMS 密钥进行加密。密钥策略授予 SES 加密通知和 Lambda 解密通知的权限。密钥轮换会自动启用。S3 存储桶使用 Amazon S3 托管密钥的服务器端加密(SSE-S3)。
失败的事件被捕获在 SQS 死信队列中。当 DLQ 中出现消息时,
将触发 CloudWatch 告警,从而能够快速检测到
处理失败。所有 Lambda 调用都记录到 CloudWatch Logs 中,
保留期为 30 天。
### 数据保留
存储在 S3 中的原始邮件将在 7 天后通过 S3 生命周期策略自动删除。请在 `template.yaml` 中调整 `ExpirationInDays` 值,以满足您组织的数据保留要求。
## 常见问题
**问:我可以使用公司的主域(例如 `acme.com`)吗?**
答:不建议这样做。更改主域上的 MX 记录会将所有企业邮件重定向到 SES。请改用专用的子域(例如 `sir.acme.com`)。请参阅[域名设置指南](#domain-setup-guidance)。
**问:如果 Lambda 函数未能处理邮件会怎样?**
答:事件将被发送到 SQS 死信队列,并触发 CloudWatch 告警。原始邮件会在 S3 中保留 7 天,允许您在解决问题后重新处理。
**问:我可以在多个 AWS 区域中部署此集成吗?**
答:可以,但每个区域都需要其独立的 SES 域验证、MX 记录和堆栈部署。SES 邮件接收仅在 `us-east-1`、`us-west-2` 和 `eu-west-1` 中可用。
**问:支持哪些 SIR API 操作?**
答:该集成支持 `CreateCaseComment`(添加评论)、`UpdateCase`(更新描述、添加受影响的账户)和 `UpdateCaseStatus`(更改案例状态)。可以通过扩展 Lambda 函数来添加其他操作。
**问:应该将其部署在哪个 AWS 账户中?**
答:请部署在 AWS Security Incident Response 处于活跃状态的账户中——
即委托管理员账户或管理账户。如果部署账户中未启用 SIR,SIR API 调用将会失败。
**问:外部各方(外部顾问、取证供应商)可以使用此功能吗?**
答:可以,只要他们作为观察者被添加到 SIR 案例中即可。Lambda 会根据案例观察者列表验证发件人的邮件。不需要 AWS 账户或控制台访问权限。
**问:支持的最大邮件大小是多少?**
答:邮件存储在 S3 中,因此来自 SNS 通知负载方面没有实际的大小限制。SES 本身支持最大 40 MB 的消息。
## 清理
删除 CloudFormation 堆栈:
```
aws cloudformation delete-stack \
--stack-name sir-email-integration \
--region
```
如果您创建了专用域进行测试,请移除 SES 域身份:
```
aws sesv2 delete-email-identity \
--email-identity \
--region
```
## CI/CD(可选)
大多数用户将直接使用 `deploy.sh` 进行部署。对于自动化部署,
此存储库包含了适用于 GitHub Actions 和 GitLab CI 的管道配置。
### GitHub Actions
位于 `.github/workflows/deploy.yml` 的工作流会在每个 PR 上运行 lint 和测试,
并在合并到 `main` 分支时进行部署。
设置:
1. 配置 GitHub 与您的 AWS 账户之间的 OIDC 信任([指南](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services))。创建一个 GitHub Actions 可以担任的 IAM 角色 —— 无需静态访问密钥。
2. 将这些密钥添加到您的 GitHub 存储库(Settings → Secrets and variables → Actions):
- `AWS_DEPLOY_ROLE_ARN` —— 用于部署的 IAM 角色 ARN
- `SES_DOMAIN` —— 您已验证的 SES 域名
- `RECIPIENT_ADDRESS` —— 用于接收 SIR 更新的邮件地址
3. (可选)在 GitHub 中配置 `production` 环境(Settings → Environments),以在部署前要求手动批准。
### GitLab CI
位于 `.gitlab-ci.yml` 的管道包含四个阶段:lint → test → build → deploy。
设置:
1. 在 GitLab 中添加 CI/CD 变量(Settings → CI/CD → Variables):
- `AWS_ACCESS_KEY_ID` 和 `AWS_SECRET_ACCESS_KEY`(或配置 OIDC)
- `SES_DOMAIN_STAGING` / `RECIPIENT_STAGING`
- `SES_DOMAIN_PROD` / `RECIPIENT_PROD`
2. 部署阶段是手动的 —— 在管道中点击 "Play" 以触发 staging 或 production。
### SES 域名设置
无论采用何种 CI/CD 方法,SES 域名验证和 MX 记录配置都是一次性的手动步骤。请参阅[开始使用 — 步骤 1](#step-1-verify-your-domain-in-ses)。
## 项目结构
```
sir-email-integration/
├── template.yaml # SAM/CloudFormation: SES → S3 → SNS → Lambda + DLQ
├── deploy.sh # Deployment script with SES verification check
├── lambda/
│ └── email_handler.py # Email parsing, sender verification, SIR API calls
├── tests/
│ ├── test_email_handler.py # Unit tests
│ └── send_test_email.py # CLI tool to send test emails via SES
├── generated-diagrams/
│ └── sir_email_architecture.png # Architecture diagram
├── .github/workflows/deploy.yml # GitHub Actions pipeline
├── .gitlab-ci.yml # GitLab CI pipeline
├── requirements.txt
├── .gitignore
└── LICENSE
```
## 许可证
本项目采用 MIT-0 许可证授权。有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
## 贡献
我们欢迎各种贡献。请提交 issue 或发送包含您建议更改的 pull request。
标签:Amazon CloudWatch, Amazon S3, Amazon SES, AWS, AWS Lambda, DPI, PB级数据处理, SecOps, Serverless, Streamlit, 事件管理, 云安全架构, 发件人验证, 安全事件响应, 安全运维, 案件管理, 死信队列, 自动化处理, 访问控制, 逆向工具, 邮件集成