

# API Gateway で HTTP API を保護する
<a name="http-api-protect"></a>

API Gateway は、悪意のあるユーザーやトラフィックの急増など、特定の脅威から API を保護するさまざまな方法を提供します。スロットリングターゲットの設定や相互 TLS の有効化などの戦略を使用して、API を保護できます。このセクションでは、API Gateway を使用してこれらの機能を有効にする方法を説明しています。

**Topics**
+ [HTTP API へのリクエストをスロットリングして API Gateway のスループットを向上させる](http-api-throttling.md)
+ [API Gateway で HTTP API の相互 TLS 認証を有効にする方法](http-api-mutual-tls.md)

# HTTP API へのリクエストをスロットリングして API Gateway のスループットを向上させる
<a name="http-api-throttling"></a>

API のスロットリングを設定して、多すぎるリクエストで 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 サポートセンター](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) および B2B アプリケーションの一般的な要件です。

相互 TLS は、API Gateway がサポートする他の[認可オペレーションおよび認証オペレーション](apigateway-control-access-to-api.md)と共に使用できます。API Gateway は、クライアントが提供する証明書を Lambda オーソライザーおよびバックエンド統合に転送します。

**重要**  
デフォルトでは、クライアントは、API Gateway が API 用に生成する `execute-api` エンドポイントを使用して API を呼び出すことができます。相互 TLS でカスタムドメイン名を使用することによってのみクライアントが API にアクセスできるようにするには、デフォルトの `execute-api` エンドポイントを無効にします。詳細については[HTTP API のデフォルトのエンドポイントを無効にする](http-api-disable-default-endpoint.md)を参照してください。

## 相互 TLS の前提条件
<a name="http-api-mutual-tls-prerequisites"></a>

相互 TLS を設定するには、以下が必要です。
+ カスタムドメイン名
+ カスタムドメイン名用の AWS Certificate Manager で構成されている少なくとも 1 つの証明書
+ 設定され 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 Private Certificate Authority 証明書を使用する
<a name="http-api-mutual-tls-non-acm-certs"></a>

ACM にインポートされた証明書、または相互 TLS を用いた AWS Private Certificate Authority からの証明書を使用するには、API Gateway には ACM が発行した `ownershipVerificationCertificate` が必要です。この所有権証明書は、ドメイン名を使用する許可を持っていることを確認するためにのみ使用されます。TLS ハンドシェイクには使用されません。まだ `ownershipVerificationCertificate` を持っていない場合は、[https://console.aws.amazon.com/acm/](https://console.aws.amazon.com/acm/) に進み、その 1 つをセットアップします。

ドメイン名の有効期間中、この証明書を有効にしておく必要があります。証明書の有効期限が切れ、自動更新が失敗した場合、ドメイン名の更新はすべてロックされます。他の変更を加える前に、有効な `ownershipVerificationCertificate` を用いて `ownershipVerificationCertificateArn` を更新する必要があります。`ownershipVerificationCertificate` は、API Gateway の別の相互 TLS ドメインのサーバー証明書として使用できません。証明書を ACM に直接再インポートする場合、発行者は以前と同じである必要があります。

### 信頼ストアの設定
<a name="http-api-mutual-tls-create-trust-store"></a>

信頼ストアは、`.pem` ファイル拡張子が付いたテキストファイルです。これらは、証明機関からの証明書の信頼できるリストです。相互 TLS を使用するには、API にアクセスするために信頼する X.509 証明書の信頼ストアを作成します。

信頼ストアには、発行元の CA 証明書からルート CA 証明書までの完全な信頼チェーンを含める必要があります。API Gateway は、信頼チェーンに存在する任意の CA によって発行されたクライアント証明書を受け入れます。パブリックまたはプライベート認証機関からの証明書を使用できます。証明書チェーンの最大長は 4 です。自己署名証明書を提供することもできます。信頼ストアでは、次のハッシュアルゴリズムがサポートされています。
+ SHA-256 以上
+ RSA-2048 以上
+ ECDSA-256 以上

API Gateway はいくつかの証明書プロパティを検証します。Lambda オーソライザーを使用して、証明書が失効しているかどうかのチェックなど、クライアントによる API の呼び出し時に追加のチェックを実行できます。API Gateway は、次のプロパティを検証します。


| 検証 | 説明 | 
| --- | --- | 
|  X.509 構文  |  証明書は X.509 構文の要件を満たしている必要があります。  | 
|  整合性  |  証明書の内容は、信頼ストアの認証機関によって署名された内容から変更されていないことが必要です。  | 
|  Validity  |  証明書の有効期間は最新のものであることが必要です。  | 
|  名前のチェーン/キーのチェーン  |  証明書の名前とサブジェクトは、途切れのないチェーンを形成する必要があります。証明書チェーンの最大長は 4 です。  | 

### 信頼ストアを 1 つのファイルで 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)」を参照してください。

**注記**  
相互 TLS は、プライベート API ではサポートされていません。

信頼ストアを 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 から警告が返されます。これは、新しい信頼ストアを使用するようにカスタムドメイン名を更新するときにも発生します。警告は、証明書の問題と、警告の発生元となった証明書のサブジェクトを示します。相互 TLS は引き続き API で有効ですが、一部のクライアントは 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 には 1 人の発行者しか存在できません。1 つの発行者を通じて、その件名に関するすべての証明書を取得する必要があります。管理できない証明書に問題があるけれども、ドメイン名の所有権を証明できる場合は、[連絡先 サポート](https://console.aws.amazon.com/support/cases#/create) からチケットを開きます。

### ドメイン名のステータスメッセージのトラブルシューティング
<a name="w2aac19c17b9c19b9"></a>

`PENDING_CERTIFICATE_REIMPORT`: これは、証明書を ACM に再インポートし、検証に失敗したことを意味します。すなわち、新しい証明書には SAN (サブジェクトの別名) があり、`ownershipVerificationCertificate` または証明書のサブジェクトまたは 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)ガイド」を参照してください。