-
Notifications
You must be signed in to change notification settings - Fork 27
/
run_audit.sh
executable file
·214 lines (185 loc) · 7.43 KB
/
run_audit.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#! /bin/bash
# script to run audit while populating local host data
# 13th Sept 2021 - Initial
# 9th Nov 2021 - Added root user check - more posix compliant for multiple OS types
# 10 Dec 2021 - Enhanced so more linux OS agnostic, less input required
# - added vars options for bespoke vars file
# - Ability to run as script from remediation role increased consistency
# 17 Dec 2021 - Added system_type variable - default Server will change to workstations with -w switch
# 02 Mar 2022 - Updated benchmark variable naming
# 06 Apr 2022 - Added format option in output inline with goss options e.g. json documentation this is for fault finding
# 03 May 2022 - update for audit variables improvement added by @pavloos - https://github.com/ansible-lockdown/RHEL8-CIS-Audit/pull/29
# 10 Jun 2022 - added format output for different type - supports json,documentation or rspecish
# 04 Oct 2022 - Changed default content location to /opt
# 14 Sep 2023 - Tidyup of code,
# linting (thanks to @cf-sewe)
# Oracle included by default if RHEL family
# benchmark vars moved
# December 2023 Added goss version and testing
# April 2024 Updating of OS discovery to work for all supported OSs
# Variables in upper case tend to be able to be adjusted
# lower case variables are discovered or built from other variables
# Goss benchmark variables (these should not need changing unless new release)
BENCHMARK=CIS # Benchmark Name aligns to the audit
BENCHMARK_VER=2.0.0
BENCHMARK_OS=RHEL8
# Goss host Variables
AUDIT_BIN="${AUDIT_BIN:-/usr/local/bin/goss}" # location of the goss executable
AUDIT_BIN_MIN_VER="0.3.21"
AUDIT_FILE="${AUDIT_FILE:-goss.yml}" # the default goss file used by the audit provided by the audit configuration
AUDIT_CONTENT_LOCATION="${AUDIT_CONTENT_LOCATION:-/opt}" # Location of the audit configuration file as available to the OS
# help output
Help()
{
# Display Help
echo "Script to run the goss audit"
echo
echo "Syntax: $0 [-f|-g|-o|-v|-w|-h]"
echo "options:"
echo "-f optional - change the format output (default value = json)"
echo "-g optional - Add a group that the server should be grouped with (default value = ungrouped)"
echo "-o optional - file to output audit data"
echo "-v optional - relative path to thevars file to load (default e.g. $AUDIT_CONTENT_LOCATION/RHEL7-$BENCHMARK/vars/$BENCHMARK.yml)"
echo "-w optional - Sets the system_type to workstation (Default - Server)"
echo "-h Print this Help."
echo
}
# Default vars that can be set
host_system_type=Server
## option statement
while getopts f:g:o:v::wh option; do
case "${option}" in
f ) FORMAT=${OPTARG} ;;
g ) GROUP=${OPTARG} ;;
o ) OUTFILE=${OPTARG} ;;
v ) VARS_PATH=${OPTARG} ;;
w ) host_system_type=Workstation ;;
h ) # display Help
Help
exit;;
? ) # Invalid option
echo "Invalid option: -${OPTARG}."
Help
exit;;
esac
done
#### Pre-Checks
# check access need to run as root or privileges due to some configuration access
if [ "$(/usr/bin/id -u)" -ne 0 ]; then
echo "Script need to run with root privileges"
exit 1
fi
#### Main Script ####
# Discover OS version aligning with audit
# Define os_vendor variable
if [ "$(uname -a | grep -cw amzn)" -ge 1 ]; then
os_vendor="AMAZON"
elif [ "$(grep -Ec "rhel|oracle" /etc/os-release)" != 0 ]; then
os_vendor="RHEL"
else
os_vendor="$(hostnamectl | grep Oper | cut -d : -f2 | awk '{print tolower($1)}')"
fi
os_maj_ver="$(grep -w VERSION_ID= /etc/os-release | awk -F\" '{print $2}' | cut -d '.' -f1)"
audit_content_version=$os_vendor$os_maj_ver-$BENCHMARK-Audit
audit_content_dir=$AUDIT_CONTENT_LOCATION/$audit_content_version
audit_vars=vars/${BENCHMARK}.yml
# Set variable for format output
if [ -z "$FORMAT" ]; then
export format="json"
else
export format=$FORMAT
fi
# Set variable for autogroup
if [ -z "$GROUP" ]; then
export host_auto_group="ungrouped"
else
export host_auto_group=$GROUP
fi
# set default variable for varfile_path
if [ -z "$VARS_PATH" ]; then
export varfile_path=$audit_content_dir/$audit_vars
else
# Check -v exists fail if not
if [ -f "$VARS_PATH" ]; then
export varfile_path=$VARS_PATH
else
echo "passed option '-v' $VARS_PATH does not exist"
exit 1
fi
fi
## System variables captured for metadata
host_machine_uuid="$(if [ -f /sys/class/dmi/id/product_uuid ]; then cat /sys/class/dmi/id/product_uuid; else dmidecode -s system-uuid; fi)"
host_epoch="$(date +%s)"
host_os_locale="$(date +%Z)"
host_os_name="$(grep "^NAME=" /etc/os-release | cut -d '"' -f2 | sed 's/ //' | cut -d' ' -f1)"
host_os_version="$(grep "^VERSION_ID=" /etc/os-release | cut -d '"' -f2)"
host_os_hostname="$(hostname)"
## Set variable audit_out
if [ -z "$OUTFILE" ]; then
export audit_out=${AUDIT_CONTENT_LOCATION}/audit_${host_os_hostname}-${BENCHMARK}-${BENCHMARK_OS}_${host_epoch}.$format
else
export audit_out=${OUTFILE}
fi
## Set the AUDIT json string
audit_json_vars='{"benchmark_type":"'"$BENCHMARK"'","benchmark_os":"'"$BENCHMARK_OS"'","benchmark_version":"'"$BENCHMARK_VER"'","machine_uuid":"'"$host_machine_uuid"'","epoch":"'"$host_epoch"'","os_locale":"'"$host_os_locale"'","os_release":"'"$host_os_version"'","os_distribution":"'"$host_os_name"'","os_hostname":"'"$host_os_hostname"'","auto_group":"'"$host_auto_group"'","system_type":"'"$host_system_type"'"}'
## Run pre checks
echo
echo "## Pre-Checks Start"
echo
export FAILURE=0
if [ -s "${AUDIT_BIN}" ]; then
echo "OK - Audit binary $AUDIT_BIN is available"
goss_installed_version="$($AUDIT_BIN -v | awk '{print $NF}' | cut -dv -f2)"
newer_version=$(echo -e "$goss_installed_version\n$AUDIT_BIN_MIN_VER" | sort -V | tail -n 1)
if [ "$goss_installed_version" = "$newer_version" ] || [ "$goss_installed_version" = "$AUDIT_BIN_MIN_VER" ]; then
echo "OK - Goss is installed and version is ok ($goss_installed_version >= $AUDIT_BIN_MIN_VER)"
else
echo "WARNING - Goss installed = ${goss_installed_version}, does not met minimum of ${AUDIT_BIN_MIN_VER}"
export FAILURE=2
fi
else
echo "WARNING - The audit binary is not available at $AUDIT_BIN "
export FAILURE=1
fi
if [ -f "${audit_content_dir}/${AUDIT_FILE}" ]; then
echo "OK - ${audit_content_dir}/${AUDIT_FILE} is available"
else
echo "WARNING - the $audit_content_dir/$AUDIT_FILE is not available"; export FAILURE=3
fi
if [ "${FAILURE}" != 0 ]; then
echo "## Pre-checks failed please see output"
exit 1
else
echo
echo "## Pre-checks Successful"
echo
fi
# format output types
# json, rspecish = grep -A 4 \"summary\": $audit_out
# tap junit no output as no summary
# documentation = tail -2 $audit_out
# defaults
output_summary="tail -2 $audit_out"
format_output="-f $format"
if [ "$format" = json ]; then
format_output="-f json -o pretty"
output_summary='grep -A 4 \"summary\": $audit_out'
elif [ "$format" = junit ] || [ "$format" = tap ]; then
output_summary=""
fi
## Run commands
echo "#############"
echo "Audit Started"
echo "#############"
echo
$AUDIT_BIN -g "$audit_content_dir/$AUDIT_FILE" --vars "$varfile_path" --vars-inline "$audit_json_vars" v $format_output > "$audit_out"
# create screen output
if [ "$(grep -c $BENCHMARK "$audit_out")" != 0 ] || [ "$format" = junit ] || [ "$format" = tap ]; then
eval $output_summary
echo "Completed file can be found at $audit_out"
echo "###############"
echo "Audit Completed"
echo "###############"
else
echo -e "Fail: There were issues when running the audit please investigate $audit_out"
fi