128 lines
4.4 KiB
Bash
128 lines
4.4 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# prowler-runner.sh
|
||
|
|
# Wraps the Prowler v5 Docker container, passing AWS credentials via environment
|
||
|
|
# variables and additional CLI flags from config/prowler-config.yaml.
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# ./prowler-runner.sh # uses default profile from ~/.aws/credentials
|
||
|
|
# ./prowler-runner.sh --profile security # use a specific AWS profile
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
CONFIG_FILE="${SCRIPT_DIR}/config/prowler-config.yaml"
|
||
|
|
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
||
|
|
CRED_FILE="${HOME}/.aws/credentials"
|
||
|
|
|
||
|
|
# Ensure output directory exists
|
||
|
|
mkdir -p "${OUTPUT_DIR}"
|
||
|
|
|
||
|
|
# Parse CLI args for optional --profile
|
||
|
|
PROFILE="default"
|
||
|
|
while [[ $# -gt 0 ]]; do
|
||
|
|
case "$1" in
|
||
|
|
--profile) PROFILE="$2"; shift 2 ;;
|
||
|
|
*) EXTRA_CLI_FLAGS="${EXTRA_CLI_FLAGS} $1"; shift ;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
|
||
|
|
# Extract AWS credentials from ~/.aws/credentials for the target profile
|
||
|
|
# Supports [default] and named profiles
|
||
|
|
extract_cred() {
|
||
|
|
local profile="$1"
|
||
|
|
local key="$2"
|
||
|
|
local section=""
|
||
|
|
while IFS= read -r line; do
|
||
|
|
line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||
|
|
if echo "$line" | grep -qE '^\[.*\]$'; then
|
||
|
|
section=$(echo "$line" | sed 's/^\[\(.*\)\]$/\1/')
|
||
|
|
elif [[ "$section" == "$profile" ]] && echo "$line" | grep -qE "^${key}[[:space:]]*="; then
|
||
|
|
echo "$line" | sed "s/^[^=]*=[[:space:]]*//" | tr -d ' '
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
done < "$CRED_FILE"
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
|
||
|
|
AWS_KEY=$(extract_cred "$PROFILE" "aws_access_key_id")
|
||
|
|
AWS_SECRET=$(extract_cred "$PROFILE" "aws_secret_access_key")
|
||
|
|
|
||
|
|
if [[ -z "$AWS_KEY" || -z "$AWS_SECRET" ]]; then
|
||
|
|
echo "[prowler-runner] ERROR: Could not extract credentials for profile '$PROFILE' from ${CRED_FILE}" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Build extra flags from config file if it exists and is non-empty
|
||
|
|
EXTRA_FLAGS=""
|
||
|
|
if [[ -f "${CONFIG_FILE}" ]]; then
|
||
|
|
while IFS=$'\n' read -r line; do
|
||
|
|
line=$(echo "${line}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/#.*//')
|
||
|
|
[[ -z "${line}" ]] && continue
|
||
|
|
if echo "${line}" | grep -qE '^[a-z_]+:'; then
|
||
|
|
key=$(echo "${line}" | cut -d: -f1 | tr -d ' ')
|
||
|
|
value=$(echo "${line}" | cut -d: -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||
|
|
case "${key}" in
|
||
|
|
regions)
|
||
|
|
for region in ${value//,/ }; do
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --region ${region}"
|
||
|
|
done
|
||
|
|
;;
|
||
|
|
severity)
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --severity ${value}"
|
||
|
|
;;
|
||
|
|
services)
|
||
|
|
for svc in ${value//,/ }; do
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --service ${svc}"
|
||
|
|
done
|
||
|
|
;;
|
||
|
|
exclude_checks)
|
||
|
|
for check in ${value//,/ }; do
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --excluded-check ${check}"
|
||
|
|
done
|
||
|
|
;;
|
||
|
|
threads)
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --aws-retries-max-attempts ${value}"
|
||
|
|
;;
|
||
|
|
compliance)
|
||
|
|
for comp in ${value//,/ }; do
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS} --compliance ${comp}"
|
||
|
|
done
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
fi
|
||
|
|
done < "${CONFIG_FILE}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
EXTRA_FLAGS="${EXTRA_FLAGS}${EXTRA_CLI_FLAGS:-}"
|
||
|
|
|
||
|
|
echo "[prowler-runner] Starting Prowler scan at $(date)"
|
||
|
|
echo "[prowler-runner] Profile: ${PROFILE}"
|
||
|
|
echo "[prowler-runner] Output directory: ${OUTPUT_DIR}"
|
||
|
|
[[ -n "${EXTRA_FLAGS}" ]] && echo "[prowler-runner] Extra flags: ${EXTRA_FLAGS}"
|
||
|
|
|
||
|
|
# Run the Prowler container
|
||
|
|
# - Pass credentials via env vars (toniblyx/prowler does not read ~/.aws from /root/.aws mount)
|
||
|
|
# - Mount ./output as /output inside the container for findings output
|
||
|
|
# - Mount ./config as /config inside the container
|
||
|
|
docker run --rm \
|
||
|
|
-e "AWS_ACCESS_KEY_ID=${AWS_KEY}" \
|
||
|
|
-e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET}" \
|
||
|
|
-e "AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-us-east-1}" \
|
||
|
|
-v "${SCRIPT_DIR}/output:/output" \
|
||
|
|
-v "${SCRIPT_DIR}/config:/config:ro" \
|
||
|
|
toniblyx/prowler:latest \
|
||
|
|
aws \
|
||
|
|
--output-formats csv \
|
||
|
|
--output-directory /output \
|
||
|
|
${EXTRA_FLAGS}
|
||
|
|
|
||
|
|
EXIT_CODE=$?
|
||
|
|
|
||
|
|
if [[ ${EXIT_CODE} -eq 0 ]]; then
|
||
|
|
echo "[prowler-runner] Scan completed successfully at $(date)"
|
||
|
|
else
|
||
|
|
echo "[prowler-runner] Scan exited with code ${EXIT_CODE}" >&2
|
||
|
|
fi
|
||
|
|
|
||
|
|
exit ${EXIT_CODE}
|