Compare commits

...

154 Commits

Author SHA1 Message Date
Jérémy Dubois 29b546584a OpenBSD - check_pkgmirror: fix openbsd mirror
2 weeks ago
Jérémy Lecour f1074dea2d use bash array for tmp files to cleanup
3 weeks ago
Jérémy Lecour f5410be26c shellcheck
3 weeks ago
Jérémy Lecour 3d7b2a676f whitespace
3 weeks ago
Jérémy Lecour 289e303801 fix syntax error
3 weeks ago
Jérémy Lecour be1e303040 improve readability
3 weeks ago
Jérémy Lecour 653f29e2d8 grep silencieux et optimisé
3 weeks ago
Jérémy Lecour c8ea1a3744 typos
3 weeks ago
William Hirigoyen f9fdc2c4ee IS_LOCALHOST_IN_POSTFIX_MYDESTINATION: fix regex and add localhost.$mydomain to check
2 months ago
David Prevot 12681b8259 Fix filename changed in 0ff69e6a07
2 months ago
William Hirigoyen 339afdcec2 Improve commit 2540c6f312
2 months ago
William Hirigoyen 6566193ebc Update CHANGELOG
2 months ago
William Hirigoyen 2540c6f312 - Add checks IS_LOCALHOST_IN_POSTFIX_MYDESTINATION, IS_SSH_FAIL2BAN_JAIL_RENAMED, IS_NO_LXC_CONTAINER, IS_LXC_PHP_FPM_SERVICE_UMASK_SET.
2 months ago
William Hirigoyen ff7aee8ea7 IS_REDIS_BACKUP: supports news and old default Redis backup path
2 months ago
Jérémy Dubois 1a2c3e0859 check_history: escape $HOME variable
2 months ago
Jérémy Dubois f7570ec865 check_pkgmirror: use our own openbsd mirror
2 months ago
Jérémy Lecour 8fd10bfeaf fix changelog
2 months ago
Jérémy Lecour 6c1d4f63ac Linux - Release 22.11
2 months ago
Jérémy Lecour 0ff69e6a07 Split versions for Debian 7-, 8 and 9+
2 months ago
William Hirigoyen 2640bb1b11 Update IS_REDIS_BACKUP path to standard location (used in zzz_evobackup)
2 months ago
Alexis Ben Miloud--Josselin a232eeebcc check_redis: enable multi-instance dump check
3 months ago
Jérémy Lecour 58a97812c6 Check Debian Security repository from apt-cache policy output
3 months ago
Jérémy Dubois 55b08445a7 OpenBSD - Release 22.10
4 months ago
David Prevot f74f1317b4 IS_PHPMYADMINAPACHECONF: check package config
4 months ago
Jérémy Dubois 76dfe5fa24 OpenBSD - check_ntp: comply with ntp configuration change on EvoBSD
4 months ago
Jérémy Lecour aeb7ea2af4 Linux - Release 22.09
5 months ago
Jérémy Lecour 5765ad2a7d restore deleted MINIFW_FILE variable
5 months ago
Jérémy Dubois 8a1bd96789 Merge branch 'openbsd'
5 months ago
Jérémy Dubois 043d1e58b1 prepare linux/openbsd split
5 months ago
Jérémy Lecour 0549b39166 Linux - Release 22.08.1
5 months ago
Jérémy Lecour 1638ed1884 IS_AUTOIF: check only statically defined interfaces
5 months ago
Jérémy Lecour a87438a41b Release linux/22.08
5 months ago
Jérémy Lecour d58c0dc335 remove all BSD specific code in Linux branch
5 months ago
Jérémy Lecour cb8d8fa738 prepare linux/openbsd split
5 months ago
Jérémy Dubois 3f88645c6f check_sshpermitrootno: do not display sshd errors
6 months ago
Jérémy Dubois f2f3155fc3 check_backupuptodate: use find with --max-depth=1 to limit the number of evaluated files
6 months ago
Jérémy Dubois 271e8623b4 check_evobackup_exclude_mount : skip if --one-file-system is used, and exclude scripts without Rsync command
6 months ago
Jérémy Dubois 2e1d873fe1 Release 22.08
6 months ago
Jérémy Dubois 18c531325d Fixed check_sshpermitrootno to check real configuration
6 months ago
William Hirigoyen (Evolix) 75f8a55e9b [IS_AUTOIF] Add support for /etc/network/interface.d
6 months ago
Jérémy Lecour 6f9607bc0e Release 22.07.1
6 months ago
Jérémy Lecour 72a85bc9ef IS_SSHPERMITROOTNO: do not display sshd errors
6 months ago
Jérémy Lecour 0c16fcf311 whitespaces
6 months ago
Jérémy Lecour 3c2b870a6d Release 22.07
6 months ago
Jérémy Lecour 69937e9c2d fix shellcheck
6 months ago
Jérémy Lecour 5c5a061d59 IS_NETWORKING_SERVICE: not in cron mode
7 months ago
Alexis Ben Miloud--Josselin 52e114e45f Corriger liste dump mongodb
7 months ago
Alexis Ben Miloud--Josselin 40753385d1 [find] -maxdepth should be before -type
8 months ago
Bruno TATU 64c7cd3424 add check if fail2ban_dbpurge is installed
8 months ago
Jérémy Dubois b8496e754d Release 22.06
8 months ago
Jérémy Dubois d35d7491f1 Fixed various shellcheck violations and added a function to cleanup files at once instead of using multiple trap rm
8 months ago
Jérémy Lecour 63dd6bf41c fix find syntax
8 months ago
Jérémy Lecour 2551401baa Release 22.06.2
8 months ago
Jérémy Lecour 3d1881fe80 IS_BACKUPUPTODATE: add --max-depth=1 to limit the number of evaluated files
8 months ago
Jérémy Lecour 78486611c5 fix changelog
8 months ago
Jérémy Lecour fb7ec6bacf Release 22.06.1
8 months ago
Jérémy Lecour bec90cb8ee Merge pull request 'IS_BACKUPUPTODATE Check all files' (#138) from check_all_files_in_backup_dir into master
8 months ago
Jérémy Lecour 5adfdcc614 Add comment to explain why looking for all files
8 months ago
Jérémy Lecour 156435220a Merge pull request 'evocheck.sh: tfix' (#140) from dprevot/evocheck:master into master
8 months ago
Jérémy Lecour 735c960621 Merge branch 'master' into master
8 months ago
Jérémy Lecour 5f9b6901cb Merge pull request 'add support for options in sources.list' (#143) from sources.list-support-option into master
8 months ago
Brice Waegeneire 1a08da8afa add support for options in sources.list
8 months ago
Jérémy Lecour 0c461689d1 Merge pull request 'sshpermitrootno: Use effective configuration.' (#135) from fix-129 into master
8 months ago
Brice Waegeneire e38aa5636f sshpermitrootno: Use effective configuration.
8 months ago
David Prevot 13859f306b evocheck.sh: tfix
continuous-integration/drone/pr Build encountered an error Details
10 months ago
Jérémy Dubois 8d460b039d check_versions: renamed "IS_VERSIONS_CHECK" to "IS_CHECK_VERSIONS" to match function name logic, and do not run check in cron mode
10 months ago
Jérémy Dubois 1281891363 Added check_root_user: make sure that root user does not have a password
10 months ago
Jérémy Dubois 3fcab1eeb3 Many improvements and bump to version 22.03. See CHANGELOG
11 months ago
Alexis Ben Miloud--Josselin 43d09c3ba1 IS_BACKUPUPTODATE Check all files
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/pr Build is failing Details
1 year ago
Jérémy Dubois 11d77659a0 Fixed check_tmoutprofile : syntax error on if/else/fi test
1 year ago
Jérémy Dubois f1c63f827f Fixed check_tmoutprofile and changed version numbering
1 year ago
Jérémy Dubois e0202f28ff Fix IS_PREEMPT remaining
2 years ago
Jérémy Dubois 8a735ca4ca Renamed multiple CARP checks
2 years ago
Jérémy Dubois af259252be Add check_advskew and boot version
2 years ago
Jérémy Dubois 5bf2959aac Update changelog and boost version number
2 years ago
Jérémy Dubois e21628fea7 Fix check_noatime : do not take into account commented entry in fstab
2 years ago
Jérémy Dubois 04139f3d60 Add check_openvpncronlog and update CHANGELOG
2 years ago
Jérémy Dubois b6f4889ac5 Fix check_raidok : the same device could be displayed multiple times
2 years ago
Jérémy Dubois b49a1fbea5 Fix check_uptodate : properly check that syspatch exists
2 years ago
Jérémy Dubois 682cd3afaa Add check_noatime and fix check_softdep
2 years ago
Jérémy Dubois 7cb6055af5 Fix check_cronpath
2 years ago
Jérémy Dubois 4798873ace Add check_backupuptodate - Check that /home/backup is not older than 2 days
3 years ago
Jérémy Dubois 8eb2c5f9bc Update changelog
3 years ago
Jérémy Dubois 5bad0301d9 Add check_ntp() - Check the ntpd configuration
3 years ago
Jérémy Dubois 57d44cbf91 Removed check_postgresql - Deprecated since we now use an API
3 years ago
Jérémy Dubois 3d86996f5d Fix check_defaultroute - We need to check if the /etc/mygate file exists before comparing it - version 6.7.3
3 years ago
Jérémy Dubois 04994ecebc Add check_defaultroute function and update CHANGELOG file to 6.7.2
3 years ago
Tristan PILAT c688b0d524 Bump to version 6.7.1
3 years ago
Tristan PILAT b58ad51307 Fix check_sudomaint function - ADMIN group does not exist anymore, we now check that the wheel group has NOPASSWD for evomaintenance
3 years ago
Tristan PILAT 5eedf3ad4d Fix check_customsyslog - We have to check whether EvoBSD is present in newsyslog.conf file
3 years ago
Tristan PILAT 239c5896df We want evocheck advbase output to be uniq
3 years ago
Tristan PILAT 8d80e5bfc8 Update CHANGELOG to 6.6.2
3 years ago
Tristan PILAT 4fead89240 Add check_sync function - If a server is a Carp member we check whether the sync.sh script is present or not
3 years ago
Tristan PILAT e0716d3197 Remove check_oldhomedir - This information is irrelevant since we always keep home directories of former sysadmins
3 years ago
Tristan PILAT c436480014 Add check_pfenabled function
3 years ago
Tristan PILAT a5a034e611 Add check_uptodate function
3 years ago
Tristan PILAT 1d47e0f8d8 Raname kerneluptodate function to uptodate
3 years ago
Tristan PILAT 82a9050e00 Now use a version-naming scheme based on OpenBSD's one
3 years ago
Tristan PILAT 0b6ad08b5b Add RAID check
3 years ago
Tristan PILAT b1868829aa It might be useful to have /usr/share/scripts in the crontab PATH
3 years ago
Tristan PILAT cf975ee14b We have no use of Vagrant here
3 years ago
Tristan PILAT f019e82255 Update main contributors of this branch
3 years ago
Tristan PILAT c72a779f6c Let's create a new changelog file for this version of evocheck
3 years ago
Tristan PILAT 68823b7c91 We can't run the OpenBSD version of evocheck in DroneCI
3 years ago
Tristan PILAT 6f5b5d78d8 Create the main function and add calls to all checks
continuous-integration/drone/push Build encountered an error Details
3 years ago
Tristan PILAT e69e08160d We now use functions instead of if statements as in the linux version of the script
3 years ago
Tristan PILAT 425b08552a Merge --version flag to --help. Both are now showing the help message
3 years ago
Tristan PILAT fe76e40b35 Delete show_version since it is now included in show_help function
3 years ago
Tristan PILAT 9164fe2459 Amend show_help function for a more complete
3 years ago
Tristan PILAT 5ee0d20fe9 Add VERSION variable from linux version
3 years ago
Tristan PILAT 82af0db8b2 Delete default configuration values since they are now included in the main function
3 years ago
Tristan PILAT ef2b234d49 Fix a mistake in the description
3 years ago
Tristan PILAT 53015152b3 We now use is_installed function to test whether a package is installed
continuous-integration/drone/push Build is failing Details
4 years ago
Tristan PILAT 12ccfa914b Fix is_installed function to work on OpenBSD
4 years ago
Tristan PILAT 477c15df8a Fix the stat command for OpenBSD
continuous-integration/drone/push Build is failing Details
4 years ago
Tristan PILAT 1add27c67d We don't have to test whether the system is Debian or OpenBSD anymore
4 years ago
Tristan PILAT 71436c2f44 Amend all the checks to use the new logging function
4 years ago
Tristan PILAT 53c7c42324 Import some functions from the cleanup branch
4 years ago
Tristan PILAT 3a18ec50a7 Since the script is compatible with sh, let's switch to /bin/sh
4 years ago
Tristan PILAT ec7de84aa7 Update default variables
continuous-integration/drone/push Build is failing Details
4 years ago
Tristan PILAT 6f55586f6b That check is not required in our use case for OpenBSD
4 years ago
Tristan PILAT f8f0effa94 Check IS_PFCUSTOM is left to be done
4 years ago
Tristan PILAT ba43de597e Check IS_PFENABLED is left to be done
4 years ago
Tristan PILAT 94cbf9e589 Fix IS_SSHPERMITROOTNO for OpenBSD
4 years ago
Tristan PILAT 7eba87917f Add VERBOSE message for the IS_RSYNC check
4 years ago
Tristan PILAT ed93ba9f5d This is not required anymore
4 years ago
Tristan PILAT 3948702561 IS_ALERTBOOT is redondant with IS_REBOOTMAIL
4 years ago
Tristan PILAT 4f1ee5a982 Update the IS_NRPE check
4 years ago
Tristan PILAT e509ea879e inetd is now disabled by default
4 years ago
Tristan PILAT 5d5291f08d Add VERBOSE message for the IS_TTYC0SECURE check
4 years ago
Tristan PILAT e3f0b45724 Let's use the proper tools to check if a package is present
4 years ago
Tristan PILAT 6a9ba37c30 Check IS_OLD_HOME_DIR is left to be done
4 years ago
Tristan PILAT d6ef05803e Update IS_HISTORY check for OpenBSD
4 years ago
Tristan PILAT 950ea6fca6 Check if /etc/.git has the proper rights
4 years ago
Tristan PILAT 8ae3707044 Check IS_BACKUPUPTODATE is left to be done
4 years ago
Tristan PILAT 08edb86da6 Update IS_UPTIME check for OpenBSD
4 years ago
Tristan PILAT e4269d793c Check whether the system should be restarted after an update is left to be done
4 years ago
Tristan PILAT 37f3c1faee Update evobackup installation check for OpenBSD
4 years ago
Tristan PILAT 823a4f9ee0 RAID check with bioctl is left to be done
4 years ago
Tristan PILAT 954eaf5e28 Add VERBOSE message for the IS_TMOUTPROFILE check
4 years ago
Tristan PILAT de487e964c Add VERBOSE message for the IS_TMPNOEXEC check
4 years ago
Tristan PILAT 53cd10f4a8 Remove incompatible or useless checks under OpenBSD
4 years ago
Tristan PILAT 4c43e1b21a Remove Linux/OpenBSD condition test and clean up some useless evocheck tests under OpenBSD
4 years ago
Tristan 4dc94a19b0 Some characters have to be escaped
continuous-integration/drone/push Build is failing Details
4 years ago
Tristan 9832da8b03 Check whether the send of a mail after every reboot is present in the rc.local file
4 years ago
Tristan d52aa4915b Now using 'command -v' instead of 'which'
continuous-integration/drone/push Build is failing Details
4 years ago
Tristan 9a52beedbe It's more readable when using that syntax with test
4 years ago
Tristan 6f4f299006 Fix a condition mistake
4 years ago
Tristan f10df11143 Add PREEMPT detection
4 years ago
Tristan 5be38dc4f5 Update OpenBSD IS_PKGMIRROR check
4 years ago
Tristan 2815c211f4 We don't need that part anymore
4 years ago
Tristan 4c83cf1a28 Under OpenBSD, for 'wheel' group activation detection in sudoers file check if /etc/sudoers exists first
4 years ago
Tristan c90de6ec1f Under OpenBSD, fix if statement for hostname.carp file detection
4 years ago
Tristan f379f6210a Under OpenBSD, add advbase value detection
4 years ago

@ -5,4 +5,4 @@ steps:
- name: run shellcheck on evocheck.sh
image: evolix/shellcheck
commands:
- LC_ALL=C.UTF-8 shellcheck evocheck.sh
- LC_ALL=C.UTF-8 shellcheck linux/evocheck.sh

2
.gitignore vendored

@ -1,4 +1,4 @@
.vagrant
tmp
*.swp
.DS_Store

@ -5,6 +5,14 @@ and this project **does not adhere to [Semantic Versioning](http://semver.org/sp
### Added
New checks :
* IS_LOCALHOST_IN_POSTFIX_MYDESTINATION
* IS_SSH_FAIL2BAN_JAIL_RENAMED
* IS_NO_LXC_CONTAINER
* IS_LXC_PHP_FPM_SERVICE_UMASK_SET
* use bash array for tmp files to cleanup
### Changed
### Deprecated
@ -13,8 +21,85 @@ and this project **does not adhere to [Semantic Versioning](http://semver.org/sp
### Fixed
* IS_EVOBACKUP_INCS: fix quote.
* IS_PURGE_FAIL2BAN: fix function never called in main().
### Security
## [22.11] 2022-11-27
### Added
* New script for Debian 7 and earlier
* New script for Debian 8
* IS_PHPMYADMINAPACHECONF: check that package configuration has not been pulled in
### Changed
* IS_DEBIANSECURITY: check Debian Security repository from apt-cache policy output
### Removed
* Main script is not compatible with Debian 8 and earlier anymore
## [22.09] 2022-09-14
### Fixed
* restore deleted MINIFW_FILE variable
## [22.08.1] 2022-08-29
### Changed
* IS_AUTOIF: check only statically defined interfaces
## [22.08] 2022-08-29
### Added
* IS_AUTOIF: add support for /etc/network/interfaces.d
### Removed
* remove all BSD specific code
## [22.07.1] 2022-07-28
### Changed
* IS_SSHPERMITROOTNO: do not display sshd errors
## [22.07] 2022-07-28
### Added
* IS_FAIL2BAN_PURGE: workaround to purge fail2ban database on stretch and buster
### Changed
* IS_NETWORKING_SERVICE: not in cron mode
### Fixed:
* IS_BACKUPUPTODATE: correct order for find(1) arguments
## [22.06.2] 2022-06-09
### Changed
* IS_BACKUPUPTODATE: add --max-depth=1 to limit the number of evaluated files
## [22.06.1] 2022-06-06
### Changed
* IS_BACKUPUPTODATE: look for all files (with find) instead of simple "file globbing" on first level.
* IS_DEBIANSECURITY: support source list options
* IS_SSHPERMITROOTNO: analyze real configuration, instead of parsing the file
## [22.06] 2022-06-03
### Added

@ -0,0 +1,1307 @@
#!/bin/bash
# EvoCheck
# Script to verify compliance of a Linux (Debian) server
# powered by Evolix
VERSION="22.11"
readonly VERSION
# base functions
show_version() {
cat <<END
evocheck version ${VERSION} (Jessie)
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>,
Alexis Ben Miloud--Josselin <abenmiloud@evolix.fr>,
and others.
evocheck comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU General Public License v3.0 for details.
END
}
show_help() {
cat <<END
evocheck is a script that verifies Evolix conventions on Linux (Debian) servers.
Usage: evocheck
or evocheck --cron
or evocheck --quiet
or evocheck --verbose
Options
--cron disable a few checks
-v, --verbose increase verbosity of checks
-q, --quiet nothing is printed on stdout nor stderr
-h, --help print this message and exit
--version print version and exit
END
}
detect_os() {
# OS detection
DEBIAN_RELEASE=""
LSB_RELEASE_BIN=$(command -v lsb_release)
if [ -e /etc/debian_version ]; then
DEBIAN_MAIN_VERSION=$(cut -d "." -f 1 < /etc/debian_version)
if [ "${DEBIAN_MAIN_VERSION}" -ne "8" ]; then
echo "Debian ${DEBIAN_MAIN_VERSION} is incompatible with this version of evocheck." >&2
echo "This version is built for Debian 8 only." >&2
exit
fi
DEBIAN_RELEASE="jessie"
fi
}
is_pack_web(){
test -e /usr/share/scripts/web-add.sh || test -e /usr/share/scripts/evoadmin/web-add.sh
}
is_pack_samba(){
test -e /usr/share/scripts/add.pl
}
is_installed(){
for pkg in "$@"; do
dpkg -l "$pkg" 2> /dev/null | grep -q -E '^(i|h)i' || return 1
done
}
# logging
failed() {
check_name=$1
shift
check_comments=$*
RC=1
if [ "${QUIET}" != 1 ]; then
if [ -n "${check_comments}" ] && [ "${VERBOSE}" = 1 ]; then
printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" >> "${main_output_file}"
else
printf "%s FAILED!\n" "${check_name}" >> "${main_output_file}"
fi
fi
}
# check functions
check_lsbrelease(){
if [ -x "${LSB_RELEASE_BIN}" ]; then
## only the major version matters
lhs=$(${LSB_RELEASE_BIN} --release --short | cut -d "." -f 1)
rhs=$(cut -d "." -f 1 < /etc/debian_version)
test "$lhs" = "$rhs" || failed "IS_LSBRELEASE" "release is not consistent between lsb_release (${lhs}) and /etc/debian_version (${rhs})"
else
failed "IS_LSBRELEASE" "lsb_release is missing or not executable"
fi
}
# Verifying check_mailq in Nagios NRPE config file. (Option "-M postfix" need to be set if the MTA is Postfix)
check_nrpepostfix() {
if is_installed postfix; then
{ test -e /etc/nagios/nrpe.cfg \
&& grep -qr "^command.*check_mailq -M postfix" /etc/nagios/nrpe.*;
} || failed "IS_NRPEPOSTFIX" "NRPE \"check_mailq\" for postfix is missing"
fi
}
# Check if mod-security config file is present
check_customsudoers() {
grep -E -qr "umask=0077" /etc/sudoers* || failed "IS_CUSTOMSUDOERS" "missing umask=0077 in sudoers file"
}
check_vartmpfs() {
FINDMNT_BIN=$(command -v findmnt)
if [ -x "${FINDMNT_BIN}" ]; then
${FINDMNT_BIN} /var/tmp --type tmpfs --noheadings > /dev/null || failed "IS_VARTMPFS" "/var/tmp is not a tmpfs"
else
df /var/tmp | grep -q tmpfs || failed "IS_VARTMPFS" "/var/tmp is not a tmpfs"
fi
}
check_serveurbase() {
is_installed serveur-base || failed "IS_SERVEURBASE" "serveur-base package is not installed"
}
check_logrotateconf() {
test -e /etc/logrotate.d/zsyslog || failed "IS_LOGROTATECONF" "missing zsyslog in logrotate.d"
}
check_syslogconf() {
grep -q "^# Syslog for Pack Evolix serveur" /etc/*syslog.conf \
|| failed "IS_SYSLOGCONF" "syslog evolix config file missing"
}
check_debiansecurity() {
# Look for enabled "Debian-Security" sources from the "Debian" origin
apt-cache policy | grep "\bl=Debian-Security\b" | grep "\bo=Debian\b" | grep --quiet "\bc=main\b"
test $? -eq 0 || failed "IS_DEBIANSECURITY" "missing Debian-Security repository"
}
check_aptitude() {
test -e /usr/bin/aptitude && failed "IS_APTITUDE" "aptitude may not be installed on Debian >=8"
}
check_aptgetbak() {
test -e /usr/bin/apt-get.bak && failed "IS_APTGETBAK" "prohibit the installation of apt-get.bak with dpkg-divert(1)"
}
check_usrro() {
grep /usr /etc/fstab | grep -qE "\bro\b" || failed "IS_USRRO" "missing ro directive on fstab for /usr"
}
check_tmpnoexec() {
FINDMNT_BIN=$(command -v findmnt)
if [ -x "${FINDMNT_BIN}" ]; then
options=$(${FINDMNT_BIN} --noheadings --first-only --output OPTIONS /tmp)
echo "${options}" | grep -qE "\bnoexec\b" || failed "IS_TMPNOEXEC" "/tmp is not mounted with 'noexec'"
else
mount | grep "on /tmp" | grep -qE "\bnoexec\b" || failed "IS_TMPNOEXEC" "/tmp is not mounted with 'noexec' (WARNING: findmnt(8) is not found)"
fi
}
check_mountfstab() {
# Test if lsblk available, if not skip this test...
LSBLK_BIN=$(command -v lsblk)
if test -x "${LSBLK_BIN}"; then
for mountPoint in $(${LSBLK_BIN} -o MOUNTPOINT -l -n | grep '/'); do
grep -Eq "$mountPoint\W" /etc/fstab \
|| failed "IS_MOUNT_FSTAB" "partition(s) detected mounted but no presence in fstab"
done
fi
}
check_listchangesconf() {
if [ -e "/etc/apt/listchanges.conf" ]; then
lines=$(grep -cE "(which=both|confirm=1)" /etc/apt/listchanges.conf)
if [ "$lines" != 2 ]; then
failed "IS_LISTCHANGESCONF" "apt-listchanges config is incorrect"
fi
else
failed "IS_LISTCHANGESCONF" "apt-listchanges config is missing"
fi
}
check_customcrontab() {
found_lines=$(grep -c -E "^(17 \*|25 6|47 6|52 6)" /etc/crontab)
test "$found_lines" = 4 && failed "IS_CUSTOMCRONTAB" "missing custom field in crontab"
}
check_sshallowusers() {
grep -E -qir "(AllowUsers|AllowGroups)" /etc/ssh/sshd_config /etc/ssh/sshd_config.d \
|| failed "IS_SSHALLOWUSERS" "missing AllowUsers or AllowGroups directive in sshd_config"
}
check_diskperf() {
perfFile="/root/disk-perf.txt"
test -e $perfFile || failed "IS_DISKPERF" "missing ${perfFile}"
}
check_tmoutprofile() {
grep -sq "TMOUT=" /etc/profile /etc/profile.d/evolinux.sh || failed "IS_TMOUTPROFILE" "TMOUT is not set"
}
check_alert5boot() {
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
}
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
}
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 started"
}
check_nrpeperms() {
if [ -d /etc/nagios ]; then
nagiosDir="/etc/nagios"
actual=$(stat --format "%a" $nagiosDir)
expected="750"
test "$expected" = "$actual" || failed "IS_NRPEPERMS" "${nagiosDir} must be ${expected}"
fi
}
check_minifwperms() {
if [ -f "/etc/default/minifirewall" ]; then
actual=$(stat --format "%a" "/etc/default/minifirewall")
expected="600"
test "$expected" = "$actual" || failed "IS_MINIFWPERMS" "/etc/default/minifirewall must be ${expected}"
fi
}
check_nrpedisks() {
NRPEDISKS=$(grep command.check_disk /etc/nagios/nrpe.cfg | grep "^command.check_disk[0-9]" | sed -e "s/^command.check_disk\([0-9]\+\).*/\1/" | sort -n | tail -1)
DFDISKS=$(df -Pl | grep -c -E -v "(^Filesystem|/lib/init/rw|/dev/shm|udev|rpc_pipefs)")
test "$NRPEDISKS" = "$DFDISKS" || failed "IS_NRPEDISKS" "there must be $DFDISKS check_disk in nrpe.cfg"
}
check_nrpepid() {
{ test -e /etc/nagios/nrpe.cfg \
&& grep -q "^pid_file=/var/run/nagios/nrpe.pid" /etc/nagios/nrpe.cfg;
} || failed "IS_NRPEPID" "missing or wrong pid_file directive in nrpe.cfg"
}
check_grsecprocs() {
if uname -a | grep -q grsec; then
{ grep -q "^command.check_total_procs..sudo" /etc/nagios/nrpe.cfg \
&& grep -A1 "^\[processes\]" /etc/munin/plugin-conf.d/munin-node | grep -q "^user root";
} || failed "IS_GRSECPROCS" "missing munin's plugin processes directive for grsec"
fi
}
check_apachemunin() {
if test -e /etc/apache2/apache2.conf; then
pattern="/server-status-[[:alnum:]]{4,}"
{ grep -r -q -s -E "^env.url.*${pattern}" /etc/munin/plugin-conf.d \
&& { grep -q -s -E "${pattern}" /etc/apache2/apache2.conf \
|| grep -q -s -E "${pattern}" /etc/apache2/mods-enabled/status.conf;
};
} || failed "IS_APACHEMUNIN" "server status is not properly configured"
fi
}
# Verification mytop + Munin si MySQL
check_mysqlutils() {
MYSQL_ADMIN=${MYSQL_ADMIN:-mysqladmin}
if is_installed mysql-server; then
# You can configure MYSQL_ADMIN in evocheck.cf
if ! grep -qs "^user *= *${MYSQL_ADMIN}" /root/.my.cnf; then
failed "IS_MYSQLUTILS" "${MYSQL_ADMIN} missing in /root/.my.cnf"
fi
if ! test -x /usr/bin/mytop; then
if ! test -x /usr/local/bin/mytop; then
failed "IS_MYSQLUTILS" "mytop binary missing"
fi
fi
if ! grep -qs '^user *=' /root/.mytop; then
failed "IS_MYSQLUTILS" "credentials missing in /root/.mytop"
fi
fi
}
# Verification de la configuration du raid soft (mdadm)
check_raidsoft() {
if test -e /proc/mdstat && grep -q md /proc/mdstat; then
{ grep -q "^AUTOCHECK=true" /etc/default/mdadm \
&& grep -q "^START_DAEMON=true" /etc/default/mdadm \
&& grep -qv "^MAILADDR ___MAIL___" /etc/mdadm/mdadm.conf;
} || failed "IS_RAIDSOFT" "missing or wrong config for mdadm"
fi
}
# Verification du LogFormat de AWStats
check_awstatslogformat() {
if is_installed apache2 awstats; then
awstatsFile="/etc/awstats/awstats.conf.local"
grep -qE '^LogFormat=1' $awstatsFile \
|| failed "IS_AWSTATSLOGFORMAT" "missing or wrong LogFormat directive in $awstatsFile"
fi
}
# Verification de la présence de la config logrotate pour Munin
check_muninlogrotate() {
{ test -e /etc/logrotate.d/munin-node \
&& test -e /etc/logrotate.d/munin;
} || failed "IS_MUNINLOGROTATE" "missing lorotate file for munin"
}
# Verification de l'activation de Squid dans le cas d'un pack mail
check_squid() {
squidconffile="/etc/squid*/squid.conf"
if is_pack_web && (is_installed squid || is_installed squid3); then
host=$(hostname -i)
# shellcheck disable=SC2086
http_port=$(grep -E "^http_port\s+[0-9]+" $squidconffile | awk '{ print $2 }')
{ grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT" "/etc/default/minifirewall" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d $host -j ACCEPT" "/etc/default/minifirewall" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.(1|0/8) -j ACCEPT" "/etc/default/minifirewall" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port.* $http_port" "/etc/default/minifirewall";
} || grep -qE "^PROXY='?on'?" "/etc/default/minifirewall" \
|| failed "IS_SQUID" "missing squid rules in minifirewall"
fi
}
check_evomaintenance_fw() {
if [ -f "/etc/default/minifirewall" ]; then
hook_db=$(grep -E '^\s*HOOK_DB' /etc/evomaintenance.cf | tr -d ' ' | cut -d= -f2)
rulesNumber=$(grep -c "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s .* -m state --state ESTABLISHED,RELATED -j ACCEPT" "/etc/default/minifirewall")
if [ "$hook_db" = "1" ] && [ "$rulesNumber" -lt 2 ]; then
failed "IS_EVOMAINTENANCE_FW" "HOOK_DB is enabled but missing evomaintenance rules in minifirewall"
fi
fi
}
# Verification de la conf et de l'activation de mod-deflate
check_moddeflate() {
f=/etc/apache2/mods-enabled/deflate.conf
if is_installed apache2.2; then
{ test -e $f && grep -q "AddOutputFilterByType DEFLATE text/html text/plain text/xml" $f \
&& grep -q "AddOutputFilterByType DEFLATE text/css" $f \
&& grep -q "AddOutputFilterByType DEFLATE application/x-javascript application/javascript" $f;
} || failed "IS_MODDEFLATE" "missing AddOutputFilterByType directive for apache mod deflate"
fi
}
# Verification de la conf log2mail
check_log2mailrunning() {
if is_pack_web && is_installed log2mail; then
pgrep log2mail >/dev/null || failed "IS_LOG2MAILRUNNING" "log2mail is not running"
fi
}
check_log2mailapache() {
conf=/etc/log2mail/config/default
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/apache2/error.log" $conf \
|| failed "IS_LOG2MAILAPACHE" "missing log2mail directive for apache"
fi
}
check_log2mailmysql() {
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/syslog" /etc/log2mail/config/{default,mysql,mysql.conf} \
|| failed "IS_LOG2MAILMYSQL" "missing log2mail directive for mysql"
fi
}
check_log2mailsquid() {
if is_pack_web && is_installed log2mail; then
grep -s -q "^file = /var/log/squid.*/access.log" /etc/log2mail/config/* \
|| failed "IS_LOG2MAILSQUID" "missing log2mail directive for squid"
fi
}
# Verification si bind est chroote
check_bindchroot() {
if is_installed bind9; then
if netstat -utpln | grep "/named" | grep :53 | grep -qvE "(127.0.0.1|::1)"; then
if grep -q '^OPTIONS=".*-t' /etc/default/bind9 && grep -q '^OPTIONS=".*-u' /etc/default/bind9; then
md5_original=$(md5sum /usr/sbin/named | cut -f 1 -d ' ')
md5_chrooted=$(md5sum /var/chroot-bind/usr/sbin/named | cut -f 1 -d ' ')
if [ "$md5_original" != "$md5_chrooted" ]; then
failed "IS_BINDCHROOT" "the chrooted bind binary is different than the original binary"
fi
else
failed "IS_BINDCHROOT" "bind process is not chrooted"
fi
fi
fi
}
# /etc/network/interfaces should be present, we don't manage systemd-network yet
check_network_interfaces() {
if ! test -f /etc/network/interfaces; then
IS_AUTOIF=0
IS_INTERFACESGW=0
failed "IS_NETWORK_INTERFACES" "systemd network configuration is not supported yet"
fi
}
# Verify if all if are in auto
check_autoif() {
interfaces=$(/sbin/ifconfig -s | tail -n +2 | grep -E -v "^(lo|vnet|docker|veth|tun|tap|macvtap|vrrp)" | cut -d " " -f 1 |tr "\n" " ")
for interface in $interfaces; do
if grep -Rq "^iface $interface" /etc/network/interfaces* && ! grep -Rq "^auto $interface" /etc/network/interfaces*; then
failed "IS_AUTOIF" "Network interface \`${interface}' is statically defined but not set to auto"
test "${VERBOSE}" = 1 || break
fi
done
}
# Network conf verification
check_interfacesgw() {
number=$(grep -Ec "^[^#]*gateway [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /etc/network/interfaces)
test "$number" -gt 1 && failed "IS_INTERFACESGW" "there is more than 1 IPv4 gateway"
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 la mise en place d'evobackup
check_evobackup() {
evobackup_found=$(find /etc/cron* -name '*evobackup*' | wc -l)
test "$evobackup_found" -gt 0 || failed "IS_EVOBACKUP" "missing evobackup cron"
}
# Vérification de l'exclusion des montages (NFS) dans les sauvegardes
check_evobackup_exclude_mount() {
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
# 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
}
# Verification de la presence du userlogrotate
check_userlogrotate() {
if is_pack_web; then
test -x /etc/cron.weekly/userlogrotate || failed "IS_USERLOGROTATE" "missing userlogrotate cron"
fi
}
# Verification de la syntaxe de la conf d'Apache
check_apachectl() {
if is_installed apache2; then
/usr/sbin/apache2ctl configtest 2>&1 | grep -q "^Syntax OK$" \
|| failed "IS_APACHECTL" "apache errors detected, run a configtest"
fi
}
# Check if there is regular files in Apache sites-enabled.
check_apachesymlink() {
if is_installed apache2; then
apacheFind=$(find /etc/apache2/sites-enabled ! -type l -type f -print)
nbApacheFind=$(wc -m <<< "$apacheFind")
if [[ $nbApacheFind -gt 1 ]]; then
if [[ $VERBOSE == 1 ]]; then
while read -r line; do
failed "IS_APACHESYMLINK" "Not a symlink: $line"
done <<< "$apacheFind"
else
failed "IS_APACHESYMLINK"
fi
fi
fi
}
# Check if there is real IP addresses in Allow/Deny directives (no trailing space, inline comments or so).
check_apacheipinallow() {
# Note: Replace "exit 1" by "print" in Perl code to debug it.
if is_installed apache2; then
grep -IrE "^[^#] *(Allow|Deny) from" /etc/apache2/ \
| grep -iv "from all" \
| grep -iv "env=" \
| perl -ne 'exit 1 unless (/from( [\da-f:.\/]+)+$/i)' \
|| failed "IS_APACHEIPINALLOW" "bad (Allow|Deny) directives in apache"
fi
}
# Check if default Apache configuration file for munin is absent (or empty or commented).
check_muninapacheconf() {
muninconf="/etc/apache2/conf-available/munin.conf"
if is_installed apache2; then
test -e $muninconf && grep -vEq "^( |\t)*#" "$muninconf" \
&& failed "IS_MUNINAPACHECONF" "default munin configuration may be commented or disabled"
fi
}
# Check if default Apache configuration file for phpMyAdmin is absent (or empty or commented).
check_phpmyadminapacheconf() {
phpmyadminconf0="/etc/apache2/conf-available/phpmyadmin.conf"
phpmyadminconf1="/etc/apache2/conf-enabled/phpmyadmin.conf"
if is_installed apache2; then
test -e $phpmyadminconf0 && grep -vEq "^( |\t)*#" "$phpmyadminconf0" \
&& failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf0) may be commented or disabled"
test -e $phpmyadminconf1 && grep -vEq "^( |\t)*#" "$phpmyadminconf1" \
&& failed "IS_PHPMYADMINAPACHECONF" "default phpmyadmin configuration ($phpmyadminconf1) may be commented or disabled"
fi
}
# Verification si le système doit redémarrer suite màj kernel.
check_kerneluptodate() {
if is_installed linux-image*; then
# shellcheck disable=SC2012
kernel_installed_at=$(date -d "$(ls --full-time -lcrt /boot | tail -n1 | awk '{print $6}')" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$kernel_installed_at" -gt "$last_reboot_at" ]; then
failed "IS_KERNELUPTODATE" "machine is running an outdated kernel, reboot advised"
fi
fi
}
# Check if the server is running for more than a year.
check_uptime() {
if is_installed linux-image*; then
limit=$(date -d "now - 2 year" +%s)
last_reboot_at=$(($(date +%s) - $(cut -f1 -d '.' /proc/uptime)))
if [ "$limit" -gt "$last_reboot_at" ]; then
failed "IS_UPTIME" "machine has an uptime of more than 2 years, reboot on new kernel advised"
fi
fi
}
# Check if munin-node running and RRD files are up to date.
check_muninrunning() {
if ! pgrep munin-node >/dev/null; then
failed "IS_MUNINRUNNING" "Munin is not running"
elif [ -d "/var/lib/munin/" ] && [ -d "/var/cache/munin/" ]; then
limit=$(date +"%s" -d "now - 10 minutes")
if [ -n "$(find /var/lib/munin/ -name '*load-g.rrd')" ]; then
updated_at=$(stat -c "%Y" /var/lib/munin/*/*load-g.rrd |sort |tail -1)
[ "$limit" -gt "$updated_at" ] && failed "IS_MUNINRUNNING" "Munin load RRD has not been updated in the last 10 minutes"
else
failed "IS_MUNINRUNNING" "Munin is not installed properly (load RRD not found)"
fi
if [ -n "$(find /var/cache/munin/www/ -name 'load-day.png')" ]; then
updated_at=$(stat -c "%Y" /var/cache/munin/www/*/*/load-day.png |sort |tail -1)
grep -sq "^graph_strategy cron" /etc/munin/munin.conf && [ "$limit" -gt "$updated_at" ] && failed "IS_MUNINRUNNING" "Munin load PNG has not been updated in the last 10 minutes"
else
failed "IS_MUNINRUNNING" "Munin is not installed properly (load PNG not found)"
fi
else
failed "IS_MUNINRUNNING" "Munin is not installed properly (main directories are missing)"
fi
}
# Check if files in /home/backup/ are up-to-date
check_backupuptodate() {
backup_dir="/home/backup"
if [ -d "${backup_dir}" ]; then
if [ -n "$(ls -A ${backup_dir})" ]; then
find "${backup_dir}" -maxdepth 1 -type f | while read -r file; do
limit=$(date +"%s" -d "now - 2 day")
updated_at=$(stat -c "%Y" "$file")
if [ "$limit" -gt "$updated_at" ]; then
failed "IS_BACKUPUPTODATE" "$file has not been backed up"
test "${VERBOSE}" = 1 || break;
fi
done
else
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is empty"
fi
else
failed "IS_BACKUPUPTODATE" "${backup_dir}/ is missing"
fi
}
check_etcgit() {
export GIT_DIR="/etc/.git" GIT_WORK_TREE="/etc"
git rev-parse --is-inside-work-tree > /dev/null 2>&1 \
|| failed "IS_ETCGIT" "/etc is not a git repository"
}
# Check if /etc/.git/ has read/write permissions for root only.
check_gitperms() {
GIT_DIR="/etc/.git"
if test -d $GIT_DIR; then
expected="700"
actual=$(stat -c "%a" $GIT_DIR)
[ "$expected" = "$actual" ] || failed "IS_GITPERMS" "$GIT_DIR must be $expected"
fi
}
# Check if no package has been upgraded since $limit.
check_notupgraded() {
last_upgrade=0
upgraded=false
for log in /var/log/dpkg.log*; do
if zgrep -qsm1 upgrade "$log"; then
# There is at least one upgrade
upgraded=true
break
fi
done
if $upgraded; then
last_upgrade=$(date +%s -d "$(zgrep -h upgrade /var/log/dpkg.log* | sort -n | tail -1 | cut -f1 -d ' ')")
fi
if grep -qs '^mailto="listupgrade-todo@' /etc/evolinux/listupgrade.cnf \
|| grep -qs -E '^[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^\*]' /etc/cron.d/listupgrade; then
# Manual upgrade process
limit=$(date +%s -d "now - 180 days")
else
# Regular process
limit=$(date +%s -d "now - 90 days")
fi
install_date=0
if [ -d /var/log/installer ]; then
install_date=$(stat -c %Z /var/log/installer)
fi
# Check install_date if the system never received an upgrade
if [ "$last_upgrade" -eq 0 ]; then
[ "$install_date" -lt "$limit" ] && failed "IS_NOTUPGRADED" "The system has never been updated"
else
[ "$last_upgrade" -lt "$limit" ] && failed "IS_NOTUPGRADED" "The system hasn't been updated for too long"
fi
}
# Check if reserved blocks for root is at least 5% on every mounted partitions.
check_tune2fs_m5() {
min=5
parts=$(grep -E "ext(3|4)" /proc/mounts | cut -d ' ' -f1 | tr -s '\n' ' ')
FINDMNT_BIN=$(command -v findmnt)
for part in $parts; do
blockCount=$(dumpe2fs -h "$part" 2>/dev/null | grep -e "Block count:" | grep -Eo "[0-9]+")
# If buggy partition, skip it.
if [ -z "$blockCount" ]; then
continue
fi
reservedBlockCount=$(dumpe2fs -h "$part" 2>/dev/null | grep -e "Reserved block count:" | grep -Eo "[0-9]+")
# Use awk to have a rounded percentage
# python is slow, bash is unable and bc rounds weirdly
percentage=$(awk "BEGIN { pc=100*${reservedBlockCount}/${blockCount}; i=int(pc); print (pc-i<0.5)?i:i+1 }")
if [ "$percentage" -lt "${min}" ]; then
if [ -x "${FINDMNT_BIN}" ]; then
mount=$(${FINDMNT_BIN} --noheadings --first-only --output TARGET "${part}")
else
mount="unknown mount point"
fi
failed "IS_TUNE2FS_M5" "Partition ${part} (${mount}) has less than ${min}% reserved blocks (${percentage}%)"
fi
done
}
check_broadcomfirmware() {
LSPCI_BIN=$(command -v lspci)
if [ -x "${LSPCI_BIN}" ]; then
if ${LSPCI_BIN} | grep -q 'NetXtreme II'; then
{ is_installed firmware-bnx2 \
&& grep -q "^deb http://mirror.evolix.org/debian.* non-free" /etc/apt/sources.list;
} || failed "IS_BROADCOMFIRMWARE" "missing non-free repository"
fi
else
failed "IS_BROADCOMFIRMWARE" "lspci not found in ${PATH}"
fi
}
check_hardwareraidtool() {
LSPCI_BIN=$(command -v lspci)
if [ -x "${LSPCI_BIN}" ]; then
if ${LSPCI_BIN} | grep -q 'MegaRAID'; then
# shellcheck disable=SC2015
is_installed megacli && { is_installed megaclisas-status || is_installed megaraidsas-status; } \
|| failed "IS_HARDWARERAIDTOOL" "Mega tools not found"
fi
if ${LSPCI_BIN} | grep -q 'Hewlett-Packard Company Smart Array'; then
is_installed cciss-vol-status || failed "IS_HARDWARERAIDTOOL" "cciss-vol-status not installed"
fi
else
failed "IS_HARDWARERAIDTOOL" "lspci not found in ${PATH}"
fi
}
check_listupgrade() {
test -f /etc/cron.d/listupgrade \
|| failed "IS_LISTUPGRADE" "missing listupgrade cron"
test -x /usr/share/scripts/listupgrade.sh \
|| failed "IS_LISTUPGRADE" "missing listupgrade script or not executable"
}
check_sql_backup() {
if (is_installed "mysql-server" || is_installed "mariadb-server"); then
# You could change the default path in /etc/evocheck.cf
SQL_BACKUP_PATH=${SQL_BACKUP_PATH:-"/home/backup/mysql.bak.gz"}
for backup_path in ${SQL_BACKUP_PATH}; do
if [ ! -f "${backup_path}" ]; then
failed "IS_SQL_BACKUP" "MySQL dump is missing (${backup_path})"
test "${VERBOSE}" = 1 || break
fi
done
fi
}
check_postgres_backup() {
if is_installed "postgresql-9*" || is_installed "postgresql-1*"; then
# If you use something like barman, you should disable this check
# You could change the default path in /etc/evocheck.cf
POSTGRES_BACKUP_PATH=${POSTGRES_BACKUP_PATH:-"/home/backup/pg.dump.bak*"}
for backup_path in ${POSTGRES_BACKUP_PATH}; do
if [ ! -f "${backup_path}" ]; then
failed "IS_POSTGRES_BACKUP" "PostgreSQL dump is missing (${backup_path})"
test "${VERBOSE}" = 1 || break
fi
done
fi
}
check_mongo_backup() {
if is_installed "mongodb-org-server"; then
# 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
# Skip indexes file.
if ! [[ "$file" =~ indexes ]]; then
limit=$(date +"%s" -d "now - 2 day")
updated_at=$(stat -c "%Y" "$file")
if [ -f "$file" ] && [ "$limit" -gt "$updated_at" ]; then
failed "IS_MONGO_BACKUP" "MongoDB hasn't been dumped for more than 2 days"
break
fi
fi
done
else
failed "IS_MONGO_BACKUP" "MongoDB dump directory is missing (${MONGO_BACKUP_PATH})"
fi
fi
}
check_ldap_backup() {
if is_installed slapd; then
# You could change the default path in /etc/evocheck.cf
LDAP_BACKUP_PATH=${LDAP_BACKUP_PATH:-"/home/backup/ldap.bak"}
test -f "$LDAP_BACKUP_PATH" || failed "IS_LDAP_BACKUP" "LDAP dump is missing (${LDAP_BACKUP_PATH})"
fi
}
check_redis_backup() {
if is_installed redis-server; then
# You could change the default path in /etc/evocheck.cf
# REDIS_BACKUP_PATH may contain space-separated paths, example:
# REDIS_BACKUP_PATH='/home/backup/redis-instance1/dump.rdb /home/backup/redis-instance2/dump.rdb'
REDIS_BACKUP_PATH=${REDIS_BACKUP_PATH:-"/home/backup/redis/dump.rdb"}
for file in ${REDIS_BACKUP_PATH}; do
test -f "${file}" || failed "IS_REDIS_BACKUP" "Redis dump is missing (${file})"
done
fi
}
check_elastic_backup() {
if is_installed elasticsearch; then
# You could change the default path in /etc/evocheck.cf
ELASTIC_BACKUP_PATH=${ELASTIC_BACKUP_PATH:-"/home/backup-elasticsearch"}
test -d "$ELASTIC_BACKUP_PATH" || failed "IS_ELASTIC_BACKUP" "Elastic snapshot is missing (${ELASTIC_BACKUP_PATH})"
fi
}
check_duplicate_fs_label() {
# Do it only if thereis blkid binary
BLKID_BIN=$(command -v blkid)
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"
done
tmpOutput=$(sort < "$tmpFile" | uniq -d)
# If there is no duplicate, uniq will have no output
# So, if $tmpOutput is not null, there is a duplicate
if [ -n "$tmpOutput" ]; then
# shellcheck disable=SC2086
labels=$(echo -n $tmpOutput | tr '\n' ' ')
failed "IS_DUPLICATE_FS_LABEL" "Duplicate labels: $labels"
fi
else
failed "IS_DUPLICATE_FS_LABEL" "blkid not found in ${PATH}"
fi
}
check_evolix_user() {
grep -q -E "^evolix:" /etc/passwd \
&& failed "IS_EVOLIX_USER" "evolix user should be deleted, used only for install"
}
check_evoacme_cron() {
if [ -f "/usr/local/sbin/evoacme" ]; then
# Old cron file, should be deleted
test -f /etc/cron.daily/certbot && failed "IS_EVOACME_CRON" "certbot cron is incompatible with evoacme"
# evoacme cron file should be present
test -f /etc/cron.daily/evoacme || failed "IS_EVOACME_CRON" "evoacme cron is missing"
fi
}
check_evoacme_livelinks() {
EVOACME_BIN=$(command -v evoacme)
if [ -x "$EVOACME_BIN" ]; then
# Sometimes evoacme is installed but no certificates has been generated
numberOfLinks=$(find /etc/letsencrypt/ -type l | wc -l)
if [ "$numberOfLinks" -gt 0 ]; then
for live in /etc/letsencrypt/*/live; do
actualLink=$(readlink -f "$live")
actualVersion=$(basename "$actualLink")
certDir=$(dirname "$live")
certName=$(basename "$certDir")
# shellcheck disable=SC2012
lastCertDir=$(ls -ds "${certDir}"/[0-9]* | tail -1)
lastVersion=$(basename "$lastCertDir")
if [[ "$lastVersion" != "$actualVersion" ]]; then
failed "IS_EVOACME_LIVELINKS" "Certificate \`$certName' hasn't been updated"
test "${VERBOSE}" = 1 || break
fi
done
fi
fi
}
check_apache_confenabled() {
# Starting from Jessie and Apache 2.4, /etc/apache2/conf.d/
# must be replaced by conf-available/ and config files symlinked
# to conf-enabled/
if [ -f /etc/apache2/apache2.conf ]; then
test -d /etc/apache2/conf.d/ \
&& failed "IS_APACHE_CONFENABLED" "apache's conf.d directory must not exists"
grep -q 'Include conf.d' /etc/apache2/apache2.conf \
&& failed "IS_APACHE_CONFENABLED" "apache2.conf must not Include conf.d"
fi
}
check_meltdown_spectre() {
# For Jessie this is quite complicated to verify and we need to use kernel config file
if grep -q "BOOT_IMAGE=" /proc/cmdline; then
kernelPath=$(grep -Eo 'BOOT_IMAGE=[^ ]+' /proc/cmdline | cut -d= -f2)
kernelVer=${kernelPath##*/vmlinuz-}
kernelConfig="config-${kernelVer}"
# Sometimes autodetection of kernel config file fail, so we test if the file really exists.
if [ -f "/boot/${kernelConfig}" ]; then
grep -Eq '^CONFIG_PAGE_TABLE_ISOLATION=y' "/boot/$kernelConfig" \
|| failed "IS_MELTDOWN_SPECTRE" \
"PAGE_TABLE_ISOLATION must be enabled in kernel, outdated kernel?"
grep -Eq '^CONFIG_RETPOLINE=y' "/boot/$kernelConfig" \
|| failed "IS_MELTDOWN_SPECTRE" \
"RETPOLINE must be enabled in kernel, outdated kernel?"
fi
fi
}
check_old_home_dir() {
homeDir=${homeDir:-/home}
for dir in "$homeDir"/*; do
statResult=$(stat -c "%n has owner %u resolved as %U" "$dir" \
| grep -Eve '.bak' -e '\.[0-9]{2}-[0-9]{2}-[0-9]{4}' \
| grep "UNKNOWN")
# There is at least one dir matching
if [[ -n "$statResult" ]]; then
failed "IS_OLD_HOME_DIR" "$statResult"
test "${VERBOSE}" = 1 || break
fi
done
}
check_tmp_1777() {
actual=$(stat --format "%a" /tmp)
expected="1777"
test "$expected" = "$actual" || failed "IS_TMP_1777" "/tmp must be $expected"
}
check_root_0700() {
actual=$(stat --format "%a" /root)
expected="700"
test "$expected" = "$actual" || failed "IS_ROOT_0700" "/root must be $expected"
}
check_usrsharescripts() {
actual=$(stat --format "%a" /usr/share/scripts)
expected="700"
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
}
check_sshpermitrootno() {
sshd_args="-C addr=,user=,host=,laddr=,lport=0"
# shellcheck disable=SC2086
if ! (sshd -T ${sshd_args} 2> /dev/null | grep -qi 'permitrootlogin no'); then
failed "IS_SSHPERMITROOTNO" "PermitRoot should be set to no"
fi
}
check_evomaintenanceusers() {
if [ -f /etc/sudoers.d/evolinux ]; then
sudoers="/etc/sudoers.d/evolinux"
else
sudoers="/etc/sudoers"
fi
# combine users from User_Alias and sudo group
users=$({ grep "^User_Alias *ADMIN" $sudoers | cut -d= -f2 | tr -d " "; grep "^sudo" /etc/group | cut -d: -f 4; } | tr "," "\n" | sort -u)
for user in $users; do
user_home=$(getent passwd "$user" | cut -d: -f6)
if [ -n "$user_home" ] && [ -d "$user_home" ]; then
if ! grep -qs "^trap.*sudo.*evomaintenance.sh" "${user_home}"/.*profile; then
failed "IS_EVOMAINTENANCEUSERS" "${user} doesn't have an evomaintenance trap"
test "${VERBOSE}" = 1 || break
fi
fi
done
}
check_evomaintenanceconf() {
f=/etc/evomaintenance.cf
if [ -e "$f" ]; then
perms=$(stat -c "%a" $f)
test "$perms" = "600" || failed "IS_EVOMAINTENANCECONF" "Wrong permissions on \`$f' ($perms instead of 600)"
{ grep "^export PGPASSWORD" $f | grep -qv "your-passwd" \
&& grep "^PGDB" $f | grep -qv "your-db" \
&& grep "^PGTABLE" $f | grep -qv "your-table" \
&& grep "^PGHOST" $f | grep -qv "your-pg-host" \
&& grep "^FROM" $f | grep -qv "jdoe@example.com" \
&& grep "^FULLFROM" $f | grep -qv "John Doe <jdoe@example.com>" \
&& grep "^URGENCYFROM" $f | grep -qv "mama.doe@example.com" \
&& grep "^URGENCYTEL" $f | grep -qv "06.00.00.00.00" \
&& grep "^REALM" $f | grep -qv "example.com"
} || failed "IS_EVOMAINTENANCECONF" "evomaintenance is not correctly configured"
else
failed "IS_EVOMAINTENANCECONF" "Configuration file \`$f' is missing"
fi
}
check_privatekeyworldreadable() {
# a simple globbing fails if directory is empty
if [ -n "$(ls -A /etc/ssl/private/)" ]; then
for f in /etc/ssl/private/*; do
perms=$(stat -L -c "%a" "$f")
if [ "${perms: -1}" != 0 ]; then
failed "IS_PRIVKEYWOLRDREADABLE" "$f is world-readable"
test "${VERBOSE}" = 1 || break
fi
done
fi
}
check_evobackup_incs() {
if is_installed bkctld; then
bkctld_cron_file=${bkctld_cron_file:-/etc/cron.d/bkctld}
if [ -f "${bkctld_cron_file}" ]; then
root_crontab=$(grep -v "^#" "${bkctld_cron_file}")
echo "${root_crontab}" | grep -q "bkctld inc" || failed "IS_EVOBACKUP_INCS" "\`bkctld inc' is missing in ${bkctld_cron_file}"
echo "${root_crontab}" | grep -qE "(check-incs.sh|bkctld check-incs)" || failed "IS_EVOBACKUP_INCS" "\`check-incs.sh' is missing in ${bkctld_cron_file}"
else
failed "IS_EVOBACKUP_INCS" "Crontab \`${bkctld_cron_file}' is missing"
fi
fi
}
check_osprober() {