

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用加密日志中的 CloudWatch 日志数据 AWS Key Management Service
<a name="encrypt-log-data-kms"></a>

日志组数据始终在 CloudWatch 日志中加密。默认情况下， CloudWatch Logs 使用具有 256 位高级加密标准 Galois/Counter 模式 (AES-GCM) 的服务器端加密来加密静态日志数据。此外，您也可以使用 AWS Key Management Service 进行这一加密。如果这样做，则使用密 AWS KMS 钥进行加密。在日志组级别启用加密，方法 AWS KMS 是在创建日志组时或日志组存在之后，将 KMS 密钥与日志组关联起来。

**重要**  
CloudWatch 日志现在支持加密上下文，使用`kms:EncryptionContext:aws:logs:arn`作为密钥，使用日志组的 ARN 作为该密钥的值。如果您的日志组已使用 KMS 密钥加密，并且您希望将密钥限制在单个账户和日志组中使用，则应分配一个新的 KMS 密钥，该 KMS 密钥在 IAM policy 中包含一个条件。有关更多信息，请参阅 [AWS KMS 密钥和加密上下文](#encrypt-log-data-kms-policy)。

**重要**  
CloudWatch Log `kms:ViaService` s 现在支持允许日志代表您 AWS KMS 拨打电话。您应该将其添加到在密钥策略或 IA CloudWatch M 中调用 Logs 的角色中。有关更多信息，请参阅 [kms: ViaService](https://docs.aws.amazon.com/kms/latest/developerguide/conditions-kms.html#conditions-kms-via-service)。

将 KMS 密钥与日志组关联后，该日志组所有新摄取的数据都将使用该密钥加密。这些数据在整个保留期内以加密格式存储。 CloudWatch 只要有请求，日志就会解密这些数据。 CloudWatch 每当请求加密数据时，日志都必须具有 KMS 密钥的权限。

如果您稍后解除 KMS 密钥与日志组的关联，Logs 将使用 CloudWatch CloudWatch 日志默认加密方法对新摄取的数据进行加密。之前采集的所有使用 KMS 密钥加密的数据仍使用 KMS 密钥进行加密。 CloudWatch 解除关联 KMS 密钥后，日志仍然可以返回该数据，因为 CloudWatch 日志仍然可以继续引用该密钥。但是，如果密钥稍后被禁用，则 CloudWatch Logs 将无法读取使用该密钥加密的日志。

**重要**  
CloudWatch 日志仅支持对称 KMS 密钥。请勿使用非对称密钥对日志组中的数据进行加密。有关更多信息，请参阅[使用对称和非对称密钥](https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html)。

## 限制
<a name="encryption-limits"></a>
+ 要执行下列步骤，您必须具有以下权限：`kms:CreateKey`、`kms:GetKeyPolicy` 和 `kms:PutKeyPolicy`。
+ 将密钥与日志组关联或解除关联后，最多可能需要五分钟时间，此操作才能生效。
+ 如果您撤消 CloudWatch 日志对关联密钥的访问权限或删除关联的 KMS 密钥，则无法再检索 CloudWatch 日志中的加密数据。
+ 您无法使用 CloudWatch 控制台将 KMS 密钥与现有日志组关联。

## 步骤 1：创建 AWS KMS 密钥
<a name="create-cmk"></a>

要创建 KMS 密钥，请使用以下 [create-key](https://docs.aws.amazon.com/cli/latest/reference/kms/create-key.html) 命令：

```
aws kms create-key
```

输出包含密钥的密钥 ID 和 Amazon 资源名称（ARN）。下面是示例输出：

```
{
    "KeyMetadata": {
        "Origin": "AWS_KMS",
        "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
        "Description": "",
        "KeyManager": "CUSTOMER",
        "Enabled": true,
        "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "CreationDate": 1478910250.94,
        "Arn": "arn:aws:kms:us-west-2:123456789012:key/6f815f63-e628-448c-8251-e40cb0d29f59",
        "AWSAccountId": "123456789012",
        "EncryptionAlgorithms": [
            "SYMMETRIC_DEFAULT"
        ]
    }
}
```

## 步骤 2：设置 KMS 密钥的权限
<a name="cmk-permissions-lg"></a>

默认情况下，所有 AWS KMS 密钥都是私有的。只有资源所有者可以使用它来加密和解密数据。但是，资源拥有者可以将 KMS 密钥的访问权限授予其他用户和资源。通过此步骤，您可以授予 CloudWatch 日志服务主体和呼叫者角色使用密钥的权限。此服务主体必须位于存储 KMS 密钥的同一 AWS 区域。

作为最佳实践，我们建议您将 KMS 密钥的使用限制在您指定的 AWS 账户或日志组中。

首先，`policy.json`使用以下[get-key-policy](https://docs.aws.amazon.com/cli/latest/reference/kms/get-key-policy.html)命令保存 KMS 密钥的默认策略：

```
aws kms get-key-policy --key-id key-id --policy-name default --output text > ./policy.json
```

在文本编辑器中打开 `policy.json` 文件，然后从以下语句之一中添加粗体的部分。使用逗号将现有语句与新语句分隔。这些语句使用`Condition`章节来增强 AWS KMS 密钥的安全性。有关更多信息，请参阅 [AWS KMS 密钥和加密上下文](#encrypt-log-data-kms-policy)。

本示例中的 `Condition` 部分将密钥限制为单个日志组 ARN。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "key-default-1",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
            "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.us-east-1.amazonaws.com"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Describe*"
            ],
            "Resource": "*",
            "Condition": {
                "ArnEquals": {
                "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:111122223333:log-group:log-group-name"
                }
            }
        }
    ]
}
```

------

本示例中的 `Condition` 部分对 AWS KMS 密钥的使用进行限制，只有指定账户才能使用该密钥，但该密钥可用于任何日志组。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "key-default-1",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
            "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Principal": {
            "Service": "logs.us-east-1.amazonaws.com"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Describe*"
            ],
            "Resource": "*",
            "Condition": {
                "ArnLike": {
                "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:123456789012:*"
                }
            }
        }
    ]
}
```

------

接下来，为将调用 CloudWatch 日志的角色添加权限。为此，您可以向 AWS KMS 密钥策略添加其他声明，也可以通过 IAM 对角色本身进行说明。 CloudWatch 记录`kms:ViaService`用户 AWS KMS 代表客户拨打电话。有关更多信息，请参阅 [kms: ViaService](https://docs.aws.amazon.com/kms/latest/developerguide/conditions-kms.html#conditions-kms-via-service)。

要在 AWS KMS 密钥策略中添加权限，请在密钥策略中添加以下附加声明。如果您使用此方法，则作为最佳实践，请将策略范围仅限于将与 AWS KMS 加密日志组交互的角色。

```
{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::account_id:role/role_name"
  },
  "Action": [
    "kms:Encrypt",
    "kms:ReEncrypt*",
    "kms:Decrypt",
    "kms:GenerateDataKey*",
    "kms:Describe*"
  ],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "kms:ViaService": [
        "logs.region.amazonaws.com"
      ]
    }
  }
}
```

或者，如果您想在 IAM 中管理角色权限，则可以通过以下策略添加等效权限。您可以将此策略添加到现有角色策略中，也可以将其作为单独的额外策略附加到角色。如果您使用此方法，则作为最佳实践，请将策略范围仅限于将用于日志加密的 AWS KMS 密钥。有关更多信息，请参阅[编辑 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-edit.html)。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:Decrypt",
                "kms:GenerateDataKey*",
                "kms:Describe*"
            ],
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": [
                        "logs.us-east-1.amazonaws.com"
                    ]
                }
            },
            "Resource": "arn:aws:kms:us-east-1:444455556666:key/key_id"
        }
    ]
}
```

------

最后，使用以下[put-key-policy](https://docs.aws.amazon.com/cli/latest/reference/kms/put-key-policy.html)命令添加更新的策略：

```
aws kms put-key-policy --key-id key-id --policy-name default --policy file://policy.json
```

## 步骤 3：将日志组与 KMS 密钥关联
<a name="associate-cmk"></a>

可以在创建日志组时或创建完成后将 KMS 密钥与它关联。

要查看日志组是否已关联了 KMS 密钥，请使用以下[describe-log-groups](https://docs.aws.amazon.com/cli/latest/reference/logs/describe-log-groups.html)命令：

```
aws logs describe-log-groups --log-group-name-prefix "log-group-name-prefix"
```

如果输出包含 `kmsKeyId` 字段，则日志组将与该字段值所对应的键相关联。

**在创建日志组时将 KMS 密钥与它关联**  
按以下方式使用 [create-log-group](https://docs.aws.amazon.com/cli/latest/reference/logs/create-log-group.html) 命令：

```
aws logs create-log-group --log-group-name my-log-group --kms-key-id "key-arn"
```

**将 KMS 密钥与现有日志组关联**  
按以下方式使用 [associate-kms-key](https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html) 命令：

```
aws logs associate-kms-key --log-group-name my-log-group --kms-key-id "key-arn"
```

## 步骤 4：取消日志组与密钥的关联
<a name="disassociate-cmk"></a>

要取消与日志组关联的 KMS 密钥的关联，请使用以下[disassociate-kms-key](https://docs.aws.amazon.com/cli/latest/reference/logs/disassociate-kms-key.html)命令：

```
aws logs disassociate-kms-key --log-group-name my-log-group
```

## AWS KMS 密钥和加密上下文
<a name="encrypt-log-data-kms-policy"></a>

为了增强 AWS Key Management Service 密钥和加密日志组的安全性，Lo CloudWatch gs 现在将日志组 ARNs 作为*加密上下文*的一部分，用于加密您的日志数据。加密上下文是一组用作附加的经身份验证的数据的键值对。加密上下文允许您使用 IAM 策略条件来限制 AWS 账户和日志组对 AWS KMS 密钥的访问权限。有关更多信息，请参阅[加密上下文](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)和 [IAM JSON 策略元素：条件](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)。

我们建议您为每个加密的日志组使用不同的 KMS 密钥。

如果您有以前加密的日志组，但现在希望将日志组更改为使用仅适用于该日志组的新 KMS 密钥，请按照下列步骤操作。

**将加密的日志组转换为使用某个 KMS 密钥，并且有策略将此 KMS 密钥设置为仅限于该日志组使用**

1. 输入以下命令以查找该日志组的当前密钥的 ARN：

   ```
   aws logs describe-log-groups
   ```

   输出包括以下行。记录 ARN。您需要在步骤 7 中使用它。

   ```
   ...
   "kmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/01234567-89ab-cdef-0123-456789abcdef"
   ...
   ```

1. 输入以下命令以创建新的 KMS 密钥：

   ```
   aws kms create-key
   ```

1. 输入以下命令以将新密钥的策略保存到 `policy.json` 文件中：

   ```
   aws kms get-key-policy --key-id new-key-id --policy-name default --output text > ./policy.json
   ```

1. 使用文本编辑器打开 `policy.json` 并向策略添加 `Condition` 表达式：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Id": "key-default-1",
       "Statement": [
           {
               "Sid": "Enable IAM User Permissions",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": "kms:*",
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Principal": {
               "Service": "logs.us-east-1.amazonaws.com"
               },
               "Action": [
                   "kms:Encrypt",
                   "kms:Decrypt",
                   "kms:ReEncrypt*",
                   "kms:GenerateDataKey*",
                   "kms:Describe*"
               ],
               "Resource": "*",
               "Condition": {
                   "ArnLike": {
                   "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:111122223333:log-group:LOG-GROUP-NAME"
                   }
               }
           }
       ]
   }
   ```

------

1. 输入以下命令以将更新的策略添加到新的 KMS 密钥：

   ```
   aws kms put-key-policy --key-id new-key-ARN --policy-name default --policy file://policy.json
   ```

1. 输入以下命令以将策略与日志组关联：

   ```
   aws logs associate-kms-key --log-group-name my-log-group --kms-key-id new-key-ARN
   ```

   CloudWatch Logs 现在使用新密钥对所有新数据进行加密。

1. 接下来，从旧的密钥撤销除 `Decrypt` 之外的所有其他权限。首先，输入以下命令以检索旧策略：

   ```
   aws kms get-key-policy --key-id old-key-ARN --policy-name default --output text > ./policy.json
   ```

1. 使用文本编辑器打开 `policy.json` 并从 `Action` 列表中删除所有值，但 `kms:Decrypt` 除外

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Id": "key-default-1",
       "Statement": [
           {
               "Sid": "Enable IAM User Permissions",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": "kms:*",
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "logs.region.amazonaws.com"
               },
               "Action": [
                   "kms:Decrypt"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 输入以下命令以将更新的策略添加到旧的密钥：

   ```
   aws kms put-key-policy --key-id old-key-ARN --policy-name default --policy file://policy.json
   ```