これまでコーポレートサイトのシステムを題材として、可用性、耐障害性、スケーラビリティーを高める方法を解説してきました。今回から、このシステムのセキュリティを高める方法に焦点を当てていきます。

 AWSには「権限の管理」「検出制御」「データ保護」「インフラストラクチャの保護」というセキュリティの4分野をサポートするサービス・機能が用意されています。今回はこのうち権限の管理と検出制御を解説します。

権限の管理に使用するIAM

 仮想マシンのAmazon EC2、ロードバランサーのALB、オブジェクトストレージのAmazon S3といったAWSのサービスを利用して、コーポレートサイトのシステムを構築してきました。これらAWSのリソースに対するアクセス権限についてどう考えたらよいでしょうか。

 セキュリティのベストプラクティスは、与えるアクセス権限も、ユーザーの範囲も、必要最小限に絞り込むことです。例えば、VPC(Virtual Private Cloud)の作成、EC2インスタンスやRDSインスタンスの起動/停止といった操作はインフラ管理チームのみが行えるようにし、アプリケーション開発チームが不用意にインフラの構成を変更できないようにするといった具合です。

 AWSリソースへのアクセス権限の管理に利用するサービスが「IAM(Identity and Access Management)」です。IAMによって、AWSリソースにアクセスできるユーザーであることを確認(認証)したうえで、起動、設定、管理、終了といった操作を許可(認可)します。例えば、限られたインフラ管理担当者のみに特定のEC2インスタンスの起動・停止を許可したり、あるEC2インスタンスに特定のS3バケットへの読み書きを許可したりできます。

 AWSリソースへのアクセス方法にはAWSマネジメントコンソールの操作とAPIコールがあり、異なるセキュリティ認証情報を使用します。マネジメントコンソールでは、ユーザー名とパスワードを使用してサインインします。APIコールではアクセスキーを使用します。

 IAMにはアクセス権限をリスト化した「IAMポリシー」と、それを割り当てるユーザーの範囲である「IAMユーザー」「IAMグループ」「IAMロール」という概念が存在します。IAMユーザー、IAMグループ、IAMロールは総称して「IAMエンティティ」と呼びます。一つずつ解説します。

 IAMポリシーは、1個あるいは複数個のアクセス権限をまとめたものです。JSON(JavaScript Object Notation)形式で保存されるので、GitHubのようなバージョン管理システムによって管理できます。

 IAMポリシーでは、許可しない限りは全ての操作が拒否されます。これを「暗示的な拒否」と呼びます。

 操作を許可するには、IAMポリシーに書く必要があります。これが「明示的な許可」です。明示的な許可は、暗示的な拒否より優先されます。

 二つのアクセス権限(ステートメント)を表した、IAMポリシーの具体例を図1に挙げます。

図1 IAM ポリシーの許可・拒否ステートメント
許可ステートメントと明示的な拒否ステートメントを併用することで、他のIAMポリシーがアタッチされても、このIAMポリシーで許可したリソースにしかアクセスできないことを保証する
図1 IAM ポリシーの許可・拒否ステートメント
[画像のクリックで拡大表示]

 前半は明示的な許可ステートメントで、mytableというDynamoDBテーブル、mybucketというS3バケットおよびそこに保存された全てのオブジェクトに対するあらゆるアクションの権限を付与します。

 後半は明示的な拒否ステートメント。mytableというDynamoDBテーブル、mybucketというS3バケットおよびそこに保存された全てのオブジェクト以外へのアクションを拒否します。前半の補集合についての拒否なので、矛盾しません。デフォルトは暗示的な拒否なので、後半のステートメントがなくても同じ結果になります。

 後半のステートメントは冗長なように見えますが、明示的な拒否も定義することには意味があります。明示的な許可と明示的な拒否が存在する場合、拒否が優先されます。そのため図1のIAMポリシーをアタッチすれば、別のどんなIAMポリシーを追加しても、mytableというDynamoDBテーブル、mybucketというS3バケットおよびそこに保存された全てのオブジェクト以外へのアクションを拒否します。

IAMユーザーの集合がIAMグループ

 続いて、3種類あるIAMエンティティを説明します。

 まずIAMユーザーは、AWSリソースの操作用IDです。主に、AWSマネジメントコンソールへのサインインと、AWSリソースへのAPIコールを行う際に使用します。1個のAWSアカウントで、5000個までのIAMユーザーを作成できます。

 IAMユーザーは、アクセス権限が関連付けられた単なるIDであり、アプリケーション用に作成することもできます。その場合、アプリケーションからAWSリソースのAPIをコールする際に使います。

 アプリケーション用のIAMユーザーに対してアクセスキーを作成できます。アプリケーションはアクセスキーを使用して認証を受けます。

 IAMユーザーの集合がIAMグループです。グループ単位でアクセス権限を管理できます。例えば開発者をグループ化したDevelopersというIAMグループを作成し、開発者に共通して必要な権限を割り当てます。

 こうしておけば、開発者がプロジェクトに新たに加わったとき、その開発者のIAMユーザーをDevelopersに追加するだけで、開発者に必要な権限を割り当てることができます。同様に、開発者がプロジェクトから外れたときは、そのIAMユーザーをDevelopersから削除すれば済みます。

 一つのIAMユーザーを、複数のIAMグループに重複して所属させられます。ただしIAMグループを入れ子形式にする機能はありません。つまり、あるIAMグループに他のIAMグループが属する、という構成にはできません。

 AWSアカウント内の全てのIAMユーザーが属するIAMグループが必要になることがあります。これはデフォルトでは存在しないので、作成する必要があります。手間が掛かりますが、IAMユーザーを一つずつ割り当てます。