mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
feat(db_connector): Create a PostgreSQL connector for Prowler (#1171)
* chore(db providers): db providers first version * chore(db provider): added db provider setup into Readme * fix(csv_line): csv_line out of conditional * fix(README): text instead of varchar in table * fix(help): help message extended Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com> * fix(typo): Update README.md Co-authored-by: Pepe Fagoaga <pepe@verica.io> * fix(table): add if not exists Co-authored-by: Pepe Fagoaga <pepe@verica.io> * fix(typo): Readme postgreSQL Co-authored-by: Pepe Fagoaga <pepe@verica.io> * fix(db_connector): details to add a new provider * fix(typo): Uppercase Prowler Co-authored-by: Toni de la Fuente <toni@blyx.com> * fix(prowler): deleted unused variable * chore(checks): test db connector previous to send data * chore(input tests): input tests moved to main * fix(typo): Readme typos * chore(table): table name from pgpass file * fix(grep test): Added missing -E flag * chore(table): check of table name and Readme * chore(error colors): Added error colors * fix(tablename): table name in readme * fix(typo) * fix(db_provider): Exact match * fix(error): One line message * chore(pgpass check): Check added for pgpass file * fix(pgpass): pgpass file and permissions test * fix(unused vars): Deleted unused vars * fix(TOP_PID): Deleted TOP_PID unused var and comment * chore(db tests): Credentials, database and table tests added * fix(empty pgpass): Look for empty fields at pgpass file Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Co-authored-by: Pepe Fagoaga <pepe@verica.io> Co-authored-by: Toni de la Fuente <toni@blyx.com>
This commit is contained in:
@@ -330,6 +330,51 @@ Prowler has two parameters related to regions: `-r` that is used query AWS servi
|
||||
```
|
||||
./prowler -h
|
||||
```
|
||||
## Database providers connector
|
||||
|
||||
You can send the Prowler's output to different databases (right now only PostgreSQL is supported).
|
||||
|
||||
Jump into the section for the database provider you want to use and follow the required steps to configure it.
|
||||
### PostgreSQL
|
||||
- Install psql
|
||||
- Mac -> `brew install libpq`
|
||||
- Ubuntu -> `sudo apt-get install postgresql-client `
|
||||
- RHEL/Centos -> `sudo yum install postgresql10`
|
||||
- Configure a `~/.pgpass` file into the root folder of the user that is going to launch Prowler ([pgpass file doc](https://www.postgresql.org/docs/current/libpq-pgpass.html)), including an extra field at the end of the line, separated by `:`, to name the table, for instance:
|
||||
`hostname:port:database:username:password:prowler_findings`
|
||||
- Create a table in your PostgreSQL database to store the Prowler's data. You can use the following SQL statement to create the table:
|
||||
```
|
||||
CREATE TABLE IF NOT EXISTS prowler_findings (
|
||||
profile TEXT,
|
||||
account_number TEXT,
|
||||
region TEXT,
|
||||
check_id TEXT,
|
||||
result TEXT,
|
||||
item_scored TEXT,
|
||||
item_level TEXT,
|
||||
check_title TEXT,
|
||||
result_extended TEXT,
|
||||
check_asff_compliance_type TEXT,
|
||||
severity TEXT,
|
||||
service_name TEXT,
|
||||
check_asff_resource_type TEXT,
|
||||
check_asff_type TEXT,
|
||||
risk TEXT,
|
||||
remediation TEXT,
|
||||
documentation TEXT,
|
||||
check_caf_epic TEXT,
|
||||
resource_id TEXT,
|
||||
prowler_start_time TEXT,
|
||||
account_details_email TEXT,
|
||||
account_details_name TEXT,
|
||||
account_details_arn TEXT,
|
||||
account_details_org TEXT,
|
||||
account_details_tags TEXT
|
||||
);
|
||||
```
|
||||
- Execute Prowler with `-d` flag, for example:
|
||||
`./prowler -M csv -d postgres`
|
||||
> *Note*: This command creates a `csv` output file and stores the Prowler output in the configured PostgreSQL DB. It's an example, `-d` flag **does not** require `-M` to run.
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
@@ -490,7 +535,6 @@ Either to run Prowler once or based on a schedule this template makes it pretty
|
||||
The Cloud Formation template that helps you doing that is [here](https://github.com/prowler-cloud/prowler/blob/master/util/codebuild/codebuild-prowler-audit-account-cfn.yaml).
|
||||
|
||||
> This is a simple solution to monitor one account. For multiples accounts see [Multi Account and Continuous Monitoring](util/org-multi-account/README.md).
|
||||
|
||||
## Allowlist or remove a fail from resources
|
||||
|
||||
Sometimes you may find resources that are intentionally configured in a certain way that may be a bad practice but it is all right with it, for example an S3 bucket open to the internet hosting a web site, or a security group with an open port needed in your use case. Now you can use `-w allowlist_sample.txt` and add your resources as `checkID:resourcename` as in this command:
|
||||
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
# DB connectors
|
||||
# Supported connectors list is stored in SUPPORTED_DB_PROVIDERS
|
||||
# Once the logic of the connector is added it is needed to add it to the list also
|
||||
# Example: adding oracle to the list
|
||||
# SUPPORTED_DB_PROVIDERS="postgresql|oracle"
|
||||
# oracle_connector() { ... }
|
||||
|
||||
SUPPORTED_DB_PROVIDERS="postgresql"
|
||||
export SUPPORTED_DB_PROVIDERS
|
||||
|
||||
# Connectors for different databases
|
||||
|
||||
#POSTGRESQL connector
|
||||
postgresql_connector () {
|
||||
|
||||
CSV_REGISTRY="${1}"
|
||||
psql -q -U "${PSQL_USER}" -h "${PSQL_HOSTNAME}" -c "copy ${PSQL_TABLE} from stdin with null as E'\'\'' delimiter ','" <<< "${CSV_REGISTRY}"
|
||||
|
||||
}
|
||||
|
||||
db_exit_abnormally() {
|
||||
DB_PROVIDER="${1}"
|
||||
MESSAGE=${2}
|
||||
|
||||
echo "${OPTRED}ERROR!$OPTNORMAL Database connector for '${DB_PROVIDER}' failed. ${MESSAGE}"
|
||||
exit 2
|
||||
}
|
||||
+31
-3
@@ -44,6 +44,7 @@ HTML_LOGO_IMG="https://github.com/prowler-cloud/prowler/raw/master/util/html/pro
|
||||
TIMESTAMP=$(get_iso8601_timestamp)
|
||||
PROWLER_PARAMETERS=$@
|
||||
|
||||
|
||||
# Available parameters for outputs formats (implemented this in CSV from v2.4):
|
||||
|
||||
# $PROFILE profile used to run Prowler (--profile in AWS CLI)
|
||||
@@ -70,6 +71,8 @@ PROWLER_PARAMETERS=$@
|
||||
# $ACCOUNT_DETAILS_ORG
|
||||
# $ACCOUNT_DETAILS_TAGS
|
||||
|
||||
|
||||
|
||||
# Ensure that output directory always exists when -M is used
|
||||
if [[ $MODE ]];then
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
@@ -107,9 +110,11 @@ textPass(){
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
|
||||
CSV_LINE="${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}"
|
||||
|
||||
if [[ "${MODES[@]}" =~ "csv" ]]; then
|
||||
# Writting csv file replacing commas
|
||||
echo "${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
echo "${CSV_LINE}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
fi
|
||||
if [[ "${MODES[@]}" =~ "json" ]]; then
|
||||
generateJsonOutput "$1" "Pass" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_JSON
|
||||
@@ -134,6 +139,13 @@ textPass(){
|
||||
if [[ "${MODES[@]}" =~ "html" ]]; then
|
||||
generateHtmlOutput "$1" "PASS"
|
||||
fi
|
||||
|
||||
#checking database provider
|
||||
if [[ ${DATABASE_PROVIDER} == 'postgresql' ]]
|
||||
then
|
||||
postgresql_connector "${CSV_LINE}"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
textInfo(){
|
||||
@@ -151,9 +163,11 @@ textInfo(){
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
|
||||
CSV_LINE="${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}"
|
||||
|
||||
if [[ "${MODES[@]}" =~ "csv" ]]; then
|
||||
# Writing csv file replacing commas
|
||||
echo "${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
echo "${CSV_LINE}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
fi
|
||||
if [[ "${MODES[@]}" =~ "json" ]]; then
|
||||
generateJsonOutput "$1" "Info" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON}
|
||||
@@ -170,6 +184,12 @@ textInfo(){
|
||||
if [[ "${MODES[@]}" =~ "html" ]]; then
|
||||
generateHtmlOutput "$1" "INFO" "$CHECK_RESOURCE_ID"
|
||||
fi
|
||||
|
||||
#checking database provider
|
||||
if [[ ${DATABASE_PROVIDER} == 'postgresql' ]]
|
||||
then
|
||||
postgresql_connector "${CSV_LINE}"
|
||||
fi
|
||||
}
|
||||
|
||||
textFail(){
|
||||
@@ -217,9 +237,11 @@ textFail(){
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
|
||||
CSV_LINE="${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}"
|
||||
|
||||
if [[ "${MODES[@]}" =~ "csv" ]]; then
|
||||
# Writing csv file replacing commas
|
||||
echo "${PROFILE/,/--}${SEP}${ACCOUNT_NUM/,/--}${SEP}${REPREGION/,/--}${SEP}${TITLE_ID/,/--}${SEP}${CHECK_RESULT/,/--}${SEP}${ITEM_SCORED/,/--}${SEP}${ITEM_CIS_LEVEL/,/--}${SEP}${TITLE_TEXT/,/--}${SEP}${CHECK_RESULT_EXTENDED/,/--}${SEP}${CHECK_ASFF_COMPLIANCE_TYPE/,/--}${SEP}${CHECK_SEVERITY/,/--}${SEP}${CHECK_SERVICENAME/,/--}${SEP}${CHECK_ASFF_RESOURCE_TYPE/,/--}${SEP}${CHECK_ASFF_TYPE/,/--}${SEP}${CHECK_RISK/,/--}${SEP}${CHECK_REMEDIATION/,/--}${SEP}${CHECK_DOC/,/--}${SEP}${CHECK_CAF_EPIC/,/--}${SEP}${CHECK_RESOURCE_ID/,/--}${SEP}${PROWLER_START_TIME/,/--}${SEP}${ACCOUNT_DETAILS_EMAIL/,/--}${SEP}${ACCOUNT_DETAILS_NAME/,/--}${SEP}${ACCOUNT_DETAILS_ARN/,/--}${SEP}${ACCOUNT_DETAILS_ORG/,/--}${SEP}${ACCOUNT_DETAILS_TAGS/,/--}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
echo "${CSV_LINE}" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
|
||||
fi
|
||||
if [[ "${MODES[@]}" =~ "json" ]]; then
|
||||
generateJsonOutput "$1" "${level}" "$CHECK_RESOURCE_ID">> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON}
|
||||
@@ -247,6 +269,12 @@ textFail(){
|
||||
if [[ "${MODES[@]}" =~ "html" ]]; then
|
||||
generateHtmlOutput "$1" "${level}" "$CHECK_RESOURCE_ID"
|
||||
fi
|
||||
|
||||
#checking database provider
|
||||
if [[ ${DATABASE_PROVIDER} == 'postgresql' ]]
|
||||
then
|
||||
postgresql_connector "${CSV_LINE}"
|
||||
fi
|
||||
}
|
||||
|
||||
textTitle(){
|
||||
|
||||
@@ -46,6 +46,7 @@ TITLE_TEXT="CALLER ERROR - UNSET TITLE"
|
||||
ALLOWLIST_FILE=""
|
||||
TOTAL_CHECKS=()
|
||||
|
||||
|
||||
# Ensures command output will always be set to JSON.
|
||||
# If the default value is already set, ORIGINAL_OUTPUT will be used to store it and reset it at cleanup
|
||||
if [[ -z "${AWS_DEFAULT_OUTPUT}" ]]; then
|
||||
@@ -82,11 +83,11 @@ USAGE:
|
||||
-l List all available checks only (does not perform any check). Add -g <group_id> to only list checks within the specified group.
|
||||
-L List all groups (does not perform any check).
|
||||
-e Exclude group extras.
|
||||
-E Execute all tests except a list of specified checks separated by comma.
|
||||
-E Execute all tests except a list of specified checks separated by comma.
|
||||
(i.e. check21,check31)
|
||||
-b Do not print Prowler banner.
|
||||
-s Show scoring report (it is included by default in the html report).
|
||||
-S Send check output to AWS Security Hub. Only valid when the output mode is json-asff
|
||||
-S Send check output to AWS Security Hub. Only valid when the output mode is json-asff
|
||||
(i.e. "-M json-asff -S").
|
||||
-x Specify external directory with custom checks. S3 URI is supported.
|
||||
(i.e. /my/own/checks or s3://bucket/prefix/checks, files must start by "check").
|
||||
@@ -112,16 +113,17 @@ USAGE:
|
||||
(i.e.: "-Z check11,check12" will cause check11 and/or check12 to trigger exit code 3)
|
||||
-O <mgmnt acct ID> Specify AWS Organizations management account ID. Used to get account details, requires -R.
|
||||
(requires organizations:ListAccounts* and organizations:ListTagsForResource)
|
||||
-a <aws_cli_cmd> Build your own on-the-fly custom check by specifying the AWS CLI command to execute. Requires "-c extra9999". Omit the "aws" command and only use its parameters within quotes.
|
||||
-a <aws_cli_cmd> Build your own on-the-fly custom check by specifying the AWS CLI command to execute. Requires "-c extra9999". Omit the "aws" command and only use its parameters within quotes.
|
||||
Do not nest quotes in the aws parameter. Note that --output text is already included in the check.
|
||||
i,e. -a 'ec2 describe-security-groups --filters Name=ip-permission.to-port,Values=80 --query SecurityGroups[*].GroupId[]]'
|
||||
i,e. -a 'ec2 describe-security-groups --filters Name=ip-permission.to-port,Values=80 --query SecurityGroups[*].GroupId[]]'
|
||||
-V Show version number & exit.
|
||||
-h This help.
|
||||
-d Send output to database through database connectors supported, currently only PostgreSQL. Prowler will get the credentials and table name from your ~/.pgpass file.
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
while getopts ":hlLkqp:r:c:C:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:D:F:zZ:O:a:" OPTION; do
|
||||
while getopts ":hlLkqp:r:c:C:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:D:F:zZ:O:a:d:" OPTION; do
|
||||
case $OPTION in
|
||||
h )
|
||||
usage
|
||||
@@ -234,6 +236,9 @@ while getopts ":hlLkqp:r:c:C:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:D:F:zZ:O:a:" OPTI
|
||||
a )
|
||||
CUSTOM_CMD=$OPTARG
|
||||
;;
|
||||
d )
|
||||
DATABASE_PROVIDER=$OPTARG
|
||||
;;
|
||||
: )
|
||||
echo ""
|
||||
echo "$OPTRED ERROR!$OPTNORMAL -$OPTARG requires an argument"
|
||||
@@ -258,7 +263,7 @@ clean_up() {
|
||||
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
|
||||
fi
|
||||
# puts the AWS_DEFAULT_OUTPUT back to what it was at the start
|
||||
if [ -z "$ORIGINAL_OUTPUT"]; then
|
||||
if [ -z "$ORIGINAL_OUTPUT" ]; then
|
||||
export AWS_DEFAULT_OUTPUT="$ORIGINAL_OUTPUT"
|
||||
else
|
||||
unset AWS_DEFAULT_OUTPUT
|
||||
@@ -301,6 +306,10 @@ unset AWS_DEFAULT_OUTPUT
|
||||
. $PROWLER_DIR/include/organizations_metadata
|
||||
. $PROWLER_DIR/include/custom_checks
|
||||
. $PROWLER_DIR/include/allowlist
|
||||
. $PROWLER_DIR/include/db_connector
|
||||
|
||||
|
||||
|
||||
|
||||
# Parses the check file into CHECK_ID's.
|
||||
if [[ -n "$CHECK_FILE" ]]; then
|
||||
@@ -315,6 +324,51 @@ if [[ -n "$CHECK_FILE" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check database providers
|
||||
if [[ ${DATABASE_PROVIDER} ]]
|
||||
then
|
||||
# Check if input provider is supported
|
||||
if ! grep -w -q -E "${DATABASE_PROVIDER}" <<< "${SUPPORTED_DB_PROVIDERS}"
|
||||
then
|
||||
db_exit_abnormally "${DATABASE_PROVIDER}" "DB provider not supported, providers supported: ${SUPPORTED_DB_PROVIDERS} - EXITING!"
|
||||
elif ! command -v "psql" > /dev/null 2>&1
|
||||
then
|
||||
db_exit_abnormally "postgresql" "psql tool not installed or not found- EXITING!"
|
||||
elif [[ $(find "${HOME}/.pgpass" -perm 600 2>/dev/null) != "$HOME/.pgpass" ]]
|
||||
then
|
||||
db_exit_abnormally "postgresql" ".pgpass file not found at $HOME/.pgpass or .pgpass file permissions not matching 600 - EXITING!"
|
||||
else
|
||||
IFS=':' read -r PSQL_HOSTNAME PSQL_PORT PSQL_DATABASE PSQL_USER PSQL_PASSWORD PSQL_TABLE < "$HOME/.pgpass"
|
||||
if [[ ! ${PSQL_HOSTNAME} ]] || [[ ! ${PSQL_PORT} ]] || [[ ! ${PSQL_DATABASE} ]] || [[ ! ${PSQL_USER} ]] || [[ ! ${PSQL_PASSWORD} ]] || [[ ! ${PSQL_TABLE} ]]
|
||||
then
|
||||
db_exit_abnormally "postgresql" "Empty field into ${HOME}/.pgpass file, all fields must be filled. Please check Prowler README about .pgpass file format - EXITING!"
|
||||
fi
|
||||
export PSQL_USER
|
||||
export PSQL_HOSTNAME
|
||||
export PSQL_TABLE
|
||||
|
||||
# Once all the variables are defined and exported test if database instance is reachable
|
||||
if ! pg_isready -q -U "${PSQL_USER}" -h "${PSQL_HOSTNAME}" -p "${PSQL_PORT}"
|
||||
then
|
||||
db_exit_abnormally "postgresql" "Database listening on host ${PSQL_HOSTNAME} on port ${PSQL_PORT} connected as user ${PSQL_USER} is unreachable - EXITING!"
|
||||
# If database instance is ready time to check credentials
|
||||
elif ! PGPASSWORD="${PSQL_PASSWORD}" psql -U "${PSQL_USER}" -h "${PSQL_HOSTNAME}" -c "\q" > /dev/null 2>&1
|
||||
then
|
||||
db_exit_abnormally "postgresql" "User ${PSQL_USER} invalid or invalid credentials, please check ${HOME}/.pgpass file - EXITING!"
|
||||
# If credentials are ok -> database exists?
|
||||
elif ! PGPASSWORD="${PSQL_PASSWORD}" psql -U "${PSQL_USER}" -h "${PSQL_HOSTNAME}" "${PSQL_DATABASE}" -c "\q" > /dev/null 2>&1
|
||||
then
|
||||
db_exit_abnormally "postgresql" "Database not exists, please check ${HOME}/.pgpass file - EXITING!"
|
||||
# and finally, if database exists -> table exists ?
|
||||
elif ! PGPASSWORD="${PSQL_PASSWORD}" psql -U "${PSQL_USER}" -h "${PSQL_HOSTNAME}" "${PSQL_DATABASE}" -c "SELECT * FROM ${PSQL_TABLE};" > /dev/null 2>&1
|
||||
then
|
||||
db_exit_abnormally "postgresql" "Table ${PSQL_TABLE} not exists, please check ${HOME}/.pgpass file - EXITING!"
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
# Pre-process allowlist file if supplied
|
||||
if [[ -n "$ALLOWLIST_FILE" ]]; then
|
||||
allowlist
|
||||
|
||||
Reference in New Issue
Block a user