Amazon Web Services ブログ
Amazon VPC Lattice と Amazon EKS における AWS IAM 認証の実装
イントロダクション
Amazon VPC Lattice は、AWS ネットワークインフラストラクチャに直接組み込まれた、フルマネージドなアプリケーションネットワーキングサービスです。複数のアカウント、複数の仮想プライベートクラウド (VPC) にまたがる全てのサービスの接続、セキュア化、監視に使用できます。
Amazon Elastic Kubernetes Service (Amazon EKS) では、Kubernetes Gateway API の実装である AWS Gateway API コントローラーを通じて、Amazon VPC Lattice を使用できます。Amazon EKS のお客様は、Amazon VPC Lattice を用いることで、シンプルかつ一貫性のある方法で、標準的な Kubernetes のセマンティクスによりクラスターをまたいだ接続を設定できます。
一方で、特定のお客様ではアプリケーションレイヤーのセキュリティを強化したいという要望がありました。Amazon VPC Lattice のデザインはセキュアバイデフォルトです。これは、どのサービスを共有したいのか、どの VPC にアクセスを提供したいのかを、明確にする必要があるためです。
Amazon VPC Lattice は 3 レイヤーのフレームワークを提供しており、ネットワークの複数のレイヤーで多層防御戦略を実装できます。これらのレイヤーには、サービスネットワークと VPC の関連付け、セキュリティグループ、ネットワークアクセスコントロールリスト (ACL)、AWS Identity and Access Management (AWS IAM) 認証ポリシーが含まれ、Amazon VPC Lattice を構成することでセキュリティとコンプライアンスの目標を達成することができます。
VPC 内のセキュリティグループのサービスネットワークへの関連付けと認証ポリシーは、どちらもオプションです。セキュリティグループを設定せずに、サービスネットワークを VPC に関連付けることができます。また、認証タイプを NONE
に設定して、認証ポリシーを使用しないこともできます。
本記事では、3 つ目のレイヤー、すなわちサービスネットワークと各々のサービスに適用できる、VPC Lattice の認証ポリシーに焦点を当てます。通常、サービスネットワークの認証ポリシーはネットワーク管理者あるいはクラウド管理者によって運用され、粗い粒度での認証を実装します。例えば、AWS Organizations の指定した組織からの認証済みリクエストのみ許可します。一方、サービスの認証ポリシーでは、サービスのオーナーはネットワーク管理者やクラウド管理者がサービスネットワークのレベルで適用した粗い粒度での認証ルールよりも制限の厳しい、きめ細やかな制御を設定できます。認証ポリシーを使用することで、お客様はアプリケーションのコードを変更することなく、誰が、どのサービスに対して、どのアクションを実行できるかを定義することができます。
我々の実装では、以下の方法を示します。
- Amazon VPC Lattice サービスネットワークと Amazon EKS を構築し、Amazon VPC Lattice サービスの認証ポリシーを有効にします。
- Amazon EKS と Amazon VPC Lattice でのサイドカーパターンと Init コンテナパターンを用いて、サービスの呼び出し元が AWS IAM 認証で Amazon VPC Lattice サービスに対しての HTTP リクエストの生成を自動的におこなえるようにするソリューションを構築します。呼び出し元のアプリケーションのソースコードの変更は必要ありません。
- サービスの呼び出し元が Amazon VPC Lattice サービスネットワーク内の複数のサービスに接続できることを確認します。
ソリューション概要
Amazon VPC Lattice は AWS IAM と統合され、お客様独自のサービス間通信のために、現在 AWS サービスとやり取りする時に慣れ親しんでいるのと同様の認証・認可の機能を提供します。
サービスのアクセス制御を設定するために、アクセスポリシーを使用できます。アクセスポリシーは、サービスネットワークと個々のサービスに関連付けることができる AWS IAM リソースポリシーです。アクセスポリシーでは、PARC (Principal、Action、Resource、Condition) モデルを使用して、サービスのコンテキスト固有のアクセス制御を適用できます。例えば、所有するサービスに対してアクセス可能なサービスを定義するために、アクセスポリシーを使用できます。
Amazon VPC Lattice はクライアント認証に AWS Signature Version 4 (SigV4) を使用します。Amazon VPC Lattice のサービスで認証ポリシーを有効化した後に、署名付き Authorization
ヘッダー、x-amz-content-sha256
、x-amz-date
、x-amz-security-token
が HTTP リクエストに含まれるよう、サービスを呼び出す側を変更する必要があります。AWS SigV4 の詳細はこちらを参照してください。
Amazon VPC Lattice サービスへのリクエストに署名するために、お客様には以下の選択肢があります。
- AWS SDK を用いて、対応するプログラミング言語でリクエストに署名します。このソリューションはパフォーマンスが最適化されますが、アプリケーション開発者によるコードの変更を必要とします。実装については Amazon VPC Lattice のドキュメントを参照してください。
- AWS SIGv4 プロキシアドミッションコントローラーを活用し、AWS SIGv4 プロキシを用いて HTTP リクエストをフォワードし、AWS Sigv4 ヘッダーを追加します。詳細については、こちらの記事を参照してください。しかし、上記のソリューションには 1 つの制限があります。AWS SIGv4 プロキシアドミッションコントローラーを使用する場合、単一のホストしかサポートされません。サンプルのマニフェストでは、フロントエンドのコンテナは
localhost:8005
にリクエストをしていて、Host ヘッダーはsidecar.aws.signing-proxy/host
Annotations で静的に定義されたdatastore-lambda.sarathy.io
に置き換えられていることがわかります。言い換えると、呼び出し元のサービスは単一の Amazon VPC Lattice サービスにのみ接続できます。クライアントが複数の Amazon VPC Lattice サービスに接続する場合に、課題となります。
この記事では、完全に透過的に複数の Amazon VPC Lattice サービスに対する接続をサポートする、最適化されたソリューションを紹介します。
はじめに、Kubernetes の Pod に Init コンテナとサイドカーコンテナを導入します。
- Init コンテナ:
iptables
を実行し、ポート 8080 をリッスンする AWS SigV4 プロキシから Amazon VPC Lattice サービスへのトラフィックをインターセプトします。 - SigV4 プロキシ:
--name vpc-lattice-svcs, --unsigned-payload
フラグとロギングのオプションを含むargs
を指定して実行します。プロキシコンテナは AWS IAM roles for service accounts (IRSA) によって取得された認証情報を使用して、自動的にリクエストに署名します。
次に、Init コンテナとサイドカーコンテナを自動的に注入します。開発チームが既存の Kubernetes マニフェストに変更を加えないようにするためです。ポリシーエンジンとして Kyverno を使用します。Kyverno は Kubernetes のために設計されており、Kubernetes クラスター内で Dynamic Admission Controller として動作します。この場合、Kyverno は Kubernetes API サーバーから Mutating Admission Webhook の HTTP コールバックを受け取り、マッチするポリシーを適用して、Admission Policy を強制する結果を返します。言い換えると、Kyverno は Init コンテナとサイドカーコンテナをコーディングを必須とせずに自動的に注入することができます。
ウォークスルー
Amazon EKS における Amazon VPC Lattice と認証ポリシー
前提条件
Amazon EKS クラスターと Amazon VPC Lattice サービスの準備
ソリューションをテストするための環境を準備する必要があります。
サンプル httpbin アプリケーションを Amazon VPC Lattice サービスとしてデプロイする
以下のコマンドを使用して、httpbin を Amazon VPC Lattice サービスとしてデプロイします。
サービスネットワークの保護
この機能を実証するために、httpbin
サービスに認証ポリシーを適用し、認証されたアクセスのみを許可します。ドキュメントを参照することで、粒度の細かいポリシーを定義できます。
- AWS コンソールの VPC セクションに移動し、VPC Lattice の下の Services、右ペインの
httpbin-default
サービスを選択します。 - 次のページで Access タブの Edit access settings を選択します。
- 表示される Service access 画面で、AWS IAM から Apply policy template > Allow only authenticated access を選択します。次に Save changes を選択します。
ここで、サービスが AWS IAM 認証を必要とし、そうでなければ HTTP 403 Forbidden エラーを返すかを示すテストを実施します。
呼び出し元のアプリケーションのデプロイ
ここで、AWS IAM roles for service accounts (IRSA) を使用するようプロキシを構成し、プロキシがリクエストに署名するために AWS IAM ロールの認証情報を使用できるようにします。アイデンティティベースのポリシーである VPCLatticeServicesInvokeAccess
を AWS IAM ロールにアタッチすることで、Amazon VPC Lattice サービスを呼び出す権限をロールに付与できます。
Service Account 用の IAM ロールの作成
準備が完了したら、プロキシコンテナと一緒にサービスを呼び出すアプリケーションを準備します。プロキシコンテナはポート 8080 をリッスンし、ユーザー ID 101 として実行します。YAML スニペットは以下のとおりです。
ここでは、メインのアプリケーションからのトラフィックをインターセプトし、iptables
ユーテリティを使って Amazon VPC Lattice CIDR 169.254.171.0/24
に接続するトラフィックを EGRESS_PROXY
チェーンにルーティングし、ローカルのポート 8080 にリダイレクトしています。プロキシコンテナによってトラフィックが送信される際の無限ループを避けるため、UID が 101 かどうかをチェックすることで識別し、再度リダイレクトされないようにしています。
コンテナイメージ public.ecr.aws/d2c6w7a3/iptables
は、シンプルに iptables
がインストールされた Ubuntu Linux ディストリビューションのベースイメージです。
完全な YAML マニフェストは以下のようになります。
curl を実行することで、/get のレスポンスが表示されます。レスポンスは HTTP 200 OK です。
プロキシコンテナのログを確認することで、ヘッダーがプロキシによって追加されたことを確認できます。Authorization
ヘッダーと、x-amz-content-sha256
、x-amz-date
、x-amz-security-token
といったヘッダーがリクエストに追加されています。
ここでは、VPC_LATTICE_SERVICE_ENDPOINT
を 2 つ目のホスト名に置き換えることができます。アプリケーションコードの変更は必要としないので、複数の Amazon VPC Lattice サービスに接続することができます。
Kyverno を使って、Init コンテナとサイドカーコンテナを自動で注入する
ここで、Kyverno を活用して、Init コンテナとサイドカーコンテナを自動で注入するようにします。Kyverno がインストールされたクラスターでは、注入するための ClusterPolicy
を書くことができます。Deployment オブジェクトに vpc-lattices-svcs.amazonaws.com/agent-inject
が true
であるアノテーションが設定されると、Deployment に Init コンテナとサイドカーコンテナが注入されます。
環境変数 AWS_REGION
を指定する必要もあります。
このアプローチでは、Kubernetes Deployment の YAML に vpc-lattices-svcs.amazonaws.com/agent-inject: "true"
を指定すると、Deployment に Init コンテナとサイドカーコンテナが注入されます。
クライアントの YAML は以下です。
サイドカーは自動的に注入されます。
パッチが当たった YAML マニフェストは以下のようになります。
また、クライアントが Amazon VPC Lattice サービスに正常にアクセスできることも確認できます。
クリーンアップ
将来的な課金を避けるため、以下のコマンドを使用して Amazon VPC Lattice リソースと Amazon EKS クラスターを含む、全てのリソースを削除します。
まとめ
この記事では、Amazon VPC Lattice に AWS IAM 認証を実装する方法を、以下のようなソリューションを用いて紹介しました。
- Init コンテナを使って
iptables
コマンドを実行し、VPC Lattice へのトラフィックをインターセプトする。 - Kyverno を用いて Init コンテナとサイドカーコンテナを自動的に注入する。
- 呼び出し元のサービスは、VPC Lattice サービスネットワーク内の IAM 認証で複数のサービスに接続できるようになる。
VPC Lattice をベースにソリューションを構築し、VPC Lattice の IAM 認証を活用してセキュリティ体制を強化したい場合に、本ブログで共有した内容がお役に立てば嬉しいです。Amazon VPC Lattice の詳細については、ドキュメントやその他のブログを参照してください。
翻訳はソリューションアーキテクトの後藤が担当しました。原文はこちらです。