diff --git a/bin/hardening/8.2.5_syslog-ng_remote_host.sh b/bin/hardening/8.2.5_syslog-ng_remote_host.sh index 03ca7f3..9ef0cfa 100755 --- a/bin/hardening/8.2.5_syslog-ng_remote_host.sh +++ b/bin/hardening/8.2.5_syslog-ng_remote_host.sh @@ -14,27 +14,40 @@ set -u # One variable unset, it's over HARDENING_LEVEL=3 DESCRIPTION="Configure syslog-ng to send logs to a remote log host." -PATTERN='^destination.*(tcp|udp)[[:space:]]*\([[:space:]]*\".*\"[[:space:]]*\)' +PATTERN='destination[[:alnum:][:space:]*{]+(tcp|udp)[[:space:]]*\(\"[[:alnum:].]+\".' # This function will be called if the script status is on enabled / audit mode audit () { - FILES="$SYSLOG_BASEDIR/syslog-ng.conf $SYSLOG_BASEDIR/conf.d/*" - does_pattern_exist_in_file "$FILES" "$PATTERN" - if [ $FNRET != 0 ]; then - crit "$PATTERN is not present in $FILES" - else + FOUND=0 + FILES="$SYSLOG_BASEDIR/syslog-ng.conf $(find $SYSLOG_BASEDIR/conf.d/)" + for FILE in $FILES; do + does_pattern_exist_in_file_multiline "$FILE" "$PATTERN" + if [ $FNRET == 0 ]; then + FOUND=1 + fi + done + + if [ $FOUND == 1 ]; then ok "$PATTERN is present in $FILES" - fi + else + crit "$PATTERN is not present in $FILES" + fi } # This function will be called if the script status is on enabled mode apply () { - FILES="$SYSLOG_BASEDIR/syslog-ng.conf $SYSLOG_BASEDIR/conf.d/*" - does_pattern_exist_in_file "$FILES" "$PATTERN" - if [ $FNRET != 0 ]; then - crit "$PATTERN is not present in $FILES, please set a remote host to send your logs" - else + FOUND=0 + FILES="$SYSLOG_BASEDIR/syslog-ng.conf $(find $SYSLOG_BASEDIR/conf.d/ -type f)" + for FILE in $FILES; do + does_pattern_exist_in_file_multiline "$FILE" "$PATTERN" + if [ $FNRET == 0 ]; then + FOUND=1 + fi + done + if [ $FOUND == 1 ]; then ok "$PATTERN is present in $FILES" + else + crit "$PATTERN is not present in $FILES, please set a remote host to send your logs" fi } @@ -48,7 +61,7 @@ EOF # This function will check config parameters required check_config() { - : + : } # Source Root Dir Parameter diff --git a/bin/hardening/8.3.2_tripwire_cron.sh b/bin/hardening/8.3.2_tripwire_cron.sh index ab9c539..190d8fd 100755 --- a/bin/hardening/8.3.2_tripwire_cron.sh +++ b/bin/hardening/8.3.2_tripwire_cron.sh @@ -1,5 +1,6 @@ #!/bin/bash +# run-shellcheck # # CIS Debian Hardening # @@ -11,26 +12,34 @@ set -e # One error, it's over set -u # One variable unset, it's over +# shellcheck disable=2034 HARDENING_LEVEL=4 +# shellcheck disable=2034 DESCRIPTION="Implemet periodic execution of file integrity." -FILES='/etc/crontab /etc/cron.d/*' +FILES="/etc/crontab $(find /etc/cron.d/ -type f)" PATTERN='tripwire --check' # This function will be called if the script status is on enabled / audit mode audit () { - does_pattern_exist_in_file "$FILES" "$PATTERN" - if [ $FNRET != 0 ]; then - crit "$PATTERN is not present in $FILES" - else + FOUND=0 + for FILE in $FILES; do + does_pattern_exist_in_file "$FILE" "$PATTERN" + if [ "$FNRET" == 0 ]; then + FOUND=1 + fi + done + if [ $FOUND == 1 ]; then ok "$PATTERN is present in $FILES" + else + crit "$PATTERN is not present in $FILES" fi } # This function will be called if the script status is on enabled mode apply () { does_pattern_exist_in_file "$FILES" "$PATTERN" - if [ $FNRET != 0 ]; then + if [ "$FNRET" != 0 ]; then warn "$PATTERN is not present in $FILES, setting tripwire cron" echo "0 10 * * * root /usr/sbin/tripwire --check > /dev/shm/tripwire_check 2>&1 " > /etc/cron.d/CIS_8.3.2_tripwire else @@ -54,8 +63,9 @@ if [ -z "$CIS_ROOT_DIR" ]; then fi # Main function, will call the proper functions given the configuration (audit, enabled, disabled) -if [ -r $CIS_ROOT_DIR/lib/main.sh ]; then - . $CIS_ROOT_DIR/lib/main.sh +if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then + # shellcheck source=/opt/debian-cis/lib/main.sh + . "$CIS_ROOT_DIR"/lib/main.sh else echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening" exit 128 diff --git a/lib/utils.sh b/lib/utils.sh index 6f67cef..f488909 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -114,15 +114,42 @@ _does_pattern_exist_in_file() { if $SUDO_CMD [ -r "$FILE" ] ; then debug "$SUDO_CMD grep -q $OPTIONS -- '$PATTERN' $FILE" if $($SUDO_CMD grep -q $OPTIONS -- "$PATTERN" $FILE); then + debug "Pattern found in $FILE" FNRET=0 else + debug "Pattern NOT found in $FILE" FNRET=1 fi else debug "File $FILE is not readable!" FNRET=2 fi +} +# Look for pattern in file that can spread over multiple lines +# The func will remove commented lines (that begin with '#') +# and consider the file as one long line. +# Thus, this is not possible to look for pattern at beginning of line +# with this func ('^' and '$') +does_pattern_exist_in_file_multiline() { + local FILE="$1" + shift + local PATTERN="$*" + + debug "Checking if multiline pattern: $PATTERN is present in $FILE" + if $SUDO_CMD [ -r "$FILE" ] ; then + debug "$SUDO_CMD grep -v '^[[:space:]]*#' $FILE | tr '\n' ' ' | grep -Pq -- "$PATTERN"" + if $($SUDO_CMD grep -v '^[[:space:]]*#' $FILE | tr '\n' ' ' | grep -Pq -- "$PATTERN" ); then + debug "Pattern found in $FILE" + FNRET=0 + else + debug "Pattern NOT found in $FILE" + FNRET=1 + fi + else + debug "File $FILE is not readable!" + FNRET=2 + fi } add_end_of_file() { diff --git a/tests/docker/Dockerfile.debian10_20181226 b/tests/docker/Dockerfile.debian10_20181226 index 368bb58..657417c 100644 --- a/tests/docker/Dockerfile.debian10_20181226 +++ b/tests/docker/Dockerfile.debian10_20181226 @@ -2,7 +2,7 @@ FROM debian:buster-20181226 RUN groupadd -g 500 secaudit && useradd -u 500 -g 500 -s /bin/bash secaudit && mkdir -m 700 /home/secaudit && chown secaudit:secaudit /home/secaudit -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo syslog-ng COPY --chown=500:500 . /opt/debian-cis/ diff --git a/tests/docker/Dockerfile.debian8 b/tests/docker/Dockerfile.debian8 index c91b51c..ee66040 100644 --- a/tests/docker/Dockerfile.debian8 +++ b/tests/docker/Dockerfile.debian8 @@ -2,7 +2,7 @@ FROM debian:jessie RUN groupadd -g 500 secaudit && useradd -u 500 -g 500 -s /bin/bash secaudit && mkdir -m 700 /home/secaudit && chown secaudit:secaudit /home/secaudit -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo syslog-ng COPY --chown=500:500 . /opt/debian-cis/ diff --git a/tests/docker/Dockerfile.debian9 b/tests/docker/Dockerfile.debian9 index 14e7271..7badd43 100644 --- a/tests/docker/Dockerfile.debian9 +++ b/tests/docker/Dockerfile.debian9 @@ -2,7 +2,7 @@ FROM debian:stretch RUN groupadd -g 500 secaudit && useradd -u 500 -g 500 -s /bin/bash secaudit && mkdir -m 700 /home/secaudit && chown secaudit:secaudit /home/secaudit -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bc openssh-server sudo syslog-ng COPY --chown=500:500 . /opt/debian-cis/ diff --git a/tests/hardening/8.2.5_syslog-ng_remote_host.sh b/tests/hardening/8.2.5_syslog-ng_remote_host.sh index b333419..a8d3846 100644 --- a/tests/hardening/8.2.5_syslog-ng_remote_host.sh +++ b/tests/hardening/8.2.5_syslog-ng_remote_host.sh @@ -1,10 +1,49 @@ # run-shellcheck test_audit() { +#set -x + describe Running on blank host - register_test retvalshouldbe 0 - dismiss_count_for_test + register_test retvalshouldbe 1 # shellcheck disable=2154 run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all - # TODO fill comprehensive tests + cp -a /etc/syslog-ng/syslog-ng.conf /tmp/syslog-ng.conf.bak + + echo "destination mySyslog tcp (\"syslog.example.tld\")" >> /etc/syslog-ng/syslog-ng.conf + grep syslog.example.tld /etc/syslog-ng/syslog-ng.conf + + describe Checking one line conf + register_test retvalshouldbe 0 + run oneline /opt/debian-cis/bin/hardening/"${script}".sh --audit-all + + + cp -a /tmp/syslog-ng.conf.bak /etc/syslog-ng/syslog-ng.conf + cat >> /etc/syslog-ng/syslog-ng.conf </etc/syslog-ng/conf.d/1_tcp_destination + echo "destination mySyslog tcp (\"syslog.example.tld\")" >> /etc/syslog-ng/conf.d/1_tcp_destination + cat /etc/syslog-ng/conf.d/1_tcp_destination + + + describe Checking file in subdirectory + register_test retvalshouldbe 0 + run subfile /opt/debian-cis/bin/hardening/"${script}".sh --audit-all + + + + # Cleanup + #mv /tmp/syslog-ng.conf.bak /etc/syslog-ng/syslog-ng.conf + + rm /etc/syslog-ng/conf.d/1_tcp_destination + } diff --git a/tests/hardening/8.3.2_tripwire_cron.sh b/tests/hardening/8.3.2_tripwire_cron.sh index b333419..3b3af16 100644 --- a/tests/hardening/8.3.2_tripwire_cron.sh +++ b/tests/hardening/8.3.2_tripwire_cron.sh @@ -1,10 +1,14 @@ # run-shellcheck test_audit() { describe Running on blank host - register_test retvalshouldbe 0 - dismiss_count_for_test + register_test retvalshouldbe 1 # shellcheck disable=2154 run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all - # TODO fill comprehensive tests + sed -i 's/audit/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg + /opt/debian-cis/bin/hardening/"${script}".sh || true + + describe Checking auto resolved state + register_test retvalshouldbe 0 + run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all }