Skip to content

本文为 SPIRE 官方文档 plugin_server_nodeattestor_aws_iid.md 的中文译本,以英文原文为准。 🔗 穿越源码分析:Server 详解 · NodeAttestor

Server 插件:NodeAttestor "aws_iid"

必须与 Agent 侧 aws_iid 插件配合使用

aws_iid 插件使用 AWS 实例元数据 API(Instance Metadata API)和 AWS 实例身份文档(Instance Identity document)自动对实例进行认证。它还允许运维人员在定义 SPIFFE ID 认证策略时使用 AWS 实例 ID(Instance ID)。由 aws_iid 认证器认证的 agent 会被签发形如 spiffe://example.org/spire/agent/aws_iid/ACCOUNT_ID/REGION/INSTANCE_ID 的 SPIFFE ID。此外,本插件还会将 agent 基于 AWS IID 的 SPIFFE ID 解析为一组 selector。

Configuration(配置)

ConfigurationDescriptionDefault
access_key_idAWS access key idAWS_ACCESS_KEY_ID 环境变量的值
secret_access_keyAWS secret access keyAWS_SECRET_ACCESS_KEY 环境变量的值
skip_block_device跳过防篡改机制,该机制会检查以确保底层根卷(root volume)在认证前未被分离(detached)。false
disable_instance_profile_selectors禁用获取用于 selector 的、被认证实例的 instance profile 信息。适用于 server 无法访问 iam.amazonaws.com 的场景。false
assume_role要担任(assume)的角色空字符串,可选参数。
partitionSPIRE server 所运行的 AWS 分区(partition)<aws|aws-cn|aws-us-gov>aws
verify_organization验证节点属于指定的 AWS 组织(Organization)见下文
validate_eks_cluster_membership验证节点属于指定的 EKS 集群 见下文

示例配置:

hcl
    NodeAttestor "aws_iid" {
        plugin_data {
            access_key_id = "ACCESS_KEY_ID"
            secret_access_key = "SECRET_ACCESS_KEY"
        }
    }

如果设置了 assume_role,SPIRE server 会担任由模板 arn:{{Partition}}:iam::{{AccountID}}:role/{{AssumeRole}} 指定的角色,其中 Partition 来自 AWS NodeAttestor 插件配置(若指定),否则设为 'aws';AccountID 取自 SPIRE agent 发送给 SPIRE server 的 AWS IID 文档;AssumeRole 来自 AWS NodeAttestor 插件配置。关于模板引擎的详情,见模板引擎文档

在以下配置中,

hcl
    NodeAttestor "aws_iid" {
        plugin_data {
            assume_role = "spire-server-delegate"
        }
    }

假设 spire agent 发送的 AWS IID 文档包含 accountId : 12345678,则 spire server 在为节点认证发起任何 AWS 调用之前,会先担任 "arn:aws:iam::12345678:role/spire-server-delegate" 角色。如果配置了 assume_role,即使 spire-server 和 spire agent 部署在同一账户中,spire server 也总是会担任该角色。

启用 AWS 节点认证的组织(Organization)校验

要为 AWS 节点认证方法配置组织校验,可使用以下配置:

Field NameDescriptionConstraints
management_account_id组织的账户 id(Account id)必填
management_account_region管理账户 id 所在的区域(Region)可选
assume_org_role具备列出账户(list accounts)能力的 IAM 角色名必填
org_account_map_ttl将账户列表缓存指定时长。应 >= 1 分钟。默认 3 分钟。可选

使用 verify_organization 块将启用组织校验的节点认证方法。采用上述配置时,spire server 会构造并尝试担任如下角色:arn:aws:iam::management_account_id:role/assume_org_role。若不使用该功能,则该块(例如 verify_organization = {})不应为空——由于它是可选的,应将其完全移除,否则就应填入全部必填参数,即 management_account_idassume_org_role

assume_role 所指的角色必须创建在管理账户 management_account_id 中,并且它应当与 spire server 所担任的角色之间存在信任关系(trust relationship)。下面是一份示例策略,展示了所需的权限以及需要在管理账户中创建的信任关系。

策略(Policy):

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "organizations:ListAccounts",
            "Effect": "Allow",
            "Resource": "*",
            "Sid": "SpireOrganizationListAccountRole"
        }
    ]
}

信任关系(Trust Relationship):

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CrossAccountAssumeRolePolicy",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::account-id-where-spire-is-running:role/spire-control-plane-root-server",
                    "arn:aws:iam::account-id-where-spire-is-running:role/spire-control-plane-regional-server"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

启用 AWS 节点认证的 EKS 集群校验

要为 AWS 节点认证方法配置 EKS 集群校验,可使用以下配置:

Field NameDescriptionConstraints
eks_cluster_names允许节点所属的 EKS 集群名称列表必填

使用 validate_eks_cluster_membership 块将启用 EKS 集群校验的节点认证方法。采用上述配置时,SPIRE server 会验证被认证节点属于所指定的 EKS 集群之一。若不使用该功能,则该块(例如 validate_eks_cluster_membership = {})不应为空——由于它是可选的,应将其完全移除,否则就应填入全部必填参数,即 eks_cluster_names

示例配置:

hcl
NodeAttestor "aws_iid" {
    plugin_data {
        validate_eks_cluster_membership = {
            eks_cluster_names = ["production-cluster", "staging-cluster"]
        }
    }
}

SPIRE server 会验证被认证的 EC2 实例属于某个自动伸缩组(Auto Scaling Group),而该伸缩组隶属于所指定的 EKS 集群之一。校验过程如下:

  1. 获取每个指定 EKS 集群的节点组(node group)列表
  2. 对每个节点组,获取其关联的自动伸缩组(Auto Scaling Group)
  3. 检查被认证的实例 ID 是否存在于这些自动伸缩组中的任意一个内

EKS 校验所需的 AWS IAM 权限

由所配置凭据标识的用户或角色,必须具备用于 EKS 集群校验的额外权限:

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EKSClusterValidation",
            "Effect": "Allow",
            "Action": [
                "eks:ListNodegroups",
                "eks:DescribeNodegroup",
                "autoscaling:DescribeAutoScalingGroups"
            ],
            "Resource": "*"
        }
    ]
}

禁用 Instance Profile 选择器

如果 spire-server 运行在没有公网访问的环境中,设置 disable_instance_profile_selectors = true 可阻止 server 向 iam.amazonaws.com 发起请求。这是必要的,因为此时 spire-server 无法获取元数据信息,从而会导致节点认证失败。

启用此项后,IAM Role selector 信息将不再可用。

AWS IAM 权限

由所配置凭据标识的用户或角色,必须具备 ec2:DescribeInstances 权限。

以下是从 AWS 获取实例信息所需的 IAM 策略示例。

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "iam:GetInstanceProfile"
            ],
            "Resource": "*"
        }
    ]
}

注意: 使用可选的校验特性时,还需要额外的权限:

  • 组织校验(verify_organization):organizations:ListAccounts
  • EKS 集群校验(validate_eks_cluster_membership):eks:ListNodegroupseks:DescribeNodegroupautoscaling:DescribeAutoScalingGroups

有关安全凭据的更多信息,见 https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html

支持的选择器(Supported Selectors)

本插件生成以下与 agent 运行所在实例相关的 selector:

SelectorExampleDescription
Account IDaws_iid:account_id:123456789012实例所属 AWS 账户的 ID。
Availability Zoneaws_iid:az:us-west-2b实例运行所在的可用区(Availability Zone)。
IAM roleaws_iid:iamrole:arn:aws:iam::123456789012:role/Blog实例的 instance profile 中的某个 IAM 角色
Image IDaws_iid:image:id:ami-5fb8c835用于启动该实例的 AMI 的 ID。
Instance IDaws_iid:instance:id:i-0b22a22eec53b9321实例的 ID。
Instance Tagaws_iid:tag:name:blog实例标签的键(例如 name)与值(例如 blog)
Regionaws_iid:region:us-west-2实例运行所在的区域(Region)。
Security Group IDaws_iid:sg:id:sg-01234567实例所属安全组的 id
Security Group Nameaws_iid:sg:name:blog实例所属安全组的名称

所有 selector 的类型均为 aws_iid

只有当实例关联了 IAM Instance Profile 且 disable_instance_profile_selectors = false 时,生成的 selector 集合中才会包含 IAM role selector。

Security Considerations(安全考量)

AWS 实例身份文档(Instance Identity Document)是本认证器用于证明节点身份的凭据,默认情况下节点上运行的任何进程都可访问它。因此,节点上的非 agent 代码有可能向 SPIRE Server 完成认证,从而获取该节点被授权运行的任意工作负载身份(workload identity)。

尽管许多运维人员会选择配置系统以阻止对实例身份文档的访问,但 SPIRE 项目无法保证这一安全态势。为缓解相关风险,aws_iid 节点认证器实现了首次使用即信任(Trust On First Use,简称 TOFU)语义。对于任意给定节点,认证只能发生一次,后续的认证尝试都将被拒绝。

非 agent 代码仍有可能先于 SPIRE Agent 完成节点认证;不过这种情况很容易被迅速发现,因为此时 SPIRE Agent 将无法启动,并且 SPIRE Agent 和 SPIRE Server 都会记录该事件。此类情况应作为可能的安全事件加以调查。