はじめに

アプリケーション開発部の田村です。自社で運営するサービス開発を担当しています。
私が担当するサービス開発では実行環境にAWSを利用しています。
今回はAWSマネジメントコンソールで遭遇する権限エラーの解決方法についてお話します。 まだAWSの経験が浅い方には有益な情報になると思い記事にします。

想定読者

  • AWS IAMユーザ、IAMポリシーについて多少知識がある方
  • IAMポリシーの設定のデバッグを少しでも楽にしたい方
  • IAM Policy Simulatorでも解決できない問題を抱えている方

IAMポリシーのエラー調査

プロジェクトでAWSを利用する場合、担当者ごとにIAMユーザを作成しそのIAMユーザが行う上で必要最低限の権限を付与する運用が望ましいです。

そこで利用するAWSのサービス(AWS EC2、Amazon S3など)の操作から考えてIAMユーザにIAMポリシーを設定していきます。

ただ、正しく設定してるつもりでも「許可してるはずなのに画面に権限エラーやAccess Deniedがでる」となる場合があります。そういった場合、何がおかしいか調査をしていくことになるのですが一般的には次のように調査をします。

IAMポリシーを手で少しずつ修正して動作確認する

当然この方法でも解決しますが場合によっては効率が悪く、オペレーションミス・ヒューマンエラーのリスクが高くなります。

IAM Policy Simulator

https://policysim.aws.amazon.com/

私の第一選択肢はこれです。 IAMユーザやIAMロール、グループに対して、各種APIを発行した時の実行可否を効率よく調査できます。
ユーザ管理のポリシーに関してはその場で修正して試すことが出来ますし、実行時の環境情報(Resourceやアクセス元IPなど)もパラメータとして指定出来るので非常に重宝します。

APIを実行してみる

AWSマネジメントコンソールでは、サービスごとでエラー時に表示されるエラーメッセージの内容が異なります。
画面に有益なエラー情報が出ないサービスもあり、そういう場合はその画面で実行されてるであろうAPIを推測します。
そしてそのAPIをaws cliなどを用いて実行して、画面からは得られないエラーメッセージを取得して調査に役立てます。

例えば、Amazon S3でのファイルのダウンロードでaws cliを用いるのであれば、aws s3やaws s3apiといったコマンドで確認することが出来ます。

$ aws s3 cp s3://hogehoge/text.txt ./

download failed: s3://hogehoge/text.txt to ./text.txt An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

IAM Policy Simulatorでも調査が難しい事例

IAM Policy Simulatorを使えばまず問題は解決するのですが、中には厄介な事例も存在します。
例えばIAM Policy Simulatorが使えない、画面にAPIのエラーメッセージにも有益な情報がない、こういった状況も存在します。
今回はその状況を再現させてどのように調査するかを説明します。

環境の再現とエラー発生

今回はAmazon S3のバケットへのフルアクセス権限を持ったIAMユーザと暗号化が設定されたAmazon S3バケットを用いて再現します。

※1〜4はAmazon S3及びAWS KMS、AWS IAMの権限のあるパワーユーザ等で作業をしてください。

1. 暗号化用のKMS カスタマーキーの作成

AWS KMSの画面を開き、「カスタマー管理型のキー」からキーの作成を行います。

「キーを設定」では「対称」を選択。

キーの名前を入力します。

次のキーの管理アクセス許可を定義キーの使用アクセス許可を定義はあえて何も選択せずに進めます。
最後に確認画面で「完了」を押下して作成します。 作成されると一覧に表示されます。

2. 検証用のAmazon S3バケットの作成

検証用にAmazon S3バケットを作成します。下記のように設定して作成します。
※バケット名「iam-error-test」で作成していますが、エラーになる場合はさらに固有のポストフィックスをつけてください。

3. 適当なファイルをアップロード

作成したバケットに適当なファイルをアップロードしておきます。

4. Amazon S3に対するフル権限を持ったIAMユーザを作成

AWS IAMの画面で新しくIAMユーザを作成します。設定するIAMポリシーには「AmazonS3FullAccess」をアタッチします。

ユーザ名は「s3_full_access」

「AmazonS3FullAccess」をアタッチ

5. 作成したIAMユーザでログインする

先程作成したIAMユーザ「s3_full_access」でログインしてください。

6. Amazon S3からファイルダウンロードする

先程作成した検証用のバケットを開き、ファイルのダウンロードをしてみます。
すると下記のようなエラー画面が表示され、ファイルをダウンロード出来ません。

調査方法

それでは調査をしていきます。
調査は通常、ある程度権限のあるパワーユーザーで行います。

IAMポリシーとバケットポリシーの確認

まず、IAMユーザ「s3_full_access」のIAMポリシーですが、これは先程見たとおり「AmazonS3FullAccess」を付与しているため問題ありません。
次にバケット「iam-error-test」のバケットポリシーも未設定で明示的に拒否するような設定はありません。

IAM Policy Simulatorで確認

目視で確認したところでは特に問題がないので、次にIAM Policy Simulatorで実際の挙動を確認してみます。
https://policysim.aws.amazon.com/

ユーザで「s3_full_access」を選び、下記のようにセットして「Run Simulation」を押下します。
ダウンロードなのでアクションは「GetObject」だろうという推測です。

すると成功しました。「GetObject」は問題ないようです。

そこで、もしかすると「ダウンロード」を押下すると「GetObject」以外のAmazon S3のAPIが呼ばれていると推測してみます。
APIは大量にあるので一気に実行して効率化を図ります。
「Select All」を選択するとAmazon S3の全アクションが選択されます。この状態で再度「Run Simulation」を押下します。

全て成功しました。IAMポリシーやS3のバケットポリシーには問題がないようです。

AWS CloudTrailによる調査

ここまでの調査でAmazon S3に対する権限には問題はないといえそうです。
そうなると、「ダウンロード」ボタンを押下した時にAmazon S3以外のサービスのAPIが呼ばれている可能性があると考えることが出来ます。
そこでそのAPIが何かを調べる必要があります。
ここでAWS CloudTrailを利用することにします。 ※AWS CloudTrailを有効にしていない場合はまず有効化してください。

AWS CloudTrail

AWS CloudTrailとはリンク先の説明どおりなのですが、 具体的にはAWS上で実行されたAPIの履歴を全て記録してくれるサービスです。
「いつ、誰が、どのサービス・リソースに対してどのAPIを実行したか」などを確認することが出来ます。
AWSマネジメントコンソール上での操作も全てAPIとして実行されているので、このサービスを使えば「AWSマネジメントコンソールに誰がいつログインして何を行ったか」を追跡することが出来ます。
このことから一般的には証跡監査の目的で利用するサービスですが今回は、「AWSマネジメントコンソール上でのある操作によってどんなAPIが実行されてるのか」を確認する目的で活用していきます。

事前準備

AWS CloudTrailによる調査を円滑に進めるために、s3_full_accessユーザで先程のS3バケットのファイルダウンロードエラーを再実行しておきましょう。エラーが起きたらs3_full_accessユーザでAWSの操作は何もしないようにします。
エラー発生後に不要な操作をしてしまうとエラー発生と無関係のイベントまで抽出されるので調査の妨げになります。

調査

AWS CloudTrailの画面を開きイベント履歴を開きます。
次にユーザ名を「s3_full_access」でフィルタリングし、「イベントをダウンロード」でCSVファイルとしてダウンロードします。

CSVファイルを見てみます。先頭行が最新のイベントです。
1行目のイベントはAWS KMS、後続行はAmazon S3のイベントです。
s3_full_accessユーザはエラー発生後、何も操作をしていないのでAmazon S3上での操作中にAWS KMSのAPIを呼び出している可能性が考えられます。
AWS KMSのDecryptを呼び出していますが、「Error code」列を見ると「AccessDenied」となっています。

※今回CSVファイルをダウンロードして確認していますが、AWSコンソール上でも確認可能です。
デフォルトでは「Error code」列が表示されてないのでページングの右にある鍵アイコンで表示列を設定してください。

この情報から次のような推測ができます。

  • Amazon S3のバケットに暗号化設定がされているのではないか
  • 暗号化されている場合、AWS KMSのカスタマーキーでのDecryptが許可されていないのではないか

解決

今回は自分で設定したので確認するまでもないですが、推測通りS3バケットには暗号化設定がされています。
また指定しているAWS KMSのカスタマーキー「iam-error-test」にはs3_full_accessの使用許可を与えていません。

AWS KMSのキーポリシーでs3_full_accessにkms:Decryptを許可することで正常にダウンロードが出来るようになります。
※今回の場合、rootに権限を与えているのでIAM Policyでも設定できます。
https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policies.html#key-policy-default

まとめ

AWS CloudTrailは運用監査などを目的に用いられるサービスですが開発時にはこのような使い方も出来るので、有効化し活用することがよいと考えます。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。