Amazon GuardDuty Malware Protection for Amazon S3をCloudFormationで実装してみた

2024.06.13

こんにちは、シマです。
皆さんはS3のファイルにマルウェアスキャンをしていますか?先日、S3に対するネイティブなマルウェア検出と保護の機能である「Amazon GuardDuty Malware Protection for Amazon S3」がリリースされました。

新しいサービスがリリースされるとIaCで実装したくてウズウズしますよね?ということで今回は、CloudFormationで実装していこうと思います。

内容

既に作成済みのS3バケットに対して「Amazon GuardDuty Malware Protection for Amazon S3」を有効にするためのCloudFormationテンプレートを以下の内容で実装しました。

guarddutyMalwareProtectionS3.yml

AWSTemplateFormatVersion: "2010-09-09"
Description: create MalwareProtectionPlan

Parameters:
  s3bucketName:
    Type: String
    Default: s3name

Resources:
  mpptest:
    Type: AWS::GuardDuty::MalwareProtectionPlan
    Properties:
      Actions:
        Tagging:
          Status: ENABLED
      ProtectedResource:
        S3Bucket:
          BucketName: !Ref s3bucketName
      Role: !ImportValue test-mpprole

パラメータが少なく、サクッと作れるところが良いところですね。各プロパティの詳細は公式ドキュメントをご確認ください。

IAMロール周りは、AWS管理コンソールから「Amazon GuardDuty Malware Protection for Amazon S3」を有効化するときに表示される以下のボタンから表示される内容で作成しています。
内容は上記のままですが、念のため今回利用しているテンプレートを以下に記載しておきます。

iam.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: create MalwareProtectionPlan

Parameters:
  s3bucketName:
    Type: String
    Default: s3namexxx
  keyid:
    Type: String
    Default: xxxxxxx

Resources:
  mpprole:
    Type: AWS::IAM::Role
    Properties:
      Path: /
      RoleName: test-mpprole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - sts:AssumeRole
            Principal:
              Service:
                - malware-protection-plan.guardduty.amazonaws.com

  mpppolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: test-mpppolicy
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: AllowManagedRuleToSendS3EventsToGuardDuty
            Effect: Allow
            Action:
              - events:PutRule
              - events:DeleteRule
              - events:PutTargets
              - events:RemoveTargets
            Resource:
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3*
            Condition:
              StringLike:
                events:ManagedBy: malware-protection-plan.guardduty.amazonaws.com
          - Sid: AllowGuardDutyToMonitorEventBridgeManagedRule
            Effect: Allow
            Action:
              - events:DescribeRule
              - events:ListTargetsByRule
            Resource:
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3*
          - Sid: AllowPostScanTag
            Effect: Allow
            Action:
              - s3:PutObjectTagging
              - s3:GetObjectTagging
              - s3:PutObjectVersionTagging
              - s3:GetObjectVersionTagging
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::${s3bucketName}/*
          - Sid: AllowEnableS3EventBridgeEvents
            Effect: Allow
            Action:
              - s3:PutBucketNotification
              - s3:GetBucketNotification
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::${s3bucketName}
          - Sid: AllowPutValidationObject
            Effect: Allow
            Action:
              - s3:PutObject
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::${s3bucketName}/malware-protection-resource-validation-object
          - Effect: Allow
            Action:
              - s3:ListBucket
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::${s3bucketName}
          - Sid: AllowMalwareScan
            Effect: Allow
            Action:
              - s3:GetObject
              - s3:GetObjectVersion
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::${s3bucketName}/*
          - Sid: AllowDecryptForMalwareScan
            Effect: Allow
            Action:
              - kms:GenerateDataKey
              - kms:Decrypt
            Resource: !Sub arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${keyid}
            Condition:
              StringLike:
                kms:ViaService: s3.*.amazonaws.com
      Roles:
        - !Ref mpprole

Outputs:
  Outputaymdpappmd:
    Description: Create mpprole Arn
    Value: !GetAtt mpprole.Arn
    Export:
      Name: test-mpprole

念のためサクッと動作確認

いつものEicarテストファイルを対象のS3バケットへアップロードすると、「GuardDutyMalwareScanStatus」タグが付与され、「THREATS_FOUND」と判定されましたので、想定通り動作していますね。

最後に

今回はAmazon GuardDuty Malware Protection for Amazon S3をCloudFormationで実装してみました。

本記事がどなたかのお役に立てれば幸いです。