evocheck/evocheck.sh

328 lines
9.9 KiB
Bash
Raw Normal View History

#!/bin/sh
2009-07-05 01:58:11 +02:00
# EvoCheck
2020-04-21 16:59:08 +02:00
# Script to verify compliance of an OpenBSD server powered by Evolix
2009-07-05 01:58:11 +02:00
2009-09-14 18:58:38 +02:00
# Disable LANG*
2019-03-22 17:51:56 +01:00
2009-09-14 18:58:38 +02:00
export LANG=C
export LANGUAGE=C
2009-07-19 02:01:50 +02:00
# Default return code : 0 = no error
RC=0
# Verbose function
verbose() {
msg="${1:-$(cat /dev/stdin)}"
2019-01-17 11:02:40 +01:00
[ "${VERBOSE}" -eq 1 ] && [ -n "${msg}" ] && echo "${msg}"
}
2009-07-19 02:01:50 +02:00
# Source configuration file
2009-07-05 01:58:11 +02:00
test -f /etc/evocheck.cf && . /etc/evocheck.cf
# Functions
show_version() {
cat <<END
evocheck version ${VERSION}
Copyright 2009-2019 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>
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 OpenBSD 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
}
is_installed(){
for pkg in "$@"; do
pkg_info | grep -q $pkg || 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}" 2>&1
else
printf "%s FAILED!\n" "${check_name}" 2>&1
fi
fi
}
# Parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
while :; do
case $1 in
-h|-\?|--help)
show_help
exit 0
;;
--version)
show_version
exit 0
;;
--cron)
IS_KERNELUPTODATE=0
IS_UPTIME=0
;;
-v|--verbose)
VERBOSE=1
;;
-q|--quiet)
QUIET=1
VERBOSE=0
;;
--)
# End of all options.
shift
break
;;
-?*|[[:alnum:]]*)
# ignore unknown options
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*)
# Default case: If no more options then break out of the loop.
break
;;
esac
shift
done
# If --cron is passed, ignore some checks.
if [ "$1" = "--cron" ]; then
IS_KERNELUPTODATE=0
IS_UPTIME=0
fi
if [ "$IS_UMASKSUDOERS" = 1 ]; then
grep -E -qr "umask=0077" /etc/sudoers* || failed "IS_UMASKSUDOERS" "sudoers must set umask to 0077"
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_TMPNOEXEC" = 1 ]; then
mount | grep "on /tmp" | grep -q noexec || failed "IS_TMPNOEXEC" "/tmp should be mounted with the noexec option"
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_TMOUTPROFILE" = 1 ]; then
grep -q TMOUT= /etc/skel/.profile /root/.profile || failed "IS_TMOUTPROFILE" "In order to fix, add 'export TMOUT=36000' to both /etc/skel/.profile and /root/.profile files"
fi
# Check RAID state (bioctl)
#if [ "$IS_RAIDOK" = 1 ]; then
# TODO
#fi
# Check Evoackup installation
if [ "$IS_EVOBACKUP" = 1 ]; then
if [ -f /etc/daily.local ]; then
grep -qE "^sh /usr/share/scripts/zzz_evobackup" /etc/daily.local || failed "IS_EVOBACKUP" "Make sure 'sh /usr/share/scripts/zzz_evobackup' is present and activated in /etc/daily.local"
else
failed "IS_EVOBACKUP" "Make sure /etc/daily.local exists and 'sh /usr/share/scripts/zzz_evobackup' is present and activated in /etc/daily.local"
fi
fi
2018-03-29 22:29:50 +02:00
# Check whether the system should be restarted (after a kernel update)
#if [ "$IS_KERNELUPTODATE" = 1 ]; then
# TODO
#fi
# Check if the server is running for more than a year.
if [ "$IS_UPTIME" = 1 ]; then
2019-03-22 14:57:18 +01:00
if [ $(uptime | cut -d" " -f 4) -gt 365 ]; then
failed "IS_UPTIME" "The server is running for more than a year!"
fi
fi
2018-03-29 22:29:50 +02:00
# Check if files in /home/backup/ are up-to-date
#if [ "$IS_BACKUPUPTODATE" = 1 ]; then
# TODO
#fi
2016-06-16 18:08:22 +02:00
# Check if /etc/.git/ has read/write permissions for root only.
if [ "$IS_GITPERMS" = 1 ]; then
test -d /etc/.git && [ "$(stat -f %p /etc/.git/)" = "40700" ] || failed "IS_GITPERMS" "The directiry /etc/.git sould be in 700"
fi
2017-05-31 16:01:19 +02:00
#if [ "$IS_OLD_HOME_DIR" = 1 ]; then
#fi
Squashed commit of the following: commit db23167246678114668d640f88ed9e2f6397ded2 Author: Benoît S <bserie@evolix.fr> Date: Thu Jun 28 11:48:22 2018 +0200 Add a check for kernel config gile commit ae1ec7b2b9f3bd2d1c78af544562dd207ef5f330 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 18:01:07 2018 +0200 Redo the jessie part commit 62b61aabf169ebc9e7e741f4190507f177a9642d Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:49:44 2018 +0200 Well... For Stretch use only /sys/devices/system/cpu/vulnerabilities/ commit 33b19090e6c2462228f9f650f1e83da0b5928406 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:45:11 2018 +0200 Add check for spectre v2 commit 3451218a167e5b2efebed1f80234c9d2596546d3 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:33:24 2018 +0200 Do not use the BOOT_IMAGE trick commit ee60e28a5add36fb6b55231f8e39f275b5592409 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:30:18 2018 +0200 We cannot rely on dmesg commit 57bd4312cea6ce1d5b9c23e3e8307f1bc42852cb Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 14:46:46 2018 +0100 Breakline indentation commit d2278292ccf4340913ac6982961e0f011e077a3a Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 14:45:12 2018 +0100 Diffrent test for Jessie kernel commit 1418d4306e81152fa949821484a7d1226e1f2d5b Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 11:52:43 2018 +0100 Modified Meltdown check to handle kaiser and pti commit 2c6d075e2a9749d2805fb52ec5a2c7274f73dfc7 Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 11:24:42 2018 +0100 Add IS_MELTDOWN We check kaiser flags in /proc/cpuinfo and CONFIG_PAGE_TABLE_ISOLATION in kernel config file.
2018-06-28 11:52:31 +02:00
if [ "$IS_ADVBASE" = 1 ]; then
if ls /etc/hostname.carp* 1> /dev/null 2>&1; then
for advbase in $(ifconfig carp | grep advbase | awk -F 'advbase' '{print $2}' | awk '{print $1}' | xargs); do
if [[ "$advbase" -gt 1 ]]; then
failed "IS_ADVBASE" "At least one CARP interface has advbase greater than 5 seconds!"
Squashed commit of the following: commit db23167246678114668d640f88ed9e2f6397ded2 Author: Benoît S <bserie@evolix.fr> Date: Thu Jun 28 11:48:22 2018 +0200 Add a check for kernel config gile commit ae1ec7b2b9f3bd2d1c78af544562dd207ef5f330 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 18:01:07 2018 +0200 Redo the jessie part commit 62b61aabf169ebc9e7e741f4190507f177a9642d Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:49:44 2018 +0200 Well... For Stretch use only /sys/devices/system/cpu/vulnerabilities/ commit 33b19090e6c2462228f9f650f1e83da0b5928406 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:45:11 2018 +0200 Add check for spectre v2 commit 3451218a167e5b2efebed1f80234c9d2596546d3 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:33:24 2018 +0200 Do not use the BOOT_IMAGE trick commit ee60e28a5add36fb6b55231f8e39f275b5592409 Author: Benoît S <bserie@evolix.fr> Date: Wed Jun 27 17:30:18 2018 +0200 We cannot rely on dmesg commit 57bd4312cea6ce1d5b9c23e3e8307f1bc42852cb Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 14:46:46 2018 +0100 Breakline indentation commit d2278292ccf4340913ac6982961e0f011e077a3a Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 14:45:12 2018 +0100 Diffrent test for Jessie kernel commit 1418d4306e81152fa949821484a7d1226e1f2d5b Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 11:52:43 2018 +0100 Modified Meltdown check to handle kaiser and pti commit 2c6d075e2a9749d2805fb52ec5a2c7274f73dfc7 Author: Benoît.S <benpro@benpro.fr> Date: Thu Jan 11 11:24:42 2018 +0100 Add IS_MELTDOWN We check kaiser flags in /proc/cpuinfo and CONFIG_PAGE_TABLE_ISOLATION in kernel config file.
2018-06-28 11:52:31 +02:00
fi
done
fi
fi
if [ "$IS_PREEMPT" = 1 ]; then
if ls /etc/hostname.carp* 1> /dev/null 2>&1; then
preempt=$(sysctl net.inet.carp.preempt | cut -d"=" -f2)
if [[ "$preempt" -ne 1 ]]; then
failed "IS_PREEMPT" "The preempt function is not activated! Please type 'sysctl net.inet.carp.preempt=1' in"
2019-03-12 17:33:01 +01:00
fi
if [ -f /etc/sysctl.conf ]; then
grep -qE "^net.inet.carp.preempt=1" /etc/sysctl.conf || failed "IS_PREEMPT" "The preempt parameter is not permanently activated! Please add 'net.inet.carp.preempt=1' in /etc/sysctl.conf"
else
failed "IS_PREEMPT" "Make sure /etc/sysctl.conf exists and contains the line 'net.inet.carp.preempt=1'"
fi
fi
fi
if [ "$IS_REBOOTMAIL" = 1 ]; then
if [ -f /etc/rc.local ]; then
grep -qE '^date \| mail -s "boot/reboot of' /etc/rc.local || failed "IS_REBOOTMAIL" "Make sure the line 'date | mail -s \"boot/reboot of \$hostname' is present in the /etc/rc.local file!"
else
failed "IS_REBOOTMAIL" "Make sure /etc/rc.local exist and 'date | mail -s \"boot/reboot of \$hostname' is present!"
fi
fi
2018-03-29 22:29:50 +02:00
2019-03-22 17:36:01 +01:00
#if [ "$IS_PFENABLED" = 1 ]; then
# TODO
#fi
2019-03-22 17:36:23 +01:00
#if [ "$IS_PFCUSTOM" = 1 ]; then
# TODO
#fi
if [ "$IS_SOFTDEP" = 1 ]; then
grep -q "softdep" /etc/fstab || failed "IS_SOFTDEP" ""
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_WHEEL" = 1 ]; then
if [ -f /etc/sudoers ]; then
grep -qE "^%wheel.*$" /etc/sudoers || failed "IS_WHEEL" ""
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_PKGMIRROR" = 1 ]; then
grep -qE "^https://cdn\.openbsd\.org/pub/OpenBSD" /etc/installurl || failed "IS_PKGMIRROR" "Check whether the right repo is present in the /etc/installurl file"
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_HISTORY" = 1 ]; then
2019-03-22 17:17:55 +01:00
file=/root/.profile
grep -qE "^HISTFILE=\$HOME/.histfile" $file && grep -qE "^export HISTSIZE=10000" $file || failed "IS_HISTORY" "Make sure both 'HISTFILE=$HOME/.histfile' and 'export HISTSIZE=10000' are present in /root/.profile"
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_VIM" = 1 ]; then
if ! is_installed vim; then
failed "IS_VIM" "vim is not installed! Please add with pkg_add vim"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_TTYC0SECURE" = 1 ]; then
grep -Eqv "^ttyC0.*secure$" /etc/ttys || failed "IS_TTYC0SECURE" "First tty should be secured"
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_CUSTOMSYSLOG" = 1 ]; then
grep -q Evolix /etc/newsyslog.conf || failed "IS_CUSTOMSYSLOG" ""
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_SUDOMAINT" = 1 ]; then
f=/etc/sudoers
grep -q "Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh" $f \
&& grep -q "ADMIN ALL=NOPASSWD: MAINT" $f \
|| failed "IS_SUDOMAINT" ""
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_POSTGRESQL" = 1 ]; then
if ! is_installed postgresql-client; then
failed "IS_POSTGRESQL" "postgresql-client is not installed! Please add with pkg_add postgresql-client"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_NRPE" = 1 ]; then
if ! is_installed monitoring-plugins || ! is_installed nrpe; then
failed "IS_NRPE" "nrpe and/or monitoring-plugins are not installed! Please add with pkg_add nrpe monitoring-plugins"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_RSYNC" = 1 ]; then
if ! is_installed rsync; then
failed "IS_RSYNC" "rsync is not installed! Please add with pkg_add rsync"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_CRONPATH" = 1 ]; then
grep -q "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" /var/cron/tabs/root || failed "IS_CRONPATH" ""
fi
2009-07-05 01:58:11 +02:00
if [ "$IS_TMP_1777" = 1 ]; then
ls -ld /tmp | grep -q drwxrwxrwt || failed "IS_TMP_1777" ""
2009-07-05 01:58:11 +02:00
fi
if [ "$IS_ROOT_0700" = 1 ]; then
ls -ld /root | grep -q drwx------ || failed "IS_ROOT_0700" ""
2009-07-05 01:58:11 +02:00
fi
if [ "$IS_USRSHARESCRIPTS" = 1 ]; then
ls -ld /usr/share/scripts | grep -q drwx------ || failed "IS_USRSHARESCRIPTS" ""
2009-07-05 01:58:11 +02:00
fi
2009-07-13 01:44:31 +02:00
if [ "$IS_SSHPERMITROOTNO" = 1 ]; then
grep -qE ^PermitRoot /etc/ssh/sshd_config && ( grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config || failed "IS_SSHPERMITROOTNO" "" )
2009-07-13 01:44:31 +02:00
fi
2009-07-18 17:21:00 +02:00
if [ "$IS_EVOMAINTENANCEUSERS" = 1 ]; then
# Can be changed in evocheck.cf
homeDir=${homeDir:-/home}
sudoers="/etc/sudoers"
for i in $( (grep "^User_Alias *ADMIN" $sudoers | cut -d= -f2 | tr -d " "; grep ^sudo /etc/group |cut -d: -f 4) | tr "," "\n" |sort -u); do
grep -qs "^trap.*sudo.*evomaintenance.sh" ${homeDir}/${i}/.*profile
if [ $? != 0 ]; then
failed "IS_EVOMAINTENANCEUSERS" "$i doesn't have evomaintenance trap!"
2017-11-14 17:34:41 +01:00
fi
2019-03-25 17:10:22 +01:00
done
2009-07-18 17:21:00 +02:00
fi
# Verification de la configuration d'evomaintenance
if [ "$IS_EVOMAINTENANCECONF" = 1 ]; then
f=/etc/evomaintenance.cf
( test -e $f \
2019-03-25 17:10:22 +01:00
&& test $(stat -f %p $f) = "100600" \
&& 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" ""
fi