跳至内容

如何将密钥或敏感信息安全地传递给 Amazon ECS 任务中的容器?

3 分钟阅读
0

我想将密钥或敏感信息安全地传递给 Amazon Elastic Container Service (Amazon ECS) 任务中的容器。

简短描述

如果您以明文形式传递敏感数据,则可能会引发安全问题。这些数据可能会在 AWS 管理控制台中,或通过 DescribeTaskDefinition AWS API 被发现。

作为安全最佳实践,请将敏感信息作为环境变量传递给容器。要将数据安全地注入容器,请引用存储在 Parameter Store(AWS Systems Manager 的一项功能)中的值。您也可以在 Amazon ECS 任务定义中使用 AWS Secrets Manager。然后,您可以将敏感信息作为环境变量或在容器的日志配置中公开。

解决方法

**注意:**如果在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

先决条件:

  • 如果使用 AWS Fargate 启动类型,则您的任务必须使用 AWS Fargate 平台版本 1.3.0 或更高版本
  • 如果使用 Amazon Elastic Compute Cloud (Amazon EC2) 启动类型,则您的容器实例必须使用 amazon-ecs-agent 1.22.0 或更高版本。有关详细信息,请参阅 GitHub 网站上的 Changelog
  • 要注入 JSON 密钥,您的 Fargate 平台必须运行 1.4.0 或更高版本 (Linux),或 1.0.0 版本 (Windows)。
  • 要使用特定的 JSON 密钥或密钥版本,您的容器实例的 ECS 容器代理必须运行 1.37.0 或更高版本才能进行密钥注入。
  • 要将密钥的完整内容注入到日志配置或环境变量中,您的容器实例的 ECS 容器代理必须运行 1.22.0 或更高版本。

创建 IAM 角色和策略

完成以下步骤:

  1. 将您的敏感信息存储在 Parameter Store 或 Secrets Manager 中。

    对于 Parameter Store,请运行以下 put-parameter AWS CLI 命令:

    aws ssm put-parameter --type SecureString --name awsExampleParameter --value awsExampleValue

    **注意:**请将 awsExampleParameter 替换为您自己的参数。将 awsExampleValue 替换为您的密钥值。

    对于 Secrets Manager,请运行以下 create-secret AWS CLI 命令:

    aws secretsmanager create-secret --name awsExampleParameter --secret-string awsExampleValue

    **注意:**请将 awsExampleParameter 替换为您自己的参数。将 awsExampleValue 替换为您的密钥值。ECS 容器代理使用任务执行角色从 Parameter Store 或 Secrets Manager 获取信息。该任务执行角色必须被授予 ssm:GetParameterssecretsmanager:GetSecretValuekms:Decrypt 操作的权限。

  2. 打开 AWS Identity and Access Management (IAM) 控制台

  3. 创建一个具有信任关系的角色,以用于 ecs-tasks.amazonaws.com
    角色的信任策略示例:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "Service": "ecs-tasks.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
  4. 选择 Roles(角色),然后选择您创建的角色。

  5. Permissions(权限)选项卡下,选择 Add permissions(添加权限)下拉列表。

  6. 选择 Create inline policy(创建内联策略),然后选择 JSON 选项卡。

  7. 附加以下策略:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ssm:GetParameters",
            "secretsmanager:GetSecretValue"
          ],
          "Resource": [
            "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter",
            "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter*"
          ]
        }
      ]
    }

    **注意:**请将 us-east-1awsExampleAccountID 替换为您用于存储参数的 AWS 区域和账户。将 awsExampleParameter 替换为您创建的参数的名称。您可以使用 AWS Key Management Service (AWS KMS) 客户自主管理型密钥对 Parameter Store 或 Secrets Manager 中的数据进行加密。要使用客户自主管理型密钥,请获取 kms:Decrypt 权限。

  8. (可选)将托管策略 AmazonECSTaskExecutionRolePolicy 附加到您创建的角色。

**重要事项:**将日志发送到 Amazon CloudWatch 或使用存储在 Amazon Elastic Container Registry (Amazon ECR) 中的映像的任务必须具有托管策略。

在 ECS 任务定义中引用敏感信息

使用 Amazon ECS 控制台或 AWS CLI 在 ECS 任务定义中引用敏感信息。

使用 Amazon ECS 控制台

完成以下步骤:

  1. 打开 Amazon ECS 控制台
  2. 在导航窗格中,选择 Task Definitions(任务定义),然后选择 Create new task definition(创建新任务定义)。
    对于 Task definition family(任务定义系列),输入一个名称。
    对于 Launch type(启动类型),选择 AWS FargateAmazon EC2 instances(Amazon EC2 实例)作为启动类型。
  3. 对于 Task execution role(任务执行角色),选择您创建的任务执行 IAM 角色。
  4. Container Definitions(容器定义)部分的 Environment variables(环境变量)部分下,选择 Add environment variable(添加环境变量)。
  5. 对于 Key(密钥),输入您的环境变量的密钥。
  6. ValueType 下拉列表中,选择 ValueFrom
  7. 在密钥文本框中,输入您的 Parameter Store 或 Secrets Manager 资源的 Amazon 资源名称 (ARN)。
    **注意:**您也可以在日志驱动程序配置中指定密钥。

使用 AWS CLI

使用 secrets 部分在任务定义中将 Parameter Store 或 Secrets Manager 资源引用为环境变量。或者,使用 secretOptions 部分将 Parameter Store 或 Secrets Manager 引用为日志配置选项。

任务定义示例:

{
  "requiresCompatibilities": [
    "EC2"
  ],
  "family": "Web",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "httpd",
      "memory": 128,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "splunk",
        "options": {
          "splunk-url": "https://sample.splunk.com:8080"
        },
        "secretOptions": [
          {
            "name": "splunk-token",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter"
          }
        ]
      },
      "secrets": [
        {
          "name": "DATABASE_PASSWORD",
          "valueFrom": "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter"
        }
      ]
    }
  ],
  "executionRoleArn": "arn:aws:iam::awsExampleAccountID:role/awsExampleRoleName"
}

**注意:**请将 us-east-1awsExampleAccountID 替换为您的区域和账户 ID。将 awsExampleParameter 替换为您创建的参数。将 awsExampleRoleName 替换为您创建的角色。

然后,运行以下 register-task-definition AWS CLI 命令以注册任务定义:

aws ecs register-task-definition --family-name yourTaskDefinitionFamily --cli-input-json file://pathToYourJsonFile

**注意:**请将 yourTaskDefinitionFamily 替换为您的任务定义系列名称。

当您使用此定义启动任务时,ECS 容器代理会自动解析密钥。然后,容器代理会将这些值作为环境变量注入到容器中。

更新密钥并部署更改

启动 ECS 容器时,容器会将敏感数据注入其中。如果您更新或轮换密钥或 Parameter Store 参数,容器不会自动接收更新后的值。您必须启动一项新任务。如果您的任务是服务的一部分,请更新该服务。要强制服务启动新任务,请使用 Force new deployment(强制实施新部署)选项。

要强制实施新部署,请完成以下步骤:

  1. 打开 Amazon ECS 控制台
  2. 选择 Clusters(集群),然后选择包含您的服务的集群。
  3. Update(更新)下拉列表中选择 Force New Deployment(强制实施新部署)。
    **注意:**要通过 AWS CLI 强制实施新部署,请运行带有 --force-new-deployment 标志的 update-service 命令。

相关信息

更新 Amazon ECS 容器代理