From 200bbf9a7dda534e8d59717c782369a0cb25c59f Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Tue, 28 Apr 2020 00:47:42 -0400 Subject: [PATCH 01/29] org-multi-account initial commit --- util/org-multi-account/ProwlerEC2.yaml | 449 ++++++++++++++++++ util/org-multi-account/ProwlerRole.yaml | 116 +++++ util/org-multi-account/ProwlerS3.yaml | 72 +++ .../src/run-prowler-reports-v4.sh | 93 ++++ 4 files changed, 730 insertions(+) create mode 100644 util/org-multi-account/ProwlerEC2.yaml create mode 100644 util/org-multi-account/ProwlerRole.yaml create mode 100644 util/org-multi-account/ProwlerS3.yaml create mode 100644 util/org-multi-account/src/run-prowler-reports-v4.sh diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml new file mode 100644 index 00000000..c33f9895 --- /dev/null +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -0,0 +1,449 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create Prowler EC2 with UserData (Shell Scripts, & AWS CLI Profiles) + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: EC2 Instance Settings + Parameters: + - BuildNumber + - Ec2Name + - InstanceType + - KeyPair + - SubnetId + - VpcId + - Ec2Role + - LatestAmazonLinux2AmiId + - ProwlerCron + - Label: + default: S3 Settings + Parameters: + - S3 + - S3Account + - 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 + Ec2Name: + Type: String + Description: Enter Name for EC2 Instance to create + Default: Prowler-EC2 + InstanceType: + Description: Enter Instance Type + Type: String + Default: t2.micro + KeyPair: + Description: Choose a KeyPair + Type: AWS::EC2::KeyPair::KeyName + Default: delgjul-labctaudit + SubnetId: + Description: Choose Subnet + Type: AWS::EC2::Subnet::Id + Default: subnet-04dfbeda2dc588875 + VpcId: + Description: Choose VPC + Type: AWS::EC2::VPC::Id + Default: vpc-0285f35dd91ac4c58 + Ec2Role: + Description: Enter Name for EC2 Instance Role to create + Type: String + Default: ProwlerEC2-Role + ProwlerCron: + Description: Enter cron schedule. Default, runs everyday at 1am. See https://crontab.guru/, for syntax help. + Type: String + Default: 10 * * * * + LatestAmazonLinux2AmiId: + Type: AWS::SSM::Parameter::Value + 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 + + S3: + Type: String + Description: Enter S3 Bucket to grant rights to EC2 Instance + Default: prowler-417425889548-us-east-1 + S3Account: + Type: String + Description: Enter AWS Account Number where S3 Bucket resides + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 417425889548 + + 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-nbfb46ay7u + CrossAccountRole: + Type: String + Description: Enter CrossAccount Role you will be using across the AWS Organization + 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 + Tags: + - Key: Name + Value: !Ref Ec2Name + 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 S3 + 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://${S3} + export S3ACCOUNT=${S3Account} + 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 ansi2html detect-secrets + prowler-reports: + files: + # /home/ec2-user/run-prowler-reports-v4.sh: + # source: !Sub https://${S3}.s3.${AWS::Region}.amazonaws.com/run-prowler-reports-v4.sh + # mode: "000700" + # owner: ec2-user + # group: ec2-user + /home/ec2-user/run-prowler.sh: + content: | + #!/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 + + # Download Prowler + rm -rf prowler + git clone https://github.com/toniblyx/prowler.git + + # 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" + + # Create Folder to Store Prowler Reports + mkdir -p prowler-reports + + # CleanUp Last Ran Prowler Reports + rm -rf prowler-reports/*.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 + THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) + PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) + 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" + for accountId in $ACCOUNTS_IN_ORGS; do + # Unset AWS Profile Variables + unset_aws + # Run Prowler + Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" + echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" + ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" + echo "Report stored locally at: $Report" + # Upload Prowler Report to S3 + s3_account_session + aws s3 cp "$Report" "$S3/reports/" + echo "" + done + + mode: "000700" + owner: ec2-user + group: ec2-user + + prowler-schedule: + files: + /home/ec2-user/prowlercron: + content: !Sub | + ${ProwlerCron} run-prowler-reports-v4.sh + mode: "000600" + owner: ec2-user + group: ec2-user + commands: + 01-create-prowler-cron-job: + command: | + sudo -u ec2-user crontab /home/ec2-user/prowlercron + + ProwlerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupName: Prowler-EC2-RemoteAdministration + GroupDescription: Allow Remote Administration + VpcId: !Ref VpcId + SecurityGroupIngress: + - Description: Allow SSH Administration + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourcePrefixListId: pl-60b85b09 + 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: + RoleName: !Ref Ec2Role + 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:::${S3} + - !Sub arn:${AWS::Partition}:s3:::${S3}/* + 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 where Prowler EC2 resides + Value: !Ref AWS::AccountId + ProwlerEc2Role: + Description: Prowler EC2 Instance Role + Value: !Ref ProwlerEc2Role + ProwlerS3: + Description: S3 Bucket for Prowler Reports + Value: !Ref S3 diff --git a/util/org-multi-account/ProwlerRole.yaml b/util/org-multi-account/ProwlerRole.yaml new file mode 100644 index 00000000..0ca8997d --- /dev/null +++ b/util/org-multi-account/ProwlerRole.yaml @@ -0,0 +1,116 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create the Cross-Account IAM Prowler Role + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: EC2 Settings + Parameters: + - Ec2Account + - Ec2Role + - Label: + default: S3 Settings + Parameters: + - S3 + - Label: + default: CrossAccount Role + Parameters: + - CrossAccountRole + +Parameters: + S3: + Type: String + Description: Enter S3 Bucket to grant rights to EC2 Instance + Default: prowler-417425889548-us-east-1 + Ec2Account: + Type: String + Description: Enter AWS Account Number where EC2 Instance resides + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 544425379660 + Ec2Role: + Type: String + Description: Enter Instance Role given to EC2 Instance (to grant sts:AssumeRole rights). + Default: ProwlerEC2-Role + CrossAccountRole: + Type: String + Description: Enter Name for CrossAccount Role to be created + Default: ProwlerXA-Role + +Resources: + ProwlerRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Ref CrossAccountRole + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: + # - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} + - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:root + Action: + - sts:AssumeRole + Condition: + StringLike: + aws:PrincipalArn: !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} + 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:::${S3} + - !Sub arn:${AWS::Partition}:s3:::${S3}/* + 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: Prowler CrossAccount Role + Value: !Ref CrossAccountRole diff --git a/util/org-multi-account/ProwlerS3.yaml b/util/org-multi-account/ProwlerS3.yaml new file mode 100644 index 00000000..e30eab9f --- /dev/null +++ b/util/org-multi-account/ProwlerS3.yaml @@ -0,0 +1,72 @@ +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-nbfb46ay7u + S3Prefix: + Type: String + Description: > + Enter S3 Bucket Name Prefix (in lowercase). + Bucket will be named: prefix-accountid-region + 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 + 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 + 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 S3 Resides + Value: !Ref AWS::AccountId diff --git a/util/org-multi-account/src/run-prowler-reports-v4.sh b/util/org-multi-account/src/run-prowler-reports-v4.sh new file mode 100644 index 00000000..4fc05b6c --- /dev/null +++ b/util/org-multi-account/src/run-prowler-reports-v4.sh @@ -0,0 +1,93 @@ +#!/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 + +# Download Prowler +rm -rf prowler +git clone https://github.com/toniblyx/prowler.git + +# 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" + +# Create Folder to Store Prowler Reports +mkdir -p prowler-reports + +# CleanUp Last Ran Prowler Reports +rm -rf prowler-reports/*.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 +THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) +PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) +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" +for accountId in $ACCOUNTS_IN_ORGS; do + # Unset AWS Profile Variables + unset_aws + # Run Prowler + Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" + echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" + ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" + echo "Report stored locally at: $Report" + # Upload Prowler Report to S3 + s3_account_session + aws s3 cp "$Report" "$S3/reports/" + echo "" +done From 09e4feb09568cc7cb67582712a3442b5fbdc4d04 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Tue, 28 Apr 2020 12:35:57 -0400 Subject: [PATCH 02/29] stopped embedding script into CF, download script --- util/org-multi-account/ProwlerEC2.yaml | 106 +------------------------ 1 file changed, 3 insertions(+), 103 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index c33f9895..5ef07d70 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -189,116 +189,16 @@ Resources: sudo -u ec2-user pip install --user boto3 awscli ansi2html detect-secrets prowler-reports: files: - # /home/ec2-user/run-prowler-reports-v4.sh: - # source: !Sub https://${S3}.s3.${AWS::Region}.amazonaws.com/run-prowler-reports-v4.sh - # mode: "000700" - # owner: ec2-user - # group: ec2-user - /home/ec2-user/run-prowler.sh: - content: | - #!/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 - - # Download Prowler - rm -rf prowler - git clone https://github.com/toniblyx/prowler.git - - # 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" - - # Create Folder to Store Prowler Reports - mkdir -p prowler-reports - - # CleanUp Last Ran Prowler Reports - rm -rf prowler-reports/*.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 - THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) - PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) - 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" - for accountId in $ACCOUNTS_IN_ORGS; do - # Unset AWS Profile Variables - unset_aws - # Run Prowler - Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" - echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" - ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" - echo "Report stored locally at: $Report" - # Upload Prowler Report to S3 - s3_account_session - aws s3 cp "$Report" "$S3/reports/" - echo "" - done - + /home/ec2-user/run-prowler-reports.sh: + source: !Sub https://${S3}.s3.${AWS::Region}.amazonaws.com/run-prowler-reports.sh mode: "000700" owner: ec2-user group: ec2-user - prowler-schedule: files: /home/ec2-user/prowlercron: content: !Sub | - ${ProwlerCron} run-prowler-reports-v4.sh + ${ProwlerCron} run-prowler-reports.sh mode: "000600" owner: ec2-user group: ec2-user From 94b978a934de562e5205a177e2b5ed4c3eaa6a8a Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Tue, 28 Apr 2020 12:36:10 -0400 Subject: [PATCH 03/29] renamed --- util/org-multi-account/README.md | 83 +++++++++++++++++++ ...r-reports-v4.sh => run-prowler-reports.sh} | 0 2 files changed, 83 insertions(+) create mode 100644 util/org-multi-account/README.md rename util/org-multi-account/src/{run-prowler-reports-v4.sh => run-prowler-reports.sh} (100%) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md new file mode 100644 index 00000000..8cd71b14 --- /dev/null +++ b/util/org-multi-account/README.md @@ -0,0 +1,83 @@ +# Organizational Prowler Deployment + +Created by: Julio Delgado Jr. + +Deploys Prowler to assess all Accounts in an AWS Organization. + +[Prowler](https://github.com/toniblyx/prowler) is an independent third-party command line tool for AWS Security Best Practices Assessment, Auditing, Hardening, and Forensic Readiness. It evaluates guidelines of the CIS Amazon Web Services Foundations Benchmark and dozens of additional checks, including for GDPR, and HIPAA. + +--- + +## Solution Goals + +- Use 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 +- Adhere to the principle of least privilege. +- Support an AWS Multi-Account approach + - Runs Prowler against All accounts in the AWS Organization + +--- + +## Components + +1. [ProwlerS3.yaml](util\org-multi-account\ProwlerS3.yaml) + - Creates Private S3 Bucket for Prowler script and reports. + - Public Access Block permissions enabled. + - SSE-S3 used for encryption + - Versioning Enabled + - Bucket Policy only grants GetObject, PutObject, and ListObject to Principals from the same AWS Organization. +1. [ProwlerRole.yaml](util\org-multi-account\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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. +1. [ProwlerEC2.yaml](util\org-multi-account\ProwlerEC2.yaml) + - Creates Prowler EC2 instance + - Uses the Latest Amazon Linux 2 AMI + - Uses "t2.micro" Instance Type + - 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](util\org-multi-account\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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. + - Role has rights to Assume Cross-Account Role from Component #2. +1. [run-prowler-reports.sh](util\org-multi-account\src\run-prowler-reports.sh) + - Script is documented accordingly. + - 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](util\org-multi-account\ProwlerS3.yaml) in the Logging Account. + - Could be deployed to any account in the AWS Organizations, if desired. +1. Upload [run-prowler-reports.sh](util\org-multi-account\src\run-prowler-reports.sh) to the root of the S3 Bucket created in Step #1. +1. Deploy [ProwlerRole.yaml](util\org-multi-account\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. +1. Deploy [ProwlerEC2.yaml](util\org-multi-account\ProwlerEC2.yaml) in the Audit/Security Account + - Could be deployed to any account in the AWS Organizations, if desired. +1. Scheduled: Run Prowler against all Accounts in AWS Organization, based on schedule you provided, and set for the cron job. +1. Adhoc: Run Prowler against all Accounts in AWS Organization + - Connect to Prowler EC2 Instance + - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user + - If using SSH, then login as "ec2-user" + - Run Script: /home/ec2-user/run-prowler-reports.sh diff --git a/util/org-multi-account/src/run-prowler-reports-v4.sh b/util/org-multi-account/src/run-prowler-reports.sh similarity index 100% rename from util/org-multi-account/src/run-prowler-reports-v4.sh rename to util/org-multi-account/src/run-prowler-reports.sh From e0b6d4a21d1e7f739f96d004a349e70d9e956dbc Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Tue, 28 Apr 2020 18:33:29 -0400 Subject: [PATCH 04/29] Added Adhoc: Run Prowler Interactively --- util/org-multi-account/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 8cd71b14..b8ab32eb 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -81,3 +81,11 @@ Deploys Prowler to assess all Accounts in an AWS Organization. - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user - If using SSH, then login as "ec2-user" - Run Script: /home/ec2-user/run-prowler-reports.sh +1. Adhoc: Run Prowler Interactively + - Connect to Prowler EC2 Instance + - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user + - If using SSH, then login as "ec2-user" + - Run Prowler. See [Usage Examples](https://github.com/toniblyx/prowler#usage) + - See CloudFormation Data variables for Prowler (Cross-Account Role, S3 bucket, and AWS Account # where S3 bucket resides) + + cat /home/ec2-user/.awsvariables From 129a22e9c3ff0400b7b2ec11385471acf2e69634 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Tue, 28 Apr 2020 18:53:04 -0400 Subject: [PATCH 05/29] updated cron job settings --- util/org-multi-account/ProwlerEC2.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 5ef07d70..8ac45456 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -61,7 +61,7 @@ Parameters: ProwlerCron: Description: Enter cron schedule. Default, runs everyday at 1am. See https://crontab.guru/, for syntax help. Type: String - Default: 10 * * * * + Default: "0 1 * * *" LatestAmazonLinux2AmiId: Type: AWS::SSM::Parameter::Value Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters. @@ -196,16 +196,16 @@ Resources: group: ec2-user prowler-schedule: files: - /home/ec2-user/prowlercron: + /home/ec2-user/mycron-prowler: content: !Sub | - ${ProwlerCron} run-prowler-reports.sh + ${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/prowlercron + sudo -u ec2-user crontab /home/ec2-user/mycron-prowler ProwlerSecurityGroup: Type: AWS::EC2::SecurityGroup From 0cf97a99b30c1282a475241430b66c8f56951f77 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 17:21:42 -0400 Subject: [PATCH 06/29] Renamed Parameters, Updated Descriptions --- util/org-multi-account/ProwlerEC2.yaml | 48 +++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 8ac45456..43c5aefb 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -5,10 +5,10 @@ Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: - default: EC2 Instance Settings + default: Prowler EC2 Instance Settings Parameters: - BuildNumber - - Ec2Name + - ProwlerEc2Name - InstanceType - KeyPair - SubnetId @@ -19,8 +19,8 @@ Metadata: - Label: default: S3 Settings Parameters: - - S3 - - S3Account + - ProwlerS3 + - ProwlerS3Account - Label: default: CrossAccount Role Parameters: @@ -34,9 +34,9 @@ Parameters: AllowedPattern: ^\d*$ ConstraintDescription: Build Number must be a numeric string. Default: 1 - Ec2Name: + ProwlerEc2Name: Type: String - Description: Enter Name for EC2 Instance to create + Description: Enter Name for Prowler EC2 Instance to create Default: Prowler-EC2 InstanceType: Description: Enter Instance Type @@ -55,25 +55,25 @@ Parameters: Type: AWS::EC2::VPC::Id Default: vpc-0285f35dd91ac4c58 Ec2Role: - Description: Enter Name for EC2 Instance Role to create + Description: Enter Name for EC2 Instance Role to create and attach to Prowler EC2 Instance Type: String Default: ProwlerEC2-Role ProwlerCron: - Description: Enter cron schedule. Default, runs everyday at 1am. See https://crontab.guru/, for syntax help. + 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 - Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters. + 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 - S3: + ProwlerS3: Type: String - Description: Enter S3 Bucket to grant rights to EC2 Instance + Description: Enter S3 Bucket for Prowler Reports Default: prowler-417425889548-us-east-1 - S3Account: + ProwlerS3Account: Type: String - Description: Enter AWS Account Number where S3 Bucket resides + 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: 417425889548 @@ -86,7 +86,7 @@ Parameters: Default: o-nbfb46ay7u CrossAccountRole: Type: String - Description: Enter CrossAccount Role you will be using across the AWS Organization + Description: Enter CrossAccount Role Prowler will be using to assess AWS Accounts in the AWS Organization. (ProwlerCrossAccountRole) Default: ProwlerXA-Role Resources: @@ -105,7 +105,7 @@ Resources: - !Ref ProwlerSecurityGroup Tags: - Key: Name - Value: !Ref Ec2Name + Value: !Ref ProwlerEc2Name UserData: Fn::Base64: !Sub | @@ -119,7 +119,7 @@ Resources: S3AccessCreds: type: S3 buckets: - - !Ref S3 + - !Ref ProwlerS3 roleName: Ref: ProwlerEc2Role AWS::CloudFormation::Init: @@ -174,8 +174,8 @@ Resources: files: /home/ec2-user/.awsvariables: content: !Sub | - export S3=s3://${S3} - export S3ACCOUNT=${S3Account} + export S3=s3://${ProwlerS3} + export S3ACCOUNT=${ProwlerS3Account} export ROLE=${CrossAccountRole} mode: "000600" owner: ec2-user @@ -190,7 +190,7 @@ Resources: prowler-reports: files: /home/ec2-user/run-prowler-reports.sh: - source: !Sub https://${S3}.s3.${AWS::Region}.amazonaws.com/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 @@ -312,8 +312,8 @@ Resources: - Sid: AllowGetPutListObject Effect: Allow Resource: - - !Sub arn:${AWS::Partition}:s3:::${S3} - - !Sub arn:${AWS::Partition}:s3:::${S3}/* + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* Action: - s3:GetObject - s3:PutObject @@ -339,11 +339,11 @@ Resources: Outputs: ProwlerEc2Account: - Description: AWS Account where Prowler EC2 resides + Description: AWS Account Number where Prowler EC2 Instance resides. Value: !Ref AWS::AccountId ProwlerEc2Role: - Description: Prowler EC2 Instance Role + 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 S3 + Value: !Ref ProwlerS3 From 7816fd06483754f481998b3961a20cce1162c388 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 17:21:52 -0400 Subject: [PATCH 07/29] Renamed Parameters, Updated Descriptions --- util/org-multi-account/ProwlerRole.yaml | 39 ++++++++++++------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/util/org-multi-account/ProwlerRole.yaml b/util/org-multi-account/ProwlerRole.yaml index 0ca8997d..f640b5ad 100644 --- a/util/org-multi-account/ProwlerRole.yaml +++ b/util/org-multi-account/ProwlerRole.yaml @@ -7,55 +7,54 @@ Metadata: - Label: default: EC2 Settings Parameters: - - Ec2Account - - Ec2Role + - ProwlerEc2Account + - ProwlerEc2Role - Label: default: S3 Settings Parameters: - - S3 + - ProwlerS3 - Label: default: CrossAccount Role Parameters: - - CrossAccountRole + - ProwlerCrossAccountRole Parameters: - S3: + ProwlerS3: Type: String - Description: Enter S3 Bucket to grant rights to EC2 Instance + Description: Enter S3 Bucket for Prowler Reports Default: prowler-417425889548-us-east-1 - Ec2Account: + ProwlerEc2Account: Type: String - Description: Enter AWS Account Number where EC2 Instance resides + 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. Default: 544425379660 - Ec2Role: + ProwlerEc2Role: Type: String - Description: Enter Instance Role given to EC2 Instance (to grant sts:AssumeRole rights). + Description: Enter Instance Role that will be given to the Prowler EC2 Instance (needed to grant sts:AssumeRole rights). Default: ProwlerEC2-Role - CrossAccountRole: + ProwlerCrossAccountRole: Type: String - Description: Enter Name for CrossAccount Role to be created + Description: Enter Name for CrossAccount Role to be created for Prowler tto assess AWS Accounts in the AWS Organization. Default: ProwlerXA-Role Resources: ProwlerRole: Type: AWS::IAM::Role Properties: - RoleName: !Ref CrossAccountRole + RoleName: !Ref ProwlerCrossAccountRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - # - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} - - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:root + - !Sub arn:${AWS::Partition}:iam::${ProwlerEc2Account}:root Action: - sts:AssumeRole Condition: StringLike: - aws:PrincipalArn: !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} + 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 @@ -96,8 +95,8 @@ Resources: - Sid: AllowGetPutListObject Effect: Allow Resource: - - !Sub arn:${AWS::Partition}:s3:::${S3} - - !Sub arn:${AWS::Partition}:s3:::${S3}/* + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* Action: - s3:GetObject - s3:PutObject @@ -112,5 +111,5 @@ Resources: Outputs: ProwlerCrossAccountRole: - Description: Prowler CrossAccount Role - Value: !Ref CrossAccountRole + Description: CrossAccount Role to be used by Prowler to assess AWS Accounts in the AWS Organization. + Value: !Ref ProwlerCrossAccountRole From 299cb7e54140098c166b3444600f9804557448da Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 17:22:29 -0400 Subject: [PATCH 08/29] Renamed Parameters, Updated Descriptions --- util/org-multi-account/ProwlerS3.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/util/org-multi-account/ProwlerS3.yaml b/util/org-multi-account/ProwlerS3.yaml index e30eab9f..c9d39c02 100644 --- a/util/org-multi-account/ProwlerS3.yaml +++ b/util/org-multi-account/ProwlerS3.yaml @@ -4,10 +4,13 @@ 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. + 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-nbfb46ay7u + # Default: o-abcde12345 S3Prefix: Type: String Description: > @@ -68,5 +71,5 @@ Outputs: Description: S3 Bucket for Prowler Reports Value: !Ref ProwlerS3 ProwlerS3Account: - Description: AWS Account Number where S3 Resides + Description: AWS Account Number where Prowler S3 Bucket resides. Value: !Ref AWS::AccountId From d716cf2664875150dcb7b903a33d794bc7023f91 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 17:23:28 -0400 Subject: [PATCH 09/29] more documentation and links --- util/org-multi-account/README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index b8ab32eb..938e731d 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -1,8 +1,7 @@ # Organizational Prowler Deployment - Created by: Julio Delgado Jr. -Deploys Prowler to assess all Accounts in an AWS Organization. +Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, create assessment reports in HTML, and store them in an S3 bucket. [Prowler](https://github.com/toniblyx/prowler) is an independent third-party command line tool for AWS Security Best Practices Assessment, Auditing, Hardening, and Forensic Readiness. It evaluates guidelines of the CIS Amazon Web Services Foundations Benchmark and dozens of additional checks, including for GDPR, and HIPAA. @@ -29,7 +28,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization. 1. [ProwlerS3.yaml](util\org-multi-account\ProwlerS3.yaml) - Creates Private S3 Bucket for Prowler script and reports. - Public Access Block permissions enabled. - - SSE-S3 used for encryption + - SSE-S3 used with Amazon S3 Default Encryption - Versioning Enabled - Bucket Policy only grants GetObject, PutObject, and ListObject to Principals from the same AWS Organization. 1. [ProwlerRole.yaml](util\org-multi-account\ProwlerRole.yaml) @@ -55,8 +54,14 @@ Deploys Prowler to assess all Accounts in an AWS Organization. - Role has rights to Assume Cross-Account Role from Component #2. 1. [run-prowler-reports.sh](util\org-multi-account\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 + - ansi2html -la: used to generate HTML assessment report + - NOTE: Script can be modified to run Prowler as desired. - In summary: - - Download latest version of [Prowler ](https://github.com/toniblyx/prowler) + - 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 @@ -69,10 +74,13 @@ Deploys Prowler to assess all Accounts in an AWS Organization. 1. Deploy [ProwlerS3.yaml](util\org-multi-account\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](util\org-multi-account\src\run-prowler-reports.sh) to the root of the S3 Bucket created in Step #1. 1. Deploy [ProwlerRole.yaml](util\org-multi-account\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. + - 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](util\org-multi-account\ProwlerEC2.yaml) in the Audit/Security Account - Could be deployed to any account in the AWS Organizations, if desired. 1. Scheduled: Run Prowler against all Accounts in AWS Organization, based on schedule you provided, and set for the cron job. From 36e9f5174d420ef4ac0b32a4255081eccad1d9e7 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 17:24:00 -0400 Subject: [PATCH 10/29] reduced sts calls, updated comments --- .../src/run-prowler-reports.sh | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/util/org-multi-account/src/run-prowler-reports.sh b/util/org-multi-account/src/run-prowler-reports.sh index 4fc05b6c..9b12b9d2 100644 --- a/util/org-multi-account/src/run-prowler-reports.sh +++ b/util/org-multi-account/src/run-prowler-reports.sh @@ -3,11 +3,13 @@ # 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 +cd /home/ec2-user || exit -# Download Prowler -rm -rf prowler -git clone https://github.com/toniblyx/prowler.git +# 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 @@ -21,7 +23,7 @@ echo "ROLE: $ROLE" # Create Folder to Store Prowler Reports mkdir -p prowler-reports -# CleanUp Last Ran Prowler Reports +# CleanUp Last Ran Prowler Reports, as they are already stored in S3. rm -rf prowler-reports/*.html # Function to unset AWS Profile Variables @@ -31,8 +33,9 @@ unset_aws() { unset_aws # Find THIS Account AWS Number -THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) -PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) +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" @@ -84,10 +87,13 @@ for accountId in $ACCOUNTS_IN_ORGS; do # Run Prowler Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" - ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" + ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" echo "Report stored locally at: $Report" # Upload Prowler Report to S3 s3_account_session aws s3 cp "$Report" "$S3/reports/" echo "" done + +# Unset AWS Profile Variables +unset_aws From 4230e9dc1316d829d665fb39c58392e91b2828ed Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 30 Apr 2020 20:12:19 -0400 Subject: [PATCH 11/29] added elapsed times, support run prower parallel --- .../src/run-prowler-reports.sh | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/util/org-multi-account/src/run-prowler-reports.sh b/util/org-multi-account/src/run-prowler-reports.sh index 9b12b9d2..c8a44216 100644 --- a/util/org-multi-account/src/run-prowler-reports.sh +++ b/util/org-multi-account/src/run-prowler-reports.sh @@ -82,18 +82,30 @@ s3_account_session() { echo "AWS Accounts in Organization" echo "$ACCOUNTS_IN_ORGS" for accountId in $ACCOUNTS_IN_ORGS; do - # Unset AWS Profile Variables - unset_aws - # Run Prowler - Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" - echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" - ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" - echo "Report stored locally at: $Report" - # Upload Prowler Report to S3 - s3_account_session - aws s3 cp "$Report" "$S3/reports/" - echo "" + # shellcheck disable=SC2015 + test "$(jobs | wc -l)" -ge 1 && wait || true + { + START_TIME=$SECONDS + # Unset AWS Profile Variables + unset_aws + # Run Prowler + Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" + echo -e "Assessing AWS Account: $accountId, using Role: $ROLE on $(date)" + ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" + echo "Report stored locally at: $Report" + # Upload Prowler Report to S3 + s3_account_session + aws s3 cp "$Report" "$S3/reports/" + 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 From 1be68b1e00decc0502fb788ac9cfb853ece365be Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:42:30 -0400 Subject: [PATCH 12/29] Updated Patterns,Descriptions,Defaults,Tags --- util/org-multi-account/ProwlerEC2.yaml | 28 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 43c5aefb..0f3c2fde 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -37,6 +37,8 @@ Parameters: 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 @@ -45,18 +47,17 @@ Parameters: KeyPair: Description: Choose a KeyPair Type: AWS::EC2::KeyPair::KeyName - Default: delgjul-labctaudit SubnetId: Description: Choose Subnet Type: AWS::EC2::Subnet::Id - Default: subnet-04dfbeda2dc588875 VpcId: Description: Choose VPC Type: AWS::EC2::VPC::Id - Default: vpc-0285f35dd91ac4c58 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. @@ -69,24 +70,28 @@ Parameters: ProwlerS3: Type: String - Description: Enter S3 Bucket for Prowler Reports - Default: prowler-417425889548-us-east-1 + 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: 417425889548 + 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-nbfb46ay7u + 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: @@ -106,6 +111,8 @@ Resources: Tags: - Key: Name Value: !Ref ProwlerEc2Name + - Key: App + Value: Prowler UserData: Fn::Base64: !Sub | @@ -212,6 +219,9 @@ Resources: Properties: GroupName: Prowler-EC2-RemoteAdministration GroupDescription: Allow Remote Administration + Tags: + - Key: App + Value: Prowler VpcId: !Ref VpcId SecurityGroupIngress: - Description: Allow SSH Administration @@ -247,7 +257,11 @@ Resources: 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: From ac5212990a6bb8ca73b5ff2851756fc219e0b7aa Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:42:56 -0400 Subject: [PATCH 13/29] Updated Patterns,Descriptions,Defaults,Tags --- util/org-multi-account/ProwlerRole.yaml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/util/org-multi-account/ProwlerRole.yaml b/util/org-multi-account/ProwlerRole.yaml index f640b5ad..544cf1cd 100644 --- a/util/org-multi-account/ProwlerRole.yaml +++ b/util/org-multi-account/ProwlerRole.yaml @@ -21,28 +21,36 @@ Metadata: Parameters: ProwlerS3: Type: String - Description: Enter S3 Bucket for Prowler Reports - Default: prowler-417425889548-us-east-1 + 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. - Default: 544425379660 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 tto assess AWS Accounts in the AWS Organization. + 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: From 29378a1339fbf405387d9d365b4804845c34ac94 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:43:50 -0400 Subject: [PATCH 14/29] Updated Patterns,Defaults,Tags,BucketPolicy --- util/org-multi-account/ProwlerS3.yaml | 36 ++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/util/org-multi-account/ProwlerS3.yaml b/util/org-multi-account/ProwlerS3.yaml index c9d39c02..17b9f8b3 100644 --- a/util/org-multi-account/ProwlerS3.yaml +++ b/util/org-multi-account/ProwlerS3.yaml @@ -9,13 +9,16 @@ Parameters: 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-nbfb46ay7u - # Default: o-abcde12345 + Default: o-abcde12345 S3Prefix: Type: String Description: > Enter S3 Bucket Name Prefix (in lowercase). - Bucket will be named: prefix-accountid-region + 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: @@ -35,6 +38,9 @@ Resources: RestrictPublicBuckets: True VersioningConfiguration: Status: Enabled + Tags: + - Key: App + Value: Prowler Metadata: cfn_nag: rules_to_suppress: @@ -60,12 +66,36 @@ Resources: 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 From 25cb42e3c4b7ad509d58df112c0605d81bfbe6ae Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:44:50 -0400 Subject: [PATCH 15/29] added parallel_accounts variable --- util/org-multi-account/src/run-prowler-reports.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/org-multi-account/src/run-prowler-reports.sh b/util/org-multi-account/src/run-prowler-reports.sh index c8a44216..2e797a76 100644 --- a/util/org-multi-account/src/run-prowler-reports.sh +++ b/util/org-multi-account/src/run-prowler-reports.sh @@ -81,9 +81,10 @@ s3_account_session() { # 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 1 && wait || true + test "$(jobs | wc -l)" -ge $PARALLEL_ACCOUNTS && wait || true { START_TIME=$SECONDS # Unset AWS Profile Variables From f4af505270878e0290ab6c1248283ece86746e64 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:45:20 -0400 Subject: [PATCH 16/29] better markdown for code, more documentation --- util/org-multi-account/README.md | 99 +++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 938e731d..5711480c 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -1,4 +1,5 @@ # Organizational Prowler Deployment + Created by: Julio Delgado Jr. Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, create assessment reports in HTML, and store them in an S3 bucket. @@ -25,24 +26,24 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ## Components -1. [ProwlerS3.yaml](util\org-multi-account\ProwlerS3.yaml) +1. [ProwlerS3.yaml](ProwlerS3.yaml) - Creates Private S3 Bucket for Prowler script and reports. - Public Access Block permissions enabled. - SSE-S3 used with Amazon S3 Default Encryption - Versioning Enabled - Bucket Policy only grants GetObject, PutObject, and ListObject to Principals from the same AWS Organization. -1. [ProwlerRole.yaml](util\org-multi-account\ProwlerRole.yaml) +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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. -1. [ProwlerEC2.yaml](util\org-multi-account\ProwlerEC2.yaml) +1. [ProwlerEC2.yaml](ProwlerEC2.yaml) - Creates Prowler EC2 instance - Uses the Latest Amazon Linux 2 AMI - Uses "t2.micro" Instance Type - 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](util\org-multi-account\src\run-prowler-reports.sh) script from Prowler S3 from Component #1. + - 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 @@ -52,14 +53,27 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. - Role has rights to Assume Cross-Account Role from Component #2. -1. [run-prowler-reports.sh](util\org-multi-account\src\run-prowler-reports.sh) +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 - ansi2html -la: used to generate HTML assessment report + + ```bash + ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" + ``` + - 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 @@ -72,28 +86,69 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ## Instructions -1. Deploy [ProwlerS3.yaml](util\org-multi-account\ProwlerS3.yaml) in the Logging Account. +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](util\org-multi-account\src\run-prowler-reports.sh) to the root of the S3 Bucket created in Step #1. -1. Deploy [ProwlerRole.yaml](util\org-multi-account\ProwlerRole.yaml) in the Master Account +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](util\org-multi-account\ProwlerEC2.yaml) in the Audit/Security Account +1. Deploy [ProwlerEC2.yaml](ProwlerEC2.yaml) in the Audit/Security Account - Could be deployed to any account in the AWS Organizations, if desired. -1. Scheduled: Run Prowler against all Accounts in AWS Organization, based on schedule you provided, and set for the cron job. -1. Adhoc: Run Prowler against all Accounts in AWS Organization - - Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user - - If using SSH, then login as "ec2-user" - - Run Script: /home/ec2-user/run-prowler-reports.sh -1. Adhoc: Run Prowler Interactively - - Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user - - If using SSH, then login as "ec2-user" - - Run Prowler. See [Usage Examples](https://github.com/toniblyx/prowler#usage) - - See CloudFormation Data variables for Prowler (Cross-Account Role, S3 bucket, and AWS Account # where S3 bucket resides) +1. Prowler will run against all Accounts in AWS Organization, based on the schedule you provided, and therefore set in a cron job for ec2-user. - cat /home/ec2-user/.awsvariables +--- + +## 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. + +### Run Prowler Adhoc 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 -u ec2-user + - If using SSH, then login as "ec2-user" +1. Run Prowler Script + + ```bash + cd /home/ec2-user + ./run-prowler-reports.sh + ``` + +### Run Prowler Adhoc Interactively + +1. Connect to Prowler EC2 Instance + - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u 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 -u 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 + ``` From 872881570425fdc1f3354a45913b4e4a11cc19bf Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:46:37 -0400 Subject: [PATCH 17/29] . --- util/org-multi-account/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 5711480c..a88b52ad 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -1,4 +1,4 @@ -# Organizational Prowler Deployment +# Organizational Prowler Deployment Created by: Julio Delgado Jr. From 95135305d73303c4c5f23b1ef96cd7905314609c Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:48:44 -0400 Subject: [PATCH 18/29] updated links --- util/org-multi-account/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index a88b52ad..4037e479 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -43,7 +43,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - Uses "t2.micro" Instance Type - 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. + - 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 @@ -53,7 +53,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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 GetObject, PutObject, and ListObject 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) +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. @@ -90,7 +90,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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. 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) From bb46702d370adda90aaf3c1f4ef1174cb88b4df8 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 11:50:05 -0400 Subject: [PATCH 19/29] updates --- util/org-multi-account/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 4037e479..71893c96 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -10,7 +10,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ## Solution Goals -- Use minimal technologies, so solution can be more easily adopted, and further enhanced as needed. +- 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. @@ -18,8 +18,8 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - Staying cohesive with Prowler, for scripting, only leveraging: - Bash Shell - AWS CLI -- Adhere to the principle of least privilege. -- Support an AWS Multi-Account approach +- Adhering to the principle of least privilege. +- Supporting an AWS Multi-Account approach - Runs Prowler against All accounts in the AWS Organization --- From 159ae3ac32a251e0ed58ec8bc271697ab8f9eb76 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:07:15 -0400 Subject: [PATCH 20/29] removed ingress rule --- util/org-multi-account/ProwlerEC2.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 0f3c2fde..994da482 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -223,12 +223,6 @@ Resources: - Key: App Value: Prowler VpcId: !Ref VpcId - SecurityGroupIngress: - - Description: Allow SSH Administration - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - SourcePrefixListId: pl-60b85b09 SecurityGroupEgress: - Description: Allow HTTP Outbound IpProtocol: tcp From d2503ad1d3a8d9a40e0b50b37f284a840c2e35d2 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:07:31 -0400 Subject: [PATCH 21/29] more links, formatting --- util/org-multi-account/README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 71893c96..eb66d9f0 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -21,6 +21,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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.*** --- @@ -28,30 +29,30 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre 1. [ProwlerS3.yaml](ProwlerS3.yaml) - Creates Private S3 Bucket for Prowler script and reports. - - Public Access Block permissions enabled. - - SSE-S3 used with Amazon S3 Default Encryption + - 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 only grants GetObject, PutObject, and ListObject to Principals from the same AWS Organization. + - 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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. + - 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 + - Uses ```t2.micro``` Instance Type - 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 ```/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 GetObject, PutObject, and ListObject rights to Prowler S3 from Component #1. + - 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. From 8fd2c17b5de5eae35976eb7f31aa96d1e629b5f2 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:08:56 -0400 Subject: [PATCH 22/29] . --- util/org-multi-account/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index eb66d9f0..2466b7be 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -98,7 +98,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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, based on the schedule you provided, and therefore set in a cron job for ec2-user. +1. Prowler will run against all Accounts in AWS Organization, based on the schedule you provided, and set in a cron job for ec2-user. --- From 378dd888086e09d2de8c17846c9b4f543e187ef0 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:09:29 -0400 Subject: [PATCH 23/29] . --- util/org-multi-account/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 2466b7be..b39099cf 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -98,7 +98,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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, based on the schedule you provided, and set in a cron job for ec2-user. +1. Prowler will run against all Accounts in AWS Organization, per the schedule you provided, and set in a cron job for ec2-user. --- From 23dc8ce88329b1d9fb8b6aa7cc845ec92249abec Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:12:57 -0400 Subject: [PATCH 24/29] . --- util/org-multi-account/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index b39099cf..b5b9a90d 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -98,7 +98,7 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre - 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. +1. Prowler will run against all Accounts in AWS Organization, per the schedule you provided, and set in a cron job for ```ec2-user``` --- @@ -107,14 +107,14 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ### 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. Cron job for ```ec2-user``` is managing the schedule. 1. This solution implemented this automatically. Nothing for you to do. ### Run Prowler Adhoc 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 -u ec2-user - - If using SSH, then login as "ec2-user" + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo -u ec2-user``` + - If using SSH, then login as ```ec2-user``` 1. Run Prowler Script ```bash @@ -125,8 +125,8 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ### Run Prowler Adhoc Interactively 1. Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user - - If using SSH, then login as "ec2-user" + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo -u ec2-user``` + - If using SSH, then login as ```ec2-user``` 1. See Cross-Account Role and S3 Bucket being used for Prowler ```bash @@ -144,8 +144,8 @@ Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, cre ### Upgrading Prowler to Latest Version 1. Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to "ec2-user", via: sudo -u ec2-user - - If using SSH, then login as "ec2-user" + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo -u 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 From d095ea75d84c83345a46a304ca895f9af52a03b5 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 12:14:36 -0400 Subject: [PATCH 25/29] intro --- util/org-multi-account/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index b5b9a90d..935639af 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -2,9 +2,7 @@ Created by: Julio Delgado Jr. -Deploys Prowler to assess all Accounts in an AWS Organization on a schedule, create assessment reports in HTML, and store them in an S3 bucket. - -[Prowler](https://github.com/toniblyx/prowler) is an independent third-party command line tool for AWS Security Best Practices Assessment, Auditing, Hardening, and Forensic Readiness. It evaluates guidelines of the CIS Amazon Web Services Foundations Benchmark and dozens of additional checks, including for GDPR, and HIPAA. +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. --- From 49456424fada3afb315cb975a161c27c45ca0555 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Sun, 3 May 2020 13:02:46 -0400 Subject: [PATCH 26/29] example --- util/org-multi-account/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 935639af..6215fe2c 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -1,4 +1,4 @@ -# Organizational Prowler Deployment +# Example Solution: Organizational Prowler Deployment Created by: Julio Delgado Jr. @@ -6,7 +6,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in --- -## Solution Goals +## 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 From d6033e287d84acd677af1bd7149898620d6dd5f6 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Wed, 6 May 2020 10:55:42 -0400 Subject: [PATCH 27/29] encryption of ebs volume --- util/org-multi-account/ProwlerEC2.yaml | 8 ++++++++ util/org-multi-account/README.md | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 994da482..78b936e7 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -108,6 +108,14 @@ Resources: 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 diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 6215fe2c..c52272e1 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -40,6 +40,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in - 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. @@ -47,7 +48,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in - 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 + - 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. From a58ee251b5614287dcd1e8d9ce0e71b31bc5edd8 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Thu, 28 May 2020 13:43:55 -0400 Subject: [PATCH 28/29] adhoc & switch user in session manager --- util/org-multi-account/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index c52272e1..3bc0fb42 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -109,10 +109,10 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in 1. Cron job for ```ec2-user``` is managing the schedule. 1. This solution implemented this automatically. Nothing for you to do. -### Run Prowler Adhoc against all Accounts in AWS Organization +### 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 -u ec2-user``` + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash; su - ec2-user``` - If using SSH, then login as ```ec2-user``` 1. Run Prowler Script @@ -121,10 +121,10 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in ./run-prowler-reports.sh ``` -### Run Prowler Adhoc Interactively +### Ad hoc Run Prowler Interactively 1. Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo -u ec2-user``` + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash; su - ec2-user``` - If using SSH, then login as ```ec2-user``` 1. See Cross-Account Role and S3 Bucket being used for Prowler @@ -143,7 +143,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in ### Upgrading Prowler to Latest Version 1. Connect to Prowler EC2 Instance - - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo -u ec2-user``` + - If using Session Manager, then after login, switch to ```ec2-user```, via: ```sudo bash; 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 From 9e2580cc3412394ba39db215ac11a8dd3207bcb4 Mon Sep 17 00:00:00 2001 From: Julio Delgado Jr Date: Fri, 5 Jun 2020 12:06:33 -0400 Subject: [PATCH 29/29] removed ansi2html, added -M html --- util/org-multi-account/ProwlerEC2.yaml | 2 +- util/org-multi-account/README.md | 11 ++++------- util/org-multi-account/src/run-prowler-reports.sh | 13 +++++-------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml index 78b936e7..ad9390e4 100644 --- a/util/org-multi-account/ProwlerEC2.yaml +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -201,7 +201,7 @@ Resources: yum install python-pip git jq -y 02-install-prowler-prereqs-pip: command: | - sudo -u ec2-user pip install --user boto3 awscli ansi2html detect-secrets + sudo -u ec2-user pip install --user boto3 awscli detect-secrets prowler-reports: files: /home/ec2-user/run-prowler-reports.sh: diff --git a/util/org-multi-account/README.md b/util/org-multi-account/README.md index 3bc0fb42..71c6faad 100644 --- a/util/org-multi-account/README.md +++ b/util/org-multi-account/README.md @@ -1,7 +1,5 @@ # Example Solution: Organizational Prowler Deployment -Created by: Julio Delgado Jr. - 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. --- @@ -59,10 +57,9 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in - -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 - - ansi2html -la: used to generate HTML assessment report ```bash - ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" + ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 -M html ``` - NOTE: Script can be modified to run Prowler as desired. @@ -112,7 +109,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in ### 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; su - ec2-user``` + - 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 @@ -124,7 +121,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in ### 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; su - ec2-user``` + - 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 @@ -143,7 +140,7 @@ Deploys [Prowler](https://github.com/toniblyx/prowler) to assess all Accounts in ### 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; su - ec2-user``` + - 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 diff --git a/util/org-multi-account/src/run-prowler-reports.sh b/util/org-multi-account/src/run-prowler-reports.sh index 2e797a76..54201b84 100644 --- a/util/org-multi-account/src/run-prowler-reports.sh +++ b/util/org-multi-account/src/run-prowler-reports.sh @@ -20,11 +20,8 @@ echo "S3: $S3" echo "S3ACCOUNT: $S3ACCOUNT" echo "ROLE: $ROLE" -# Create Folder to Store Prowler Reports -mkdir -p prowler-reports - # CleanUp Last Ran Prowler Reports, as they are already stored in S3. -rm -rf prowler-reports/*.html +rm -rf prowler/output/*.html # Function to unset AWS Profile Variables unset_aws() { @@ -90,13 +87,13 @@ for accountId in $ACCOUNTS_IN_ORGS; do # Unset AWS Profile Variables unset_aws # Run Prowler - Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" echo -e "Assessing AWS Account: $accountId, using Role: $ROLE on $(date)" - ./prowler/prowler -R "$ROLE" -A "$accountId" -g cislevel1 | ansi2html -la >"$Report" - echo "Report stored locally at: $Report" + # 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 "$Report" "$S3/reports/" + 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))