
関連するソリューション

マネージドサービス(運用・保守)
デジタルソリューション営業部
エバンジェリスト 松岡 政之 
季節はすっかり秋になり涼しい日が増えてきました。寒さのせいか最近お腹の調子が悪い日が続いています。
皆様も体調には十二分にお気を付けください。
1.はじめに
AWSの環境を運用していると、利用者にAWSのサービスを払い出すためにIAMでポリシーを作成する機会が多々あるかと思います。その際、ポリシーを作成したのは良くても微妙に必要な権限が足りずエラーが出てしまうことはありませんでしょうか。また、利用者に払い出したのは良くても思っていた以上に多種のサービスが絡み合っていて想定外の権限が不足しており、利用できないといった問い合わせがきた経験はありませんでしょうか。
こういった場合、CloudTrailのログからどの権限が不足しているのかを洗い出して新たにポリシーに追加していく必要がありますが、ログを調査するとなるとなかなかの重労働です。CloudTrailログから不足している権限をもっと簡単に抽出できないものかとSplunk等のログ統合管理システム等の導入を検討された方も少なくないのではないでしょうか。
というわけで、今回はそのような悩みを持つ方への朗報となりえるのか確認するために2022年10月5日にリリースされたばかりの新機能を見ていきたいと思います。なんと、CloudTrailのログから必要なIAMポリシーを抽出して自動生成してくれる機能です。
こちらの機能のリリースノートは下記URLにあります。
IAM Access Analyzer により、AWS CloudTrail の履歴を確認して 140 の AWS サービスで使用されるアクションを特定し、きめ細かいポリシーを生成することが可能に(https://aws.amazon.com/jp/about-aws/whats-new/2022/10/iam-access-analyzer-cloudtrail-history-identify-actions-140-aws-services-fine-grained-policies/ 外部リンク )
それでは、試していきましょう。
2.検証準備
2-1. CloudTrailの準備
CloudTrailはAWSアカウント内での操作をAPIレベルで記録してくれるサービスなので、IAMポリシーの権限不足時や不正な操作の調査時などに活用できます。不正ログインされた場合の検知等にも利用できるためAWSアカウントをとったら必ず有効化しておくべきといっても過言ではないサービスです。ただし、保管されたログに対するストレージの料金が課金されるのでご注意ください。
2-2. IAMユーザーの準備
今回はEC2の読み取り権限のみを付与したIAMユーザーでEC2インスタンスの作成を試し、不足した権限の抽出を試していきたいと思います。
というわけで、test01というIAMユーザーを作成し、デフォルトで用意されているAmazonEC2ReadOnlyAccessポリシーを割り当てます。
それでは作成したIAMユーザーでサインインして試していきましょう。
3.実証
3-1. EC2インスタンスの作成試行
今回はミニマムで検証を行いたいので、セキュリティグループやパブリックIP等は新規に作成せず、EBSの暗号化もなしで作成します。
ですが、test01にはEC2インスタンスを作成する権限はありませんので、もちろん以下の通り失敗します。
3-2. ポリシー自動生成
それでは管理者ユーザーに切り替えて実施していきます。
「2-2. IAMユーザーの準備」でお示ししたIAMユーザーの画面の下部に「CloudTrailイベントに基づいてポリシーを生成」という項目があります。こちらの「ポリシーの生成」をポチっとします。
すると下図に示す通り、分析するCloudTrailログとその期間を指定します。そして、分析に使用するロールも指定する必要がありますが、今回は初めてなので「新しいサービスロールを作成して使用」を選択します。

すると以下に示すような画面に遷移します。するとCloudTrailのログに残された検出されたアクションの一覧が表示されます。つまり、EC2インスタンスを作成するのに必要な権限が表示されているはずです。
下側のオプションは手動で権限を追加できる機能ですが、今回は自動生成の検証なので使用しません。
ただし、ここで表示されているポリシーはそのままではリージョンやアカウントIDなどが変数として埋め込まれており、そのままでは使用できません。
というわけで、変数部分を次のように編集して使えるようにします。
講座/資格生成されたポリシー | 修正後 |
---|---|
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:CreateTags", "ec2:DescribeAccountAttributes", "ec2:DescribeAddresses", "ec2:DescribeAvailabilityZones", "ec2:DescribeHosts", "ec2:DescribeImages", "ec2:DescribeInstanceTypeOfferings", "ec2:DescribeInstanceTypes", "ec2:DescribeInstances", "ec2:DescribeKeyPairs", "ec2:DescribeSecurityGroups", "ec2:DescribeSnapshots", "ec2:DescribeSubnets", "ec2:DescribeTags", "ec2:DescribeVolumes", "ec2:DescribeVpcs", "ec2:GetEbsEncryptionByDefault", "elasticloadbalancing:DescribeLoadBalancers" ], "Resource": "*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}:${Account}:instance/${InstanceId}" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}:${Account}:network-interface/${NetworkInterfaceId}" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}:${Account}:security-group/${SecurityGroupId}" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}:${Account}:subnet/${SubnetId}" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}:${Account}:volume/${VolumeId}" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:${Region}::image/${ImageId}" } ] } |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:CreateTags", "ec2:DescribeAccountAttributes", "ec2:DescribeAddresses", "ec2:DescribeAvailabilityZones", "ec2:DescribeHosts", "ec2:DescribeImages", "ec2:DescribeInstanceTypeOfferings", "ec2:DescribeInstanceTypes", "ec2:DescribeInstances", "ec2:DescribeKeyPairs", "ec2:DescribeSecurityGroups", "ec2:DescribeSnapshots", "ec2:DescribeSubnets", "ec2:DescribeTags", "ec2:DescribeVolumes", "ec2:DescribeVpcs", "ec2:GetEbsEncryptionByDefault", "elasticloadbalancing:DescribeLoadBalancers" ], "Resource": "*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::instance/*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::network-interface/*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::security-group/*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::subnet/*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::volume/*" }, { "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "arn:aws:ec2:us-east-1::image/*" } ] } |
ここまでの流れで不足していたポリシーが作成され、IAMユーザーにアタッチされます。自分でCloudTrailのログを調べてポリシーを作っていくことと比べるとだいぶ楽ですね。ちなみにロールの場合でも同様にポリシーを作成してアタッチすることができます。
まとめ
結果として、リージョンやアカウントIDなどの一部可変の値については手動で修正する必要はありましたが、自動で不足している権限を補うポリシーが作成されました。自身でポリシーを作成したことがある方はかなり手間が軽減されていることがわかるかと思います。
ただし、今回紹介した機能ではCloudTrailログに出力されたものだけが対象となります。やりたいアクションのAPIを実行しようとする前に別のアクションの権限不足等で失敗しCloudTrailログに残っていない場合、ポリシーとして生成されないであろうことが推測されます。おそらくそういった場合は、今回行った手順を複数回繰り返すことで少しずつ不足している権限を補っていくことができるのではないかと思います。
今回はあまり時間が取れず1つのパターンでの検証となりましたが、とても使えそうな機能なので時間を見つけていろんなパターン・サービスで試してみたいと思います。また情報がたまったら続報をお伝えするかもしれません。お読みいただいた皆様も、自身の使い方に今回の機能が役立つか触ってみてはいかがでしょうか。
それではよいクラウドライフを!