scanner
  • About Scanner
  • When to use it
  • Architecture
  • Getting Started
  • Playground Guide
    • Overview
    • Part 1: Search and Analysis
    • Part 2: Detection Rules
    • Wrapping Up
  • Log Data Sources
    • Overview
    • List
      • AWS
        • AWS Aurora
        • AWS CloudTrail
        • AWS CloudWatch
        • AWS ECS
        • AWS EKS
        • AWS GuardDuty
        • AWS Lambda
        • AWS Route53 Resolver
        • AWS VPC Flow
        • AWS VPC Transit Gateway Flow
        • AWS WAF
      • Cloudflare
        • Audit Logs
        • Firewall Events
        • HTTP Requests
        • Other Datasets
      • Crowdstrike
      • Custom via Fluentd
      • Fastly
      • GitHub
      • Jamf
      • Lacework
      • Osquery
      • OSSEC
      • Sophos
      • Sublime Security
      • Suricata
      • Syslog
      • Teleport
      • Windows Defender
      • Windows Sysmon
      • Zeek
  • Indexing Your Logs in S3
    • Linking AWS Accounts
      • Manual setup
        • AWS CloudShell
      • Infra-as-code
        • AWS CloudFormation
        • Terraform
        • Pulumi
    • Creating S3 Import Rules
      • Configuration - Basic
      • Configuration - Optional Transformations
      • Previewing Imports
      • Regular Expressions in Import Rules
  • Using Scanner
    • Query Syntax
    • Aggregation Functions
      • avg()
      • count()
      • countdistinct()
      • eval()
      • groupbycount()
      • max()
      • min()
      • percentile()
      • rename()
      • stats()
      • sum()
      • table()
      • var()
      • where()
    • Detection Rules
      • Event Sinks
      • Out-of-the-Box Detection Rules
      • MITRE Tags
    • API
      • Ad hoc queries
      • Detection Rules
      • Event Sinks
      • Validating YAML files
    • Built-in Indexes
      • _audit
    • Role-Based Access Control (RBAC)
    • Beta features
      • Scanner for Splunk
        • Getting Started
        • Using Scanner Search Commands
        • Dashboards
        • Creating Custom Content in Splunk Security Essentials
      • Scanner for Grafana
        • Getting Started
      • Jupyter Notebooks
        • Getting Started with Jupyter Notebooks
        • Scanner Notebooks on Github
      • Detection Rules as Code
        • Getting Started
        • Writing Detection Rules
        • CLI
        • Managing Synced Detection Rules
      • Detection Alert Formatting
        • Customizing PagerDuty Alerts
      • Scalar Functions and Operators
        • coalesce()
        • if()
        • arr.join()
        • math.abs()
        • math.round()
        • str.uriencode()
  • Single Sign On (SSO)
    • Overview
    • Okta
      • Okta Workforce
      • SAML
  • Self-Hosted Scanner
    • Overview
Powered by GitBook
On this page
  • If your S3 buckets are in multiple regions
  • Setting up bucket notifications

Was this helpful?

  1. Indexing Your Logs in S3
  2. Linking AWS Accounts
  3. Infra-as-code

AWS CloudFormation

Getting started with CloudFormation

PreviousInfra-as-codeNextTerraform

Last updated 2 months ago

Was this helpful?

You can use this CloudFormation file to set up the IAM role, IAM policies, S3 bucket, and SNS topic to integrate with Scanner.

You can get the ScannerAWSAccountID and ScannerExternalID from your Scanner support engineer or from the Scanner UI.

The CloudFormation file is available here for copy-paste, or you can download it from this link:

---
AWSTemplateFormatVersion: "2010-09-09"

Description: Scanner S3 Indexing Integration

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Scanner Auth Parameters
        Parameters:
          - ScannerExternalID
    ParameterLabels:
      ScannerExternalID:
        default: Scanner External ID
      ScannerAWSAccountID:
        default: Scanner AWS Account ID
      S3BucketToIndex:
        default: S3 Bucket to Index
      S3BucketKmsKeyArn:
        default: KMS Key for "S3 Bucket To Index"

Parameters:
  ScannerExternalID:
    Description: Scanner provides an External ID to use here.
    Type: String
  ScannerAWSAccountID:
    Description: Scanner provides its AWS Account ID to use here.
    Type: String
  S3BucketToIndex:
    Description: Enter the name of the S3 bucket that you would like Scanner to index.
    Type: String
  S3BucketKmsKeyArn:
    Default: ""
    Description: Enter the ARN of the KMS key used to encrypt "S3 Bucket To Index". Not needed if the bucket does not use a KMS key.
    Type: String

Conditions:
  HasS3BucketKmsKeyArn: !Not [ !Equals [ !Ref S3BucketKmsKeyArn, "" ] ]

Resources:
  ScannerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: "scnr-ScannerRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                Ref: ScannerAWSAccountID
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId:
                  Ref: ScannerExternalID

  ScannerIndexFilesBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: "Retain"
    Properties:
      BucketName: !Sub
        - "scanner-index-files-${Suffix}"
        - Suffix: !Ref ScannerExternalID
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - BucketKeyEnabled: true
            ServerSideEncryptionByDefault:
              SSEAlgorithm: "aws:kms"
      LifecycleConfiguration:
        Rules:
          - Id: ExpireTagging
            Status: Enabled
            TagFilters:
              - Key: "Scnr-Lifecycle"
                Value: "expire"
            ExpirationInDays: 1
          - Id: AbortIncompleteMultiPartUploads
            Status: Enabled
            AbortIncompleteMultipartUpload:
              DaysAfterInitiation: 1

  LogsBucketEventNotificationTopic:
    Type: AWS::SNS::Topic

  LogsBucketEventNotificationTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: s3.amazonaws.com
            Action: sns:Publish
            Resource: "*"
      Topics:
        - !Ref LogsBucketEventNotificationTopic

  LogsBucketEventNotificationTopicSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref LogsBucketEventNotificationTopic
      Endpoint: !Sub
        - "arn:aws:sqs:${InstanceRegion}:${ScannerAWSAccountID}:scnr-S3ObjectCreatedNotificationsQueue"
        - InstanceRegion: !Ref "AWS::Region"
          ScannerAWSAccountID: !Ref ScannerAWSAccountID
      Protocol: "sqs"
      RawMessageDelivery: true

  ScannerPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: ScannerPolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - s3:ListAllMyBuckets
              - s3:GetBucketLocation
              - s3:GetBucketTagging
            Resource: "*"
          - Effect: Allow
            Action:
              - s3:GetBucketEncryption
              - s3:GetBucketNotification
              - s3:ListBucket
              - s3:GetObject
              - s3:GetObjectTagging
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:aws:s3:::"
                    - Ref: S3BucketToIndex
              - Fn::Join:
                  - ""
                  - - "arn:aws:s3:::"
                    - Ref: S3BucketToIndex
                    - "/*"
          - Effect: Allow
            Action:
              - s3:GetLifecycleConfiguration
              - s3:ListBucket
              - s3:GetObject
              - s3:GetObjectTagging
              - s3:PutObject
              - s3:PutObjectTagging
              - s3:DeleteObject
              - s3:DeleteObjectTagging
              - s3:DeleteObjectVersion
              - s3:DeleteObjectVersionTagging
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:aws:s3:::scanner-index-files-"
                    - Ref: ScannerExternalID
              - Fn::Join:
                  - ""
                  - - "arn:aws:s3:::scanner-index-files-"
                    - Ref: ScannerExternalID
                    - "/*"
          - !If
            - HasS3BucketKmsKeyArn
            -
              # Add KMS permissions if there is a key
              Effect: Allow
              Action:
                - kms:Decrypt
                - kms:DescribeKey
              Resource: !Ref S3BucketKmsKeyArn
            -
              # Otherwise, omit this statement
              !Ref "AWS::NoValue"
      Roles:
        - Ref: ScannerRole

Outputs:
  ScannerRoleARN:
    Description: The ARN of the new Scanner IAM Role
    Value:
      Fn::GetAtt:
        - ScannerRole
        - Arn

  ScannerIndexFilesBucketName:
    Description: The name of the new S3 bucket that will store Scanner Index Files
    Value: !Ref ScannerIndexFilesBucket

Permissions needed to launch the CloudFormation template

To launch (and rollback) the template successfully, your IAM role will need the following IAM permissions.


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "sid1",
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:PutEncryptionConfiguration",
                "s3:PutLifecycleConfiguration",
                "s3:PutBucketPublicAccessBlock"
            ],
            "Resource": "arn:aws:s3:::scanner-index-files-*"
        },
        {
            "Sid": "sid2",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:GetRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:PutRolePolicy",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
            ],
            "Resource": [
                "arn:aws:iam::*:role/*-ScannerRole-*"
            ]
        },
        {
            "Sid": "sid3",
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackEvents",
                "cloudformation:ListStacks",
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:GetTemplateSummary"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "sid4",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketNotification",
                "s3:PutBucketNotification"
            ],
            "Resource": [
                "arn:aws:s3:::<s3_bucket_you_want_to_index>"
            ]
        }
    ]
}

If your S3 buckets are in multiple regions

If the S3 buckets that you want to index are in multiple regions, edit the CloudFormation file to do the following:

  • Create one AWS::SNS::Topic per region.

  • Create an AWS::SNS::Subscription for each SNS topic, all pointing to the same SQS queue in your Scanner instance.

Setting up bucket notifications

To allow Scanner to index log files continuously, you will need to configure your S3 buckets to send "object created" notifications to an SNS topic created by CloudFormation earlier, which will forward the notifications to an SQS queue running in your Scanner instance. Setting up bucket notifications cannot be done directly in CloudFormation without the CloudFormation stack taking full ownership of the S3 bucket, which we don't necessarily want.

Here is how to set up bucket event notifications manually using the AWS console.

Navigate to S3 > (Click on your bucket) > Properties.

Scroll down to Event notifications.

Click Create event notification

Give it an Event name. Optionally provide a Prefix and Suffix to filter down to a specific set of files.

Select the checkbox next to All object create events - s3:ObjectCreated:*.

Scroll down to Destination. Select SNS topic. Under Specify SNS topic, select Choose from your SNS topics. Select the SNS topic created by Scanner's CloudFormation template earlier:

scnr-LogsBucketEventNotificationTopic

This SNS topic is already configured with a subscription to push bucket event notifications to Scanner's SQS queue.

Click Save changes.

Object creation notifications should now be sent to your Scanner instance.

What if I already have a conflicting destination for bucket event notifications?

You might be sending bucket notifications to a different destination already, like to the SQS queue of another vendor, to a different SNS topic, or to a Lambda function.

To resolve this situation, we recommend the following configuration:

  • Configure the bucket to push event notifications to an SNS topic.

  • Configure the SNS topic to relay messages to multiple destinations by creating subscriptions:

    • Create a topic subscription for Scanner

      • Protocol: SQS

      • Endpoint: ARN of your Scanner instance's SQS queue. Your contacts on the Scanner team can give this to you.

      • Enable raw message delivery.

    • Create topic subscriptions for your other vendors and destinations.

cloudformation/2025-02/scanner.yml