Compare commits
222 Commits
Author | SHA1 | Date |
---|---|---|
|
7041505446 | |
![]() |
4dbb3d030d | |
|
fb14549843 | |
|
1d995764a9 | |
![]() |
5402fa0dee | |
![]() |
f024f9d9e8 | |
![]() |
e80a7781c7 | |
![]() |
79a61e3046 | |
![]() |
95539ea38c | |
![]() |
77be2c3fe1 | |
![]() |
f4948b5611 | |
![]() |
ad85fd9784 | |
![]() |
668791208a | |
![]() |
f546fb97f0 | |
![]() |
be53bce0e5 | |
![]() |
f2d1f43e85 | |
![]() |
f5887eb43c | |
![]() |
59a14150db | |
![]() |
3bf5c4fcb7 | |
![]() |
5d15f373c2 | |
![]() |
5fe7a88fab | |
![]() |
ad50601931 | |
![]() |
9b1946d9a0 | |
![]() |
443c232b95 | |
![]() |
868fe9d7c0 | |
|
5b0a011eda | |
![]() |
081a8166cc | |
![]() |
8f58aa00ee | |
![]() |
d92a8862e8 | |
![]() |
1067bc6a27 | |
![]() |
42cbd14123 | |
|
ed602d9e83 | |
|
b3db84a8f7 | |
![]() |
24d3f67718 | |
|
171924d99c | |
|
e09e5b3e53 | |
![]() |
7c40af199b | |
![]() |
152653d773 | |
![]() |
6414a8c70e | |
![]() |
9d011b71b0 | |
|
ad9231d9a9 | |
|
442d1446b5 | |
|
90c1f854cf | |
|
02e2d4c5c0 | |
|
4008fb3128 | |
|
0dae32a135 | |
![]() |
ae797122ad | |
![]() |
96ea77b345 | |
|
baf26b23c4 | |
|
8d22e5ea85 | |
|
011c62f984 | |
![]() |
da28729577 | |
![]() |
03f9a4eb15 | |
![]() |
e21c4e8233 | |
![]() |
1bb00c10bd | |
![]() |
ff92e3889e | |
![]() |
97a98c8df3 | |
![]() |
32d2a94b71 | |
![]() |
e5aa1aa323 | |
![]() |
c852fb188d | |
![]() |
c621431e05 | |
![]() |
ccb6c3e4f8 | |
![]() |
8db26f1622 | |
![]() |
e172c27f63 | |
![]() |
72e4b3f045 | |
![]() |
9361e5a9cf | |
![]() |
6ca6686cb3 | |
|
8ae087b799 | |
|
29b546584a | |
|
f1074dea2d | |
|
f5410be26c | |
|
3d7b2a676f | |
|
289e303801 | |
|
be1e303040 | |
|
653f29e2d8 | |
|
c8ea1a3744 | |
![]() |
f9fdc2c4ee | |
![]() |
12681b8259 | |
![]() |
339afdcec2 | |
![]() |
6566193ebc | |
![]() |
2540c6f312 | |
![]() |
ff7aee8ea7 | |
|
1a2c3e0859 | |
|
f7570ec865 | |
|
8fd10bfeaf | |
|
6c1d4f63ac | |
|
0ff69e6a07 | |
![]() |
2640bb1b11 | |
![]() |
a232eeebcc | |
|
58a97812c6 | |
|
55b08445a7 | |
![]() |
f74f1317b4 | |
|
76dfe5fa24 | |
|
aeb7ea2af4 | |
|
5765ad2a7d | |
|
8a1bd96789 | |
|
043d1e58b1 | |
|
0549b39166 | |
|
1638ed1884 | |
|
a87438a41b | |
|
d58c0dc335 | |
|
cb8d8fa738 | |
|
3f88645c6f | |
|
f2f3155fc3 | |
|
271e8623b4 | |
|
2e1d873fe1 | |
|
18c531325d | |
|
75f8a55e9b | |
|
6f9607bc0e | |
|
72a85bc9ef | |
|
0c16fcf311 | |
|
3c2b870a6d | |
|
69937e9c2d | |
|
5c5a061d59 | |
![]() |
52e114e45f | |
![]() |
40753385d1 | |
|
64c7cd3424 | |
|
b8496e754d | |
|
d35d7491f1 | |
|
63dd6bf41c | |
|
2551401baa | |
|
3d1881fe80 | |
|
78486611c5 | |
|
fb7ec6bacf | |
|
bec90cb8ee | |
|
5adfdcc614 | |
|
156435220a | |
|
735c960621 | |
|
5f9b6901cb | |
![]() |
1a08da8afa | |
|
0c461689d1 | |
![]() |
e38aa5636f | |
![]() |
13859f306b | |
|
8d460b039d | |
|
1281891363 | |
|
3fcab1eeb3 | |
![]() |
43d09c3ba1 | |
|
11d77659a0 | |
|
f1c63f827f | |
|
e0202f28ff | |
|
8a735ca4ca | |
|
af259252be | |
|
5bf2959aac | |
|
e21628fea7 | |
|
04139f3d60 | |
|
b6f4889ac5 | |
|
b49a1fbea5 | |
|
682cd3afaa | |
|
7cb6055af5 | |
|
4798873ace | |
|
8eb2c5f9bc | |
|
5bad0301d9 | |
|
57d44cbf91 | |
|
3d86996f5d | |
|
04994ecebc | |
![]() |
c688b0d524 | |
![]() |
b58ad51307 | |
![]() |
5eedf3ad4d | |
![]() |
239c5896df | |
![]() |
8d80e5bfc8 | |
![]() |
4fead89240 | |
![]() |
e0716d3197 | |
![]() |
c436480014 | |
![]() |
a5a034e611 | |
![]() |
1d47e0f8d8 | |
![]() |
82a9050e00 | |
![]() |
0b6ad08b5b | |
![]() |
b1868829aa | |
![]() |
cf975ee14b | |
![]() |
f019e82255 | |
![]() |
c72a779f6c | |
![]() |
68823b7c91 | |
![]() |
6f5b5d78d8 | |
![]() |
e69e08160d | |
![]() |
425b08552a | |
![]() |
fe76e40b35 | |
![]() |
9164fe2459 | |
![]() |
5ee0d20fe9 | |
![]() |
82af0db8b2 | |
![]() |
ef2b234d49 | |
![]() |
53015152b3 | |
![]() |
12ccfa914b | |
![]() |
477c15df8a | |
![]() |
1add27c67d | |
![]() |
71436c2f44 | |
![]() |
53c7c42324 | |
![]() |
3a18ec50a7 | |
![]() |
ec7de84aa7 | |
![]() |
6f55586f6b | |
![]() |
f8f0effa94 | |
![]() |
ba43de597e | |
![]() |
94cbf9e589 | |
![]() |
7eba87917f | |
![]() |
ed93ba9f5d | |
![]() |
3948702561 | |
![]() |
4f1ee5a982 | |
![]() |
e509ea879e | |
![]() |
5d5291f08d | |
![]() |
e3f0b45724 | |
![]() |
6a9ba37c30 | |
![]() |
d6ef05803e | |
![]() |
950ea6fca6 | |
![]() |
8ae3707044 | |
![]() |
08edb86da6 | |
![]() |
e4269d793c | |
![]() |
37f3c1faee | |
![]() |
823a4f9ee0 | |
![]() |
954eaf5e28 | |
![]() |
de487e964c | |
![]() |
53cd10f4a8 | |
![]() |
4c43e1b21a | |
![]() |
4dc94a19b0 | |
![]() |
9832da8b03 | |
![]() |
d52aa4915b | |
![]() |
9a52beedbe | |
![]() |
6f4f299006 | |
![]() |
f10df11143 | |
![]() |
5be38dc4f5 | |
![]() |
2815c211f4 | |
![]() |
4c83cf1a28 | |
![]() |
c90de6ec1f | |
![]() |
f379f6210a |
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.vagrant
|
||||
|
||||
tmp
|
||||
*.swp
|
||||
.DS_Store
|
||||
|
|
13
README.md
13
README.md
|
@ -52,7 +52,7 @@ For Debian versions : `is_debian`, `is_debian_stretch`, `is_debian_jessie`…
|
|||
For packs : `is_pack_web`, `is_pack_samba`.
|
||||
For installed packages : `is_installed <package> [<package>]`.
|
||||
|
||||
### Extact variables
|
||||
### Extract variables
|
||||
|
||||
It's better not to inline function calls inside tests. Instead of this :
|
||||
|
||||
|
@ -72,8 +72,19 @@ test "$expected" = "$actual" || failed "IS_MINIFWPERMS"
|
|||
|
||||
It's better to verify that a file, a directory or a command is present before using it, even if it's true in more than 99% of situations.
|
||||
|
||||
|
||||
## How to build the package for a new Debian release
|
||||
|
||||
Pre-tasks:
|
||||
|
||||
* Execute shellcheck on scripts `*.sh` and fix or disable the relevant checks.
|
||||
* Prepare `linux/CHANGELOG` and `openbsd/CHANGELOG` for release.
|
||||
* Update version number is scripts :
|
||||
|
||||
```
|
||||
sed -i 's/VERSION=".*"/VERSION="<MAJOR>.<MINOR>"/g' */evocheck*.sh
|
||||
```
|
||||
|
||||
On the master branch, add the last stable version with a release tag.
|
||||
```
|
||||
git tag -s v<VERSION> -m 'New release'
|
||||
|
|
|
@ -13,8 +13,198 @@ and this project **does not adhere to [Semantic Versioning](http://semver.org/sp
|
|||
|
||||
### Fixed
|
||||
|
||||
## [23.11.1]
|
||||
|
||||
### Fixed
|
||||
|
||||
* IS_EVOBACKUP_EXCLUDE_MOUNT: fix another regression introduced in previous release
|
||||
|
||||
### Security
|
||||
|
||||
## [23.11]
|
||||
|
||||
### Added
|
||||
|
||||
* trixie and forky support (Debian 13, 14)
|
||||
* IS_LXC_OPENSSH: check in openssh is installed in containers
|
||||
* IS_LXC_PHP_BAD_DEBIAN_VERSION: check if php containers use the expected Debian release
|
||||
* IS_DEBIANSECURITY_LXC: IS_DEBIANSECURITY in containers
|
||||
* IS_SURY_LXC: IS_SURY in containers
|
||||
* IS_OLDPUB_LXC: IS_OLDPUB in containers
|
||||
* IS_ETCGIT_LXC: IS_ETCGIT in containers
|
||||
* IS_GITPERMS_LXC: IS_GITPERMS in containers
|
||||
|
||||
### Changed
|
||||
|
||||
* IS_SSHALLOWUSERS: add Debian 12 condition
|
||||
* IS_PHPEVOLINUXCONF: update for bookworm
|
||||
* IS_MINIFWINCLUDES, IS_NRPEPID: Change Debian release detection logic
|
||||
|
||||
### Fixed
|
||||
|
||||
* IS_EVOBACKUP_EXCLUDE_MOUNT: fix regression introduced in previous version
|
||||
|
||||
## [23.10] 2023-10-26
|
||||
|
||||
### Added
|
||||
|
||||
* IS_MINIFW: better detection of minifirewall status
|
||||
* IS_OLDPUB: pub.evolix.net has been supersed by pub.evolix.org since Stretch
|
||||
* IS_NEWPUB: verify that the new public repository is present
|
||||
* IS_DRBDTWOPRIMARIES: check there are not 2 DRBD primaries at the same time.
|
||||
* IS_SURY: check that if sury is enabled, then a safeguard must be in place
|
||||
|
||||
### Changed
|
||||
|
||||
* IS_BACKPORTSCONF: does not require preferences anymore
|
||||
|
||||
### Fixed
|
||||
|
||||
* IS_BINDCHROOT: fix /etc/default path for Debian >= 11 (renamed from bind9 to named)
|
||||
* IS_EVOBACKUP_EXCLUDE_MOUNT: adapt to new version of evobackup (#148)
|
||||
|
||||
## [23.07] 2023-07-07
|
||||
|
||||
### Fixed
|
||||
* IS_REDIS_BACKUP: full rewrite of the check to be more flexible, and also check time of dump.
|
||||
|
||||
## [23.04.01] 2023-04-07
|
||||
|
||||
### Fixed
|
||||
* IS_POSTFIX_MYDESTINATION: fix regex not working (again).
|
||||
|
||||
## [23.04] 2023-04-07
|
||||
|
||||
### Changed
|
||||
* IS_LOCALHOST_IN_POSTFIX_MYDESTINATION: renamed to IS_POSTFIX_MYDESTINATION
|
||||
|
||||
### Fixed
|
||||
* IS_POSTFIX_MYDESTINATION: fix regex not working.
|
||||
|
||||
## [23.03.01] 2023-03-01
|
||||
|
||||
### Fixed
|
||||
* Fix version number.
|
||||
|
||||
## [23.03] 2023-03-01
|
||||
|
||||
### Added
|
||||
|
||||
* Log output and runtime config to /var/log/evocheck.log.
|
||||
|
||||
### Changed
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
* IS_LOCALHOST_IN_POSTFIX_MYDESTINATION: set grep quiet.
|
||||
* IS_LXC_PHP_FPM_SERVICE_UMASK_SET: fix inverted test condition.
|
||||
|
||||
### Security
|
||||
|
||||
## [23.02] 2023-02-10
|
||||
|
||||
### Fixed
|
||||
|
||||
* Release with the correct version number.
|
||||
|
||||
## [22.12] 2023-02-10
|
||||
|
||||
### Added
|
||||
|
||||
New checks :
|
||||
|
||||
* IS_LOCALHOST_IN_POSTFIX_MYDESTINATION
|
||||
* IS_SSH_FAIL2BAN_JAIL_RENAMED
|
||||
* IS_NO_LXC_CONTAINER
|
||||
* IS_LXC_PHP_FPM_SERVICE_UMASK_SET
|
||||
|
||||
### Changed
|
||||
|
||||
* Use bash array for tmp files to cleanup.
|
||||
|
||||
### Fixed
|
||||
|
||||
* IS_EVOBACKUP_INCS: fix quote.
|
||||
* IS_PURGE_FAIL2BAN: fix function never called in main().
|
||||
* IS_NOTUPGRADED: silence "grep: (...) binary file matches" messages.
|
||||
|
||||
## [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="23.11.1"
|
||||
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
|
||||