我目前正在开发和启动一个相对简单的云形成堆栈。只是一些简单的 RDS 内容,通过外部 CI+CD 服务触发。
然而,我目前的开发周期效率极低,纯粹是因为我不知道 IAM 权限需要什么持续集成我设立的 IAM 组。
我将尝试运行 Cloudformation 模板的部署,但设置时出现一些错误并开始回滚。回滚将失败,因为它需要不同的权限来删除迄今为止成功创建的内容。我添加了我发现的两个新权限,删除了堆栈(因为它处于该ROLLBACK_FAILED
状态),然后重试。
我可以对所有我需要的服务的权限进行通配符处理,但在将某些 AWS 凭证交给外部服务时,这并不是最佳做法。
因为这个。有没有办法知道我根据云信息模板具体需要设置哪些 IAM 权限?或者,是否有一些针对每个 Cloudformation 资源的 IAM 权限列表?我是否过于迂腐,试图限制尽可能多的权限?还是我永远注定要尝试 IAM 权限调整?
答案1
有一个解决这个问题的办法,我很喜欢。它是:
- 使用特定测试用户登录
- 使用此用户从控制台手动创建资源
- 转到 CloudTrail 并查看事件历史记录,并观察“eventName”的值。
这eventName
完全对应于 boto3 中的 API 调用名称以及相关权限的 IAM 策略中的操作。因此,您将了解创建特定类型资源所需执行的所有步骤。
接下来您只需要记住并理解 CloudFormation 操作本身就可以了。
答案2
我自己也曾遇到过完全相同的问题,但找不到我想要的答案。
相反,我绘制了一张包含所有相关部分的图表,并从以下方面考虑了每个部分:
- What does it need to do?
- Which resources does it touch/manage?
然后,对于图表的每个部分,我编制了一个我认为需要的 IAM 访问列表,并编写了一个包含所需的一切的具体策略。
然后我重新创建了 CloudFormation 堆栈,仍然错过了一些权限,但大部分已经被我创建的策略涵盖。
希望我的回答能帮到你。
答案3
这是一个具有挑战性的问题,也是一个需要正确解决的重要问题,特别是在向第三方提供凭证的情况下。
完全自动化这一过程实际上是不可能的/不切实际的,因为所需的权限可能非常广泛,尤其是当您考虑到对云形成模板的更改很容易导致需要更多权限时,具体取决于您碰巧更改的内容。通常,对堆栈的更新也可能触发资源替换,这实际上需要删除、创建和更新的所有权限。使用一项 AWS 服务中的一项功能可能需要其他几项服务的权限,依此类推。
或者,每个 Cloudformation 资源是否都需要一些 IAM 权限列表
由于 CloudFormation 可以做基本上任何东西,这很快就会成为服务/资源的通配符权限。此外,由于服务之间使用的交互不计其数,即使在单个服务产品中也是如此,因此越来越难以预测需要哪些权限。情况也会根据您的环境发生很大变化。例如,您可能已经或可能尚未创建管理 RDS 或 ECS 等服务所需的服务相关角色——或者您可能已启用加密,需要潜在访问 KMS 或客户管理密钥或 CloudHSM。
因此,简而言之,对于您的具体问题,答案是这样做是不可能的/不切实际的。正如其他人所说,您可能能够执行一组任务,然后观察使用了哪些 IAM 操作,但如果您没有穷尽 CFN 可能遇到的所有情况,这可能是不完整的。
但是,根据您的目标,您可以使用多种策略在易于配置和安全性之间取得平衡:
仅允许通过 CloudFormation 执行操作。
使用aws:CalledViaFirst
全局条件键,您可以确保策略授予的权限仅在通过 CloudFormation 获取时才有效。在这种情况下,主体将无法直接通过 API 执行操作,而只允许 CloudFormation 代表主体执行这些操作。
如果您结合限制主体有权创建/删除/更新的 CloudFormation 堆栈来执行此操作,那么可能会形成一个相当明确的权限边界,或者至少是一个良好的起点。
例如,您的保单部分内容可能如下:
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"AllowDDBAndKMSActionsViaCFN",
"Effect":"Allow",
"Action":[
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource":[
"arn:aws:dynamodb:region:111122223333:table",
"arn:aws:kms:region:111122223333:key/example"
],
"Condition":{
"StringEquals":{
"aws:CalledViaFirst":[
"cloudformation.amazonaws.com"
]
}
}
}
]
}
这样,主体就无法直接访问 DynamoDB 或您的 KMS 密钥,但仍允许启动需要这些权限的 CloudFormation 更改。
即使在这种情况下,由于 CloudFormation 可以管理几乎任何东西,包括 IAM,所以您显然仍然需要小心授予哪些操作,即使是通过 CFN。
适当地限定资源范围
这个非常基础。如果您正确确定Resource:
策略的键的范围,这可能会帮助您减少此主体可以管理的爆炸半径。此外,您可以考虑使用条件键来实现类似的目的。例如,您可能有一个命名约定,允许您将资源指定为stack-name*
或使用条件键(如资源标签)。
定义你采取哪些行动不想要被允许
有时定义你不您希望 IAM 角色能够执行哪些操作,而不是定义您想要允许的操作。一种显而易见的方法是使用“拒绝”策略,但可以使用更强大的工具来NotAction
更灵活地定义这一点。
例如,您可能希望允许除某些“危险”操作之外的所有操作。
Statement": [
{
"Effect": "Allow",
"NotAction": [
"iam:*",
"organizations:*",
"account:*"
],
"Resource": "*"
}, ...
这还将使您可以灵活地使用附加语句来允许我们在以前的策略中不允许的某些操作:
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:ListRoles",
"account:ListRegions"
],
"Resource": "*"
}
如果我们在之前的策略中使用Deny
for ,这是不可能的。使用with ,我们可以获得更大的灵活性。iam:*
NotAction
Allow
按源 IP 限制直接操作
有时,您的 CICD 仍需要直接操作的权限。可以使用aws:SourceIp
条件键为直接操作添加另一层安全性。如果您自行托管 CICD 系统,或者您的提供商发布其公共 IP 地址,则可以使用此条件来防止您的凭据被其他系统使用。
请记住,当 AWS 服务代表您调用其他服务(例如 CFN,但还有许多其他服务)时,密钥SourceIp
不存在,因此请相应地制定策略。
例子:
"Statement": [
{
"Sid": "PrincipalPutObjectIfIpAddress",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-service-bucket/*",
"Condition": {
"Bool": {"aws:ViaAWSService": "false"},
"IpAddress": {"aws:SourceIp": "123.45.167.89"}
}
}
使用短期凭证
在某些 CICD 系统中,可能可以注入暂时的通过 AssumeRole 调用获取的 AWS 凭证 — 或者您可以使用 API 自行自动执行此操作。这样,如果凭证在一次性情况下被泄露,它们将不会永远有效。
总之,使用这样的技术可以帮助您快速定义策略,以达到良好的平衡,能够完成大部分/全部您需要做的事情,而又不会太过宽松,同时还能减轻因凭证被泄露或潜在滥用/事故而产生的风险。