当我启动附加了加密卷的实例时,实例立即停止,并显示错误消息“client error on launch”。

上次更新日期:2022 年 1 月 7 日

我启动了附加了加密卷的 Amazon Elastic Compute Cloud (Amazon EC2) 实例,但实例未成功启动。实例立即从“待处理”状态变为“关闭”状态,然后最终变为“已终止”状态。我在已终止的实例上运行 AWS Command Line Interface (AWS CLI) 命令 describe-instances,并获得了以下错误消息:

....
"StateReason": {
  "Code": "Client.InternalError"
  "Message": "Client.InternalError: Client error on launch"
},
....

如何解决此问题?

简短描述

在以下情况下,附加了加密卷的 EC2 实例会发生此问题:

  • 启动实例的 AWS Key Management Service (AWS KMS) 或 AWS Identity and Access Management (IAM) 用户没有所需的权限。
  • KMS 密钥的使用受 SourceIp 条件密钥的限制。

IAM 用户必须具有 AWS KMS 的权限才能解密 AWS KMS 密钥。

要允许解密 KMS 密钥访问,您必须将密钥策略与 IAM 策略或授权结合使用。仅凭 IAM 策略不足以允许访问 KMS 密钥,但您可以将它们与 KMS 密钥的策略结合使用。

在原定设置中,KMS 密钥仅授予对根账户的访问权限。向 IAM 用户或角色提供 EC2 完全权限时,AWS KMS 权限必须明确授予对 KMS 密钥策略的访问权限。

解决方法

创建 IAM 策略以允许 IAM 委托人调用 AWS KMS API

注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

1.    打开 IAM 控制台,选择策略,然后选择创建策略

2.    选择 JSON 选项卡,然后使用资源密钥 ARN 复制并粘贴此策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:Encrypt",
        "kms:GenerateDataKey*",
        "kms:DescribeKey",
        "kms:CreateGrant"
      ],
      "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
    }
  ]
}

3.    选择 Review policy(查看策略)。

4.    在名称中,输入对您有意义的名称,然后选择创建策略

5.    选择您在步骤 4 中创建的策略。

6.    选择策略使用选项卡,然后选择附上

7.    在名称中,选择要授予 KMS 密钥访问权限的 IAM 实体,然后选择附上策略

授予 IAM 委托人对 KMS 密钥的显式访问权限

1.    打开 AWS KMS 控制台,然后选择客户管理的密钥

2.    在密钥 ID 中,选择您的密钥 ID

3.    在密钥用户中,选择添加

4.    在名称中,选择 IAM 用户或角色,然后选择添加

注意:如果您使用的是自定义密钥策略而不是原定设置的密钥策略,则 KMS 密钥必须明确授予以下权限:

{
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
        "arn:aws:iam::123456789012:role/MyRoleName",
          "arn:aws:iam::123456789012:user/MyUserName"
        ]
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow attachment of persistent resources",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
      "arn:aws:iam::123456789012:role/MyRoleName",
          "arn:aws:iam::123456789012:user/MyUserName"
        ]
      },
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": "true"
        }
      }
    }

使用 IP 地址条件

如果您使用 AWS KMS 保护集成服务中的数据,则在指定 IP 地址条件运算符时或在同一访问策略语句中指定 aws:SourceIp 条件密钥时要小心。将加密的 Amazon Elastic Block Store (Amazon EBS) 卷附加到 Amazon EC2 实例会引发 Amazon EC2 向 AWS KMS 发送请求。该请求将解密卷的加密数据密钥。该请求来自与 EC2 实例关联的 IP 地址,而不是用户的 IP 地址。这意味着如果设置了 SourceIp 条件,则解密请求将被拒绝,并且实例失败。

使用 kms:ViaService 条件密钥。AWS KMS 允许代表您从该服务进行交互。确保委托人有权使用 KMS 密钥和集成服务。有关更多信息,请参阅 kms:ViaService 条件密钥限制

注意:具有登录用户的 EC2 实例无法与此条件进行交互 – 只有代表您的服务才能进行交互。此交互将记录在 AWS CloudTrail 日志中以供您查看。

在以下示例中,向 AWS KMS 提供 API 调用的 CloudTrail 条目。这是通过 Amazon EC2 基础设施调用的,而不是从特定 IP 地址调用的。当您向用户添加允许 AWS KMS 与 Amazon EC2 交互的策略时,API 调用即可完成。

"userIdentity": {
  "sessionContext": {
  "sessionIssuer": {
    "accountId": "450822418798",
    "principalId": "450822418798:aws:ec2-infrastructure",
    "userName": "aws:ec2-infrastructure",
    "arn": "arn:aws:iam::450822418798:role/aws:ec2-infrastructure",
    "type": "Role"
   },
...
  "eventType": "AwsApiCall",
  "@log_group": "CloudTrail/AllRegionLogGroup",
  "awsRegion": "eu-west-1",
  "requestParameters": {
    "encryptionContext": {
    "aws:ebs:id": "vol-0ca158925aa9c1883"
    }
}