Whether you are looking to improve your AWS security posture or checking compliance against cybersecurity frameworks, Prowler is an amazing open source tool developed by Toni de la Fuente. Toni has created a tool to check over 200 security controls in AWS ranging from ensuring S3 buckers are not publicly accessible to encryption everywhere.
Toni's Github portal provides extensive documentation on how to use the tool, but I wanted to share a CloudFormation template that I created to automate the deployment in AWS to run compliance checks and then decommission the stack and remove all resources.
Launching EC2 Instance for Prowler
First, we will want launch an EC2 instance and run a bash script to download the necessary software, install, and configure Prowler.
ProwlerInstance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref InstanceSecurityGroup
KeyName: !Ref KeyName
IamInstanceProfile: !Ref ProwlerInstanceProfile
Tags:
-
Key: Name
Value: Prowler
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
Encrypted: true
# Run bash to install and configure Prowler
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
sudo yum update -y
sudo yum remove -y awscli
cd /home/ec2-user
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/home/ec2-user/awscliv2.zip"
unzip /home/ec2-user/awscliv2.zip
sudo /home/ec2-user/aws/install
sudo yum install -y python3 jq git
sudo pip3 install detect-secrets==1.0.3
git clone https://github.com/prowler-cloud/prowler /home/ec2-user/prowler
chown -R ec2-user:ec2-user /home/ec2-user/prowler
Create an instance profile
Create an instance profile tied to a role with necessary permissions to run the audit.
ProwlerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: prowler-ec2-instance-profile
Path: /
Roles:
- !Ref ProwlerEc2InstanceRole
Provide access to run Prowler
Next we will want to generate a role that has view-only and security audit permission that is required by Prowler to run compliance checks.
ProwlerEc2InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: prowler-ec2-instance-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
Path: /
Security Group
We'll want to create a security group to only allow SSH access into the EC2 instance.
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow ssh from specific host
GroupName: ProwlerSecurityGroup
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: 'tcp'
FromPort: '22'
ToPort: '22'
CidrIp: !Ref CidrIp
Parameters
Lastly, to improve automation, we will pass parameters into the CloudFormation template. If you launch the template via the console, some of these settings will be selected via a dropdown. For launching via the command-line interface, pass the parameters through a JSON file.
ImageId : Default is AWS Linux 2 ami-0e1d30f2c40c4c701
InstanceType : Default is t3.micro
VpcId : VPC to launch EC2 instance into
SubnetId : Subnet for EC2 instance
KeyName : Keypair to use
CidrIp : CIDR range for SSH x.x.x.x/x
Parameters:
ImageId:
Type: String
Description: AMI - Linux 2
Default: 'ami-0e1d30f2c40c4c701'
InstanceType:
Type: String
Description: Instance type to be used - t3.micro default
Default: t3.micro
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC to be used
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet to be used
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Keyname
CidrIp:
Type: String
Description: CidrIp to be used to connect from x.x.x.x/x
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "Network Configuration"
Parameters:
- ImageId
- InstanceType
- VpcId
- SubnetId
- KeyName
- CidrIp
Final YAML Script
After putting all this together. The final YAML scripts looks like the following. The code is also available at Github.
AWSTemplateFormatVersion: "2010-09-09"
Description: "Create EC2 instanace with Prowler pre-configured and tied to roles to run"
# Template Parameters
# ImageId : Default is AWS Linux 2 ami-0e1d30f2c40c4c701
# InstanceType : Default is t3.micro
# VpcId : VPC to launch in
# SubnetId : Subnet to connect
# KeyName : Keypair to use
# CidrIp : CIDR range for SSH x.x.x.x/x
Resources:
# Create Prowler Instance - Parameters for ImageId, InstanceType, SubnetId, SecurityGroupIds, and KeyName
ProwlerInstance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref InstanceSecurityGroup
KeyName: !Ref KeyName
IamInstanceProfile: !Ref ProwlerInstanceProfile
Tags:
-
Key: Name
Value: Prowler
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
Encrypted: true
# Run bash to install and configure Prowler
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
sudo yum update -y
sudo yum remove -y awscli
cd /home/ec2-user
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/home/ec2-user/awscliv2.zip"
unzip /home/ec2-user/awscliv2.zip
sudo /home/ec2-user/aws/install
sudo yum install -y python3 jq git
sudo pip3 install detect-secrets==1.0.3
git clone https://github.com/prowler-cloud/prowler /home/ec2-user/prowler
chown -R ec2-user:ec2-user /home/ec2-user/prowler
ProwlerInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: prowler-ec2-instance-profile
Path: /
Roles:
- !Ref ProwlerEc2InstanceRole
# Create Security Group
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow ssh from specific host
GroupName: ProwlerSecurityGroup
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: 'tcp'
FromPort: '22'
ToPort: '22'
CidrIp: !Ref CidrIp
# Create EC2 Instance Role to run security checks and attach to instance
ProwlerEc2InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: prowler-ec2-instance-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
Path: /
# Parameters for cloudformation template with some defaults
Parameters:
ImageId:
Type: String
Description: AMI - Linux 2
Default: 'ami-0e1d30f2c40c4c701'
InstanceType:
Type: String
Description: Instance type to be used - t3.micro default
Default: t3.micro
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC to be used
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet to be used
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Keyname
CidrIp:
Type: String
Description: CidrIp to be used to connect from x.x.x.x/x
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "Network Configuration"
Parameters:
- ImageId
- InstanceType
- VpcId
- SubnetId
- KeyName
- CidrIp
Conditions: {}
Running Prowler
After launching the CloudFormation template, simply sign into the EC2 instance and change into the /home/ec2-user/prowler directory.
To start, I recommend running Prowler with the HTML output file option. This provides a dynamic HTML file that you can review all the findings.
./prowler -M html
You can run direct output to multiple formats at once such as csv and json
./prowler -M csv,json,html
Decommissioning the resources
After you run Prowler, copy the output files to another system or S3 for review and record keeping. Go back into CloudFormation and delete the stack to remove all the resources that were generated.
Next steps
Prowler is also supported by AWS Security Hub, so you can send your findings directly to Security Hub. There's also a workshop available to build security dashboards in Quicksight from Prowler data. Details for this integration can be found at Building Prowler into a QuickSight powered AWS Security Dashboard.
Top comments (1)
Really insightful article, thank you for sharing!