複数のアクセス拒否設定をしたS3バケットをCloudFormationで作ってみた

2021.05.20

データアナリティクス事業本部の鈴木です。

バケットポリシーを使うと、S3バケットに、特定のIPやIAMからのみアクセス許可し、それ以外は拒否するような設定ができます。 要件によっては同時に複数のアクセス拒否設定をする必要があると思います。このような場合に、CloudFormationのテンプレートをどう書けば良いか知りたかったので実験してみました。

試してみたアクセス制限

以下の3種類を試してみました。

  • IPからのアクセス制限
  • IAMからのアクセス制限
  • VPCエンドポイントからのアクセス制限

今回は特に「同時に制限をかけて、どれか一つでもOKだったらアクセスできる」ようにする方法に注目しました。

テンプレートを作成する

早速、テンプレートを作成してみます。 バケットポリシーに複数のアクセス制限をつけるときのポイントは、ハイライトした34-45行目です。

AWSTemplateFormatVersion: 2010-09-09
Description: Access Restricted S3 Bucket

Parameters:
  S3BucketName:
    Description: Type of this BacketName.
    Type: String

Resources:
  SampleBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Sub ${S3BucketName}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  SampleBucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: !Ref SampleBucket
      PolicyDocument:
        Statement:
          - Action:
            - 's3:*'
            Effect: Deny
            Sid: MultiRestrictPolicy
            Resource: 
              - !Sub 'arn:aws:s3:::${SampleBucket}'
              - !Sub 'arn:aws:s3:::${SampleBucket}/*'
            Principal: '*'
            Condition:
              StringNotLike:
                'aws:userId':
                  - "AROAxxxxxxxxxxxxxxxxx:*"
              NotIpAddress:
                'aws:SourceIp':
                  - 111.222.333.444/32
              StringNotEquals:
                'aws:SourceVpce':
                  - "vpce-1a2b3c4d"
                "aws:CalledVia":
                  - "cloudformation.amazonaws.com"          

Outputs:
  SampleBucket:
    Value: !Ref SampleBucket

アクセス拒否の条件は、Conditionブロックに記載します。Conditionブロック内のCondition要素はAND条件で評価されるので、以下の条件を共に満たす場合はアクセスを拒否するという意味になります(どれか一つでも満たしていればアクセスすることができます)。

  • IPの制限:SourceIpが111.222.333.444/32ではないとき
  • IAMの制限:userIdが"AROAxxxxxxxxxxxxxxxxx:*"にマッチしないとき
  • VPCエンドポイントの制限:SourceVpceがvpce-1a2b3c4dではないとき

IAMの制限については、急にaws:userIdの話をし始めたのでなんのこっちゃですが、以下の記事を参考にしています。

また、アクセス制限をするときは、Cloudformationがリソースにアクセスできるよう、44-45行目のように、CalledViaも条件に入れておきます。

バケットへアクセスしてみる

上記で作成したテンプレートを使って、バケットとバケットポリシーを作成し、アクセスできる場合とできない場合をピックアップして、設定の効果を確認しました。

IPとIAMが許可されているとき

まず、許可されたIPかつ許可されたIAMで、コンソールからバケットにアクセスしてみます。 バケットの中身を見ることができました。

IPもIAMも違うし、VPCエンドポイントも経由していないとき

続いて、IPもIAM許可されていないし、VPCエンドポイントも経由していない条件で、コンソールからバケットにアクセスしてみます。 このときはちゃんとアクセス制限されていることが分かります。 アクセス制限されている例

※条件が難しかったので、記載されたIPとIAMロールが自分のものと違うバケットポリシーのテンプレートを作成しました。

さいごに

検証のため、何度もトライ&エラーしましたが、CloudFormationのテンプレートにしておくことで、簡単に作ったり消したりすることができ、とても便利でした。ただし、CalledViaの条件をつけ忘れると、消せなくなってしまうので、忘れずに条件に入れるようにしましょう!

参考