Amazon API GatewayからNLBへVPC Linkで通信する際の暗号化方法
はじめに
Amazon API Gatewayを用いてAPIを構築する際、VPC内のプライベートリソース(例えばEC2やECSタスク)と通信するためにVPC Linkを利用するケースは多くあります。VPC Linkを用いることで、インターネットを経由せずにAPI GatewayからVPC内のリソースへ安全に通信できます。
VPCLinkを用いた通信においてTLS暗号化を実現したい場合には、いくつかの技術的な検討ポイントが存在します。本記事では、Amazon API GatewayからNLBへVPC Linkで通信する際に、カスタムのプライベートDNS名を用いて通信を暗号化する方法について、実際の手順とともに詳しく解説します。
想定するシステム構成とユースケース
基本的な構成
本記事で想定するシステム構成は以下の通りです。
Amazon API Gatewayを利用することでクライアントからAPI Gatewayまでの通信は必ずHTTPSで暗号化されていますが、更にAPI GatewayからNLBへの通信も同様に暗号化したい場合があります。
ユースケース
API GatewayとNLB間の通信を暗号化したいユースケースとしては、以下のような状況が考えられます。
| ユースケース | 理由 |
|---|---|
| セキュリティコンプライアンス要件 | 金融機関や医療機関など、規制の厳しい業界では通信全体をエンドツーエンドで暗号化することが求められる |
| 多層防御の実現 | AWS内の通信であっても暗号化することでセキュリティレベルを向上 |
| 監査要件 | 内部監査や外部監査において、すべての通信経路で暗号化されていることの証明が必要 |
| データ保護の強化 | 機密性の高いデータを扱う場合、たとえAWS内であっても通信を暗号化して保護 |
前提条件
本記事で解説する方法を実施するにあたっては、以下の前提条件があります。
必須要件
-
パブリックに使えるドメインを保有していること
- 例:
example.comをRoute 53などで管理している - 理由:後述する手順の中でパブリックDNSに対してDNSレコードの登録が必要となるため
- 例:
-
AWS Certificate Manager(ACM)などで証明書が発行できること
- TLS暗号化を行う場合に必要
- パブリックDNSにレコード登録が必要となる
環境要件
- Amazon API Gateway(REST APIまたはHTTP API)
- Network Load Balancer(NLB)
- VPC内のターゲットリソース(EC2、ECS等)
- Route 53などでパブリックホストゾーンを管理していること
カスタムプライベートDNS名を利用した通信の設定手順
手順の全体像
カスタムプライベートDNS名を利用してAPI GatewayからNLBへ通信する手順は、大きく以下のステップに分かれます。
- VPC Linkの作成
- VPC Linkに対応するエンドポイントサービスの特定
- プライベートDNS名の設定と検証
- DNSレコードの登録
- API Gatewayの統合設定
- 動作確認
それでは、各ステップを詳しく見ていきましょう。
ステップ1:VPC Linkの作成
まず、Amazon API GatewayのマネジメントコンソールからVPC Linkを作成します。
※この作業の前にNLBを作成することが必要ですがそれは割愛しています。
手順
- AWSマネジメントコンソールでAmazon API Gatewayを開く
- 左側のメニューから「VPCリンク」を選択
- 「Create」ボタンをクリック
- 以下の情報を入力:
- VPCリンクバージョン: こだわりがない限りVPC リンク V2を選択
- Name: VPCリンクの名前
- Target NLB: 通信先となるNetwork Load Balancerを選択
- サブネット: NLBが配置されているサブネットを選択
- 「Create」をクリックして作成完了を待つ
VPC Linkの作成には数分かかる場合があります。ステータスが「Available」になるまで待ちます。
注意: VPC Linkの作成時、内部的にVPC Endpoint Serviceが自動的に作成されます。この自動作成されたエンドポイントサービスを次のステップで利用します。
ステップ2:エンドポイントサービスの特定
VPC Linkを作成すると、AWS内部で対応するVPC Endpoint Serviceが自動的に作成されます。このエンドポイントサービスにプライベートDNS名を設定する必要があります。
手順
- AWSマネジメントコンソールでVPCを開く
- 左側のメニューの中の「PrivateLinkとLattice」→「エンドポイントサービス」を選択
- 表示されるエンドポイントサービスの一覧から、ステップ1で作成したVPC Linkに対応するものを探す
エンドポイントサービスの特定方法
私が確認した限り、VPC Linkとエンドポイントサービスの対応関係を一覧で直接確認する方法は現時点では提供されていません。そのため、以下の手順で対応するエンドポイントサービスを見つける必要があります。
- エンドポイントサービスの一覧から各サービスをクリック
- 「ロードバランサー」タブを選択
- 表示されるロードバランサー名が、VPC Link作成時に指定したNLBと同じものかを確認
- 一致するものが見つかるまで繰り返す
ヒント: エンドポイントサービスの名前には
com.amazonaws.vpce.{region}.vpce-svc-{id}という形式が使われています。作成日時やタグなども参考にすると特定しやすくなります。
ステップ3:プライベートDNS名の設定
対象のエンドポイントサービスが特定できたら、プライベートDNS名を設定します。
手順
- 対象のエンドポイントサービスを選択
- 「アクション」メニューから「プライベートDNS名を変更」を選択
- 「プライベートDNS名をサービスに関連づける」にチェックを入れる
- 「プライベートDNS名」フィールドに使用したいDNS名を入力
- 例:
api-internal.example.com
- 例:
- 「変更を保存」ボタンをクリック
ステップ4:ドメインの検証とDNSレコードの登録
プライベートDNS名を設定すると、AWSがドメインの所有権を確認するための検証情報を生成します。
手順
- 対象のエンドポイントサービスの「詳細」タブを開く
- 「ドメインの検証名」と「ドメインの検証値」にランダムな文字列が表示されていることを確認
- Route 53などのDNSサービスで、パブリックホストゾーンに以下のレコードを登録
DNSレコードの登録内容
名前:{ドメインの検証名}.{利用するドメイン名}
タイプ:TXT
値:{ドメインの検証値}
TTL:300(推奨)
具体例:
名前:_vpce-svc-12345abcde.api-internal.example.com
タイプ:TXT
値:"vpce:aBcDeFgHiJkLmNoPqRsTuVwXyZ"
TTL:300
参考資料
DNSレコード登録の詳細については、AWSの公式ドキュメントを参照してください:
https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/manage-dns-names.html
ステップ5:ドメイン検証の完了確認
DNSレコードを登録してから、AWSがドメインの検証を完了するまで数分から数十分かかります。
確認手順
- 対象のエンドポイントサービスの「詳細」タブを開く
- 「ドメインの検証ステータス」フィールドを確認
- ステータスが「Verified」になっていることを確認
ステータスの意味
| ステータス | 意味 |
|---|---|
| Pending Verification | 検証待ち。DNSレコードの登録または伝播待ち |
| Verified | 検証完了。プライベートDNS名が利用可能 |
| Failed | 検証失敗。DNSレコードの設定を確認する必要がある |
検証が「Failed」となった場合、以下を確認してください:
- DNSレコードが正しく登録されているか
- パブリックホストゾーンに登録されているか(プライベートホストゾーンではない)
- TTLが経過してDNSの変更が伝播しているか
- TXTレコードの値が正確にコピーされているか
ステップ6:API Gatewayの統合設定
ドメイン検証が完了したら、API Gatewayで対象のエンドポイントを設定します。
手順
- AWSマネジメントコンソールでAmazon API Gatewayを開く
- 対象のAPI(RESTまたはHTTP API)を選択
- 対象のリソース/メソッドを作成または選択
- 「統合リクエスト」の設定を開く
- 以下の項目を設定:
| 項目 | 設定値 | 説明 |
|---|---|---|
| 統合タイプ | VPCリンク | VPC Link経由での通信を指定 |
| VPCリンク | 作成したVPC Linkを選択 | ステップ1で作成したもの |
| エンドポイントURL | http://{プライベートDNS名} |
例:http://api-internal.example.com
|
| HTTPメソッド | 適切なメソッドを選択 | GET、POST等 |
- その他の項目(ヘッダー、クエリパラメータ等)は適宜設定
- 設定を保存
エンドポイントURLの指定について
この時点では、TLS暗号化を行わない場合はhttp://を指定します。TLS暗号化を行う場合の設定については、後述の「TLS暗号化を行う場合の追加設定」セクションで解説します。
ステップ7:動作確認
API Gatewayの設定が完了したら、テスト機能を使用して動作を確認します。
手順
- API Gatewayの「リソース」画面で、設定したメソッドを選択
- 「テスト」タブをクリック
- 必要に応じてパラメータやボディを入力
- 「テスト」ボタンをクリック
- レスポンスが正常に返ってくることを確認
確認ポイント
- HTTPステータスコード200(または適切なステータス)が返ってくるか
- レスポンスボディが期待通りの内容か
- CloudWatch Logsでエラーが発生していないか
- NLBのターゲットが正常にリクエストを受信しているか
TLS暗号化を行う場合の追加設定
ここまでの手順で、カスタムプライベートDNS名を用いた通信は確立できました。しかし、この状態ではAPI GatewayとNLB間の通信はHTTPで行われており、暗号化されていません。
通信を暗号化するには、以下の追加設定が必要です。
手順1:ACMで証明書を発行
まず、プライベートDNS名用のSSL/TLS証明書をAWS Certificate Manager(ACM)で発行します。
証明書発行手順
- AWSマネジメントコンソールでAWS Certificate Managerを開く
- 「証明書をリクエスト」をクリック
- 「パブリック証明書をリクエスト」を選択
- 完全修飾ドメイン名(FQDN)を入力
- 例:
api-internal.example.com
- 例:
- 検証方法として「DNS検証」を選択(推奨)
- 「リクエスト」をクリック
DNS検証の実施
証明書のリクエスト後、ACMがDNS検証用のCNAMEレコード情報を提供します。
- 証明書の詳細画面で、CNAMEレコードの情報を確認
- Route 53などのDNSサービスで、パブリックホストゾーンにCNAMEレコードを登録
- 検証が完了するまで待つ(通常数分〜数十分)
- 証明書のステータスが「発行済み」になることを確認
重要: ここでも、プライベートホストゾーンではなく、パブリックホストゾーンにレコードを登録する必要があります。
手順2:NLBでTLSリスナーを作成
次に、NLBにTLSリスナーを作成し、ACMで発行した証明書を関連付けます。
リスナー作成手順
- AWSマネジメントコンソールでEC2を開く
- 左側のメニューから「ロードバランサー」を選択
- 対象のNLBを選択
- 「リスナー」タブで「リスナーを追加」をクリック
- 以下の設定を行う:
| 項目 | 設定値 | 説明 |
|---|---|---|
| プロトコル | TLS | TLS暗号化を有効化 |
| ポート | 443 | HTTPS標準ポート |
| デフォルトアクション | 転送先ターゲットグループを選択 | 次で作成するTCPターゲットグループ |
| セキュリティポリシー | ELBSecurityPolicy-TLS-1-2-2017-01(推奨) | TLS 1.2以上を使用 |
| デフォルトSSL証明書 | ACMから作成した証明書を選択 |
api-internal.example.comの証明書 |
- 「保存」をクリック
手順3:TCPターゲットグループの作成
NLBからバックエンドへの通信は、TLSではなくTCPで行います。
ターゲットグループ作成手順
- EC2コンソールの「ターゲットグループ」を選択
- 「ターゲットグループの作成」をクリック
- 以下の設定を行う:
| 項目 | 設定値 | 説明 |
|---|---|---|
| ターゲットタイプ | インスタンス、IP、Lambda等 | バックエンドのタイプに応じて選択 |
| ターゲットグループ名 | 任意の名前 | 例:my-tcp-target-group
|
| プロトコル | TCP | TLSではなくTCP |
| ポート | バックエンドのポート | 例:8080、80等 |
| VPC | NLBと同じVPC | |
| ヘルスチェックプロトコル | TCP または HTTP/HTTPS | バックエンドに応じて選択 |
- ターゲットの登録(EC2インスタンスやIPアドレス)
- 「作成」をクリック
※今回はNLBで暗号化の終端を行う想定としています。要件としてEndToEndの暗号化が必要な場合にはNLBでの終端は行わずにバックエンドのEC2やECSタスク側で復号するという選択肢もあります。その場合は若干設定が変わりますがこの記事ではそこまでは対象としません。
手順4:API GatewayでHTTPSエンドポイントを指定
最後に、API Gatewayの統合設定でエンドポイントURLをhttps://に変更します。
変更手順
- API Gatewayのマネジメントコンソールで対象のAPIを開く
- 対象のリソース/メソッドを選択
- 「統合リクエスト」を開く
-
エンドポイントURLを以下のように変更:
- 変更前:
http://api-internal.example.com - 変更後:
https://api-internal.example.com
- 変更前:
- 設定を保存
動作確認
- API Gatewayの「テスト」機能で動作確認
- 正常にレスポンスが返ってくることを確認
- CloudWatch Logsで通信が成功していることを確認
これで、API GatewayからNLBへの通信がTLSで暗号化されました。
セキュリティグループの設定に関する重要な注意点
Network Load Balancerはセキュリティグループを利用可能ですが、API GatewayからNLBへVPC Link経由で通信を行う際には、特別な設定が必要です。
PrivateLinkのセキュリティ設定をオフにする
API GatewayがVPC Link経由でNLBに接続する場合、通信はPrivateLinkを介して行われます。この通信がNLBのセキュリティグループによってブロックされないようにするため、PrivateLinkのセキュリティ設定をオフにする必要があります。
設定手順
- AWSマネジメントコンソールでEC2を開く
- 「ロードバランサー」から対象のNLBを選択
- 「セキュリティ」タブを開く
- 「PrivateLinkのセキュリティ設定」セクションを探す
- 「PrivateLinkのセキュリティ設定」をオフにする
- 変更を保存
なぜオフにする必要があるのか?
PrivateLinkのセキュリティ設定がオンになっていると、VPC Endpoint経由の通信がNLBのセキュリティグループのインバウンドルールでフィルタリングされます。しかし、API GatewayのVPC Linkからの通信は、通常のVPC内通信とは異なる経路を通るため、セキュリティグループでは適切に制御できません。
そのため、この設定をオフにすることで、VPC Endpoint経由の通信がセキュリティグループをバイパスし、確実にNLBに到達できるようになります。
詳細は以下を参照ください。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-nlb-for-vpclink-using-console.html
トラブルシューティング
API GatewayからNLBへのVPC Link通信を設定する際に発生しやすい問題と、その解決方法をまとめます。
問題1:ドメイン検証が「Failed」になる
症状
エンドポイントサービスのドメイン検証ステータスが「Failed」と表示される。
原因と解決方法
| 原因 | 確認方法 | 解決方法 |
|---|---|---|
| DNSレコードが登録されていない | Route 53などでTXTレコードを確認 | ドメインの検証名と検証値を使ってTXTレコードを正しく登録 |
| プライベートホストゾーンに登録している | ホストゾーンの種類を確認 | パブリックホストゾーンにレコードを登録し直す |
| TTLが長すぎてDNSが伝播していない |
nslookupやdigコマンドで確認 |
TTLが経過するまで待つ、または短いTTL(例:300秒)に変更 |
| TXTレコードの値が間違っている | レコードの内容を再確認 | 検証値を正確にコピーして再登録 |
検証コマンド例
# TXTレコードが正しく登録されているか確認
nslookup -type=TXT _vpce-svc-12345abcde.api-internal.example.com
# または
dig TXT _vpce-svc-12345abcde.api-internal.example.com
問題2:API Gatewayのテストで5xxエラーが返る
症状
API Gatewayのテスト実行時、HTTPステータス5xx(Internal Server Errorなど)が返される。
原因と解決方法
| 原因 | 確認方法 | 解決方法 |
|---|---|---|
| VPC Linkが正常に作成されていない | VPC Linkのステータスを確認 | ステータスが「Available」になるまで待つ |
| NLBのターゲットが正常でない | NLBのターゲットグループでヘルスチェックを確認 | ターゲットのヘルスチェックが「healthy」になるよう修正 |
| プライベートDNS名が解決できない | エンドポイントサービスの検証ステータスを確認 | ドメイン検証が「Verified」になっているか確認 |
| NLBリスナーの設定ミス | NLBのリスナー設定を確認 | リスナーのポートとプロトコルが正しいか確認 |
| セキュリティグループでブロックされている | NLBのセキュリティグループを確認 | PrivateLinkのセキュリティ設定をオフにする |
CloudWatch Logsの確認
API Gatewayの実行ログを有効化している場合、CloudWatch Logsで詳細なエラー情報を確認できます:
- API Gatewayの「ステージ」設定を開く
- 「ログ/トレース」タブで「CloudWatch Logs」を有効化
- CloudWatch Logsコンソールでロググループ
/aws/apigateway/{api-name}を確認
問題3:TLS証明書のエラー
症状
API Gatewayからのリクエストで、SSL/TLS証明書に関するエラーが発生する。
原因と解決方法
| 原因 | 確認方法 | 解決方法 |
|---|---|---|
| 証明書のドメイン名が一致していない | ACM証明書のドメイン名を確認 | 証明書のドメイン名とプライベートDNS名が一致しているか確認 |
| 証明書が発行されていない | ACMで証明書のステータスを確認 | DNS検証を完了させ、証明書が「発行済み」になるまで待つ |
| NLBに証明書が関連付けられていない | NLBのリスナー設定を確認 | TLSリスナーにACM証明書を正しく関連付ける |
| 証明書の有効期限が切れている | ACMで証明書の有効期限を確認 | 新しい証明書を発行し、NLBに関連付け直す |
問題4:ターゲットへのトラフィックが届かない
症状
API Gatewayからリクエストは成功するが、バックエンドのアプリケーションにトラフィックが届いていない。
原因と解決方法
| 原因 | 確認方法 | 解決方法 |
|---|---|---|
| ターゲットグループが空 | ターゲットグループのターゲット一覧を確認 | EC2インスタンスやIPアドレスを登録 |
| ターゲットのヘルスチェックが失敗 | ターゲットのステータスを確認 | ヘルスチェック設定を見直し、ターゲットの正常性を確保 |
| ターゲットのセキュリティグループが制限している | ターゲット(EC2等)のセキュリティグループを確認 | NLBからの通信を許可するインバウンドルールを追加 |
| アプリケーションが起動していない | ターゲットに直接アクセスして確認 | アプリケーションを起動、またはデプロイを確認 |
補足
今回紹介した方法を使わなくてももっとシンプルにAPI Gateway-NLB間の通信を暗号化することは可能です。
その方法はパブリックDNSにNLBのIPアドレスをAレコードで登録してしまう方法です。
そうすることでAPI Gatewayはインターネット上で名前解決してNLBに通信することが可能となります。
但しこの方法ではPrivateSubnetに存在するNLBのIPアドレスをインターネット上に公開してしまうこととなり、それ自体がセキュリティ上望ましくないため今回紹介した方法を考えました。
まとめ
本記事では、Amazon API GatewayからNetwork Load BalancerへVPC Linkで通信する際に、カスタムプライベートDNS名を用いて通信を行う方法、さらにTLS暗号化を実現する方法について詳しく解説しました。
主要なポイント
1. カスタムプライベートDNS名の設定
- VPC Linkを作成すると自動的にVPC Endpoint Serviceが作成される
- エンドポイントサービスにプライベートDNS名を設定
- パブリックDNSにTXTレコードを登録してドメイン所有権を検証
- 検証完了後、API GatewayからプライベートDNS名で通信可能
2. TLS暗号化の実装
- ACMでプライベートDNS名の証明書を発行
- NLBにTLSリスナーを作成し、証明書を関連付け
- ターゲットグループはTCPプロトコルで作成(NLBでTLS終端)
- API GatewayのエンドポイントURLを
https://に変更
3. セキュリティ設定
- NLBの「PrivateLinkのセキュリティ設定」をオフにする
適用すべきケース
この構成は、以下のようなケースで特に有効です:
- セキュリティコンプライアンス要件が厳しい環境
- エンドツーエンド暗号化が求められる金融・医療系システム
- ゼロトラストセキュリティの実現を目指す組織
- 監査対応で通信の暗号化を証明する必要がある場合
運用上の注意点
- 証明書の有効期限管理:ACMは自動更新されますが、定期的に確認
- ドメイン検証の維持:DNSレコードを誤って削除しないよう注意
API GatewayとNLB間の通信を適切に暗号化することで、セキュリティ要件を満たしながら、スケーラブルで保守性の高いシステムを構築できます。本記事が、読者の皆様のAWS環境におけるセキュリティ向上に貢献できれば幸いです。
