こんにちは。SCSKのふくちーぬです。
DX(デジタルフォーメーション)が加速する現代のビジネス環境において、APIを公開しサービス連携を実現してAPIエコノミーを拡大していくことが重要となっています。これはUberやStripe、楽天等のパブリックAPIに限らずプライベート(社内)APIについても同様です。企業内に埋もれたデータ活用が叫ばれている中で、API の重要性はますます高まっています。プライベート API を組織内で効果的に運用するための実践的なアプローチとして、カスタムドメインの活用方法について解説します。
Amazon API Gatewayについて
Amazon API Gatewayは、AWS が提供するフルマネージド型のAPI管理サービスです。REST、HTTP、および WebSocket の API を作成、公開、管理、保護するために使用されます。これによって、開発者はサーバレスアーキテクチャやマイクロサービスを構築する際に、スケーラブルで高可用な API を迅速にデプロイすることが可能です。
REST APIでは、HTTP API よりも柔軟かつ強力な認証・認可(IAM認証やLambda Authorizer、Amazon Cognitoと連携したOauth2.0認証)に始まり様々な機能を有しています。
- 高度な認証機能
- API流量の制御
- データ変換とバリデーション機能
- バージョン管理、カスタムドメイン
- アクセスログ、実行ログのモニタリング
- AWS Lambdaを始めとしたマイクロサービスとの統合
本記事ではエンタープライズで頻繁に採用実績のある、REST型APIを取り上げています。
デフォルトドメイン vs カスタムドメインの利用について
以下の観点でも解説していますが、エンタープライズの本番環境利用用途であればカスタムドメインを利用する方針がベストプラクティスです。パブリックAPIにおいても、同様です。デフォルトドメインだと、企業ブランドイメージや視認性が悪く使い勝手も良くはありません。
デフォルトドメイン
curl https://<apiid>.execute-api.<awsリージョン>.amazonaws.com/<stage>/<resourcepath>
カスタムドメイン
curl https://fukuchiiinu.net/<stage>/<resourcepath>
ガバナンスとコンプライアンス
デフォルトドメインでは、迅速な導入による俊敏性は確保できるものの、ガバナンス管理が難しくなります。
カスタムドメインでは、ドメインの一貫性を保つことができ、社内ポリシーやセキュリティガイドラインに適した統制要件を満たすことができます。
運用ライフサイクル
デフォルトドメインでは、ドメインについてはAWS管理されます。
そのため、API開発者者はPoC環境では迅速にプロトタイピング作成等に使用できます。一方、ドメインは一意のIDによって自動で割り当てられるためAPIを再作成した場合は、クライアントサイド開発者はURL等の変更を余儀なくされ運用負荷が高まります。
カスタムドメインでは、独自ドメインで用意できるため、APIの再作成や追加等があってもクライアントサイドは柔軟に対応することが可能です。ドメインについては、利用者側で管理するため社内発行CAを利用する場合は証明書の管理が必要になりますが、ACM発行証明書で代替できる場合は自動更新されます。
デフォルトドメイン利用時の構成
オンプレミス環境からから、RDSのデータベースに格納されている情報に安全にアクセスするシナリオを考えてみます。
- オンプレミス業務アプリケーションがデータ取得のためのAPIリクエストを発行
- Direct Connectを通じてた閉域網でアクセス
- VPCエンドポイントを経由してプライベート型のAPI Gatewayにリクエストが到達
- バックエンドのVPC Lambdaを起動
- Lambdaがプライベートサブネット内のRDSからデータ取得
- 取得したデータがオンプレミス環境のアプリケーションに返却
以下のように、デフォルトドメイン利用時は、VPCエンドポイント及びPrivate型のAPI Gatewayの構成で社内向けAPIやシステム間連携などで、安全な通信とアクセス制御を実現できます。
API Gatewayの各種APIエンドポイントを叩く用のVPCエンドポイントを作成する必要があります。
com.amazonaws.<リージョン>.execute-api
VPCエンドポイントでのアクセス制御
本構成の場合、クライアントサイドからAWSへの玄関口はVPCエンドポイントとなります。そのため、VPCエンドポイントにアタッチされているセキュリティグループにてホワイトリスト形式でのアクセス制御をすることが重要です。
具体的には、クライアントサイド(オンプレミスのサーバやVPC内のEC2や、VPC Lambda等)のIPアドレスやセキュリティグループをホワイトリスト形式で登録することで、その他のクライアントからのアクセスをブロックすることができます。
Amazon API Gatewayでのアクセス制御
Amazon API Gatewayでは、リソースポリシーを利用して、特定のVPCエンドポイント経由でのみアクセスできるよう制御します。
許可ステートメントと拒否ステートメントを組み合わせることで、特定のVPCエンドポイントからのみAPIアクセスができるよう強固なセキュリティ制御をしています。
“*/*/*/*”のパターンについては、APIのID・ステージ・リソースパス・メソッドで制御することも可能です。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<awsリージョン>:<awsアカウントid>:*/*/*/*", "Condition": { "StringEquals": { "aws:SourceVpce": "<vpcエンドポイントid>" } } }, { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:<awsリージョン>:<awsアカウントid>:*/*/*/*", "Condition": { "StringNotEquals": { "aws:SourceVpce": "<vpcエンドポイントid>" } } } ] }
TLS通信について
以下のプロセスで、デフォルトドメイン/カスタムドメインでAPIにアクセスする際のTLS通信が行われます。
- DNS解決
- クライアントがドメイン名の名前解決
- オンプレミスのDNSサーバまたは、Amaozn Route53インバウンドエンドポイント経由でAmazon Route53 ResolverでIPアドレスに解決
- TCP接続確立
- 3ウェイハンドシェイク
- TLSハンドシェイク
- ClientHello:クライアントサイドのブラウザまたは業務アプリケーションが対応しているTLSバージョンと暗号スイートのリストを提示
- ServerHello:API GatewayがTLS1.2と特定の暗号スイートを選択
- Certificate:API GatewayがAWS管理証明書またはACM証明書の情報を送信
- KeyExchange:ECDHE鍵交換で共通の秘密鍵を安全に確立
- Finished:双方が暗号化モードに切り替わり完了
- 証明書検証
- クライアントサイドが証明書チェーンを検証
- ドメイン名、有効期限、発行者を確認
- データ交換
- 確立した暗号化通信にて、HTTPリクエスト/レスポンスを交換
- 接続終了
プライベート型のAPI Gatewayにおいては、TLSバージョンが強制されており、TLS1.2のみをサポートしています。(TLS1.3については、未サポート)
暗号スイートについては、下記表に記載されているように比較的近代的なものが利用できますが、こちらも制御はできません。
カスタムドメイン利用時の構成
プライベートAPIにおいて、カスタムドメインを使用する主要パターンを説明します。API Gatewayにおいて、カスタムドメインがサポートされていますので、ELB(ALB、NLB)のコストや管理負荷が不要であるパターン1が推奨構成です。
パターン1:VPCエンドポイント+Amazon API Gateway
本構成は、re:Invent2024で発表されたアップデートとなります。従来までは、Amazon API Gateway単体ではカスタムドメイン設定がネイティブにサポートしていませんでしたので、待望の機能拡張となります。
- カスタムドメインを作成します
- ACM証明書をカスタムドメイン名と合わせて設定します
- ベースパスマッピングを行い、複数のプライベートAPIのステージをマッピングします
- カスタムドメイン名とVPCエンドポイント間で、ドメイン名アクセスを関連付けます
本アップデートにより、証明書の管理をAmazon API Gatewayのみで完結することができ、TLS通信の一貫性を保ったエンドツーエンドの安全な通信が確立できるようになりました。
VPCエンドポイントでのアクセス制御
本構成の場合、デフォルトドメイン利用時と同様のアクセス制御します。クライアントサイドからAWSへの玄関口はVPCエンドポイントとなります。そのため、VPCエンドポイントにアタッチされているセキュリティグループにてホワイトリスト形式でのアクセス制御をすることが重要です。
Amazon API Gatewayでのアクセス制御
デフォルトドメイン利用時と同様のアクセス制御を実施します。Amazon API Gatewayでは、リソースポリシーを利用して、特定のVPCエンドポイント経由でのみアクセスできるよう制御します。
TLS通信について
デフォルトドメイン利用時と同様のプロセスです。利用する証明書の管理が異なります。
パターン2:ALB+VPCエンドポイント+Amazon API Gateway
本構成は、API Gateway単体ではカスタムドメイン設定がネイティブにサポートしていなかったため、Application Load Balancerを前段に挟む構成となっています。つまりALBは、リバースプロキシとして機能を提供します。そしてACM証明書は、ALBとAPI Gatewayで同一の証明書を関連付けます。
- カスタムドメインを作成します
- ACM証明書をカスタムドメイン名と合わせて設定します
- ベースパスマッピングを行い、複数のプライベートAPIのステージをマッピングします
- リソースポリシーにてドメインに対するアクセス制御をします
- リスナーとしてHTTPS:443を持つALBを作成します。加えてALBとACM証明書を関連付けます。
- ALBのターゲットグループとして、VPCエンドポイントを指定します
ALBでのアクセス制御
本構成の場合、クライアントサイドからAWSへの玄関口はALBとなります。ALBにアタッチされているセキュリティグループにてホワイトリスト形式でのアクセス制御をしましょう。
VPCエンドポイントでのアクセス制御
VPCエンドポイントのセキュリティグループでは、ALBからのアクセスのみを受け付けることができるよう、ALBのセキュリティグループからのインバウンドアクセス許可をします。
API Gatewayでのアクセス制御
デフォルトドメイン利用時と同様のアクセス制御を実施します。
TLS通信について
本構成では、①クライアントサイド-ALB間の通信と②ALB-API Gateway間の通信でTLS終端されます。クライアントサイドでの証明書検証に加えて、API Gateway側でも正しく証明書検証を実施します。
パターン3:NLB+VPCエンドポイント+Amazon API Gateway
本構成もパターン2と同様に、re:Invent2024以前でのカスタムドメインを利用する際の代替案の一つです。パターン2との違いとしては、Network Load Balancerに置き換わっています。
- カスタムドメインを作成します
- ACM証明書をカスタムドメイン名と合わせて設定します
- ベースパスマッピングを行い、複数のプライベートAPIのステージをマッピングします
- リソースポリシーにてドメインに対するアクセス制御をします
- リスナーとしてTLS:443を持つALBを作成します。加えてNLBとACM証明書を関連付けます。
- NLBのターゲットグループとして、VPCエンドポイントを指定します
NLBでのアクセス制御
本構成の場合、クライアントサイドからAWSへの玄関口はNLBとなります。2023/7までは、NLBにセキュリティグループをアタッチできなかったため、AWS Network FirewallやネットワークACLを利用する必要がありました。
現在はサポートされているため、NLBにセキュリティグループを必ずアタッチしてホワイトリスト形式でのアクセス制御をしましょう。
VPCエンドポイントでのアクセス制御
ALBの場合と同様です。
VPCエンドポイントのセキュリティグループでは、NLBからのアクセスのみを受け付けることができるよう、NLBのセキュリティグループからのインバウンドアクセス許可をします。
API Gatewayでのアクセス制御
デフォルトドメイン利用時と同様のアクセス制御を実施します。
TLS通信について
本構成では、①クライアントサイド-NLB間の通信と②NLB-API Gateway間の通信でTLS終端されます。しかし、NLBではTLSリスナーの場合、証明書の検証を実施しないという仕様があります。
ターゲットグループに TLS プロトコルが設定されている場合、ロードバランサーは、ターゲットにインストールした証明書を使用して、ターゲットと TLS 接続を確立します。ロードバランサーはこれらの証明書を検証しません。したがって、自己署名証明書または期限切れの証明書を使用できます。
そのため、通常通りクライアントサイドではNLBに関連付いた証明書の検証は実施します。NLBではSNI自体は転送しますが証明書を検証しないため、TLSパススルーで動くということになります。つまり、NLBでは正規の証明書を関連付けて、API Gateway側では異なる証明書(期限切れの証明書など)を関連付けていても通信が確立してしまいます。
このようなリスクを最小限に抑えるために、証明書を不用意に変更されないような仕組みとして、予防的統制と発見的統制を取り入れた多層防御を導入することもできます。
予防的統制
- AWSのIAMポリシーによる権限制御
- CloudFormationテンプレートによる一元的な管理
発見的統制
- Config+Lambdaのカスタムルールによる継続的な監視 or EventBridge+CloudTrailによる変更検知
- 証明書が不一致になった際の自動修復ルール
- アラーム通知
ログの取得
API Gatewayでは、アクセスログ及び実行ログをCloudWatchLogsへ出力できるので、どちらもONにします。
API Gatewayのアクセスログ
アクセスログはセキュリティ監査とトラブルシューティングのために必須です。デフォルトのログ形式に加えて要件に併せて追加のパラメータを設定します。
{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user","requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod","resourcePath":"$context.resourcePath", "status":"$context.status","protocol":"$context.protocol", "responseLength":"$context.responseLength" }
例えばXrayによるAPIの可視性、WAFによるAPIのL7防御をしている際は、追加のパラメータを設定します。
ALB/NLBのアクセスログ
加えて、ALB/NLBではアクセスログを取得できるため、アクセスログをS3に出力します。
ALB/NLBのアクセスログでは、API Gatewayのアクセスログ・実行ログでは取得できない下記の情報を取得することができます。
・リクエストサイズ(received_bytes / received_bytes)
・レスポンスサイズ(sent_bytes / sent_bytes)
・TLSプロトコルバージョン(ssl_protocol / tls_protocol_version)
・暗号スイート(ssl_cipher / tls_cipher)
リクエスト/レスポンスサイズを継続的にモニタリングしておくことで、バッファーオーバーフロー攻撃/データ流出/DDoS攻撃等の兆候を捉えることができます。これに加えてWAFのリクエストヘッダやボディ検査をすることで、異常なリクエストについてBlockすることが可能となります。
また暗号化プロトコルと暗号スイート情報を取得しておくことで、脆弱性のある暗号化設定がされていないか継続的に監視することができます。
API Gatewayの実行ログ
実行ログでは、リクエスト/レスポンスのパラメタータ・ボディの記録に加えてバックエンドのエラー情報も含まれるものになります。
エンタープライズ利用において、実行ログでは”データトレース”はオフに設定して、”エラーと情報ログ”のみ記録します。
OWASPのAPIセキュリティに関する文書や、AWS公式ドキュメントにおいても、
ログ内に機密情報(個人情報やデータペイロード)に記録されないように設定するように
との記載があります。
Error messages include stack traces, or expose other sensitive information
最後に
いかがだったでしょうか。
企業内のデータ分析やデータ連携をするニーズが増えている中、プライベート APIは安全かつ効率的な基盤となります。
本記事で紹介したベストプラクティスを活用して、エンタープライズ固有の要件に沿った最適なプライベートAPIを実装いただけますと幸いです。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~🔥