本文是以下文章的续篇:
有关 Active Directory 和 IAM Identity Center 集成方法的详细信息,请参考以下文章。
背景
之前,我们为需要使用 AWS 的员工分配了访问权限以支持某个项目。现在,由于另一个项目也在考虑使用 AWS,我们预计未来不仅在业务环境中,甚至在各项目中 AWS 的使用都会逐渐扩大。
目前,Active Directory 和 IAM Identity Center 已完成集成,因此我们决定与以前一样,为需要访问的员工分配权限。
问题
在之前的设置中,没有施加特定的限制,而是使用了 AWS 预定义的 PowerUserAccess 策略。由于 PowerUserAccess 提供了很高的权限,因此我们借此机会建立更严格的控制措施,将访问权限限制到最低。我们的目标包括:
- 防止对其他项目使用的 VPC 进行更改、删除或资源部署。
- 能够识别 VPC 与哪个项目相关联。
- 限制使用不必要的 AWS 服务。
方法
在之前的设置中,通过 IAM Identity Center 使用权限集定义了 AWS 账户的访问权限,并将其分配给用户。
这次,我们将为每个项目定义权限集,并将其分配给属于这些项目的用户。
每个权限集都将根据标签限制可用的 VPC。这使得可以为每个项目区分访问权限。
以下是简化的示意图:
需要注意的是,有些员工(例如 User 2)可能同时属于多个项目。
在 IAM Identity Center 中,可以为单个用户分配多个权限集。
因此,对于参与多个项目的用户,我们将授予多重访问权限。
管理员方面的步骤
在 Active Directory 中已经创建了组,目前 IAM Identity Center 的用户和组如下:
我们将删除之前分配的权限集(PowerUserAccess),并通过创建新的权限集重新分配权限。
图像
现在,将为分配到 Project B 的用户设置访问权限。
权限将仅允许对特定 VPC 进行创建、更新和删除操作,同时允许对所有资源进行只读访问。
创建权限集
我们将分配自定义策略,并附加 AWS 定义的 ReadOnlyAccess 和 AmazonEC2FullAccess。
虽然之前的权限集是通过管理控制台创建的,这次我们将使用 AWS CLI。
描述:提供对 AWS 服务和资源的只读访问权限。
https://docs.aws.amazon.com/zh_cn/aws-managed-policy/latest/reference/ReadOnlyAccess.html
描述:通过提供对 Amazon EC2 的完全访问权限 AWS Management Console。
https://docs.aws.amazon.com/zh_cn/aws-managed-policy/latest/reference/AmazonEC2FullAccess.html
- 运行以下 AWS CLI 命令以创建权限集。
INSTNACE_ARN=$(aws sso-admin list-instances \
--query "Instances[].InstanceArn" \
--output text)
aws sso-admin create-permission-set \
--instance-arn $INSTNACE_ARN \
--name "ProjectB" \
--session-duration "PT1H"
- 运行以下 AWS CLI 命令,将 AWS 预定义的 ReadOnlyAccess 策略和 AmazonEC2FullAccess 策略附加到权限集中。
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
--instance-arn $INSTNACE_ARN \
--query "PermissionSets" \
--output text | tr "\t" "\n" |
while read line
do
aws sso-admin describe-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn ${line} \
--query "PermissionSet.[Name,PermissionSetArn]" \
--output text
done | grep -w "ProjectB" | awk '{print $2}')
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
- 运行以下 AWS CLI 命令附加内联策略。
cat << EOF > inline-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCreateVpc",
"Effect": "Deny",
"Action": [
"ec2:CreateVpc"
],
"Resource": "*",
"Condition": {
"StringNotEqualsIfExists": {
"aws:RequestTag/Project": "ProjectB"
}
}
},
{
"Sid": "DenyChangeTag",
"Effect": "Deny",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"Null": {
"ec2:ResourceTag/Project": "false"
},
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectB"
}
}
},
{
"Sid": "DenyModifyAndDelete",
"Effect": "Deny",
"Action": [
"ec2:Delete*",
"ec2:ModifyVpcAttribute"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectB"
}
}
}
]
}
EOF
aws sso-admin put-inline-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--inline-policy file://inline-policy.json
- DenyCreateVpc 声明
该声明在满足以下任一条件时拒绝创建 VPC:- 未指定 Project 标签。
- 指定的 Project 标签值不是 ProjectB。
- DenyChangeTag 声明
该声明在满足以下所有条件时拒绝创建标签:- 资源的 Project 标签不为 null(资源已有 Project 标签)。注意:如果没有此条件,创建带指定标签的 VPC 也将被拒绝。
- 资源的 Project 标签值不是 ProjectB。
- DenyModifyAndDelete 声明
该声明限制对 Project 标签值不是 ProjectB 的资源的操作。这包括:- 拒绝更改 VPC 属性。
- 拒绝删除标签、删除 VPC 等操作。
分配组
- 运行以下 AWS CLI 命令,将权限集分配给组。
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
--query "Instances[].IdentityStoreId" \
--output text)
GROUP_ID=$(aws identitystore list-groups \
--identity-store-id $IDENTITYSTORE_ID \
--query "Groups[?DisplayName=='ProjectB@corp.awsexample.com'].GroupId" \
--output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
--query "Instances[].OwnerAccountId" \
--output text)
aws sso-admin create-account-assignment \
--instance-arn $INSTNACE_ARN \
--target-id $ACCOUNT_ID \
--target-type AWS_ACCOUNT \
--permission-set-arn $PERMISSIONSET_ARN \
--principal-type GROUP \
--principal-id $GROUP_ID
附加工作
对于其他项目,按照类似的方式进行操作。运行上述的 AWS CLI 命令,为 ProjectA 创建并分配权限集。
AWS CLI 命令
# Step1
INSTNACE_ARN=$(aws sso-admin list-instances \
--query "Instances[].InstanceArn" \
--output text)
aws sso-admin create-permission-set \
--instance-arn $INSTNACE_ARN \
--name "ProjectA" \
--session-duration "PT1H"
# Step2
PERMISSIONSET_ARN=$(aws sso-admin list-permission-sets \
--instance-arn $INSTNACE_ARN \
--query "PermissionSets" \
--output text | tr "\t" "\n" |
while read line
do
aws sso-admin describe-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn ${line} \
--query "PermissionSet.[Name,PermissionSetArn]" \
--output text
done | grep -w "ProjectA" | awk '{print $2}')
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--managed-policy-arn "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
# Step3
cat << EOF > inline-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCreateVpc",
"Effect": "Deny",
"Action": [
"ec2:CreateVpc"
],
"Resource": "*",
"Condition": {
"StringNotEqualsIfExists": {
"aws:RequestTag/Project": "ProjectA"
}
}
},
{
"Sid": "DenyChangeTag",
"Effect": "Deny",
"Action": [
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"Null": {
"ec2:ResourceTag/Project": "false"
},
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectA"
}
}
},
{
"Sid": "DenyModifyAndDelete",
"Effect": "Deny",
"Action": [
"ec2:Delete*",
"ec2:ModifyVpcAttribute"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:ResourceTag/Project": "ProjectA"
}
}
}
]
}
EOF
aws sso-admin put-inline-policy-to-permission-set \
--instance-arn $INSTNACE_ARN \
--permission-set-arn $PERMISSIONSET_ARN \
--inline-policy file://inline-policy.json
# Step4
IDENTITYSTORE_ID=$(aws sso-admin list-instances \
--query "Instances[].IdentityStoreId" \
--output text)
GROUP_ID=$(aws identitystore list-groups \
--identity-store-id $IDENTITYSTORE_ID \
--query "Groups[?DisplayName=='ProjectA@corp.awsexample.com'].GroupId" \
--output text)
ACCOUNT_ID=$(aws sso-admin list-instances \
--query "Instances[].OwnerAccountId" \
--output text)
aws sso-admin create-account-assignment \
--instance-arn $INSTNACE_ARN \
--target-id $ACCOUNT_ID \
--target-type AWS_ACCOUNT \
--permission-set-arn $PERMISSIONSET_ARN \
--principal-type GROUP \
--principal-id $GROUP_ID
标签策略设置
此步骤不是必需的,但进行设置会非常有帮助。
通过设置标签策略,可以防止仅大小写不同的重复标签的创建。
需要注意的是,标签策略并不是强制性的。
虽然可以通过将 aws:TagKeys
条件集成到内联策略中实现相同的效果,但为了避免内联策略过于冗长和复杂,我们选择使用标签策略。
要防止只有键的大小写形式不同的重复标签,请使用
https://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/access_tags.htmlaws:TagKeys
条件来定义用户可以应用的标签键,或使用带有 AWS Organizations 的标签策略。
- 通过以下 URL 在您的组织中启用标签策略:
https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy
图像
- 访问以下 URL 创建标签策略:
https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy/create- 策略名称: Project
- 标签键: Project
- 合规选项:
- ☑ 使用您在上面为标签键指定的大写形式。
- ☑ 为此标签键指定允许值。
ProjectA
ProjectB
- 要执行的资源类型:
- ☑ 阻止针对此标签的不合规操作。
- 选择所有选项。
- ☑ 阻止针对此标签的不合规操作。
图像
- 从 [目标(Target)] 选项卡,将策略附加到所需的账户。
图像
标签策略严格检查标签键和值的大小写,并将值限制为指定的选项。例如:
键(Key) | 值(Value) | 是否允许 |
---|---|---|
Project | ProjectC | ❌ 不允许 |
ProjecT | ProjectA | ❌ 不允许 |
project | ProjectA | ❌ 不允许 |
Project | projecta | ❌ 不允许 |
Project | ProjectA | ✅ 允许 |
Project | ProjectB | ✅ 允许 |
用户方面的步骤
如果 MFA 已经注册,可以跳过第 1 和第 3 步。
- 在智能手机上安装 Google Authenticator(MFA 认证应用程序)。
[Google Play / App Store] - 访问以下门户 URL,输入用户名和密码。
将<Directory ID>
替换为您的实际目录 ID。
https://<Directory ID>
.awsapps.com/start - 注册 MFA 设备:
- 选择认证应用程序。
- 显示 QR 码。
- 打开 Google Authenticator 并扫描 QR 码。
- 在应用程序中添加的 AWS SSO 条目中输入显示的 6 位认证代码。
- 从 [账户] 选项卡中,选择对应项目的权限集并登录。
图像
指导员工根据当前正在进行的项目选择相应的权限集登录。
虽然在项目之间切换可能有些繁琐,但使用浏览器的隐身模式或私密窗口可以同时登录多个项目。
目前,我们已限制了 VPC 的访问并为用户分配了权限。
但随着 AWS 服务使用范围的扩大,可能需要更多的限制。
尽管过程可能较为复杂,但我们会根据需要持续更新内联策略。
补充说明
使用 IAM 用户 或 IAM Identity Center 提供的 ABAC(基于属性的访问控制) 可以根据用户属性实现动态访问限制。相关官方文档:
但上述方法似乎无法为参与多个项目的员工分配多重访问权限。
因此,我们选择了较为繁琐的方法,通过创建多个权限集进行应对。
未来,我们将继续探索更优的解决方案。