Compare commits

...

31 commits

Author SHA1 Message Date
Jérémy Lecour 735c960621 Merge branch 'master' into master 2022-06-06 14:46:42 +02:00
Jérémy Lecour 5f9b6901cb Merge pull request 'add support for options in sources.list' (#143) from sources.list-support-option into master
Reviewed-on: evolix/evocheck#143
2022-06-06 11:17:10 +02:00
Brice Waegeneire 1a08da8afa add support for options in sources.list
Exemple for such syntax (from the manual):
deb [ arch=amd64,armel ] http://deb.debian.org/debian bullseye main
2022-06-03 11:20:37 +02:00
Jérémy Lecour 0c461689d1 Merge pull request 'sshpermitrootno: Use effective configuration.' (#135) from fix-129 into master
Reviewed-on: evolix/evocheck#135
2022-06-03 11:15:45 +02:00
Brice Waegeneire e38aa5636f sshpermitrootno: Use effective configuration.
Fixes #129.
2022-06-03 11:03:50 +02:00
Jérémy Lecour 9ad34bd485 fix changelog 2022-06-03 09:11:54 +02:00
Jérémy Lecour 38276b0271 Release 22.06 2022-06-03 09:10:19 +02:00
Jérémy Lecour 1d75b5fbbf fix CHANGELOG 2022-06-03 09:07:46 +02:00
Jérémy Lecour 5fa58e8321 Add abenmiloud to authors 2022-06-03 09:07:46 +02:00
Alexis Ben Miloud--Josselin d834e69cf6 Add IS_NETWORKING_SERVICE check 2022-06-03 09:07:46 +02:00
Jérémy Lecour d94dad77bb IS_AUTOIF: Ignore WireGuard interfaces 2022-06-03 09:06:17 +02:00
Gregory Colpart 294c96b077 Fix Debian security repo for Bullseye, cf https://www.debian.org/releases/stable/errata 2022-05-31 11:04:35 +02:00
Bruno TATU 3935bccfab #65947 meilleure détection de dump compressé ou non pour mongo 2022-05-25 17:02:28 +02:00
William Hirigoyen (Evolix) 124efe7f38 Ajoute le cas /etc/init.d/alert5 pour IS_ALERT5MINIFW et IS_ALERT5BOOT 2022-05-25 12:22:55 +02:00
Jérémy Lecour 40687bc294 Release 22.05 2022-05-12 15:45:54 +02:00
Jérémy Lecour 7a57016da1 IS_EVOBACKUP_EXCLUDE_MOUNT: exclude scripts without Rsync command 2022-05-12 15:44:23 +02:00
Jérémy Lecour 7ff09cd973 Release 22.04.1 2022-04-25 10:33:11 +02:00
Jérémy Lecour bef0eba539 IS_EVOBACKUP_EXCLUDE_MOUNT: fix one-file-system restriction 2022-04-25 10:32:26 +02:00
Jérémy Lecour f5b19ad656 fix various shellcheck violations 2022-04-25 10:08:49 +02:00
Jérémy Lecour e1bafc2a0a Release 22.04 2022-04-25 09:57:09 +02:00
Jérémy Lecour 3694b364d3 IS_EVOBACKUP_EXCLUDE_MOUNT : skip if --one-file-system is used 2022-04-25 09:55:12 +02:00
David Prevot 13859f306b evocheck.sh: tfix
Some checks failed
continuous-integration/drone Build is failing
2022-04-19 17:47:57 +02:00
Alexis Ben Miloud--Josselin b92d81fd91 Typo in check_version' error message 2022-04-19 14:22:15 +02:00
Jérémy Dubois 6eeca5eacd check_versions: "IS_CHECK_VERSIONS" was checked but "IS_VERSIONS_CHECK" was echoed, now "IS_CHECK_VERSIONS" everywhere 2022-04-14 09:45:39 +02:00
Mathieu Trossevin 3c0a88074f
Update changelog 2022-03-29 16:27:15 +02:00
Mathieu Trossevin a14c83904f
check_debiansecurity: https://security.debian.org/debian-security is valid on bullseye
The documentation for upgrading from buster and
https://www.debian.org/security/ use 2 different URLs for the security
repository. Consider both as valid.
2022-03-29 16:23:20 +02:00
Jérémy Dubois dabf05b4b7 Release 22.03.1 2022-03-22 11:01:43 +01:00
Jérémy Dubois e921420d20 check_autoif : Ignore lxcbr interfaces, new in bullseye 2022-03-22 11:01:21 +01:00
Jérémy Lecour 26be0dfe72 Release 22.03 2022-03-15 23:23:24 +01:00
Jérémy Lecour 93f8440c92 check_versions : track minifirewall version 2022-03-15 23:21:49 +01:00
Jérémy Lecour 1f81732c44 Better cleanup of temporary files + buffer for main output 2022-01-27 18:42:48 +01:00
2 changed files with 160 additions and 49 deletions

View file

@ -5,8 +5,6 @@ and this project **does not adhere to [Semantic Versioning](http://semver.org/sp
### Added
check_mysqlmunin : Complain if munin plugin mysql_commands returns an error
### Changed
### Deprecated
@ -17,6 +15,60 @@ check_mysqlmunin : Complain if munin plugin mysql_commands returns an error
### Security
## [22.06] 2022-06-03
### Added
* IS_AUTOIF: Ignore WireGuard interfaces
* IS_NETWORKING_SERVICE: check if networking service is enabled
### Changed
* IS_DEBIANSECURITY: Fix Debian security repo for Bullseye, cf https://www.debian.org/releases/stable/errata
## [22.05] 2022-05-12
### Changed
* IS_EVOBACKUP_EXCLUDE_MOUNT: exclude scripts without Rsync command
## [22.04.1] 2022-04-25
### Changed
* fix various shellcheck violations
### Fixed
* IS_EVOBACKUP_EXCLUDE_MOUNT: fix one-file-system restriction
## [22.04] 2022-04-25
### Changed
* IS_EVOBACKUP_EXCLUDE_MOUNT : skip if --one-file-system is used
### Fixed
* check_versions: "IS_CHECK_VERSIONS" was checked but "IS_VERSIONS_CHECK" was echoed, now "IS_CHECK_VERSIONS" everywhere
### Security
* check_debiansecurity: Consider both https://deb\.debian\.org/debian-security/ and https://security\.debian\.org/debian-security/ as valid since both are documented as such.
## [22.03.1] 2022-03-22
### Changed
* check_autoif : Ignore lxcbr interfaces, new since bullseye
## [22.03] 2022-03-15
### Added
* check_mysqlmunin : Complain if munin plugin mysql_commands returns an error
* check_versions : track minifirewall version
## [21.10.4] 2021-10-25
### Changed
@ -33,7 +85,8 @@ check_mysqlmunin : Complain if munin plugin mysql_commands returns an error
## [21.10.2] 2021-10-22
### Changed
Let's try the --version flag before falling back to grep for the constant
* Let's try the --version flag before falling back to grep for the constant
## [21.10.1] 2021-10-01

View file

@ -4,7 +4,7 @@
# Script to verify compliance of a Debian/OpenBSD server
# powered by Evolix
VERSION="21.10.4"
VERSION="22.06"
readonly VERSION
# base functions
@ -13,13 +13,14 @@ show_version() {
cat <<END
evocheck version ${VERSION}
Copyright 2009-2021 Evolix <info@evolix.fr>,
Copyright 2009-2022 Evolix <info@evolix.fr>,
Romain Dessort <rdessort@evolix.fr>,
Benoit Série <bserie@evolix.fr>,
Gregory Colpart <reg@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
Tristan Pilat <tpilat@evolix.fr>,
Victor Laborie <vlaborie@evolix.fr>
Victor Laborie <vlaborie@evolix.fr>,
Alexis Ben Miloud--Josselin <abenmiloud@evolix.fr>,
and others.
evocheck comes with ABSOLUTELY NO WARRANTY. This is free software,
@ -142,9 +143,9 @@ failed() {
RC=1
if [ "${QUIET}" != 1 ]; then
if [ -n "${check_comments}" ] && [ "${VERBOSE}" = 1 ]; then
printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" 2>&1
printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" >> "${main_output_file}"
else
printf "%s FAILED!\n" "${check_name}" 2>&1
printf "%s FAILED!\n" "${check_name}" >> "${main_output_file}"
fi
fi
}
@ -234,11 +235,12 @@ check_syslogconf() {
check_debiansecurity() {
if is_debian_bullseye; then
# https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.html#security-archive
pattern="^deb https://deb\.debian\.org/debian-security/? bullseye-security main"
# https://www.debian.org/security/
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? bullseye-security main"
elif is_debian_buster; then
pattern="^deb http://security\.debian\.org/debian-security/? buster/updates main"
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? buster/updates main"
elif is_debian_stretch; then
pattern="^deb http://security\.debian\.org/debian-security/? stretch/updates main"
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? stretch/updates main"
else
pattern="^deb.*security"
fi
@ -328,11 +330,16 @@ check_tmoutprofile() {
check_alert5boot() {
if is_debian_buster || is_debian_bullseye; then
grep -qs "^date" /usr/share/scripts/alert5.sh || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script"
test -f /etc/systemd/system/alert5.service || failed "IS_ALERT5BOOT" "alert5 unit file is missing"
systemctl is-enabled alert5 -q || failed "IS_ALERT5BOOT" "alert5 unit is not enabled"
if [ -f /etc/systemd/system/alert5.service ]; then
systemctl is-enabled alert5.service -q || failed "IS_ALERT5BOOT" "alert5 unit is not enabled"
else
failed "IS_ALERT5BOOT" "alert5 unit file is missing"
fi
else
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^date" /etc/rc2.d/S*alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script"
elif [ -n "$(find /etc/init.d/ -name 'alert5')" ]; then
grep -q "^date" /etc/init.d/alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 int script"
else
failed "IS_ALERT5BOOT" "alert5 init script is missing"
fi
@ -346,6 +353,9 @@ check_alert5minifw() {
if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then
grep -q "^/etc/init.d/minifirewall" /etc/rc2.d/S*alert5 \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 init script"
elif [ -n "$(find /etc/init.d/ -name 'alert5')" ]; then
grep -q "^/etc/init.d/minifirewall" /etc/init.d/alert5 \
|| failed "IS_ALERT5MINIFW" "Minifirewall is not started by alert5 init script"
else
failed "IS_ALERT5MINIFW" "alert5 init script is missing"
fi
@ -353,7 +363,7 @@ check_alert5minifw() {
}
check_minifw() {
/sbin/iptables -L -n | grep -q -E "^ACCEPT\s*all\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
|| failed "IS_MINIFW" "minifirewall seems not starded"
|| failed "IS_MINIFW" "minifirewall seems not started"
}
check_minifw_includes() {
if is_debian_bullseye; then
@ -567,7 +577,7 @@ check_network_interfaces() {
# Verify if all if are in auto
check_autoif() {
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
interfaces=$(/sbin/ip address show up | grep "^[0-9]*:" | grep -E -v "(lo|vnet|docker|veth|tun|tap|macvtap|vrrp)" | cut -d " " -f 2 | tr -d : | cut -d@ -f1 | tr "\n" " ")
interfaces=$(/sbin/ip address show up | grep "^[0-9]*:" | grep -E -v "(lo|vnet|docker|veth|tun|tap|macvtap|vrrp|lxcbr|wg)" | cut -d " " -f 2 | tr -d : | cut -d@ -f1 | tr "\n" " ")
else
interfaces=$(/sbin/ifconfig -s | tail -n +2 | grep -E -v "^(lo|vnet|docker|veth|tun|tap|macvtap|vrrp)" | cut -d " " -f 1 |tr "\n" " ")
fi
@ -585,6 +595,16 @@ check_interfacesgw() {
number=$(grep -Ec "^[^#]*gateway [0-9a-fA-F]+:" /etc/network/interfaces)
test "$number" -gt 1 && failed "IS_INTERFACESGW" "there is more than 1 IPv6 gateway"
}
# Verification de létat du service networking
check_networking_service() {
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
if systemctl is-enabled networking.service > /dev/null; then
if ! systemctl is-active networking.service > /dev/null; then
failed "IS_NETWORKING_SERVICE" "networking.service is not active"
fi
fi
fi
}
# Verification de la mise en place d'evobackup
check_evobackup() {
evobackup_found=$(find /etc/cron* -name '*evobackup*' | wc -l)
@ -592,18 +612,24 @@ check_evobackup() {
}
# Vérification de l'exclusion des montages (NFS) dans les sauvegardes
check_evobackup_exclude_mount() {
excludes_file=$(mktemp)
# shellcheck disable=SC2064
trap "rm -f ${excludes_file}" 0
excludes_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.evobackup_exclude_mount.XXXXX")
files_to_cleanup="${files_to_cleanup} ${excludes_file}"
# shellcheck disable=SC2044
for evobackup_file in $(find /etc/cron* -name '*evobackup*' | grep -v -E ".disabled$"); do
grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}"
not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}")
for mount in ${not_excluded}; do
failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script"
done
# if the file seems to be a backup script, with an Rsync invocation
if grep -q "^\s*rsync" "${evobackup_file}"; then
# If rsync is not limited by "one-file-system"
# then we verify that every mount is excluded
if ! grep -q -- "^\s*--one-file-system" "${evobackup_file}"; then
grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}"
not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}")
for mount in ${not_excluded}; do
failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script"
done
fi
fi
done
rm -rf "${excludes_file}"
}
# Verification de la presence du userlogrotate
check_userlogrotate() {
@ -809,8 +835,10 @@ check_tune2fs_m5() {
check_evolinuxsudogroup() {
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
if grep -q "^evolinux-sudo:" /etc/group; then
grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \
|| failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file"
if [ -f /etc/sudoers.d/evolinux ]; then
grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \
|| failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file"
fi
fi
fi
}
@ -943,7 +971,7 @@ check_mongo_backup() {
# You could change the default path in /etc/evocheck.cf
MONGO_BACKUP_PATH=${MONGO_BACKUP_PATH:-"/home/backup/mongodump"}
if [ -d "$MONGO_BACKUP_PATH" ]; then
for file in "${MONGO_BACKUP_PATH}"/*/*.{json,bson}; do
for file in "${MONGO_BACKUP_PATH}"/*/*.{json,bson}.*; do
# Skip indexes file.
if ! [[ "$file" =~ indexes ]]; then
limit=$(date +"%s" -d "now - 2 day")
@ -1064,8 +1092,10 @@ check_squidevolinuxconf() {
check_duplicate_fs_label() {
# Do it only if thereis blkid binary
BLKID_BIN=$(command -v blkid)
if [ -x "$BLKID_BIN" ]; then
tmpFile=$(mktemp -p /tmp)
if [ -n "$BLKID_BIN" ]; then
tmpFile=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.duplicate_fs_label.XXXXX")
files_to_cleanup="${files_to_cleanup} ${tmpFile}"
parts=$($BLKID_BIN -c /dev/null | grep -ve raid_member -e EFI_SYSPART | grep -Eo ' LABEL=".*"' | cut -d'"' -f2)
for part in $parts; do
echo "$part" >> "$tmpFile"
@ -1078,7 +1108,6 @@ check_duplicate_fs_label() {
labels=$(echo -n $tmpOutput | tr '\n' ' ')
failed "IS_DUPLICATE_FS_LABEL" "Duplicate labels: $labels"
fi
rm "$tmpFile"
else
failed "IS_DUPLICATE_FS_LABEL" "blkid not found in ${PATH}"
fi
@ -1188,14 +1217,20 @@ check_usrsharescripts() {
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
}
check_sshpermitrootno() {
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
if grep -q "^PermitRoot" /etc/ssh/sshd_config; then
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
fi
sshd_args="-C addr=,user=,host=,laddr=,lport=0"
if is_debian_jessie || is_debian_stretch; then
# Noop, we'll use the default $sshd_args
:
elif is_debian_buster; then
sshd_args="${sshd_args},rdomain="
else
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
# NOTE: From Debian Bullseye 11 onward, with OpenSSH 8.1, the argument
# -T doesn't require the additional -C.
sshd_args=
fi
# XXX: We want parameter expension here
if ! (sshd -T $sshd_args | grep -q 'permitrootlogin no'); then
failed "IS_SSHPERMITROOTNO" "PermitRoot should be set to no"
fi
}
check_evomaintenanceusers() {
@ -1369,7 +1404,7 @@ download_versions() {
elif is_openbsd; then
versions_url="https://upgrades.evolix.org/versions-${OPENBSD_RELEASE}"
else
failed "IS_VERSIONS_CHECK" "error determining os release"
failed "IS_CHECK_VERSIONS" "error determining os release"
fi
# fetch timeout, in seconds
@ -1382,9 +1417,9 @@ download_versions() {
elif command -v GET; then
GET -t ${timeout}s "${versions_url}" > "${versions_file}"
else
failed "IS_VERSIONS_CHECK" "failed to find curl, wget or GET"
failed "IS_CHECK_VERSIONS" "failed to find curl, wget or GET"
fi
test "$?" -eq 0 || failed "IS_VERSIONS_CHECK" "failed to download ${versions_url} to ${versions_file}"
test "$?" -eq 0 || failed "IS_CHECK_VERSIONS" "failed to download ${versions_url} to ${versions_file}"
}
get_command() {
local program
@ -1397,6 +1432,7 @@ get_command() {
listupgrade) command -v "evolistupgrade.sh" ;;
old-kernel-autoremoval) command -v "old-kernel-autoremoval.sh" ;;
mysql-queries-killer) command -v "mysql-queries-killer.sh" ;;
minifirewall) echo "/etc/init.d/minifirewall" ;;
## General case, where the program name is the same as the command name
*) command -v "${program}" ;;
@ -1417,6 +1453,9 @@ get_version() {
add-vm)
grep '^VERSION=' "${command}" | head -1 | cut -d '=' -f 2
;;
minifirewall)
${command} version | head -1 | cut -d ' ' -f 3
;;
## Let's try the --version flag before falling back to grep for the constant
kvmstats)
if ${command} --version > /dev/null 2> /dev/null; then
@ -1442,11 +1481,11 @@ check_version() {
actual_version=$(get_version "${program}" "${command}")
# printf "program:%s expected:%s actual:%s\n" "${program}" "${expected_version}" "${actual_version}"
if [ -z "${actual_version}" ]; then
failed "IS_VERSIONS_CHECK" "failed to lookup actual version of ${program}"
failed "IS_CHECK_VERSIONS" "failed to lookup actual version of ${program}"
elif dpkg --compare-versions "${actual_version}" lt "${expected_version}"; then
failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is older than expected version ${expected_version}"
failed "IS_CHECK_VERSIONS" "${program} version ${actual_version} is older than expected version ${expected_version}"
elif dpkg --compare-versions "${actual_version}" gt "${expected_version}"; then
failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is newer than expected version ${expected_version}, you should update tour index."
failed "IS_CHECK_VERSIONS" "${program} version ${actual_version} is newer than expected version ${expected_version}, you should update your index."
else
: # Version check OK
fi
@ -1459,9 +1498,9 @@ add_to_path() {
echo "$PATH" | grep -qF "${new_path}" || export PATH="${PATH}:${new_path}"
}
check_versions() {
versions_file=$(mktemp --tmpdir=/tmp "evocheck-versions.XXXXX")
# shellcheck disable=SC2064
trap "rm -f ${versions_file}" 0
versions_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.versions.XXXXX")
files_to_cleanup="${files_to_cleanup} ${versions_file}"
download_versions "${versions_file}"
add_to_path "/usr/share/scripts"
@ -1475,12 +1514,10 @@ check_versions() {
if [ -n "${version}" ]; then
check_version "${program}" "${version}"
else
failed "IS_VERSIONS_CHECK" "failed to lookup expected version for ${program}"
failed "IS_CHECK_VERSIONS" "failed to lookup expected version for ${program}"
fi
fi
done
rm -f "${versions_file}"
}
main() {
@ -1489,6 +1526,9 @@ main() {
# Detect operating system name, version and release
detect_os
main_output_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.main.XXXXX")
files_to_cleanup="${files_to_cleanup} ${main_output_file}"
#-----------------------------------------------------------
# Tests communs à tous les systèmes
#-----------------------------------------------------------
@ -1559,6 +1599,7 @@ main() {
test "${IS_NETWORK_INTERFACES:=1}" = 1 && check_network_interfaces
test "${IS_AUTOIF:=1}" = 1 && check_autoif
test "${IS_INTERFACESGW:=1}" = 1 && check_interfacesgw
test "${IS_NETWORKING_SERVICE:=1}" = 1 && check_networking_service
test "${IS_EVOBACKUP:=1}" = 1 && check_evobackup
test "${IS_EVOBACKUP_EXCLUDE_MOUNT:=1}" = 1 && check_evobackup_exclude_mount
test "${IS_USERLOGROTATE:=1}" = 1 && check_userlogrotate
@ -1717,8 +1758,21 @@ main() {
# - NRPEDISK et NRPEPOSTFIX
fi
if [ -f "${main_output_file}" ]; then
lines_found=$(wc -l < "${main_output_file}")
# shellcheck disable=SC2086
if [ ${lines_found} -gt 0 ]; then
cat "${main_output_file}" 2>&1
fi
fi
exit ${RC}
}
cleanup_temp_files() {
# shellcheck disable=SC2086
rm -f ${files_to_cleanup}
}
PROGNAME=$(basename "$0")
# shellcheck disable=SC2034
@ -1732,6 +1786,10 @@ readonly ARGS
export LANG=C
export LANGUAGE=C
files_to_cleanup=""
# shellcheck disable=SC2064
trap cleanup_temp_files 0
# Source configuration file
# shellcheck disable=SC1091
test -f /etc/evocheck.cf && . /etc/evocheck.cf