3. 创建和管理客户主密钥(CMK):控制台与CLI操作,密钥策略配置要点
咱们书接上回。上一章我们把 KMS 的基础概念理清了,这一章直接上手操作。创建 CMK 其实不难,但是管好它、用对策略,才是真正体现功力的地方。我见过太多团队,密钥创建了一堆,最后审计的时候发现权限全乱套了。
所以这一章,我带你从控制台点一遍,再从 CLI 敲一遍,最后把密钥策略这个核心要点说透。你想想看,如果密钥策略写错了,那审计日志里要么全是拒绝记录,要么就是谁都能用——这两个极端都挺危险的。
3.1 控制台创建 CMK:一步步来
我第一次创建 CMK 的时候,其实也被那些配置项绕晕过。后来总结了一套流程,走熟了就觉得没什么特别的了。
- 登录 KMS 控制台:找到"客户管理密钥",点击"创建密钥"。
- 选择密钥类型:对称还是非对称?我个人的习惯是,90% 的场景用对称密钥就够了。你如果只是做 Envelope Encryption(信封加密),对称密钥够用。
- 给别名(Alias):这一步别偷懒。直接写个有意义的别名,比如
app-prod-db-encryption-key。我踩过坑——第一次设了个 test-key,结果几个月后谁都不知道这个 key 干嘛用的。 - 定义密钥管理员:这里选哪些 IAM 用户/角色可以管理这个密钥(启用/禁用/轮换)。记住,管理员不等于使用者。
- 定义密钥使用者:选哪些主体可以用这个密钥做加密/解密操作。
- 审核密钥策略:这一步是控制台生成的默认策略,我建议你把 JSON 复制出来看一眼,心里有个数。
3.2 AWS CLI 操作:效率翻倍
说实话,我都习惯用 CLI 了。特别是你要批量创建或者自动化运维的时候,点控制台太慢了。来看几个常用命令。
创建 CMK
# 创建一个对称 CMK,启用自动轮换
aws kms create-key \
--description "Production database encryption key" \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS \
--tags TagKey=Environment,TagValue=Production
# 输出会返回 KeyId 和 Arn,记得存好
这里有个细节:--origin 参数。如果你选 EXTERNAL,那把密钥材料导入的过程会比较麻烦。我建议刚开始的用户直接用 AWS_KMS,别给自己加戏。
给 CMK 加别名
# 创建别名,关联到上面那个 KeyId
aws kms create-alias \
--alias-name alias/prod-db-key \
--target-key-id 1234abcd-12ab-34cd-56ef-1234567890ab
update 修改关联的 KeyId。你得先删除旧别名,再创建新的。如果正在用的应用是用别名引用密钥的,操作前一定要确认好影响范围。我曾经在生产环境吃过这个亏——换别名时有一段时间应用找不到密钥,幸好是低峰期。
启用/禁用密钥轮换
# 启用自动轮换
aws kms enable-key-rotation --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
# 查看轮换状态
aws kms get-key-rotation-status --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
轮换这件事,AWS 默认每年一次。我个人觉得这个频率对于大多数场景都够了。但如果你有严格的合规要求,可能需要自己写脚本做更频繁的轮换。
3.3 密钥策略:这里才是大头
密钥策略,说白了就是"谁能用、怎么用、什么时候用"的规则集。我见过很多 DevOps 写了很复杂的策略,最后自己都看不懂了。其实核心就几种模式。
三种主要授权模型
| 模型 | 说明 | 适用场景 |
|---|---|---|
| 启用 IAM 策略控制 | 密钥策略允许账号内所有 IAM 策略生效 | 多团队共享同一个密钥 |
| 直接指定主体 | 密钥策略写死 IAM 角色/用户 ARN | 严格隔离环境,单应用专用密钥 |
| 跨账号授权 | 允许其他 AWS 账号的 IAM 角色使用 | 组织级共享密钥,比如日志集中加密 |
举个例子:直接限制只有特定 IAM 角色能用
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/Ec2AppRole"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*"
}
]
}
嗯,这里要注意一点:Resource: "*" 在密钥策略里是合法的,因为它默认就只对这个密钥生效。别看到星号就害怕。
跨账号配置要点
跨账号的时候,你需要在密钥策略里指定外部账号的根用户或者角色。同时,外部账号的 IAM 也要配上对应的权限。说白了就是两边都得点头才行。
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:role/SecurityAuditRole"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.us-east-1.amazonaws.com"
}
}
}
这段策略还做了进一步约束:只有通过 S3 服务发起的 Decrypt 才允许。这就是为什么我说条件键(Condition Key)是精细控制的神器。我曾经在审计日志排查里发现一例异常调用,就是因为有人没有加 kms:ViaService 限制,导致 EC2 也能用本该只给 S3 用的密钥解密数据。
3.4 本章知识体系速览
下面这张图总结了 CMK 从创建到使用的整体流程,以及密钥策略的核心决策树。你可以把它当作一张脑图来看。