mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
AWS Organizational Prowler Deployment @tekdj7
AWS Organizational Prowler Deployment
This commit is contained in:
365
util/org-multi-account/ProwlerEC2.yaml
Normal file
365
util/org-multi-account/ProwlerEC2.yaml
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
AWSTemplateFormatVersion: 2010-09-09
|
||||||
|
Description: Create Prowler EC2 with UserData (Shell Scripts, & AWS CLI Profiles)
|
||||||
|
|
||||||
|
Metadata:
|
||||||
|
AWS::CloudFormation::Interface:
|
||||||
|
ParameterGroups:
|
||||||
|
- Label:
|
||||||
|
default: Prowler EC2 Instance Settings
|
||||||
|
Parameters:
|
||||||
|
- BuildNumber
|
||||||
|
- ProwlerEc2Name
|
||||||
|
- InstanceType
|
||||||
|
- KeyPair
|
||||||
|
- SubnetId
|
||||||
|
- VpcId
|
||||||
|
- Ec2Role
|
||||||
|
- LatestAmazonLinux2AmiId
|
||||||
|
- ProwlerCron
|
||||||
|
- Label:
|
||||||
|
default: S3 Settings
|
||||||
|
Parameters:
|
||||||
|
- ProwlerS3
|
||||||
|
- ProwlerS3Account
|
||||||
|
- Label:
|
||||||
|
default: CrossAccount Role
|
||||||
|
Parameters:
|
||||||
|
- AwsOrgId
|
||||||
|
- CrossAccountRole
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
BuildNumber:
|
||||||
|
Type: String
|
||||||
|
Description: Enter Build Number (increment with Updates for cfn-init)
|
||||||
|
AllowedPattern: ^\d*$
|
||||||
|
ConstraintDescription: Build Number must be a numeric string.
|
||||||
|
Default: 1
|
||||||
|
ProwlerEc2Name:
|
||||||
|
Type: String
|
||||||
|
Description: Enter Name for Prowler EC2 Instance to create
|
||||||
|
AllowedPattern: ^[\w\s_.\/=+-]{1,128}$
|
||||||
|
ConstraintDescription: Max 128 alphanumeric characters. Also special characters supported [whitespace, _, ., /, =, +, -]
|
||||||
|
Default: Prowler-EC2
|
||||||
|
InstanceType:
|
||||||
|
Description: Enter Instance Type
|
||||||
|
Type: String
|
||||||
|
Default: t2.micro
|
||||||
|
KeyPair:
|
||||||
|
Description: Choose a KeyPair
|
||||||
|
Type: AWS::EC2::KeyPair::KeyName
|
||||||
|
SubnetId:
|
||||||
|
Description: Choose Subnet
|
||||||
|
Type: AWS::EC2::Subnet::Id
|
||||||
|
VpcId:
|
||||||
|
Description: Choose VPC
|
||||||
|
Type: AWS::EC2::VPC::Id
|
||||||
|
Ec2Role:
|
||||||
|
Description: Enter Name for EC2 Instance Role to create and attach to Prowler EC2 Instance
|
||||||
|
Type: String
|
||||||
|
AllowedPattern: ^[\w+=,.@-]{1,64}$
|
||||||
|
ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -]
|
||||||
|
Default: ProwlerEC2-Role
|
||||||
|
ProwlerCron:
|
||||||
|
Description: Enter cron schedule. Default, runs everyday at 1am. See https://crontab.guru/, for syntax help.
|
||||||
|
Type: String
|
||||||
|
Default: "0 1 * * *"
|
||||||
|
LatestAmazonLinux2AmiId:
|
||||||
|
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
|
||||||
|
Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters.
|
||||||
|
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
|
||||||
|
|
||||||
|
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]$
|
||||||
|
ConstraintDescription: Max 63 characters. Can't start or end with dash. Can use numbers and lowercase letters.
|
||||||
|
Default: prowler-123456789012-us-east-1
|
||||||
|
ProwlerS3Account:
|
||||||
|
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: 123456789012
|
||||||
|
|
||||||
|
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-abcde12345
|
||||||
|
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-Role
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
ProwlerEc2:
|
||||||
|
Type: AWS::EC2::Instance
|
||||||
|
CreationPolicy:
|
||||||
|
ResourceSignal:
|
||||||
|
Timeout: PT5M
|
||||||
|
Properties:
|
||||||
|
KeyName: !Ref KeyPair
|
||||||
|
ImageId: !Ref LatestAmazonLinux2AmiId
|
||||||
|
IamInstanceProfile: !Ref ProwlerInstanceProfile
|
||||||
|
InstanceType: !Ref InstanceType
|
||||||
|
SubnetId: !Ref SubnetId
|
||||||
|
SecurityGroupIds:
|
||||||
|
- !Ref ProwlerSecurityGroup
|
||||||
|
BlockDeviceMappings:
|
||||||
|
- DeviceName: /dev/xvda
|
||||||
|
Ebs:
|
||||||
|
Encrypted: true
|
||||||
|
KmsKeyId: alias/aws/ebs
|
||||||
|
VolumeType: standard
|
||||||
|
DeleteOnTermination: true
|
||||||
|
VolumeSize: 8
|
||||||
|
Tags:
|
||||||
|
- Key: Name
|
||||||
|
Value: !Ref ProwlerEc2Name
|
||||||
|
- Key: App
|
||||||
|
Value: Prowler
|
||||||
|
UserData:
|
||||||
|
Fn::Base64:
|
||||||
|
!Sub |
|
||||||
|
#!/bin/bash
|
||||||
|
yum update -y aws-cfn-bootstrap
|
||||||
|
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ProwlerEc2 --configsets onfirstboot --region ${AWS::Region}
|
||||||
|
yum -y update
|
||||||
|
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ProwlerEc2 --region ${AWS::Region}
|
||||||
|
Metadata:
|
||||||
|
AWS::CloudFormation::Authentication:
|
||||||
|
S3AccessCreds:
|
||||||
|
type: S3
|
||||||
|
buckets:
|
||||||
|
- !Ref ProwlerS3
|
||||||
|
roleName:
|
||||||
|
Ref: ProwlerEc2Role
|
||||||
|
AWS::CloudFormation::Init:
|
||||||
|
configSets:
|
||||||
|
onfirstboot:
|
||||||
|
- build-number
|
||||||
|
- configure-cfn
|
||||||
|
- prowler-prereqs
|
||||||
|
- prowler-reports
|
||||||
|
- prowler-schedule
|
||||||
|
onupdate:
|
||||||
|
- build-number
|
||||||
|
- prowler-prereqs
|
||||||
|
- prowler-reports
|
||||||
|
- prowler-schedule
|
||||||
|
build-number:
|
||||||
|
commands:
|
||||||
|
show-build-number:
|
||||||
|
command: !Sub |
|
||||||
|
echo "BUILDNUMBER: ${BuildNumber}"
|
||||||
|
configure-cfn:
|
||||||
|
files:
|
||||||
|
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
|
||||||
|
content: !Sub |
|
||||||
|
[cfn-auto-reloader-hook]
|
||||||
|
triggers=post.update
|
||||||
|
path=Resources.ProwlerEc2.Metadata.AWS::CloudFormation::Init
|
||||||
|
action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ProwlerEc2 --configsets onupdate --region ${AWS::Region}
|
||||||
|
runas=root
|
||||||
|
mode: "000400"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
/etc/cfn/cfn-hup.conf:
|
||||||
|
content: !Sub |
|
||||||
|
[main]
|
||||||
|
stack=${AWS::StackId}
|
||||||
|
region=${AWS::Region}
|
||||||
|
verbose=true
|
||||||
|
interval=5
|
||||||
|
mode: "000400"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
services:
|
||||||
|
sysvinit:
|
||||||
|
cfn-hup:
|
||||||
|
enabled: true
|
||||||
|
ensureRunning: true
|
||||||
|
files:
|
||||||
|
- /etc/cfn/cfn-hup.conf
|
||||||
|
- /etc/cfn/hooks.d/cfn-auto-reloader.conf
|
||||||
|
prowler-prereqs:
|
||||||
|
files:
|
||||||
|
/home/ec2-user/.awsvariables:
|
||||||
|
content: !Sub |
|
||||||
|
export S3=s3://${ProwlerS3}
|
||||||
|
export S3ACCOUNT=${ProwlerS3Account}
|
||||||
|
export ROLE=${CrossAccountRole}
|
||||||
|
mode: "000600"
|
||||||
|
owner: ec2-user
|
||||||
|
group: ec2-user
|
||||||
|
commands:
|
||||||
|
01-install-prowler-prereqs-yum:
|
||||||
|
command: |
|
||||||
|
yum install python-pip git jq -y
|
||||||
|
02-install-prowler-prereqs-pip:
|
||||||
|
command: |
|
||||||
|
sudo -u ec2-user pip install --user boto3 awscli detect-secrets
|
||||||
|
prowler-reports:
|
||||||
|
files:
|
||||||
|
/home/ec2-user/run-prowler-reports.sh:
|
||||||
|
source: !Sub https://${ProwlerS3}.s3.${AWS::Region}.amazonaws.com/run-prowler-reports.sh
|
||||||
|
mode: "000700"
|
||||||
|
owner: ec2-user
|
||||||
|
group: ec2-user
|
||||||
|
prowler-schedule:
|
||||||
|
files:
|
||||||
|
/home/ec2-user/mycron-prowler:
|
||||||
|
content: !Sub |
|
||||||
|
${ProwlerCron} bash -lc ./run-prowler-reports.sh > mycron-prowler.log
|
||||||
|
mode: "000600"
|
||||||
|
owner: ec2-user
|
||||||
|
group: ec2-user
|
||||||
|
commands:
|
||||||
|
01-create-prowler-cron-job:
|
||||||
|
command: |
|
||||||
|
sudo -u ec2-user crontab /home/ec2-user/mycron-prowler
|
||||||
|
|
||||||
|
ProwlerSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
GroupName: Prowler-EC2-RemoteAdministration
|
||||||
|
GroupDescription: Allow Remote Administration
|
||||||
|
Tags:
|
||||||
|
- Key: App
|
||||||
|
Value: Prowler
|
||||||
|
VpcId: !Ref VpcId
|
||||||
|
SecurityGroupEgress:
|
||||||
|
- Description: Allow HTTP Outbound
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 80
|
||||||
|
ToPort: 80
|
||||||
|
CidrIp: 0.0.0.0/0
|
||||||
|
- Description: Allow HTTPS Outbound
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 443
|
||||||
|
ToPort: 443
|
||||||
|
CidrIp: 0.0.0.0/0
|
||||||
|
Metadata:
|
||||||
|
cfn_nag:
|
||||||
|
rules_to_suppress:
|
||||||
|
- id: W5
|
||||||
|
reason: "Using http/https to Internet for updates."
|
||||||
|
- id: W28
|
||||||
|
reason: "Using a defined Security Group Name."
|
||||||
|
|
||||||
|
ProwlerInstanceProfile:
|
||||||
|
Type: AWS::IAM::InstanceProfile
|
||||||
|
Properties:
|
||||||
|
Roles:
|
||||||
|
- !Ref ProwlerEc2Role
|
||||||
|
|
||||||
|
ProwlerEc2Role:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
Description: Prowler EC2 Instance Role
|
||||||
|
RoleName: !Ref Ec2Role
|
||||||
|
Tags:
|
||||||
|
- Key: App
|
||||||
|
Value: Prowler
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Principal:
|
||||||
|
Service:
|
||||||
|
- ec2.amazonaws.com
|
||||||
|
Action:
|
||||||
|
- sts:AssumeRole
|
||||||
|
Policies:
|
||||||
|
- PolicyName: SSM-Agent
|
||||||
|
PolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Sid: AllowSsmAgent
|
||||||
|
Effect: Allow
|
||||||
|
Resource: "*"
|
||||||
|
Action:
|
||||||
|
- ssm:UpdateInstanceInformation
|
||||||
|
- ssm:ListInstanceAssociations
|
||||||
|
- ssm:UpdateInstanceAssociationStatus
|
||||||
|
- ssm:PutConfigurePackageResult
|
||||||
|
- ssm:GetManifest
|
||||||
|
- ssm:PutComplianceItems
|
||||||
|
- ec2messages:AcknowledgeMessage
|
||||||
|
- ec2messages:DeleteMessage
|
||||||
|
- ec2messages:FailMessage
|
||||||
|
- ec2messages:GetEndpoint
|
||||||
|
- ec2messages:GetMessages
|
||||||
|
- ec2messages:SendReply
|
||||||
|
- PolicyName: SSM-Inventory
|
||||||
|
PolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Sid: AllowPutInventory
|
||||||
|
Effect: Allow
|
||||||
|
Resource: "*"
|
||||||
|
Action:
|
||||||
|
- ssm:PutInventory
|
||||||
|
- Sid: AllowGatherInventory
|
||||||
|
Effect: Allow
|
||||||
|
Resource: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}::document/AWS-GatherSoftwareInventory
|
||||||
|
Action:
|
||||||
|
- ssm:GetDocument
|
||||||
|
- ssm:DescribeDocument
|
||||||
|
- PolicyName: SSM-SessionManager
|
||||||
|
PolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Sid: AllowSessionManager
|
||||||
|
Effect: Allow
|
||||||
|
Resource: "*"
|
||||||
|
Action:
|
||||||
|
- ssmmessages:CreateControlChannel
|
||||||
|
- ssmmessages:CreateDataChannel
|
||||||
|
- ssmmessages:OpenControlChannel
|
||||||
|
- ssmmessages:OpenDataChannel
|
||||||
|
- 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
|
||||||
|
- 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
|
||||||
|
Metadata:
|
||||||
|
cfn_nag:
|
||||||
|
rules_to_suppress:
|
||||||
|
- id: W28
|
||||||
|
reason: "Using a defined Role Name."
|
||||||
|
- id: W11
|
||||||
|
reason: "Needed for SSM features."
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
ProwlerEc2Account:
|
||||||
|
Description: AWS Account Number where Prowler EC2 Instance resides.
|
||||||
|
Value: !Ref AWS::AccountId
|
||||||
|
ProwlerEc2Role:
|
||||||
|
Description: Instance Role given to the Prowler EC2 Instance (needed to grant sts:AssumeRole rights).
|
||||||
|
Value: !Ref ProwlerEc2Role
|
||||||
|
ProwlerS3:
|
||||||
|
Description: S3 Bucket for Prowler Reports
|
||||||
|
Value: !Ref ProwlerS3
|
||||||
123
util/org-multi-account/ProwlerRole.yaml
Normal file
123
util/org-multi-account/ProwlerRole.yaml
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
AWSTemplateFormatVersion: 2010-09-09
|
||||||
|
Description: Create the Cross-Account IAM Prowler Role
|
||||||
|
|
||||||
|
Metadata:
|
||||||
|
AWS::CloudFormation::Interface:
|
||||||
|
ParameterGroups:
|
||||||
|
- Label:
|
||||||
|
default: EC2 Settings
|
||||||
|
Parameters:
|
||||||
|
- ProwlerEc2Account
|
||||||
|
- ProwlerEc2Role
|
||||||
|
- 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-123456789012-us-east-1
|
||||||
|
ProwlerEc2Account:
|
||||||
|
Type: String
|
||||||
|
Description: Enter AWS Account Number where Prowler EC2 Instance will reside.
|
||||||
|
AllowedPattern: ^\d{12}$
|
||||||
|
ConstraintDescription: An AWS Account Number must be a 12 digit numeric string.
|
||||||
|
ProwlerEc2Role:
|
||||||
|
Type: String
|
||||||
|
Description: Enter Instance Role that will be given to the Prowler EC2 Instance (needed to grant sts:AssumeRole rights).
|
||||||
|
AllowedPattern: ^[\w+=,.@-]{1,64}$
|
||||||
|
ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -]
|
||||||
|
Default: ProwlerEC2-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-Role
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
ProwlerRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
Description: Provides Prowler EC2 instance 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::${ProwlerEc2Account}:root
|
||||||
|
Action:
|
||||||
|
- sts:AssumeRole
|
||||||
|
Condition:
|
||||||
|
StringLike:
|
||||||
|
aws:PrincipalArn: !Sub arn:${AWS::Partition}:iam::${ProwlerEc2Account}:role/${ProwlerEc2Role}
|
||||||
|
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
|
||||||
|
- ec2:GetEbsEncryptionByDefault
|
||||||
|
- 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
|
||||||
105
util/org-multi-account/ProwlerS3.yaml
Normal file
105
util/org-multi-account/ProwlerS3.yaml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
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
|
||||||
|
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
|
||||||
151
util/org-multi-account/README.md
Normal file
151
util/org-multi-account/README.md
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
# Example Solution: Organizational Prowler Deployment
|
||||||
|
|
||||||
|
Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in an AWS Organization on a schedule, creates assessment reports in HTML, and stores them in an S3 bucket.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Solution Goals
|
||||||
|
|
||||||
|
- Using minimal technologies, so solution can be more easily adopted, and further enhanced as needed.
|
||||||
|
- [Amazon EC2](https://aws.amazon.com/ec2/), to run Prowler
|
||||||
|
- [Amazon S3](https://aws.amazon.com/s3/), to store Prowler script & reports.
|
||||||
|
- [AWS CloudFormation](https://aws.amazon.com/cloudformation/), to provision the AWS resources.
|
||||||
|
- [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html), Optional, but recommended, to manage the Prowler EC2 instance, without having to allow inbound ssh.
|
||||||
|
- Staying cohesive with Prowler, for scripting, only leveraging:
|
||||||
|
- Bash Shell
|
||||||
|
- AWS CLI
|
||||||
|
- Adhering to the principle of least privilege.
|
||||||
|
- Supporting an AWS Multi-Account approach
|
||||||
|
- Runs Prowler against All accounts in the AWS Organization
|
||||||
|
- ***NOTE: If using this solution, you are responsible for making your own independent assessment of the solution and ensuring it complies with your company security and operational standards.***
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
1. [ProwlerS3.yaml](ProwlerS3.yaml)
|
||||||
|
- Creates Private S3 Bucket for Prowler script and reports.
|
||||||
|
- Enables [Amazon S3 Block Public Access](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html)
|
||||||
|
- Enables SSE-S3 with [Amazon S3 Default Encryption](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html)
|
||||||
|
- Versioning Enabled
|
||||||
|
- Bucket Policy limits API actions to Principals from the same AWS Organization.
|
||||||
|
1. [ProwlerRole.yaml](ProwlerRole.yaml)
|
||||||
|
- Creates Cross-Account Role for Prowler to assess accounts in AWS Organization
|
||||||
|
- Allows Role to be assumed by the Prowler EC2 instance role in the AWS account where Prowler EC2 resides (preferably the Audit/Security account).
|
||||||
|
- Role has [permissions](https://github.com/toniblyx/prowler#custom-iam-policy) needed for Prowler to assess accounts.
|
||||||
|
- Role has rights to Prowler S3 from Component #1.
|
||||||
|
1. [ProwlerEC2.yaml](ProwlerEC2.yaml)
|
||||||
|
- Creates Prowler EC2 instance
|
||||||
|
- Uses the Latest Amazon Linux 2 AMI
|
||||||
|
- Uses ```t2.micro``` Instance Type
|
||||||
|
- Encrypts Root Volume with AWS Managed Key "aws/ebs"
|
||||||
|
- Uses [cfn-init](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-init.html) for prepping the Prowler EC2
|
||||||
|
- Installs necessary [packages](https://github.com/toniblyx/prowler#requirements-and-installation) for Prowler
|
||||||
|
- Downloads [run-prowler-reports.sh](src/run-prowler-reports.sh) script from Prowler S3 from Component #1.
|
||||||
|
- Creates ```/home/ec2-user/.awsvariables```, to store CloudFormation data as variables to be used in script.
|
||||||
|
- Creates cron job for Prowler to run on a schedule.
|
||||||
|
- Creates Prowler Security Group
|
||||||
|
- Denies inbound access. If using ssh to manage Prowler, then update Security Group with pertinent rule.
|
||||||
|
- Allows outbound 80/443 for updates, and Amazon S3 communications -
|
||||||
|
- Creates Instance Role that is used for Prowler EC2
|
||||||
|
- Role has permissions for [Systems Manager Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) communications, and [Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)
|
||||||
|
- Role has rights to Prowler S3 from Component #1.
|
||||||
|
- Role has rights to Assume Cross-Account Role from Component #2.
|
||||||
|
1. [run-prowler-reports.sh](src/run-prowler-reports.sh)
|
||||||
|
- Script is documented accordingly.
|
||||||
|
- Script loops through all AWS Accounts in AWS Organization, and by default, Runs Prowler as follows:
|
||||||
|
- -R: used to specify Cross-Account role for Prowler to assume to run its assessment.
|
||||||
|
- -A: used to specify AWS Account number for Prowler to run assessment against.
|
||||||
|
- -g cislevel1: used to specify cislevel1 checks for Prowler to assess
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 -M html
|
||||||
|
```
|
||||||
|
|
||||||
|
- NOTE: Script can be modified to run Prowler as desired.
|
||||||
|
- Script runs Prowler against 1 AWS Account at a time.
|
||||||
|
- Update PARALLEL_ACCOUNTS variable in script, to specify how many Accounts to assess with Prowler in parallel.
|
||||||
|
- If running against multiple AWS Accounts in parallel, monitor performance, and upgrade Instance Type as necessary.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PARALLEL_ACCOUNTS="1"
|
||||||
|
```
|
||||||
|
|
||||||
|
- In summary:
|
||||||
|
- Download latest version of [Prowler](https://github.com/toniblyx/prowler)
|
||||||
|
- Find AWS Master Account
|
||||||
|
- Lookup All Accounts in AWS Organization
|
||||||
|
- Run Prowler against All Accounts in AWS Organization
|
||||||
|
- Save Reports to reports prefix in S3 from Component #1
|
||||||
|
- Report Names: date+time-accountid-report.html
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Deploy [ProwlerS3.yaml](ProwlerS3.yaml) in the Logging Account.
|
||||||
|
- Could be deployed to any account in the AWS Organizations, if desired.
|
||||||
|
- See [How to get AWS Organization ID](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_details.html#orgs_view_org)
|
||||||
|
- Take Note of CloudFormation Outputs, that will be needed in deploying the below CloudFormation templates.
|
||||||
|
1. Upload [run-prowler-reports.sh](src/run-prowler-reports.sh) to the root of the S3 Bucket created in Step #1.
|
||||||
|
1. Deploy [ProwlerRole.yaml](ProwlerRole.yaml) in the Master Account
|
||||||
|
- Use CloudFormation Stacks, to deploy to Master Account, as organizational StackSets don't apply to the Master Account.
|
||||||
|
- Use CloudFormation StackSet, to deploy to all Member Accounts. See [Create Stack Set with Service-Managed Permissions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html#stacksets-orgs-associate-stackset-with-org)
|
||||||
|
- Take Note of CloudFormation Outputs, that will be needed in deploying the below CloudFormation templates.
|
||||||
|
1. Deploy [ProwlerEC2.yaml](ProwlerEC2.yaml) in the Audit/Security Account
|
||||||
|
- Could be deployed to any account in the AWS Organizations, if desired.
|
||||||
|
1. Prowler will run against all Accounts in AWS Organization, per the schedule you provided, and set in a cron job for ```ec2-user```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Post-Setup
|
||||||
|
|
||||||
|
### Run Prowler on a Schedule against all Accounts in AWS Organization
|
||||||
|
|
||||||
|
1. Prowler will run on the Schedule you provided.
|
||||||
|
1. Cron job for ```ec2-user``` is managing the schedule.
|
||||||
|
1. This solution implemented this automatically. Nothing for you to do.
|
||||||
|
|
||||||
|
### Ad hoc Run Prowler against all Accounts in AWS Organization
|
||||||
|
|
||||||
|
1. Connect to Prowler EC2 Instance
|
||||||
|
- If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash``` and ```su - ec2-user```
|
||||||
|
- If using SSH, then login as ```ec2-user```
|
||||||
|
1. Run Prowler Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/ec2-user
|
||||||
|
./run-prowler-reports.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ad hoc Run Prowler Interactively
|
||||||
|
|
||||||
|
1. Connect to Prowler EC2 Instance
|
||||||
|
- If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash``` and ```su - ec2-user```
|
||||||
|
- If using SSH, then login as ```ec2-user```
|
||||||
|
1. See Cross-Account Role and S3 Bucket being used for Prowler
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/ec2-user
|
||||||
|
cat .awsvariables
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run Prowler interactively. See [Usage Examples](https://github.com/toniblyx/prowler#usage)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/ec2-user
|
||||||
|
./prowler/prowler
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upgrading Prowler to Latest Version
|
||||||
|
|
||||||
|
1. Connect to Prowler EC2 Instance
|
||||||
|
- If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash``` and ```su - ec2-user```
|
||||||
|
- If using SSH, then login as ```ec2-user```
|
||||||
|
1. Delete the existing version of Prowler, and download the latest version of Prowler
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/ec2-user
|
||||||
|
rm -rf prowler
|
||||||
|
git clone https://github.com/toniblyx/prowler.git
|
||||||
|
```
|
||||||
109
util/org-multi-account/src/run-prowler-reports.sh
Normal file
109
util/org-multi-account/src/run-prowler-reports.sh
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
#
|
||||||
|
# Run Prowler against All AWS Accounts in an AWS Organization
|
||||||
|
|
||||||
|
# Change Directory (rest of the script, assumes your in the ec2-user home directory)
|
||||||
|
cd /home/ec2-user || exit
|
||||||
|
|
||||||
|
# Show Prowler Version, and Download Prowler, if it doesn't already exist
|
||||||
|
if ! ./prowler/prowler -V 2>/dev/null; then
|
||||||
|
git clone https://github.com/toniblyx/prowler.git
|
||||||
|
./prowler/prowler -V
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Source .awsvariables (to read in Environment Variables from CloudFormation Data)
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source .awsvariables
|
||||||
|
|
||||||
|
# Get Values from Environment Variables Created on EC2 Instance from CloudFormation Data
|
||||||
|
echo "S3: $S3"
|
||||||
|
echo "S3ACCOUNT: $S3ACCOUNT"
|
||||||
|
echo "ROLE: $ROLE"
|
||||||
|
|
||||||
|
# CleanUp Last Ran Prowler Reports, as they are already stored in S3.
|
||||||
|
rm -rf prowler/output/*.html
|
||||||
|
|
||||||
|
# Function to unset AWS Profile Variables
|
||||||
|
unset_aws() {
|
||||||
|
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
unset_aws
|
||||||
|
|
||||||
|
# Find THIS Account AWS Number
|
||||||
|
CALLER_ARN=$(aws sts get-caller-identity --output text --query "Arn")
|
||||||
|
PARTITION=$(echo "$CALLER_ARN" | cut -d: -f2)
|
||||||
|
THISACCOUNT=$(echo "$CALLER_ARN" | cut -d: -f5)
|
||||||
|
echo "THISACCOUNT: $THISACCOUNT"
|
||||||
|
echo "PARTITION: $PARTITION"
|
||||||
|
|
||||||
|
# Function to Assume Role to THIS Account & Create Session
|
||||||
|
this_account_session() {
|
||||||
|
unset_aws
|
||||||
|
role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$THISACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json)
|
||||||
|
AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId)
|
||||||
|
AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey)
|
||||||
|
AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken)
|
||||||
|
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find AWS Master Account
|
||||||
|
this_account_session
|
||||||
|
AWSMASTER=$(aws organizations describe-organization --query Organization.MasterAccountId --output text)
|
||||||
|
echo "AWSMASTER: $AWSMASTER"
|
||||||
|
|
||||||
|
# Function to Assume Role to Master Account & Create Session
|
||||||
|
master_account_session() {
|
||||||
|
unset_aws
|
||||||
|
role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$AWSMASTER":role/"$ROLE" --role-session-name ProwlerRun --output json)
|
||||||
|
AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId)
|
||||||
|
AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey)
|
||||||
|
AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken)
|
||||||
|
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
# Lookup All Accounts in AWS Organization
|
||||||
|
master_account_session
|
||||||
|
ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[*].Id --output text)
|
||||||
|
|
||||||
|
# Function to Assume Role to S3 Account & Create Session
|
||||||
|
s3_account_session() {
|
||||||
|
unset_aws
|
||||||
|
role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$S3ACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json)
|
||||||
|
AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId)
|
||||||
|
AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey)
|
||||||
|
AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken)
|
||||||
|
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Prowler against Accounts in AWS Organization
|
||||||
|
echo "AWS Accounts in Organization"
|
||||||
|
echo "$ACCOUNTS_IN_ORGS"
|
||||||
|
PARALLEL_ACCOUNTS="1"
|
||||||
|
for accountId in $ACCOUNTS_IN_ORGS; do
|
||||||
|
# shellcheck disable=SC2015
|
||||||
|
test "$(jobs | wc -l)" -ge $PARALLEL_ACCOUNTS && wait || true
|
||||||
|
{
|
||||||
|
START_TIME=$SECONDS
|
||||||
|
# Unset AWS Profile Variables
|
||||||
|
unset_aws
|
||||||
|
# Run Prowler
|
||||||
|
echo -e "Assessing AWS Account: $accountId, using Role: $ROLE on $(date)"
|
||||||
|
# remove -g cislevel for a full report and add other formats if needed
|
||||||
|
./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 -M html
|
||||||
|
echo "Report stored locally at: prowler/output/ directory"
|
||||||
|
# Upload Prowler Report to S3
|
||||||
|
s3_account_session
|
||||||
|
aws s3 cp prowler/output/ "$S3/reports/" --recursive --include "*.html"
|
||||||
|
TOTAL_SEC=$((SECONDS - START_TIME))
|
||||||
|
echo -e "Completed AWS Account: $accountId, using Role: $ROLE on $(date)"
|
||||||
|
printf "Completed AWS Account: $accountId in %02dh:%02dm:%02ds" $((TOTAL_SEC / 3600)) $((TOTAL_SEC % 3600 / 60)) $((TOTAL_SEC % 60))
|
||||||
|
echo ""
|
||||||
|
} &
|
||||||
|
done
|
||||||
|
|
||||||
|
# Wait for All Prowler Processes to finish
|
||||||
|
wait
|
||||||
|
echo "Prowler Assessments Completed against All Accounts in the AWS Organization"
|
||||||
|
|
||||||
|
# Unset AWS Profile Variables
|
||||||
|
unset_aws
|
||||||
Reference in New Issue
Block a user