【带图操作指南】Active Directory 和 IAM Identity Center 集成设置2:通过标签限制 VPC

Active Directory 和 IAM Identity Center 集成设置2:通过标签限制 VPC
  • 我们通过将 Active DirectoryIAM Identity Center 集成,为需要使用 AWS 的员工分配访问权限,但必须严格控制每个员工的访问权限。
  • 本文介绍了如何通过标签限制可用的 VPC。
  • 我们将通过图像和截图,以直观的方式介绍如何自定义权限集并分配最低权限。

本文是以下文章的续篇:
有关 Active DirectoryIAM Identity Center 集成方法的详细信息,请参考以下文章。

背景

之前,我们为需要使用 AWS 的员工分配了访问权限以支持某个项目。现在,由于另一个项目也在考虑使用 AWS,我们预计未来不仅在业务环境中,甚至在各项目中 AWS 的使用都会逐渐扩大。
目前,Active DirectoryIAM 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 定义的 ReadOnlyAccessAmazonEC2FullAccess
虽然之前的权限集是通过管理控制台创建的,这次我们将使用 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
  1. 运行以下 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"
  1. 运行以下 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"
  1. 运行以下 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 等操作。

分配组

  1. 运行以下 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 条件集成到内联策略中实现相同的效果,但为了避免内联策略过于冗长和复杂,我们选择使用标签策略。

要防止只有键的大小写形式不同的重复标签,请使用 aws:TagKeys 条件来定义用户可以应用的标签键,或使用带有 AWS Organizations 的标签策略。

https://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/access_tags.html
  1. 通过以下 URL 在您的组织中启用标签策略:
    https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy
图像
  1. 访问以下 URL 创建标签策略:
    https://us-east-1.console.aws.amazon.com/organizations/v2/home/policies/tag-policy/create
    • 策略名称: Project
    • 标签键: Project
    • 合规选项:
      • ☑ 使用您在上面为标签键指定的大写形式。
      • ☑ 为此标签键指定允许值。
        • ProjectA
        • ProjectB
    • 要执行的资源类型
      • ☑ 阻止针对此标签的不合规操作。
        • 选择所有选项。
图像
  1. [目标(Target)] 选项卡,将策略附加到所需的账户。
图像

标签策略严格检查标签键和值的大小写,并将值限制为指定的选项。例如:

键(Key)值(Value)是否允许
ProjectProjectC❌ 不允许
ProjecTProjectA❌ 不允许
projectProjectA❌ 不允许
Projectprojecta❌ 不允许
ProjectProjectA✅ 允许
ProjectProjectB✅ 允许

用户方面的步骤

如果 MFA 已经注册,可以跳过第 1 和第 3 步。

  1. 在智能手机上安装 Google Authenticator(MFA 认证应用程序)。
    [Google Play / App Store]
  2. 访问以下门户 URL,输入用户名和密码。
    <Directory ID> 替换为您的实际目录 ID。
    https://<Directory ID>.awsapps.com/start
  3. 注册 MFA 设备:
    • 选择认证应用程序。
    • 显示 QR 码。
    • 打开 Google Authenticator 并扫描 QR 码。
    • 在应用程序中添加的 AWS SSO 条目中输入显示的 6 位认证代码。
  4. [账户] 选项卡中,选择对应项目的权限集并登录。
图像

指导员工根据当前正在进行的项目选择相应的权限集登录。
虽然在项目之间切换可能有些繁琐,但使用浏览器的隐身模式或私密窗口可以同时登录多个项目。

目前,我们已限制了 VPC 的访问并为用户分配了权限。
但随着 AWS 服务使用范围的扩大,可能需要更多的限制。
尽管过程可能较为复杂,但我们会根据需要持续更新内联策略。

补充说明

使用 IAM 用户IAM Identity Center 提供的 ABAC(基于属性的访问控制) 可以根据用户属性实现动态访问限制。相关官方文档:

但上述方法似乎无法为参与多个项目的员工分配多重访问权限。
因此,我们选择了较为繁琐的方法,通过创建多个权限集进行应对。

未来,我们将继续探索更优的解决方案。

タイトルとURLをコピーしました