

# 保护 API Gateway 中的 HTTP API
<a name="http-api-protect"></a>

API Gateway 提供了多种方法来保护您的 API 免受某些威胁，例如恶意用户或流量高峰。您可以使用诸如设置目标和启用双向 TLS 等策略来保护您的 API。在本节中，您可以了解如何使用 API Gateway 启用这些功能。

**Topics**
+ [在 API Gateway 中限制对 HTTP API 的请求以提高吞吐量](http-api-throttling.md)
+ [如何针对 API Gateway 中的 HTTP API 启用双向 TLS 身份验证](http-api-mutual-tls.md)

# 在 API Gateway 中限制对 HTTP API 的请求以提高吞吐量
<a name="http-api-throttling"></a>

您可以为 API 配置节流，以帮助防止它们因请求过多而不堪重负。节流是在尽最大努力的基础上应用的，应被视为目标而不是保证的请求上限。

API Gateway 使用令牌桶算法（其中，一个令牌即一个请求）限制对 API 的请求。具体来说，API Gateway 根据您账户中的所有 API，按区域检查请求提交的速率和突发事件。在令牌桶算法中，突发可以允许这些限制的预定义超出，但在某些情况下，其他因素也可能导致限制超支。

如果请求提交超过稳态请求速率和突增限制，则 API Gateway 将开始限制请求。此时客户可能会收到 `429 Too Many Requests` 个错误响应。捕获此类异常后，客户端能够以限制速率的方式重新提交失败的请求。

作为 API 开发人员，您可以针对各个 API 阶段或方法设置目标限制，以提高账户中所有 API 的整体性能。

## 每个区域的账户级别限制
<a name="http-api-protect-throttling-account"></a>

默认情况下，API Gateway 针对每个区域限制 AWS 账户内所有 API 的每秒稳态请求 (RPS)。它还对于每个区域限制一个 AWS 账户中所有 API 的突增（即最大存储桶大小）。在 API Gateway 中，突增限制代表 API Gateway 在返回 `429 Too Many Requests` 错误响应之前可以完成目标的最大并发请求提交数量。有关限制配额的更多信息，请参阅[Amazon API Gateway 配额](limits.md)。

每个账户限制适用于指定区域内账户中的所有 API。客户可以请求我们放宽账户级别的速率限制 —— 如果具有更短的超时和较小的有效负载的 API，则可以提高限制。要请求增加每个区域的账户级别限制，请联系 [AWS Support 中心](https://console.aws.amazon.com/support/home#/)。有关更多信息，请参阅 [Amazon API Gateway 配额](limits.md)。请注意，这些限制不能高于 AWS 节流限制。

## 路由级别限制
<a name="http-api-protect-throttling-route"></a>

您可以设置路由级别限制，用于覆盖 API 中特定阶段或各个路由的账户级别请求限制。原定设置的路由节流限制不能超过账户级别的费率限制。

您可以使用 AWS CLI 配置路由级限制。以下 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) 命令为 API 的指定阶段和路由配置自定义节流。

```
aws apigatewayv2 update-stage \
    --api-id a1b2c3d4 \
    --stage-name dev \
    --route-settings '{"GET /pets":{"ThrottlingBurstLimit":100,"ThrottlingRateLimit":2000}}'
```

# 如何针对 API Gateway 中的 HTTP API 启用双向 TLS 身份验证
<a name="http-api-mutual-tls"></a>

双向 TLS 身份验证要求在客户端和服务器之间进行双向身份验证。使用双向 TLS，客户端必须提供 X.509 证书来验证其身份才能访问您的 API。双向 TLS 是物联网 (IoT) 和企业对企业应用程序的常见要求。

您可以使用双向 TLS 以及 API Gateway 支持的其他[授权和身份验证操作](apigateway-control-access-to-api.md)。API Gateway 将客户端提供的证书转发给 Lambda 授权方和后端集成。

**重要**  
默认情况下，客户端可以通过使用 API Gateway 为 API 生成的 `execute-api` 终端节点来调用您的 API。要确保客户端只能通过使用具有双向 TLS 的自定义域名访问您的 API，请禁用默认 `execute-api` 端点。要了解更多信息，请参阅“[禁用 REST API 的默认端点](http-api-disable-default-endpoint.md)”。

## 使用双向 TLS 的先决条件
<a name="http-api-mutual-tls-prerequisites"></a>

要配置双向 TLS，您需要：
+ 自定义域名
+ 至少在 AWS Certificate Manager 中为您的自定义域名配置了一个证书
+ 已配置信任存储库并上载到 Amazon S3

### 自定义域名
<a name="http-api-mutual-tls-custom-domain-name"></a>

 要为 HTTP API 启用双向 TLS，您必须为 API 配置自定义域名。您可以为自定义域名启用双向 TLS，然后向客户端提供自定义域名。要使用启用了双向 TLS 的自定义域名访问 API，客户端必须提供您在 API 请求中信任的证书。您可以在 [API Gateway 中的 HTTP API 的自定义域名](http-api-custom-domain-names.md) 中找到更多信息。

### 使用 AWS Certificate Manager 颁发的证书
<a name="http-api-mutual-tls-using-acm-issued-certs"></a>

您可以直接从 ACM 请求公开可信的证书，也可以导入公开证书或自签名证书。要在 ACM 中设置证书，请前往 [ACM](https://console.aws.amazon.com/acm/)。如果要导入证书，请继续阅读以下部分中的内容。

### 使用导入的证书或 AWS 私有证书颁发机构 证书
<a name="http-api-mutual-tls-non-acm-certs"></a>

要使用导入至 ACM 中的证书或来自 AWS 私有证书颁发机构 的带有双向 TLS 的证书，API Gateway 需要由 ACM 颁发的 `ownershipVerificationCertificate`。此所有权证书仅用于验证您是否有权使用域名。它不用于 TLS 握手。如果您还没有 `ownershipVerificationCertificate`，请前往 [https://console.aws.amazon.com/acm/](https://console.aws.amazon.com/acm/) 来设置一个。

您需要确保此证书在域名生命周期内有效。如果证书过期且自动续订失败，则域名的所有更新都将被锁定。您需要使用有效 `ownershipVerificationCertificate` 更新 `ownershipVerificationCertificateArn`，然后才能进行任何其他更改。`ownershipVerificationCertificate` 不能用作 API Gateway 中另一个双向 TLS 域的服务器证书。如果直接向 ACM 中重新导入证书，发布者必须保持不变。

### 配置信任存储库
<a name="http-api-mutual-tls-create-trust-store"></a>

信任存储库是带有 `.pem` 文件扩展名的文本文件。它们是来自证书颁发机构的证书的受信任列表。要使用双向 TLS，请创建您信任的 X.509 证书的信任存储库以访问您的 API。

您必须在信任存储库中包含完整的信任链，从颁发的 CA 证书到根 CA 证书。API Gateway 接受信任链中存在的任何 CA 发布的客户端证书。证书可以来自公有或私有证书颁发机构。证书的最大链长度可为四。您还可以提供自签名证书。信任存储库支持以下哈希算法：
+ SHA-256 或更强
+ RSA-2048 或更强
+ ECDSA-256 或更强

API Gateway 验证许多证书属性。您可以使用 Lambda 授权方在客户端调用 API 时执行其他检查，包括检查证书是否已被吊销。API Gateway 验证以下属性：


| 验证 | 说明 | 
| --- | --- | 
|  X.509 语法  |  证书必须满足 X.509 语法要求。  | 
|  完整性  |  证书的内容不得与信任存储库中证书颁发机构签名的内容有所差异。  | 
|  有效性  |  证书的有效期必须是最新的。  | 
|  名称链接/键链接  |  证书的名称和主题必须形成一个完整的链条。证书的最大链长度可为四。  | 

### 以单个文件的形式将信任存储库上载到 Amazon S3 存储桶
<a name="w2aac19c17b9b9c13"></a>

**Example certificates.pem**  

```
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
...
```

使用以下 [cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) AWS CLI 命令将 `certificates.pem` 上传到 Amazon S3 存储桶：

```
aws s3 cp certificates.pem s3://bucket-name
```

## 为自定义域名配置双向 TLS
<a name="http-api-mutual-tls-configure"></a>

要为 HTTP API 配置双向 TLS，必须为 API 使用区域自定义域名，且 TLS 最低版本为 1.2。要了解有关创建和配置自定义域名的更多信息，请参阅 [在 API Gateway 中设置区域自定义域名](apigateway-regional-api-custom-domain-create.md)。

**注意**  
私有 API 不支持双向 TLS。

将信任存储库上传到 Amazon S3 后，您可以将自定义域名配置为使用双向 TLS。使用以下 [create-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-domain-name.html) 命令创建带有双向 TLS 的自定义域名：

```
aws apigatewayv2 create-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreUri=s3://bucket-name/key-name
```

创建域名后，您必须为 API 操作配置 DNS 记录和基本路径映射。要了解更多信息，请参阅[在 API Gateway 中设置区域自定义域名](apigateway-regional-api-custom-domain-create.md)。

## 使用需要双向 TLS 的自定义域名调用 API
<a name="http-api-mutual-tls-invoke"></a>

要调用启用了双向 TLS 的 API，客户端必须在 API 请求中提供受信任证书。当客户端尝试调用您的 API 时，API Gateway 会在您的信任存储库中查找客户端证书的发布者。为使 API Gateway 继续处理请求，证书的发布者和直至根 CA 证书的完整信任链必须位于您的信任存储库中。

以下示例 `curl` 命令将请求发送到在请求中包含 `api.example.com,` 的 `my-cert.pem`。`my-key.key` 是证书的私有密钥。

```
curl -v --key ./my-key.key --cert ./my-cert.pem api.example.com
```

仅当您的信任存储库信任证书时，才会调用您的 API。以下情况将导致 API Gateway 使 TLS 握手失败，并以 `403` 状态代码拒绝请求。如果您的证书：
+ 不可信
+ 已过期
+ 未使用支持的算法

**注意**  
API Gateway 不验证证书是否已被吊销。

## 更新您的信任存储库
<a name="http-api-mutual-tls-update-truststore"></a>

要更新信任存储库中的证书，请将新的证书服务包上载到 Amazon S3。然后，您可以更新自定义域名以使用更新后的证书。

使用 [Amazon S3 版本控制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html)来维护信任存储库的多个版本。当您更新自定义域名以使用新的信任存储库版本时，如果证书无效，则 API Gateway 返回警告。

API Gateway 仅在您更新域名时才生成证书警告。如果先前上传的证书过期，API Gateway 不会通知您。

使用以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令更新自定义域名，使其使用新的信任存储库版本：

```
aws apigatewayv2 update-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreVersion='abcdef123'
```

## 禁用双向 TLS
<a name="http-api-mutual-tls-disable"></a>

要为自定义域名禁用双向 TLS，请从自定义域名中删除信任存储库，如以下命令所示。

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令更新自定义域名，使其从自定义域名中删除信任存储库：

```
aws apigatewayv2 update-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreUri=''
```

## HTTP API 的双向 TLS 故障排除
<a name="http-api-mutual-tls-troubleshooting"></a>

以下内容为您在启用双向 TLS 时可能遇到的错误和问题提供故障排除建议。

### 排查证书警告问题
<a name="http-api-mutual-tls-troubleshooting-certificate"></a>

 当使用双向 TLS 创建自定义域名时，如果信任存储库中的证书无效，则 API Gateway 会返回警告。在更新自定义域名以使用新的信任存储库时，也可能会出现这种情况。警告指示证书存在问题以及生成警告的证书的主题。仍然为您的 API 启用双向 TLS，但某些客户端可能无法访问您的 API。

要标识生成警告的证书，您需要解码信任存储库中的证书。您可以使用诸如 `openssl` 等工具对证书进行解码和标识其主题。

以下命令显示证书的内容，包括其主题：

```
openssl x509 -in certificate.crt -text -noout
```

更新或删除生成警告的证书，然后将新信任存储库上传到 Amazon S3。上载新的信任存储库后，请更新您的自定义域名以使用新的信任存储库。

### 域名冲突故障排除
<a name="w2aac19c17b9c19b7"></a>

错误 `"The certificate subject <certSubject> conflicts with an existing certificate from a different issuer."` 表示多个证书颁发机构已发布此域的证书。对于证书中的每个主题，双向 TLS 域的 API Gateway 中只能有一个发布者。您需要通过单个发布者获取该主题的所有证书。如果您无法控制的证书出现问题，但您可以证明域名的所有权，请[联系 支持](https://console.aws.amazon.com/support/cases#/create) 以提出支持请求。

### 域名状态消息故障排除
<a name="w2aac19c17b9c19b9"></a>

`PENDING_CERTIFICATE_REIMPORT`：这意味着您将证书重新导入到 ACM，并且验证失败，因为新证书具有 SAN（主题备用名称），而 `ownershipVerificationCertificate` 不涵盖该 SAN，或是证书中的主题或 SAN 不涵盖域名。某些内容可能配置不正确，或导入了无效的证书。您需要将有效证书重新导入 ACM。有关验证的更多信息，请参阅[验证域名所有权](https://docs.aws.amazon.com/acm/latest/userguide/domain-ownership-validation.html)。

`PENDING_OWNERSHIP_VERIFICATION`：这意味着您之前验证的证书已过期，ACM 无法自动续订。您需要续订证书或请求新证书。有关证书续订的更多信息，请查看 [ACM 对托管式证书续订进行故障排除](https://docs.aws.amazon.com/acm/latest/userguide/troubleshooting-renewal.html)指南。