diff --git a/util/org-multi-account/serverless_codebuild/templates/ProwlerCodeBuildStack.yaml b/util/org-multi-account/serverless_codebuild/templates/ProwlerCodeBuildStack.yaml new file mode 100644 index 00000000..d89c5452 --- /dev/null +++ b/util/org-multi-account/serverless_codebuild/templates/ProwlerCodeBuildStack.yaml @@ -0,0 +1,210 @@ +--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Creates a CodeBuild project to audit an AWS account with Prowler and stores the html report in a S3 bucket. +Parameters: + AwsOrgId: + Type: String + Description: Enter AWS Organizations ID + AllowedPattern: ^o-[a-z0-9]{10,32}$ + ConstraintDescription: The Org Id must be a 12 character string starting with o- and followed by 10 lower case alphanumeric characters. + Default: o-itdezkbz6h + CodeBuildRole: + Description: Enter Name for CodeBuild Role to create + Type: String + AllowedPattern: ^[\w+=,.@-]{1,64}$ + ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -] + Default: ProwlerCodeBuild-Role + CodeBuildSourceS3: + Type: String + Description: Enter like //.zip + ConstraintDescription: Max 63 characters. Can't start or end with dash. Can use numbers and lowercase letters. + Default: prowler-util-411267690458-ap-northeast-2/run-prowler-reports.sh.zip + ProwlerReportS3: + Type: String + Description: Enter S3 Bucket for Prowler Reports. prefix-awsaccount-awsregion + AllowedPattern: ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ + ConstraintDescription: Max 63 characters. Can't start or end with dash. Can use numbers and lowercase letters. + Default: prowler-954896828174-ap-northeast-2 + ProwlerReportS3Account: + Type: String + Description: Enter AWS Account Number where Prowler S3 Bucket resides. + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 954896828174 + CrossAccountRole: + Type: String + Description: Enter CrossAccount Role Prowler will be using to assess AWS Accounts in the AWS Organization. (ProwlerCrossAccountRole) + AllowedPattern: ^[\w+=,.@-]{1,64}$ + ConstraintDescription: Max 64 alphanumeric characters. Also special characters [+, =, ., @, -] + Default: ProwlerXA-CBRole + ProwlerReportFormat: + Type: String + Description: Enter Prowler Option like html, csv, json + Default: html + +Resources: + ProwlerCodeBuildRole: + Type: AWS::IAM::Role + Properties: + Description: Prowler CodeBuild Role + RoleName: !Ref CodeBuildRole + Tags: + - Key: App + Value: Prowler + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - codebuild.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: Prowler-S3 + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerReportS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerReportS3}/* + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + - s3:PutObjectAcl + - Sid: AllowReadOnlyS3Access + Effect: Allow + Resource: "*" + Action: + - "s3:Get*" + - "s3:List*" + - PolicyName: Prowler-CrossAccount-AssumeRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowStsAssumeRole + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:iam::*:role/${CrossAccountRole} + Action: sts:AssumeRole + Condition: + StringEquals: + aws:PrincipalOrgId: !Ref AwsOrgId + - PolicyName: Prowler-CloudWatch + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowCreateLogs + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:logs:*:*:log-group:* + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - Sid: AllowPutevent + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:logs:*:*:log-group:*:log-stream:* + Action: + - logs:PutLogEvents + + ProwlerCodeBuild: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + Source: + Type: S3 + Location: !Ref CodeBuildSourceS3 + BuildSpec: | + version: 0.2 + phases: + install: + runtime-versions: + python: 3.8 + commands: + - echo "Updating yum..." + - yum -y update + build: + commands: + - echo "Running Prowler with script" + - chmod +x run-prowler-reports.sh + - ./run-prowler-reports.sh + post_build: + commands: + - echo "Done!" + Environment: + # AWS CodeBuild free tier includes 100 build minutes of BUILD_GENERAL1_SMALL per month. + # BUILD_GENERAL1_SMALL: Use up to 3 GB memory and 2 vCPUs for builds. $0.005/minute. + # BUILD_GENERAL1_MEDIUM: Use up to 7 GB memory and 4 vCPUs for builds. $0.01/minute. + # BUILD_GENERAL1_LARGE: Use up to 15 GB memory and 8 vCPUs for builds. $0.02/minute. + # BUILD_GENERAL1_2XLARGE: Use up to 144 GB memory and 72 vCPUs for builds. $0.20/minute. + ComputeType: "BUILD_GENERAL1_SMALL" + Image: "aws/codebuild/amazonlinux2-x86_64-standard:3.0" + Type: "LINUX_CONTAINER" + EnvironmentVariables: + - Name: "S3" + Value: !Sub s3://${ProwlerReportS3} + Type: PLAINTEXT + - Name: "S3ACCOUNT" + Value: !Ref ProwlerReportS3Account + Type: PLAINTEXT + - Name: "ROLE" + Value: !Ref CrossAccountRole + Type: PLAINTEXT + - Name: "FORMAT" + Value: !Ref ProwlerReportFormat + Type: PLAINTEXT + Description: Run Prowler assessment + ServiceRole: !GetAtt ProwlerCodeBuildRole.Arn + TimeoutInMinutes: 300 + + ProwlerCWRuleRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - events.amazonaws.com + Action: + - sts:AssumeRole + Description: ProwlerCWRuleRole + RoleName: ProwlerCWRule-Role + Policies: + - PolicyName: Rule-Events + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AWSEventInvokeCodeBuild + Effect: Allow + Resource: "*" + Action: + - codebuild:StartBuild + + ProwlerRule: + Type: AWS::Events::Rule + Properties: + Description: This rule will trigger CodeBuild to audit AWS Accounts in my Organization with Prowler + ScheduleExpression: cron(0 21 * * ? *) + RoleArn: !GetAtt ProwlerCWRuleRole.Arn + Name: ProwlerExecuteRule + State: ENABLED + Targets: + - Arn: !Sub ${ProwlerCodeBuild.Arn} + Id: Prowler-CodeBuild-Target + RoleArn: !GetAtt ProwlerCWRuleRole.Arn + + +Outputs: + ProwlerEc2Account: + Description: AWS Account Number where Prowler EC2 Instance resides. + Value: !Ref AWS::AccountId + ProwlerCodeBuildRole: + Description: Instance Role given to the Prowler EC2 Instance (needed to grant sts:AssumeRole rights). + Value: !Ref ProwlerCodeBuildRole + ProwlerReportS3: + Description: S3 Bucket for Prowler Reports + Value: !Ref ProwlerReportS3 diff --git a/util/org-multi-account/serverless_codebuild/templates/ProwlerRole.yaml b/util/org-multi-account/serverless_codebuild/templates/ProwlerRole.yaml new file mode 100644 index 00000000..138d8809 --- /dev/null +++ b/util/org-multi-account/serverless_codebuild/templates/ProwlerRole.yaml @@ -0,0 +1,123 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create the Cross-Account IAM Prowler Role + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: CodeBuild Settings + Parameters: + - ProwlerCodeBuildAccount + - ProwlerCodeBulidRole + - Label: + default: S3 Settings + Parameters: + - ProwlerS3 + - Label: + default: CrossAccount Role + Parameters: + - ProwlerCrossAccountRole + +Parameters: + ProwlerS3: + Type: String + Description: Enter S3 Bucket for Prowler Reports. prefix-awsaccount-awsregion + AllowedPattern: ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ + Default: prowler-954896828174-ap-northeast-2 + ProwlerCodeBuildAccount: + Type: String + Description: Enter AWS Account Number where Prowler CodeBuild Instance will reside. + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 411267690458 + ProwlerCodeBulidRole: + Type: String + Description: Enter Instance Role that will be given to the Prowler CodeBuild (needed to grant sts:AssumeRole rights). + AllowedPattern: ^[\w+=,.@-]{1,64}$ + ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -] + Default: ProwlerCodeBuild-Role + ProwlerCrossAccountRole: + Type: String + Description: Enter Name for CrossAccount Role to be created for Prowler to assess all Accounts in the AWS Organization. + AllowedPattern: ^[\w+=,.@-]{1,64}$ + ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -] + Default: ProwlerXA-CBRole + +Resources: + ProwlerRole: + Type: AWS::IAM::Role + Properties: + Description: Provides Prowler CodeBuild permissions to assess security of Accounts in AWS Organization + RoleName: !Ref ProwlerCrossAccountRole + Tags: + - Key: App + Value: Prowler + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: + - !Sub arn:${AWS::Partition}:iam::${ProwlerCodeBuildAccount}:root + Action: + - sts:AssumeRole + Condition: + StringLike: + aws:PrincipalArn: !Sub arn:${AWS::Partition}:iam::${ProwlerCodeBuildAccount}:role/${ProwlerCodeBulidRole} + ManagedPolicyArns: + - !Sub arn:${AWS::Partition}:iam::aws:policy/SecurityAudit + - !Sub arn:${AWS::Partition}:iam::aws:policy/job-function/ViewOnlyAccess + Policies: + - PolicyName: Prowler-Additions-Policy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowMoreReadForProwler + Effect: Allow + Resource: "*" + Action: + - access-analyzer:List* + - apigateway:Get* + - apigatewayv2:Get* + - aws-marketplace:ViewSubscriptions + - dax:ListTables + - ds:ListAuthorizedApplications + - ds:DescribeRoles + - ecr:Describe* + - lambda:GetAccountSettings + - lambda:GetFunctionConfiguration + - lambda:GetLayerVersionPolicy + - lambda:GetPolicy + - opsworks-cm:Describe* + - opsworks:Describe* + - secretsmanager:ListSecretVersionIds + - sns:List* + - sqs:ListQueueTags + - states:ListActivities + - support:Describe* + - tag:GetTagKeys + - PolicyName: Prowler-S3-Reports + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + Metadata: + cfn_nag: + rules_to_suppress: + - id: W11 + reason: "Prowler requires these rights to perform its Security Assessment." + - id: W28 + reason: "Using a defined Role Name." + +Outputs: + ProwlerCrossAccountRole: + Description: CrossAccount Role to be used by Prowler to assess AWS Accounts in the AWS Organization. + Value: !Ref ProwlerCrossAccountRole diff --git a/util/org-multi-account/serverless_codebuild/templates/ProwlerS3.yaml b/util/org-multi-account/serverless_codebuild/templates/ProwlerS3.yaml new file mode 100644 index 00000000..fc0ef4d9 --- /dev/null +++ b/util/org-multi-account/serverless_codebuild/templates/ProwlerS3.yaml @@ -0,0 +1,106 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create Prowler S3 Bucket for Prowler Reports + +Parameters: + AwsOrgId: + Type: String + Description: > + Enter AWS Organizations ID. + This is used to restrict permissions to least privilege. + AllowedPattern: ^o-[a-z0-9]{10,32}$ + ConstraintDescription: The Org Id must be a 12 character string starting with o- and followed by 10 lower case alphanumeric characters. + Default: o-abcde12345 + S3Prefix: + Type: String + Description: > + Enter S3 Bucket Name Prefix (in lowercase). + Bucket will be named: prefix-awsaccount-awsregion (i.e., prowler-123456789012-us-east-1) + AllowedPattern: ^[a-z0-9][a-z0-9-]{1,33}[a-z0-9]$ + ConstraintDescription: > + Max 35 characters, as "-awsaccount-awsregion" will be added, and max name is 63 characters. + Can't start or end with dash. Can use numbers and lowercase letters. + Default: prowler + +Resources: + ProwlerS3: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub ${S3Prefix}-${AWS::AccountId}-${AWS::Region} + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: "AES256" + AccessControl: Private + PublicAccessBlockConfiguration: + BlockPublicAcls: True + BlockPublicPolicy: True + IgnorePublicAcls: True + RestrictPublicBuckets: True + VersioningConfiguration: + Status: Enabled + Tags: + - Key: App + Value: Prowler + Metadata: + cfn_nag: + rules_to_suppress: + - id: W35 + reason: "This S3 Bucket is only being used by the AWS Organization to download/upload prowler reports." + + ProwlerS3BucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref ProwlerS3 + PolicyDocument: + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Principal: "*" + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + - s3:PutObjectAcl + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* + Condition: + StringEquals: + aws:PrincipalOrgId: !Ref AwsOrgId + - Sid: DenyNonSSLRequests + Effect: Deny + Action: s3:* + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* + Principal: "*" + Condition: + Bool: + aws:SecureTransport: false + - Sid: DenyIncorrectEncryptionHeader + Effect: Deny + Principal: "*" + Action: s3:PutObject + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* + # Allow uploads with No Encryption, as S3 Default Encryption still applies. + # If Encryption is set, only allow uploads with AES256. + Condition: + "Null": + s3:x-amz-server-side-encryption: false + StringNotEquals: + s3:x-amz-server-side-encryption: AES256 + Metadata: + cfn_nag: + rules_to_suppress: + - id: F16 + reason: "This S3 Bucket Policy has a condition that only allows access to the AWS Organization." + + +Outputs: + ProwlerS3: + Description: S3 Bucket for Prowler Reports + Value: !Ref ProwlerS3 + ProwlerS3Account: + Description: AWS Account Number where Prowler S3 Bucket resides. + Value: !Ref AWS::AccountId