AWS信用号 亚马逊云 AWS 账号 API 密钥保护
你有没有在某个深夜,一边啃着冷掉的煎饼果子,一边把 AWS 的 AccessKeyId 和 SecretAccessKey 复制粘贴进本地 .env 文件,还顺手加了句注释:‘临时用,明天删’?结果——三个月后,它还在那儿,像一扇没锁的后门,静静等着被扫描器撞开。
别把密钥当密码:它不是登录凭证,是开门砖
很多人误以为 API 密钥 ≈ 微信密码,输错几次就锁号。错!AWS 的密钥一旦泄露,等于把整栋云大楼的万能钥匙交出去:可以创建 EC2 实例挖矿、开启 S3 暴力扫描、删除 RDS 数据库、甚至调用 Lambda 发送钓鱼邮件……而且——它不会过期,不设失败次数限制,不发短信验证,不记录在哪台设备上用过。你唯一能做的,就是祈祷黑客还没发现它。
真实事故现场:一个密钥引发的‘蝴蝶效应’
去年某创业公司运维小哥,在 GitHub 提交代码时忘了删掉 aws configure 的配置文件。3 小时后,CloudWatch 告警炸屏:EC2 实例数飙升至 147 台,全是 t3.micro,但 CPU 占用率恒定 99.8%。调查发现,攻击者用该密钥启动实例运行 XMRig(门罗币挖矿程序),账单单日激增 $2,300。更糟的是——密钥有 iam:CreateUser 权限,黑客顺手建了个新用户,删掉了原始密钥的审计日志权限……这已不是疏忽,是裸奔。
第一道防线:永远别用根账号密钥
AWS 根账号 = 云上皇帝印玺。它的密钥一旦泄露,连‘删除自己’的权限都有。所以,请立刻执行三件事:
- 登录 IAM 控制台 → 点击右上角用户名 → ‘安全凭证’ → 滚动到底部 → 点击‘删除访问密钥’(别犹豫,真删);
- 启用 MFA(多因素认证)——不是可选项,是生存必需;
- 创建一个命名清晰的 IAM 用户(比如
devops-prod-deploy),仅授予其PowerUserAccess或更细粒度策略(后面展开)。
记住:根账号只干两件事——开 MFA 和创建第一个 IAM 用户。其余时间,请把它锁进抽屉,贴张纸条:‘此号已退休,勿扰’。
第二道防线:用角色(Role)代替密钥
服务器要访问 S3?别给它密钥!让它‘扮演’一个角色。
EC2 实例:挂载角色,告别硬编码
创建角色时选‘AWS 服务’→‘EC2’→附加策略(比如 AmazonS3ReadOnlyAccess)。启动实例时,在‘配置实例详细信息’页勾选‘IAM 角色’。之后,你的 Python 脚本里无需任何密钥:
import boto3
s3 = boto3.client('s3') # 自动获取临时凭证,无需 aws_access_key_id!
s3.list_buckets()
好处?密钥永不落地、自动轮换(每小时刷新)、权限随实例生命周期绑定——关机即失效。
AWS信用号 跨账户/跨服务:角色信任策略是灵魂
想让 Lambda 访问另一账号的 DynamoDB?别传密钥!在目标账号创建角色,信任策略中明确指定源账号的 Lambda 执行角色 ARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
再在源账号 Lambda 执行角色中添加 sts:AssumeRole 权限——安全、解耦、审计清晰。
第三道防线:如果非用密钥不可,请把它‘关进笼子’
某些场景确实绕不开密钥:CI/CD 流水线、本地开发调试、遗留系统集成。这时,请执行‘三不原则’:
- 不硬编码:禁止写进源码、Dockerfile、Shell 脚本;
- 不存明文:禁用
~/.aws/credentials(除非配合aws-vault); - 不长期有效:所有密钥必须设置 90 天自动过期。
实操方案:aws-vault + 临时凭证
安装 aws-vault(macOS:brew install aws-vault;Linux:curl -sL https://raw.githubusercontent.com/99designs/aws-vault/master/scripts/install.sh | bash):
# 添加用户(密钥加密存入系统钥匙串)
aws-vault add my-dev-user
# 启动带临时凭证的 shell
aws-vault exec my-dev-user -- bash
# 此时 aws cli 完全可用,退出 shell 后凭证自动销毁
原理?aws-vault 不存储明文密钥,而是调用系统钥匙串(macOS Keychain / Windows Credential Manager)加密保存,并通过 STS GetSessionToken 获取 12 小时有效期的临时凭证——即使电脑被盗,密钥也无法被直接提取。
第四道防线:监控与告警——让异常无处藏身
再好的防护也需哨兵。启用 CloudTrail 并将日志投递至 CloudWatch Logs:
- 创建指标过滤器,捕获
ConsoleLogin事件中的errorMessage(失败登录); - 监控
AssumeRole调用来源 IP 是否异常(如突然出现俄罗斯、乌克兰出口 IP); - 对高频 API 调用(如
ec2:RunInstances单分钟超 5 次)触发 SNS 告警。
一行命令查密钥最近使用痕迹:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIA...XXX \
--start-time $(date -v-7D +%Y-%m-%dT%H:%M:%SZ) \
--max-items 50
终极提醒:密钥不是资产,是负债
每次生成新密钥,你就新增一笔安全债务。真正的云原生思维,是让密钥‘不存在’——用角色、用临时凭证、用 OIDC 身份联合(GitHub Actions 直接对接 IAM 角色)、用 ECS 任务角色。当你某天发现团队里没人记得密钥长啥样,恭喜,你已毕业。
最后送一句血泪口诀:
根号密钥,当场删除;
EC2 挂 Role,别喂密钥;
本地调试,aws-vault 加密;
CI/CD 用 OIDC,拒绝硬编码;
CloudTrail 日志,每天扫一眼;
密钥超过 90 天?自动禁用,不留情面。

