mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
bring in megaprowler code
This commit is contained in:
68
util/Audit_Exec_Role.yaml
Normal file
68
util/Audit_Exec_Role.yaml
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Description: Prowler Auditing Role - in Control Tower pick AWSControlTowerStackSetRole for IAM role and AWSControlTowerExecution for execution
|
||||
|
||||
Parameters:
|
||||
|
||||
AuditorAccountId:
|
||||
Default: 987600001234
|
||||
Description: AWS Account ID where the audit tooling executes
|
||||
Type: Number
|
||||
AuditRolePathName:
|
||||
Default: '/audit/prowler/XA_AuditRole_Prowler'
|
||||
Description: Path for role name in audit tooling account
|
||||
Type: String
|
||||
|
||||
Resources:
|
||||
XAAuditRole:
|
||||
Type: "AWS::IAM::Role"
|
||||
Properties: # /audit/prowler/XA_AuditRole_Prowler
|
||||
RoleName: XA_AuditRole_Prowler
|
||||
Path: "/audit/prowler/"
|
||||
ManagedPolicyArns:
|
||||
- arn:aws:iam::aws:policy/SecurityAudit
|
||||
- arn:aws:iam::aws:policy/AWSOrganizationsReadOnlyAccess
|
||||
- arn:aws:iam::aws:policy/IAMReadOnlyAccess
|
||||
AssumeRolePolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
-
|
||||
Effect: "Allow"
|
||||
Principal:
|
||||
AWS: # TODO: review permissions to see if this can be narrowed down - code build only perhaps
|
||||
- !Sub "arn:aws:iam::${AuditorAccountId}:root"
|
||||
- !Sub "arn:aws:iam::${AuditorAccountId}:role${AuditRolePathName}"
|
||||
Action:
|
||||
- "sts:AssumeRole"
|
||||
Policies:
|
||||
- PolicyName: "ProwlerPolicyAdditions"
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Sid: "ProwlerPolicyAdditions"
|
||||
Effect: "Allow"
|
||||
Resource: "*"
|
||||
Action:
|
||||
- "acm:describecertificate"
|
||||
- "acm:listcertificates"
|
||||
- "es:describeelasticsearchdomainconfig"
|
||||
- "logs:DescribeLogGroups"
|
||||
- "logs:DescribeMetricFilters"
|
||||
- "ses:getidentityverificationattributes"
|
||||
- "sns:listsubscriptionsbytopic"
|
||||
- "guardduty:ListDetectors"
|
||||
- "guardduty:GetDetector"
|
||||
- "S3:GetEncryptionConfiguration"
|
||||
- "trustedadvisor:Describe*"
|
||||
- "cloudtrail:GetEventSelectors"
|
||||
- "apigateway:GET"
|
||||
- "support:*"
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W28
|
||||
reason: "the role name is intentionally static"
|
||||
- id: W11
|
||||
reason: "the policy grants read/view/audit access only, to all resources, by design"
|
||||
- id: F3
|
||||
reason: "Support does not allow or deny access to individual actions"
|
||||
411
util/Audit_Pipeline.yaml
Normal file
411
util/Audit_Pipeline.yaml
Normal file
@@ -0,0 +1,411 @@
|
||||
---
|
||||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Description: Prowler Auditing Tools Stack
|
||||
|
||||
Metadata:
|
||||
AWS::CloudFormation::Interface:
|
||||
ParameterGroups:
|
||||
- Label:
|
||||
default: "Organizations and Accounts"
|
||||
Parameters:
|
||||
- pOrgMasterAccounts
|
||||
- pOrgExcludedAccounts
|
||||
- pStandAloneAccounts
|
||||
- Label:
|
||||
default: "Check Group and Execution"
|
||||
Parameters:
|
||||
- pProwlerCheckGroup
|
||||
- pAuditEveryXHours
|
||||
- Label:
|
||||
default: "Advanced"
|
||||
Parameters:
|
||||
- pTimeoutMinutes
|
||||
- pAuditRolePathName
|
||||
- pCustomProwlerRepo
|
||||
- pCustomProwlerCloneArgs
|
||||
ParameterLabels:
|
||||
pOrgMasterAccounts:
|
||||
default: "Organization Master Accounts"
|
||||
pOrgExcludedAccounts:
|
||||
default: "Excluded Organiztion Members"
|
||||
pStandAloneAccounts:
|
||||
default: "Stand-alone Accounts"
|
||||
pProwlerCheckGroup:
|
||||
default: "Prowler Check Group"
|
||||
pAuditEveryXHours:
|
||||
default: "Perform Audit every X hours"
|
||||
pTimeoutMinutes:
|
||||
default: "Permit Audit to run for X minutes"
|
||||
pAuditRolePathName:
|
||||
default: "Custom audit role path"
|
||||
pCustomProwlerRepo:
|
||||
default: "Custom git repo location for prowler"
|
||||
pCustomProwlerCloneArgs:
|
||||
default: "Custom arguments to git clone --depth 1"
|
||||
|
||||
Parameters:
|
||||
pAuditEveryXHours:
|
||||
Default: 24
|
||||
Type: Number
|
||||
Description: Number of hours between prowler audit runs.
|
||||
MinValue: 2
|
||||
MaxValue: 168
|
||||
pTimeoutMinutes:
|
||||
Default: 30
|
||||
Type: Number
|
||||
Description: Timeout for running prowler across the fleet
|
||||
pAuditRolePathName:
|
||||
Default: '/audit/prowler/XA_AuditRole_Prowler'
|
||||
Type: String
|
||||
Description: Role path and name which prowler will assume in the target accounts (Audit_Exec_Role.yaml)
|
||||
# TODO: Validation: begins with "/" and does NOT end with "/"
|
||||
pOrgMasterAccounts:
|
||||
Description: Comma Separated list of Organization Master Accounts, or 'none'
|
||||
Default: 'none'
|
||||
Type: String
|
||||
MinLength: 4
|
||||
AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$
|
||||
ConstraintDescription: comma separated list 12-digit account numbers, or 'none'
|
||||
pOrgExcludedAccounts: # Comma Separated list of Org Member Accounts to EXCLUDE
|
||||
Description: Comma Separated list of Skipped Organization Member Accounts, or 'none'
|
||||
Default: 'none'
|
||||
Type: String
|
||||
MinLength: 4
|
||||
AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$
|
||||
ConstraintDescription: comma separated list 12-digit account numbers, or 'none'
|
||||
pStandAloneAccounts: # Comma Separated list of Stand-Alone Accounts
|
||||
Description: Comma Separated list of Stand-alone Accounts, or 'none'
|
||||
Default: 'none'
|
||||
Type: String
|
||||
MinLength: 4
|
||||
AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$
|
||||
ConstraintDescription: comma separated list 12-digit account numbers, or 'none'
|
||||
pProwlerCheckGroup:
|
||||
Default: 'cislevel1'
|
||||
Type: String
|
||||
Description: Which group of checks should prowler run
|
||||
AllowedValues:
|
||||
- 'group1'
|
||||
- 'group2'
|
||||
- 'group3'
|
||||
- 'group4'
|
||||
- 'cislevel1'
|
||||
- 'cislevel2'
|
||||
- 'extras'
|
||||
- 'forensics-ready'
|
||||
- 'gdpr'
|
||||
- 'hipaa'
|
||||
- 'secrets'
|
||||
- 'apigateway'
|
||||
- 'rds'
|
||||
pCustomProwlerRepo:
|
||||
Type: String
|
||||
Default: 'https://github.com/toniblyx/prowler.git'
|
||||
MinLength: 10
|
||||
pCustomProwlerCloneArgs:
|
||||
Type: String
|
||||
Default: '--branch master'
|
||||
MinLength: 0
|
||||
##### TODO
|
||||
# pResultsBucket: # if specified, use an existing bucket for the data
|
||||
# pEnableAthena:
|
||||
# Default: false
|
||||
# Type: Boolean
|
||||
# Description: Set to true to enable creation of Athena/QuickSight resources
|
||||
|
||||
#### TODO
|
||||
# Conditions:
|
||||
# cUseAthena: False
|
||||
|
||||
Resources:
|
||||
|
||||
# S3 Bucket for Results, Config
|
||||
ProwlerResultsBucket:
|
||||
Type: "AWS::S3::Bucket"
|
||||
Properties:
|
||||
# BucketName: !Sub "audit-results-${AWS::AccountId}"
|
||||
Tags:
|
||||
- Key: "data-type"
|
||||
Value: "it-audit:sensitive"
|
||||
- Key: "data-public"
|
||||
Value: "NO"
|
||||
AccessControl: Private
|
||||
BucketEncryption:
|
||||
ServerSideEncryptionConfiguration:
|
||||
- ServerSideEncryptionByDefault:
|
||||
SSEAlgorithm: AES256
|
||||
PublicAccessBlockConfiguration:
|
||||
BlockPublicAcls: True
|
||||
BlockPublicPolicy: True
|
||||
IgnorePublicAcls: True
|
||||
RestrictPublicBuckets: True
|
||||
# LoggingConfiguration:
|
||||
# TODO: Enable BucketLogging - requires more parameters
|
||||
DeletionPolicy: "Retain"
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W35
|
||||
reason: "Bucket logging requires additional configuration not yet supported by this template"
|
||||
|
||||
# Policy to allow assuming the XA_AuditRole_Prowler in target accounts
|
||||
ProwlerAuditManagerRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: AuditManagerRole_Prowler
|
||||
AssumeRolePolicyDocument:
|
||||
Version: 2012-10-17
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: codebuild.amazonaws.com
|
||||
Action:
|
||||
- sts:AssumeRole
|
||||
Path: /
|
||||
Policies:
|
||||
- PolicyName: AssumeRole-XA_AuditRole_Prowler
|
||||
PolicyDocument:
|
||||
Version: 2012-10-17
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- sts:AssumeRole
|
||||
Resource:
|
||||
- !Sub "arn:aws:iam::*:role${pAuditRolePathName}"
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- s3:PutObject
|
||||
- s3:GetObject
|
||||
- s3:GetObjectVersion
|
||||
Resource:
|
||||
- !Sub "${ProwlerResultsBucket.Arn}/*"
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- s3:ListBucket
|
||||
- s3:HeadBucket
|
||||
- s3:GetBucketLocation
|
||||
- s3:GetBucketAcl
|
||||
Resource:
|
||||
- !Sub "${ProwlerResultsBucket.Arn}"
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- logs:CreateLogGroup
|
||||
- logs:CreateLogStream
|
||||
- logs:PutLogEvents
|
||||
Resource:
|
||||
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*"
|
||||
- !Sub "${ProwlerResultsBucket.Arn}"
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- ssm:GetParameters
|
||||
Resource:
|
||||
- !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/audit/prowler/config/*"
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W28
|
||||
reason: "the role name is intentionally static"
|
||||
- id: W11
|
||||
reason: "not sure where the violation of w11 is"
|
||||
|
||||
## Code Build Job
|
||||
ProwlerBuildProject:
|
||||
Type: "AWS::CodeBuild::Project"
|
||||
Properties:
|
||||
Name: PerformProwlerAudit
|
||||
Description: "Run Prowler audit on accounts in targeted organizations"
|
||||
QueuedTimeoutInMinutes: 480
|
||||
TimeoutInMinutes: !Ref pTimeoutMinutes
|
||||
ServiceRole: !Ref ProwlerAuditManagerRole
|
||||
EncryptionKey: !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:alias/aws/s3"
|
||||
Environment:
|
||||
Type: "LINUX_CONTAINER"
|
||||
ComputeType: "BUILD_GENERAL1_MEDIUM"
|
||||
PrivilegedMode: False
|
||||
Image: "aws/codebuild/standard:2.0-1.12.0"
|
||||
ImagePullCredentialsType: "CODEBUILD"
|
||||
Artifacts:
|
||||
Name: "ProwlerResults"
|
||||
Type: "S3"
|
||||
Location: !Ref ProwlerResultsBucket
|
||||
Path: "prowler"
|
||||
NamespaceType: NONE
|
||||
Packaging: NONE
|
||||
OverrideArtifactName: False
|
||||
EncryptionDisabled: False
|
||||
LogsConfig: # S3/logs/pipeline/
|
||||
CloudWatchLogs:
|
||||
Status: ENABLED
|
||||
GroupName: "audit/prowler"
|
||||
StreamName: "codebuild_runs"
|
||||
S3Logs:
|
||||
Status: DISABLED
|
||||
# Location: !Sub "${ProwlerResultsBucket.Arn}/codebuild_run_logs"
|
||||
EncryptionDisabled: False
|
||||
BadgeEnabled: False
|
||||
Tags:
|
||||
- Key: "data-type"
|
||||
Value: "it-audit:sensitive"
|
||||
- Key: "data-public"
|
||||
Value: "NO"
|
||||
Cache:
|
||||
Type: "NO_CACHE"
|
||||
Source:
|
||||
Type: NO_SOURCE
|
||||
BuildSpec: |
|
||||
version: 0.2
|
||||
env:
|
||||
parameter-store:
|
||||
PROWL_CHECK_GROUP: /audit/prowler/config/check_group
|
||||
PROWL_MASTER_ACCOUNTS: /audit/prowler/config/orgmaster_accounts
|
||||
PROWL_STANDALONE_ACCOUNTS: /audit/prowler/config/standalone_accounts
|
||||
PROWL_SKIP_ACCOUNTS: /audit/prowler/config/skip_accounts
|
||||
PROWL_AUDIT_ROLE: /audit/prowler/config/audit_role
|
||||
PROWLER_REPO: /audit/prowler/config/gitrepo
|
||||
PROWLER_CLONE_ARGS: /audit/prowler/config/gitcloneargs
|
||||
phases:
|
||||
install:
|
||||
runtime-versions:
|
||||
python: 3.7
|
||||
commands:
|
||||
- aws --version
|
||||
- git clone --depth 1 $PROWLER_REPO $PROWLER_CLONE_ARGS
|
||||
pre_build:
|
||||
commands:
|
||||
- env | grep PROWL_
|
||||
- export OUTBASE=$(date -u +"out/diagnostics/%Y/%m/%d")
|
||||
- export STAMP=$(date -u +"%Y%m%dT%H%M%SZ")
|
||||
- mkdir -p $OUTBASE || true
|
||||
- prowler/prowler -V
|
||||
- aws sts get-caller-identity > ${OUTBASE}/${STAMP}-caller-id.json
|
||||
build:
|
||||
commands:
|
||||
#### Run Prowler against this account, but don't fail the build
|
||||
# - export PROWLER_ACCOUNT_ID=$(aws sts get-caller-identity | jq -r '.Account')
|
||||
# - /bin/bash prowler/prowler -g cislevel1 -M csv -n -k > ${OUTBASE}/${STAMP}.${PROWLER_ACCOUNT_ID}.prowler.cislevel1.csv || /bin/true
|
||||
# - /bin/bash prowler/prowler -g forensics-ready -M csv -n -k > ${OUTBASE}/${STAMP}.${PROWLER_ACCOUNT_ID}.prowler.forensics-ready.csv || /bin/true
|
||||
#### Run Prowler targeting all accounts in the configured organizations
|
||||
- test -f prowler/util/config
|
||||
- /bin/bash prowler/util/megaprowler.sh out
|
||||
finally:
|
||||
- ps axuwww | grep -E 'parallel|sem|prowler'
|
||||
post_build:
|
||||
commands:
|
||||
- echo "attempting to collect any prowler credential reports ..."
|
||||
- find /tmp/ -name prowler\* | xargs -I % cp % ${OUTDIAG} || true
|
||||
artifacts:
|
||||
files:
|
||||
- out/**/*
|
||||
discard-paths: no
|
||||
|
||||
|
||||
|
||||
|
||||
ProwlerAuditTriggerRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
# RoleName: Let cloudformation create this
|
||||
AssumeRolePolicyDocument:
|
||||
Version: 2012-10-17
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: events.amazonaws.com
|
||||
Action:
|
||||
- sts:AssumeRole
|
||||
Path: /
|
||||
Policies:
|
||||
- PolicyName: AssumeRole-XA_AuditRole_Prowler
|
||||
PolicyDocument:
|
||||
Version: 2012-10-17
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- codebuild:StartBuild
|
||||
Resource:
|
||||
- !GetAtt ProwlerBuildProject.Arn
|
||||
|
||||
ProwlerAuditTrigger:
|
||||
Type: AWS::Events::Rule
|
||||
Properties:
|
||||
Description: !Sub "Execute Prowler audit every ${pAuditEveryXHours} hours"
|
||||
Name: "ScheduledProwler"
|
||||
RoleArn: !GetAtt ProwlerAuditTriggerRole.Arn
|
||||
## Other ways to define scheduling
|
||||
# ScheduleExpression: "cron(MM HH ? * * *)"
|
||||
# ScheduleExpression: "cron(45 15 ? * * *)"
|
||||
# ScheduleExpression: !Sub "rate( ${pAuditEveryXHours} hours)"
|
||||
ScheduleExpression: !Sub "rate(${pAuditEveryXHours} hours)"
|
||||
State: ENABLED
|
||||
Targets:
|
||||
- Arn: !GetAtt ProwlerBuildProject.Arn
|
||||
Id: 'ScheduledProwler'
|
||||
RoleArn: !GetAtt ProwlerAuditTriggerRole.Arn
|
||||
|
||||
ProwlerConfigCheckGroup:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "Name of the prowler check group to use"
|
||||
Name: "/audit/prowler/config/check_group"
|
||||
Type: "String"
|
||||
Value: !Ref pProwlerCheckGroup
|
||||
|
||||
ProwlerConfigMasterAccounts:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "List of organization master accounts"
|
||||
Name: "/audit/prowler/config/orgmaster_accounts"
|
||||
Type: "String"
|
||||
Value: !Ref pOrgMasterAccounts
|
||||
|
||||
ProwlerConfigStandAloneAccounts:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "List of stand-alone accounts"
|
||||
Name: "/audit/prowler/config/standalone_accounts"
|
||||
Type: "String"
|
||||
Value: !Ref pStandAloneAccounts
|
||||
|
||||
ProwlerConfigSkipAccounts:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "List of skipped organization member accounts"
|
||||
Name: "/audit/prowler/config/skip_accounts"
|
||||
Type: "String"
|
||||
Value: !Ref pOrgExcludedAccounts
|
||||
|
||||
ProwlerConfigAuditRole:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "Role used to audit target accounts"
|
||||
Name: "/audit/prowler/config/audit_role"
|
||||
Type: "String"
|
||||
Value: !Ref pAuditRolePathName
|
||||
|
||||
ProwlerConfigGitRepo:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "Git repository where prowler is gathered"
|
||||
Name: "/audit/prowler/config/gitrepo"
|
||||
Type: "String"
|
||||
Value: !Ref pCustomProwlerRepo
|
||||
|
||||
ProwlerConfigGitCloneArgs:
|
||||
Type: AWS::SSM::Parameter
|
||||
Properties:
|
||||
Description: "Git clone arguments"
|
||||
Name: "/audit/prowler/config/gitcloneargs"
|
||||
Type: "String"
|
||||
Value: !Ref pCustomProwlerCloneArgs
|
||||
|
||||
|
||||
# -- Conditional "cUseAthena"
|
||||
# Athena
|
||||
# QuickSight
|
||||
# ???
|
||||
|
||||
|
||||
Outputs:
|
||||
ResultsBucket:
|
||||
Description: S3 Bucket with Prowler Results, Logs, Configs
|
||||
Value: !Ref ProwlerResultsBucket
|
||||
32
util/config
Normal file
32
util/config
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
########### CODEBUILD CONFIGURATION ##################
|
||||
|
||||
## Collect environment parameters set by buildspec
|
||||
CHECKGROUP=${PROWL_CHECK_GROUP}
|
||||
|
||||
if [ "none" == "${PROWL_MASTER_ACCOUNTS}" ]; then
|
||||
ORG_MASTERS=""
|
||||
else
|
||||
ORG_MASTERS=$(echo ${PROWL_MASTER_ACCOUNTS} | tr "," " ")
|
||||
fi
|
||||
|
||||
if [ "none" == "${PROWL_STANDALONE_ACCOUNTS}" ]; then
|
||||
STANDALONE_ACCOUNTS=""
|
||||
else
|
||||
STANDALONE_ACCOUNTS=$(echo ${PROWL_STANDALONE_ACCOUNTS} | tr "," " ")
|
||||
fi
|
||||
|
||||
if [ "none" == "${PROWL_SKIP_ACCOUNTS}" ]; then
|
||||
SKIP_ACCOUNTS_REGEX='^$'
|
||||
else
|
||||
skip_inside=$(echo ${PROWL_SKIP_ACCOUNTS} | tr "," "|")
|
||||
SKIP_ACCOUNTS_REGEX=$(echo "(${skip_inside})" )
|
||||
fi
|
||||
|
||||
AUDIT_ROLE=${PROWL_AUDIT_ROLE}
|
||||
|
||||
# Adjust if you clone prowler from somewhere other than the default location
|
||||
PROWLER='prowler/prowler'
|
||||
|
||||
# Change this if you want to ensure it breaks in code build
|
||||
CREDSOURCE='EcsContainer'
|
||||
190
util/megaprowler.sh
Normal file
190
util/megaprowler.sh
Normal file
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
|
||||
# source the configuration data from "config" in this directory
|
||||
if [[ -f $(dirname $0)/config ]]; then
|
||||
. $(dirname $0)/config
|
||||
else
|
||||
echo "CONFIG file missing - $(dirname $0)/config"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
## Check Environment variables which are set by config
|
||||
if [[ "${ORG_MASTERS}X" == "X" && "${STANDALONE_ACCOUNTS}X" == "X" ]]; then
|
||||
echo "No audit targets specified. Failing."
|
||||
exit 15
|
||||
fi
|
||||
if [[ -z $SKIP_ACCOUNTS_REGEX ]]; then
|
||||
SKIP_ACCOUNTS_REGEX=""
|
||||
fi
|
||||
|
||||
if [[ -z $CHECKGROUP ]]; then
|
||||
echo "Missing check group from config file"
|
||||
exit -1
|
||||
fi
|
||||
if [[ -z $AUDIT_ROLE ]]; then
|
||||
echo "Missing audit role from config file"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
## ========================================================================================
|
||||
|
||||
## Check Arguments
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "NEED AN OUTPUT DIRECTORY"
|
||||
exit 2
|
||||
else
|
||||
if [[ -d $1 && -w $1 ]]; then
|
||||
OUTBASE=$1
|
||||
else
|
||||
echo "Output directory missing or write-protected"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
## Check Requirements
|
||||
if [[ -x $(which aws) ]]; then
|
||||
aws --version
|
||||
else
|
||||
echo "AWS CLI is not in PATH ... giving up"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
if [[ -x $(which jq) ]]; then
|
||||
jq --version
|
||||
else
|
||||
echo "JQ is not in PATH ... giving up"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# Ensure AWS Credentials are present in environment
|
||||
if [[ -z $CREDSOURCE ]]; then
|
||||
echo "No source for base credentials ... giving up"
|
||||
exit 5
|
||||
fi
|
||||
# if [[ Ec2InstanceMetadata ]]
|
||||
|
||||
if [[ -f ${PROWLER} && -x ${PROWLER} ]]; then
|
||||
PROWLER_VERSION=$(${PROWLER} -V)
|
||||
else
|
||||
echo "Unable to execute prowler from ${PROWLER}"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
|
||||
## Preflight checks complete
|
||||
|
||||
DAYPATH=$(date -u +%Y/%m/%d)
|
||||
STAMP=$(date -u +%Y%m%dT%H%M%SZ)
|
||||
## Create output subdirs
|
||||
OUTDATA="${OUTBASE}/data/${DAYPATH}"
|
||||
OUTLOGS="${OUTBASE}/logs/${DAYPATH}"
|
||||
mkdir -p ${OUTDATA} ${OUTLOGS}
|
||||
|
||||
|
||||
if [[ -x $(which parallel) ]]; then
|
||||
# Note: the "standard" codebuild container includes parallel
|
||||
echo "Using GNU sem/parallel, with NCPU+4 jobs"
|
||||
parallel --citation > /dev/null 2> /dev/null
|
||||
PARALLEL_START="parallel --semaphore --fg --id p_${STAMP} --jobs +4 --env AWS_SHARED_CREDENTIALS_FILE"
|
||||
PARALLEL_START_SUFFIX=''
|
||||
PARALLEL_END="parallel --semaphore --wait --id p_${STAMP}"
|
||||
else
|
||||
echo "Consider installing GNU Parallel to avoid punishing your system"
|
||||
PARALLEL_START=''
|
||||
PARALLEL_START_SUFFIX=' &'
|
||||
PARALLEL_END="echo 'WAITING BLINDLY FOR PROCESSES TO COMPLETE'; wait ; sleep 30 ; wait"
|
||||
fi
|
||||
|
||||
echo "Execution Timestamp: ${STAMP}"
|
||||
|
||||
ALL_ACCOUNTS=""
|
||||
|
||||
|
||||
# Create a temporary credential file
|
||||
export AWS_MASTERS_CREDENTIALS_FILE=$(mktemp -t prowler.masters-XXXXXX)
|
||||
echo "Preparing Credentials ${AWS_MASTERS_CREDENTIALS_FILE} ( ${CREDSOURCE} )"
|
||||
echo "# Master Credentials ${STAMP}" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
echo "" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
|
||||
AWS_TARGETS_CREDENTIALS_FILE=$(mktemp -t prowler.targets-XXXXXX)
|
||||
echo "Preparing Credentials ${AWS_TARGETS_CREDENTIALS_FILE} ( ${CREDSOURCE} )"
|
||||
echo "# Target Credentials ${STAMP}" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
|
||||
|
||||
## Visit the Organization Master accounts & build a list of all member accounts
|
||||
export AWS_SHARED_CREDENTIALS_FILE=$AWS_MASTERS_CREDENTIALS_FILE
|
||||
for org in $ORG_MASTERS ; do
|
||||
echo -n "Preparing organization $org "
|
||||
# create credential profile
|
||||
echo "[audit_${org}]" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
echo "role_arn = arn:aws:iam::${org}:role${AUDIT_ROLE}" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
echo "credential_source = ${CREDSOURCE}" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
echo "" >> $AWS_MASTERS_CREDENTIALS_FILE
|
||||
|
||||
# Get the Organization ID to use for output paths, collecting info, etc
|
||||
org_id=$(aws --output json --profile audit_${org} organizations describe-organization | jq -r '.Organization.Id' )
|
||||
|
||||
echo "( $org_id )"
|
||||
ORG_ID_LIST="${ORG_ID_LIST} ${org_id}"
|
||||
|
||||
|
||||
# Build the list of all accounts in the organizations
|
||||
aws --output json --profile audit_${org} organizations list-accounts > ${OUTLOGS}/${STAMP}-${org_id}-account-list.json
|
||||
ORG_ACCOUNTS=$( cat ${OUTLOGS}/${STAMP}-${org_id}-account-list.json | jq -r '.Accounts[].Id' | tr "\n" " ")
|
||||
ALL_ACCOUNTS="${ALL_ACCOUNTS} ${ORG_ACCOUNTS}"
|
||||
|
||||
# Add the Org's Accounts (including master) to the TARGETS_CREDENTIALS file
|
||||
for target in $ORG_ACCOUNTS ; do
|
||||
if $(echo $target | grep -qE $SKIP_ACCOUNTS_REGEX) ; then
|
||||
echo " skipping account ${target} ( ${org_id} )"
|
||||
continue
|
||||
fi
|
||||
# echo " ${org_id}_${target}"
|
||||
echo "[${org_id}_${target}]" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "role_arn = arn:aws:iam::${target}:role${AUDIT_ROLE}" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "credential_source = ${CREDSOURCE}" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
# Prepare credentials for standalone accounts
|
||||
if [[ "" != "${STANDALONE_ACCOUNTS}" ]] ; then
|
||||
# mkdir -p ${OUTBASE}/data/standalone/${DAYPATH} ${OUTBASE}/logs/standalone/${DAYPATH}
|
||||
for target in $STANDALONE_ACCOUNTS ; do
|
||||
echo "Preparing account ${target} ( standalone )"
|
||||
echo "[standalone_${target}]" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "role_arn = arn:aws:iam::${target}:role${AUDIT_ROLE}" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "credential_source = ${CREDSOURCE}" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
echo "" >> $AWS_TARGETS_CREDENTIALS_FILE
|
||||
done
|
||||
ALL_ACCOUNTS="${ALL_ACCOUNTS} ${STANDALONE_ACCOUNTS}"
|
||||
fi
|
||||
|
||||
# grep -E '^\[' $AWS_MASTERS_CREDENTIALS_FILE $AWS_TARGETS_CREDENTIALS_FILE
|
||||
|
||||
|
||||
# Switch to Target Credential Set
|
||||
export AWS_SHARED_CREDENTIALS_FILE=${AWS_TARGETS_CREDENTIALS_FILE}
|
||||
|
||||
## visit each target account
|
||||
NUM_ACCOUNTS=$(grep -cE '^\[' ${AWS_TARGETS_CREDENTIALS_FILE})
|
||||
echo "Launching ${CHECKGROUP} audit of ${NUM_ACCOUNTS} accounts"
|
||||
for member in $(grep -E '^\[' ${AWS_TARGETS_CREDENTIALS_FILE} | tr -d '][') ; do
|
||||
ORG_ID=$(echo $member | cut -d'_' -f1)
|
||||
ACCOUNT_NUM=$(echo $member | cut -d'_' -f2)
|
||||
|
||||
${PARALLEL_START} "${PROWLER} -p ${member} -n -M csv -g ${CHECKGROUP} 2> ${OUTLOGS}/${STAMP}-${ORG_ID}-${ACCOUNT_NUM}-prowler-${CHECKGROUP}.log > ${OUTDATA}/${STAMP}-${ORG_ID}-${ACCOUNT_NUM}-prowler-${CHECKGROUP}.csv ; echo \"${ORG_ID}-${ACCOUNT_NUM}-prowler-${CHECKGROUP} finished\" " ${PARALLEL_START_SUFFIX}
|
||||
done
|
||||
|
||||
echo -n "waiting for parallel threads to complete - " ; date
|
||||
${PARALLEL_END}
|
||||
|
||||
echo "Completed ${CHECKGROUP} audit with stamp ${STAMP}"
|
||||
|
||||
# mkdir -p ${OUTBASE}/logs/debug/${DAYPATH}
|
||||
# cp $AWS_MASTERS_CREDENTIALS_FILE ${OUTLOGS}/${STAMP}-master_creds.txt
|
||||
# cp $AWS_TARGETS_CREDENTIALS_FILE ${OUTLOGS}/${STAMP}-target_creds.txt
|
||||
rm $AWS_MASTERS_CREDENTIALS_FILE $AWS_TARGETS_CREDENTIALS_FILE
|
||||
Reference in New Issue
Block a user