

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

# 额外的护栏
<a name="additional-guardrails"></a>

当解决方案构建者和用户适当地使用预签名的请求时，它们为用户提供了一种安全的数据访问机制。此外，生成预签名请求的功能并不能为委托人提供他们尚未拥有的访问权限。

在这种情况下，是否需要额外的控制措施？ 采取额外控制措施的理由不是基于拒绝访问的需求，而是为了提供监控、批准使用情况和设定界限以及降低用户错误风险的能力。通过这种方式，您可以帮助确保使用是适当和必要的。

以下护栏可帮助您实现这一目标。在启用这些控件之前，您可能需要通过识别预签名的请求来确定现有使用情况。这种识别可以帮助您为护栏对现有使用情况的影响做好准备，或者在需要时计划例外情况。

## s3: SignatureAge 的护栏
<a name="s3-signature-age"></a>

预签名请求的一个决定性特征是它们描述了过期时间。请求的签名包含日期。对于预签名 URL，此日期作为`X-Amz-Date`查询字符串参数传输，对于预签名 POST，则作为[日期或 x-amz-date 标题](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html)传输。

Amazon S3 提供了一个名为 [s3: SignatureAge](https://docs.aws.amazon.com/AmazonS3/latest/API/bucket-policy-s3-sigv4-conditions.html) 的条件密钥，您可以使用它来限制从签名日期到请求的有效到期之间的最长时间。这种情况永远不会延长有效期，但可以缩短有效期。

在以下策略中，`s3:signatureAge`条件键将预签名请求的有效期限制为 15 分钟。以下示例均使用 15 分钟将有效期限制在与标准签名支持的类似时间范围内。

该策略的第二条声明拒绝任何签名版本 2 的访问权限。[此版本的签名协议已被弃用](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingAWSSDK.html#UsingAWSSDK-sig2-deprecation)，但某些 AWS 区域版本仍受支持。我们建议您在将其完全弃用之前明确屏蔽它。

您可以将以下策略应用为 AWS Organizations 服务控制策略 (SCP)。只要签名生成和使用之间的时间少于 15 分钟，用户仍然可以使用预签名请求并部署依赖于这些请求的解决方案。根据实现的不同，此限制可能不会产生任何影响，也可能导致解决方案无法使用，或者可能导致偶尔出现故障，可以重试。

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyPresignedOver15Minutes",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        }
      }
    },
    {
      "Sid": "DenySignatureVersion2",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
           "s3:signatureversion": "AWS"
        }
      }
    }
  ]
}
```

### 异常
<a name="exceptions"></a>

如果解决方案需要更长的时间才能到期，因此受到上述政策的影响，我们建议您提供一种批准例外情况的方法。为避免枚举 SCP 中的异常，请使用 a [ws: PrincipalTag](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principaltag)，如以下策略所示，以可扩展的方式管理异常。其他 AWS 示例，例如 [AWS 数据边界策略示例](https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/README.md)，则使用此策略。

如果您通过使用实现异常策略`aws:PrincipalTag`，则必须控制对委托人设置标签的访问权限。这种类型的标签可以直接来自委托人，也可以由 SCP 控制，如[控制可以设置哪些标签值的示例](https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/service_control_policies/data_perimeter_governance_scp.json)。这种类型的标签也可以来自[会话标签，这些标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)由身份提供商 (IdP) 设置或在使用时设置。 AWS STS控制访问权限`aws:PrincipalTag`是一个复杂的话题。但是，具有使用[基于属性的访问控制 (ABAC)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html) 经验的组织将具有相应的经验和控制能力，可以`aws:PrincipalTag`针对此用例进行适当的使用。

在以下示例中，该`aws:PrincipalTag`条件创建了一个例外，允许分配命名标签 (`long-presigned-allowed`) 并将其设置为的任何委托人`true`。除此之外，对签名年龄的限制不适用。

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyPresignedOver15Minutes",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        },
        "StringNotEquals": {
          "aws:PrincipalTag/long-presigned-allowed": "true"
        }
      }
    }
  ]
}
```

### 存储桶策略
<a name="bucket-policies"></a>

您可以使用策略将存储桶策略应用于所有或选定的存储桶，如下例所示。与 SCP 不同，存储桶策略还针对[服务委托](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services)人的使用情况。[附录 A](appendix-a.md) 没有记录预签名请求的任何预期服务主体使用情况，但是如果您想实施控制以证明该限制，则以下策略将提供该控制权。此外，与 SCP 不同，存储桶策略可以应用于管理账户中的委托人。

ABAC-based 异常在存储桶策略中的作用方式与 SCP 相同。存储桶政策的目标可能是适用于组织外部的委托人，因此 ABAC 的例外情况应仅限于适用ABAC控制措施的委托人。

在以下示例中，第一条语句中的`aws:PrincipalTag`条件为分配了命名标签 (`long-presigned-allowed`) 且设置为的委托人创建了一个例外`true`。除此之外，对签名年龄的限制不适用。第二条语句将此限制应用于拥有存储桶的 AWS 组织以外的所有委托人。第二条语句的范围应与 ABAC 控件相匹配，以便为委托人设置命名标签。

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyPresignedOver15MinWithExceptions",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::{bucket-name}/*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        },
        "StringNotEquals": {
          "aws:PrincipalTag/long-presigned-allowed": "true"
        }
      }
    },
    {
      "Sid": "DenyPresignedOver15MinutesOutsideOrg",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::{bucket-name}/*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        },
        "StringNotEquals": {
          "aws:PrincipalOrgID": "${aws:ResourceOrgID}"
        }
      }
    }
  ]
}
```

## 资源控制策略
<a name="rcps"></a>

您可以使用[资源控制策略 (RCP) 将策略](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)大规模应用于存储桶。与 SCP 一样，与存储桶策略不同，RCP 不以服务委托人的使用为目标。RCP 会影响任何账户的非服务委托人，但不会影响管理账户中的资源。有关详情，请参阅 [AWS Organizations 文档](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html#actions-not-restricted-by-rcps)。

与存储桶策略一样，如果您使用`aws:PrincipalTags`为委托人创建例外，请记住 ABAC 对委托人标记的控制范围。

以下 RCP 将签名期限限制为 15 分钟，从而限制了组织中所有 S3 存储桶使用预签名 URL。

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyPresignedOver15MinWithExceptions",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::*/*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        },
        "StringNotEquals": {
          "aws:PrincipalTag/long-presigned-allowed": "true",
        }
      }
    },
    {
      "Sid": "DenyPresignedOver15MinutesOutsideOrg",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::*/*",
      "Condition": {
        "NumericGreaterThan": {
          "s3:signatureAge": "900000"
        },
        "StringNotEquals": {
          "aws:PrincipalOrgID": "${aws:ResourceOrgID}"
        }
      }
    }
  ]
}
```

## s3: authType 的护栏
<a name="s3-auth-type"></a>

预签名 URL 使用[查询字符串身份验证](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)，而预签名 POST 始终使用 P [OST](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html) 身份验证。Amazon S3 支持通过 [s3: authType 条件密钥根据身份验证类型](https://docs.aws.amazon.com/AmazonS3/latest/API/bucket-policy-s3-sigv4-conditions.html)拒绝请求。 `REST-QUERY-STRING`是查询字符串的`s3:authType`值，`POST`也是 POST 的`s3:authType`值。

您可以作为 SCP 应用以下策略。该策略用于仅`s3:authType`允许基于标头的身份验证。它还配置了一种向单个用户或角色提供例外情况的方法。

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyNonHeaderAuth",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "s3:authType": "REST-HEADER",
          "aws:PrincipalTag/non-header-auth-allowed": "true"
        }
      }
    }
  ]
}
```

根据身份验证类型拒绝请求会影响使用被拒绝身份验证类型的任何解决方案或功能。例如，拒绝`REST-QUERY-STRING`会阻止用户从 Amazon S3 控制台进行上传或下载。如果您希望用户使用 Amazon S3 控制台，请不要使用此护栏，也不要将用户作为例外。另一方面，如果您不希望用户使用 Amazon S3 控制台，则可以拒绝`REST-QUERY-STRING`用户使用。

也许您已经拒绝用户直接访问 Amazon S3 资源。在这种情况下，身份验证类型的护栏是多余的。但是，`s3:authType`拒绝语句提供了深度防御的效用，因为拒绝直接访问的实现通常跨越许多控制语句，有些则有例外。

用于工作负载的角色通常不需要访问查询字符串或`POST`身份验证。支持旨在使用预签名请求的服务的角色除外。您可以为这些角色创建特定的例外情况。

您还可以使用诸如以下的策略将存储桶策略应用于所有或选定的存储桶：

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyNonHeaderAuth",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::{bucket-name}/*",
      "Condition": {
        "StringNotEquals": {
          "s3:authType": "REST-HEADER",
          "aws:PrincipalTag/non-header-auth-allowed": "true"
        }
      }
    }
  ]
}
```

此存储桶策略的作用是拒绝使用**CopyObject**和 **UploadPartCopy**API 制作跨区域副本。Amazon S3 复制不会受到影响，因为它不依赖这些 API。

如果您想使用诸如上述策略之类的存储桶策略，但仍支持跨区域**CopyObject**或 **UploadPartCopy**API，请添加`aws:ViaAWSService`类似于以下内容的条件：

```
{
  "Version": "2012-10-17", 		 	 	 		 	 	 
  "Statement": [
    {
      "Sid": "DenyNonHeaderAuth",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::{bucket-name}/*",
      "Condition": {
        "StringNotEquals": {
          "s3:authType": "REST-HEADER",
          "aws:PrincipalTag/non-header-auth-allowed": "true"
        },
        "Bool": {
          "aws:ViaAWSService": "false"
        },
      }
    }
  ]
}
```

## 将预先签名的护栏与其他护栏的例外情况结合起来
<a name="combining-exceptions"></a>

如果您不打算对您的用户和角色普遍使用护栏，则可能需要将其应用于其他常见护栏的例外情况，这样这些例外就不支持预签名的请求。

如果您有网络限制，但允许外部合作伙伴例外情况或特殊用例，则应在应用这些例外情况时屏蔽查询字符串或`POST`身份验证，除非明确标识为必填项。

## s3: SignatureAge 的局限性
<a name="s3-signature-age-limits"></a>

管理员会发现，`s3:signatureAge`更全面地了解其含义很有用。每个已签署的请求都包括`X-Amz-Date`，它应注明当前时间。此值由客户端和请求签名者填写。 AWS 拒绝它认为时间无效的请求。但是，签名者可以在 future 的时间内提前生成签名。如果请求提前发送得太早，Amazon S3 会拒绝指定未来时间的请求。但是，如果请求直到签名后才发送，则签名可能会更早生成，然后再发送。

`s3:signatureAge`仅对预签名`X-Amz-Date`请求限制签名的最大年限。 超过指定年龄的申请将被拒绝，即使保单到期`X-Amz-Expires`或`POST`保单本来会宣布其有效。 `s3:signatureAge`不会更改不包含明确到期日期的请求的有效期。它也无法控制客户端用于签名的值。`X-Amz-Date`

如果系统时钟错误，或者客户故意将日期设置为未来日期，则签名时间可能不是生成签名的时间。 这限制了解决方案`s3:signatureAge`可以控制的程度。使用生成签名的当前时间的解决方案会受到预期的限制：签名在中指定的毫秒数内保持有效。`s3:signatureAge` 不使用当前时间的解决方案会有不同的限制。一个限制是，用于签署签名的凭证必须仍然有效。作为管理员，您可以控制所颁发的临时证书的最大有效期。 您可以允许证书的有效期最长 36 小时，也可以将有效期限制在 15 分钟以内。 临时证书的到期时间不取决于的值`X-Amz-Date`。

永久凭证没有此限制。 [仅使用临时证书](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_identities_unique.html)是最佳做法，您可以明确撤销任何永久证书，这也会使基于该凭证的所有签名失效。

尽管`s3:signatureAge`以毫秒为单位，但将其设置为小于 60 秒是不切实际的，即使您的时钟同步良好，使用延迟也很低。 低于 60 秒的设置存在拒绝有效请求的风险。如果您预计签名生成和请求提交之间会出现延迟，或者时钟同步出现问题，则应在管理中考虑这些问题`s3:signatureAge`。

## 大规模定位存储桶
<a name="buckets-at-scale"></a>

SCP 和 RCP 可以`aws:PrincipalTag`用来为用户设置例外。您不能在存储桶上使用标签来控制访问权限 `aws:ResourceTag` —— [只有对象标签用于访问控制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/tagging-and-policies.html)。向要应用此控件的每个对象添加标签通常无法扩展。 

适用于许多用例的解决方案是在账户级别应用策略和例外情况，方法是更改 SCP 或 RCP 适用的账户，或者使用 aws[: ResourceAccount、aws:](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceaccount) 或 a [w](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceorgpaths) s[: ResourceOrg ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceorgid)。ResourceOrgPaths例如，可以将 SCP 或 RCP 应用于一组生产帐户。

另一种解决方案是使用[自定义 AWS Config 规则](https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules.html)来实现[侦探控件](https://docs.aws.amazon.com/prescriptive-guidance/latest/aws-security-controls/detective-controls.html)或[响应式控件](https://docs.aws.amazon.com/prescriptive-guidance/latest/aws-security-controls/responsive-controls.html)。目标是让每个存储桶都包含带有适当护栏的存储桶策略。除了测试存储桶策略的内容外，如果存储桶使用特定值标记，则自定义 AWS Config 规则还可以从存储桶中检索标签，并从规则中排除该存储桶。如果该规则未通过合规性检查，则它可以将存储桶标记为不合规，也可以调用补救措施将护栏添加到存储桶的策略中。

**注意**  
您不能将请求的标签内容限制为[PutBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html)。要控制存储桶的标记方式，您必须限制对`PutBucketTagging`和的访问权限[DeleteBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html)。