evocheck/evocheck.sh

423 lines
12 KiB
Bash
Raw Normal View History

#!/bin/sh
2009-07-05 01:58:11 +02:00
# EvoCheck
2019-03-22 17:51:56 +01:00
# Script to verify compliance of a 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 configuration values
2019-03-22 17:51:56 +01:00
IS_CUSTOMSUDOERS=1
2019-03-22 17:51:56 +01:00
IS_TMPNOEXEC=1
IS_TMOUTPROFILE=1
2019-03-22 17:51:56 +01:00
IS_RAIDOK=1
IS_EVOBACKUP=1
IS_KERNELUPTODATE=1
IS_UPTIME=1
IS_BACKUPUPTODATE=1
2016-06-16 18:08:22 +02:00
IS_GITPERMS=1
IS_OLD_HOME_DIR=1
2019-03-22 17:51:56 +01:00
IS_ADVBASE=1
IS_PREEMPT=1
IS_REBOOTMAIL=1
IS_PFENABLED=1
IS_PFCUSTOM=1
IS_SOFTDEP=1
IS_WHEEL=1
IS_PKGMIRROR=1
IS_HISTORY=1
IS_VIM=1
IS_TTYC0SECURE=1
IS_CUSTOMSYSLOG=1
IS_SUDOMAINT=1
IS_POSTGRESQL=1
IS_NRPE=1
IS_RSYNC=1
2019-03-22 17:51:56 +01:00
IS_CRONPATH=1
IS_TMP_1777=1
IS_ROOT_0700=1
IS_USRSHARESCRIPTS=1
IS_SSHPERMITROOTNO=1
IS_EVOMAINTENANCEUSERS=1
IS_EVOMAINTENANCECONF=1
# 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
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}" 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_CUSTOMSUDOERS" = 1 ]; then
grep -E -qr "umask=0077" /etc/sudoers* || echo 'IS_CUSTOMSUDOERS FAILED!'
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_TMPNOEXEC" = 1 ]; then
mount | grep "on /tmp" | grep -q noexec || echo 'IS_TMPNOEXEC FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "/tmp should be mounted with the noexec option"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_TMOUTPROFILE" = 1 ]; then
grep -q TMOUT= /etc/skel/.profile /root/.profile || echo 'IS_TMOUTPROFILE FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "In order to fix, add 'export TMOUT=36000' to both /etc/skel/.profile and /root/.profile files"
fi
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 || echo 'IS_EVOBACKUP FAILED!'
else
echo 'IS_EVOBACKUP FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "Make sure /etc/daily.local exist and 'sh /usr/share/scripts/zzz_evobackup' is present and activated in /etc/daily.local"
fi
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
echo 'IS_UPTIME FAILED!'
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" ] || echo 'IS_GITPERMS FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "The directiry /etc/.git sould be in 700"
fi
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
echo 'IS_ADVBASE FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "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
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
echo 'IS_PREEMPT FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "The preempt function is not activated! Please type 'sysctl net.inet.carp.preempt=1' in"
2019-03-12 17:33:01 +01:00
fi
fi
if [ -f /etc/sysctl.conf ]; then
grep -qE "^net.inet.carp.preempt=1" /etc/sysctl.conf || echo 'IS_PREEMPT FAILED!'
else
echo 'IS_PREEMPT FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "The preempt parameter is not permanently activated! Please add 'net.inet.carp.preempt=1' in /etc/sysctl.conf"
fi
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 || echo 'IS_REBOOTMAIL FAILED!'
else
echo 'IS_REBOOTMAIL FAILED!'
2019-03-11 16:32:58 +01:00
if [[ "$VERBOSE" == 1 ]]; then
echo "Make sure /etc/rc.local exist and 'date | mail -s \"boot/reboot of \$hostname' is present!"
2019-03-11 16:32:58 +01:00
fi
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 || echo 'IS_SOFTDEP FAILED!'
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_WHEEL" = 1 ]; then
if [ -f /etc/sudoers ]; then
grep -qE "^%wheel.*$" /etc/sudoers || echo 'IS_WHEEL FAILED!'
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 || echo 'IS_PKGMIRROR FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "Check whether the right repo is present in the /etc/installurl file"
fi
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 || echo 'IS_HISTORY FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "Make sure both 'HISTFILE=$HOME/.histfile' and 'export HISTSIZE=10000' are present in /root/.profile"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_VIM" = 1 ]; then
pkg_info | grep -q vim || echo 'IS_VIM FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "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 || echo 'IS_TTYC0SECURE FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "First tty should be secured"
fi
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_CUSTOMSYSLOG" = 1 ]; then
grep -q Evolix /etc/newsyslog.conf || echo 'IS_CUSTOMSYSLOG FAILED!'
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 \
|| echo 'IS_SUDOMAINT FAILED!'
fi
2018-03-29 22:29:50 +02:00
if [ "$IS_POSTGRESQL" = 1 ]; then
pkg_info | grep -q postgresql-client || echo 'IS_POSTGRESQL FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "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
2019-03-22 17:24:45 +01:00
( pkg_info | grep -q monitoring-plugins && pkg_info | grep -q nrpe ) || echo 'IS_NRPE FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "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
pkg info | grep -q rsync || echo 'IS_RSYNC FAILED!'
if [[ "$VERBOSE" == 1 ]]; then
echo "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 || echo 'IS_CRONPATH FAILED!'
fi
2009-07-05 01:58:11 +02:00
if [ "$IS_TMP_1777" = 1 ]; then
ls -ld /tmp | grep -q drwxrwxrwt || echo 'IS_TMP_1777 FAILED!'
2009-07-05 01:58:11 +02:00
fi
if [ "$IS_ROOT_0700" = 1 ]; then
ls -ld /root | grep -q drwx------ || echo 'IS_ROOT_0700 FAILED!'
2009-07-05 01:58:11 +02:00
fi
if [ "$IS_USRSHARESCRIPTS" = 1 ]; then
ls -ld /usr/share/scripts | grep -q drwx------ || echo 'IS_USRSHARESCRIPTS FAILED!'
2009-07-05 01:58:11 +02:00
fi
2009-07-13 01:44:31 +02:00
if [ "$IS_SSHPERMITROOTNO" = 1 ]; then
2019-03-22 17:34:05 +01:00
grep -qE ^PermitRoot /etc/ssh/sshd_config && ( grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config || echo 'IS_SSHPERMITROOTNO FAILED!' )
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}
2017-11-14 17:34:41 +01:00
if ! is_debianversion stretch; then
if [ -f /etc/sudoers.d/evolinux ]; then
sudoers="/etc/sudoers.d/evolinux"
else
sudoers="/etc/sudoers"
fi
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
echo 'IS_EVOMAINTENANCEUSERS FAILED!'
if [ "$VERBOSE" = 1 ]; then
echo "$i doesn't have evomaintenance trap!"
else
break
fi
fi
2017-11-14 17:34:41 +01:00
done
2016-05-10 16:28:07 +02:00
else
2018-03-29 22:29:50 +02:00
for i in $(getent group evolinux-sudo | cut -d':' -f4 | tr ',' ' '); do
grep -qs "^trap.*sudo.*evomaintenance.sh" ${homeDir}/$i/.*profile
if [ $? != 0 ]; then
echo 'IS_EVOMAINTENANCEUSERS FAILED!'
if [ "$VERBOSE" = 1 ]; then
echo "$i doesn't have evomaintenance trap!"
else
break
fi
fi
2017-11-14 17:34:41 +01:00
done
2016-05-10 16:28:07 +02:00
fi
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 \
&& test $(stat -c "%a" $f) = "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" ) || echo 'IS_EVOMAINTENANCECONF FAILED!'
fi