【初心者必見】Amazon S3のアクセス制御

こんにちは、高橋です。
Amazon S3はデータの保管に非常に便利なサービスです。しかしながら、S3内部のオブジェクトに関しては同じアカウント内のIAMユーザは勿論、他のAWSアカウントのユーザ、 さらにはオブジェクトを公開した場合、外部からでもアクセスできてしまいます。 そのため、S3にはバケット/オブジェクトへのアクセスを制御するためのアクセスコントロールの方法が3種類用意されています。

今回はS3のアクセス制御の方法とお客様からよく問い合わせを受けるアクセス制御の実際の設定例についてご紹介します。

Amazon S3のアクセス制御

Amazon S3のアクセス制御の方法は下記の3種類の方法があります。

  • 1. IAMポリシー
    通常のAWSサービスへのアクセス制御と同様にポリシードキュメントにてIAMユーザ/ロールに対してできるアクションやリソースの制御を行います。S3の場合、バケット、フォルダへのアクセス制御を行うことができます。

  • 2. バケットポリシー
    S3バケット毎にポリシードキュメントにてアクセス制御を行います。アクセス制御はアカウント内のIAMの他にクロスアカウント(他のAWSアカウント)のアクセス制御を行うことができます。

  • 3. Access Control List(ACL)
    バケット及びオブジェクト単位で細かなアクセス制御を行うことができます。アカウント内のIAMの他に、外部からのアクセスに対しても制御を行うことができます。

ACLに関してはIAMポリシーやバケットポリシーでDenyポリシーが設定されていた場合、IAMポリシー/バケットポリシーの拒否が優先され、個別に許可/拒否を設定するよりもバケットを分けてしまった方が管理が楽になるケースが多いため、通常の運用では利用されるケースは稀な機能となります。

そのため、基本的にアカウント内のIAMに対してアクセスを行いたい場合はIAMポリシーを、S3バケット単位でアクセス制御を行いたい場合やクロスアカウントでの利用を想定する場合はバケットポリシーを用いるのが一般的な使い分けになると考えられます。

よくあるアクセス制御例

お客様から問い合わせを受けるS3のアクセス制御に関する質問は大きく下記の2つとなります。

  • ユーザ毎にアクセスできるS3バケットを制限したい
  • S3バケットに特定のユーザしかアクセスさせたくない

今回は私の備忘を含めて、上記2つのアクセス制御の設定例を記載します。
なお、Action部は制御したい内容に適宜変更を行ってください。

IAMユーザに特定のS3バケットへのみアクセスを制限する

IAMユーザ毎にアクセスできるS3バケットを制限する場合は、IAMポリシーを用いて制限を行います。
実際に設定するIAMポリシーは以下の様になります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3::: <バケット名>/*"
            ]
        }
    ]
}

ただし、AWSコンソールからではなく、AWS CLI等で直接S3バケットにアクセスする場合は「s3:ListAllMyBuckets」を削除しても問題ありません。

特定のIAMユーザのみにS3バケットへのアクセスを制限する

あるS3バケットに特定のIAMユーザしかアクセスできない様に制限する場合は、バケットポリシーを用いて制限を行います。
実際に設定するIAMポリシーは以下のようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": " s3:GetObject",
            "Resource": [
                "arn:aws:s3:::source210219-01",
                "arn:aws:s3:::source210219-01/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:username": "<ユーザ名>"
                }
            }
        }
    ]
}

最近つまずいたアクセス制御

最後に最近つまずいたS3のアクセス制御について紹介します。

それは特定のIAMユーザのみにS3バケットへのアクセスを制限していた環境にS3のレプリケーションを実施したときでした。その環境でレプリケーションの設定を実施しましたが、設定は完了したものの、実際にオブジェクトをソースバケットに保存してもレプリケーションは失敗しました。原因を調べてみるとS3のレプリケーションの実行はレプリケーションの設定時に指定したIAMロールの権限で実施されるのに対して、バケットポリシーではこのロールに対してアクセス許可を行っていなかったためでした。

そこで先程の「特定のIAMユーザのみにS3バケットへのアクセスを制限する」を元に、レプリケーション実行用のIAMロールにもアクセスを許可しようとしましたが、ポリシーの記載が「aws:username」となっており、IAMロールを追加することができませんでした。

このようにIAMユーザとIAMロールの双方にアクセス許可を与える必要がある場合は、「aws:username」の代わりに「aws:userId」を使用し、ユーザID、ロールID設定する必要があります。なお、ユーザID、ロールIDはAWS CLIを用いて調べることが可能です。

$ aws iam get-role --role-name sample
  {
      "Role": {
          ・
          ・
          ・
      "MaxSessionDuration": 3600,
      "RoleId": "AROXXXXXXXXXXXXXXXXXX",
      "CreateDate": "2019-01-06T09:04:03Z",
          ・
          ・
          ・
  }

実際に設定するバケットポリシーは以下の様になります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "<ユーザID>",
                        "<ロールID>:*"
                    ]
                }
            }
        }
    ]
}

【著者プロフィール】

高橋 繁義(たかはし しげよし)

伊藤忠テクノソリューションズ株式会社 クラウドアーキテクト

インフラ全般のエンジニアとして20年以上活動し、現在AWS専任の技術担当兼サービス企画担当として活動中