#!/bin/sh
#################################################################################
#
# Lynis
# ------------------
#
# Copyright 2007-2013, Michael Boelen
# Copyright 2007-2021, CISOfy
#
# Website : https://cisofy.com
# Blog : http://linux-audit.com
# GitHub : https://github.com/CISOfy/lynis
#
# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
#################################################################################
#
# Logging and related files
#
#################################################################################
#
LOG_FILES_LOCS="${ROOTDIR}var/log ${ROOTDIR}var/adm"
LOGROTATE_CONFIG_FOUND=0
LOGROTATE_TOOL=""
METALOG_RUNNING=0
RFC3195D_RUNNING=0
RSYSLOG_RUNNING=0
WAZUH_AGENT_RUNNING=0
SOLARIS_LOGHOST=""
SOLARIS_LOGHOST_FOUND=0
SOLARIS_LOGHOST_LOCALHOST=0
SYSLOG_DAEMON_PRESENT=0
SYSLOG_DAEMON_RUNNING=0
SYSLOG_NG_RUNNING=0
SYSTEMD_JOURNAL_RUNNING=0
#
#################################################################################
#
InsertSection "${SECTION_LOGGING_AND_FILES}"
# Test : LOGG-2130
# Description : Check for a running syslog daemon
Register --test-no LOGG-2130 --weight L --network NO --category security --description "Check for running syslog daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for a logging daemon"
FIND=$(${PSBINARY} ax | ${GREPBINARY} -E "syslogd|syslog-ng|metalog|systemd-journal" | ${GREPBINARY} -v "grep")
if [ -z "${FIND}" ]; then
Display --indent 2 --text "- Checking for a running log daemon" --result "${STATUS_WARNING}" --color RED
LogText "Result: Could not find a syslog daemon like syslog, syslog-ng, rsyslog, metalog, systemd-journal"
ReportSuggestion "${TEST_NO}" "Check if any syslog daemon is running and correctly configured."
AddHP 0 3
else
Display --indent 2 --text "- Checking for a running log daemon" --result "${STATUS_OK}" --color GREEN
LogText "Result: Found a logging daemon"
SYSLOG_DAEMON_PRESENT=1
SYSLOG_DAEMON_RUNNING=1
AddHP 3 3
fi
fi
#
#################################################################################
#
# Test : LOGG-2132
# Description : Check for a running syslog-ng daemon
Register --test-no LOGG-2132 --weight L --network NO --category security --description "Check for running syslog-ng daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for syslog-ng daemon in process list"
if IsRunning "syslog-ng"; then
LogText "Result: Found syslog-ng in process list"
Display --indent 4 --text "- Checking Syslog-NG status" --result "${STATUS_FOUND}" --color GREEN
SYSLOG_DAEMON_PRESENT=1
SYSLOG_NG_RUNNING=1
Report "syslog_daemon_present=1"
Report "syslog_daemon[]=syslog-ng"
else
LogText "Result: Syslog-ng NOT found in process list"
Display --indent 4 --text "- Checking Syslog-NG status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2134
# Description : Check for Syslog-NG configuration file consistency
if [ ! "${SYSLOGNGBINARY}" = "" -a ${SYSLOG_NG_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no LOGG-2134 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking Syslog-NG configuration file consistency"
if [ ${SKIPTEST} -eq 0 ]; then
FIND=$(${SYSLOGNGBINARY} -s; echo $?)
if [ "${FIND}" = "0" ]; then
LogText "Result: Syslog-NG configuration file seems to be consistent"
Display --indent 6 --text "- Checking Syslog-NG consistency" --result "${STATUS_OK}" --color GREEN
else
LogText "Result: Syslog-NG configuration file seems NOT to be consistent"
Display --indent 6 --text "- Checking Syslog-NG consistency" --result "${STATUS_WARNING}" --color RED
ReportSuggestion "${TEST_NO}" "Check the Syslog-NG configuration file and/or run a manual consistency check with: syslog-ng -s"
fi
fi
#
#################################################################################
#
# Test : LOGG-2136
# Description : Check for a running systemd-journal daemon
Register --test-no LOGG-2136 --weight L --network NO --category security --description "Check for running systemd journal daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for systemd journal daemon in process list"
if IsRunning "systemd-journal"; then
Display --indent 4 --text "- Checking systemd journal status" --result "${STATUS_FOUND}" --color GREEN
SYSTEMD_JOURNAL_RUNNING=1
Report "syslog_daemon_present=1"
Report "syslog_daemon[]=systemd-journal"
else
Display --indent 4 --text "- Checking systemd journal status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2210
# Description : Check for a running metalog daemon
Register --test-no LOGG-2210 --weight L --network NO --category security --description "Check for running metalog daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for metalog daemon in process list"
if IsRunning "metalog"; then
LogText "Result: Found metalog in process list"
Display --indent 4 --text "- Checking Metalog status" --result "${STATUS_FOUND}" --color GREEN
SYSLOG_DAEMON_PRESENT=1
METALOG_RUNNING=1
Report "syslog_daemon_present=1"
Report "syslog_daemon[]=metalog"
else
LogText "Result: metalog NOT found in process list"
Display --indent 4 --text "- Checking Metalog status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2230
# Description : Check for a running rsyslog daemon
Register --test-no LOGG-2230 --weight L --network NO --category security --description "Check for running RSyslog daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for RSyslog daemon in process list"
if IsRunning "rsyslogd"; then
LogText "Result: Found rsyslogd in process list"
Display --indent 4 --text "- Checking RSyslog status" --result "${STATUS_FOUND}" --color GREEN
SYSLOG_DAEMON_PRESENT=1
RSYSLOG_RUNNING=1
Report "syslog_daemon_present=1"
Report "syslog_daemon[]=rsyslog"
else
LogText "Result: rsyslogd NOT found in process list"
Display --indent 4 --text "- Checking RSyslog status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2240
# Description : Check for a running RFC 3195 compliant daemon (syslog via TCP)
Register --test-no LOGG-2240 --weight L --network NO --category security --description "Check for running RFC 3195 compliant daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching for RFC 3195 daemon (alias syslog reliable) in process list"
if IsRunning "rfc3195d"; then
LogText "Result: Found rfc3195d in process list"
Display --indent 4 --text "- Checking RFC 3195 daemon status" --result "${STATUS_FOUND}" --color GREEN
SYSLOG_DAEMON_PRESENT=1
RFC3195D_RUNNING=1
else
LogText "Result: rfc3195d NOT found in process list"
Display --indent 4 --text "- Checking RFC 3195 daemon status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2138
# Description : Check for kernel log daemon (klogd) presence on Linux systems
# Notes : * When using metalog, rsyslog or systemd (systemd-journal), this process is not needed.
# * In combination with syslog-ng, klogd is still an addition to it, since it
# captures kernel related events and send them to syslog-ng.
# * This test should be below all other logging daemons
Register --test-no LOGG-2138 --os Linux --weight L --network NO --category security --description "Checking kernel logger daemon on Linux"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Searching kernel logger daemon (klogd)"
if [ ${RSYSLOG_RUNNING} -eq 0 ] && [ ${SYSTEMD_JOURNAL_RUNNING} -eq 0 ] && [ ${METALOG_RUNNING} -eq 0 ]; then
# Search for klogd, but ignore other lines related to klogd (like dd with input/output file)
#FIND=$(${PSBINARY} ax | ${GREPBINARY} "klogd" | ${GREPBINARY} -v "dd" | ${GREPBINARY} -v "grep")
if IsRunning "klogd"; then
LogText "Result: klogd running"
Display --indent 4 --text "- Checking klogd" --result "${STATUS_FOUND}" --color GREEN
else
LogText "Result: No klogd found"
Display --indent 4 --text "- Checking klogd" --result "${STATUS_NOT_FOUND}" --color RED
ReportWarning "${TEST_NO}" "klogd is not running, which could lead to missing kernel messages in log files"
fi
else
LogText "Result: test skipped, because other facility is being used to log kernel messages"
fi
fi
#
#################################################################################
#
# Test : LOGG-2142
# Description : Check for minilogd presence on Linux systems
Register --test-no LOGG-2142 --os Linux --weight L --network NO --category security --description "Checking minilog daemon"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Result: Checking for unkilled minilogd instances"
# Search for minilogd. It shouldn't be running normally, if another syslog daemon is started
if IsRunning "minilogd"; then
Display --indent 4 --text "- Checking minilogd instances" --result "${STATUS_WARNING}" --color RED
LogText "Result: minilogd found in process list"
# minilogd daemon seems to be running
ReportWarning "${TEST_NO}" "minilogd is running, which should normally not be running"
else
Display --indent 4 --text "- Checking minilogd instances" --result "${STATUS_NOT_FOUND}" --color WHITE
LogText "Result: No minilogd is running"
fi
fi
#
#################################################################################
#
# Test : LOGG-2144
# Description : Check for wazuh-agent presence on Linux systems
Register --test-no LOGG-2144 --os Linux --weight L --network NO --category security --description "Checking wazuh-agent"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Result: Searching for wazuh-agent instances in the process list"
if IsRunning "wazuh-agent"; then
LogText "Result: Found wazuh-agent in process list"
Display --indent 4 --text "- Checking wazuh-agent status" --result "${STATUS_FOUND}" --color GREEN
WAZUH_AGENT_RUNNING=1
else
LogText "Result: wazuh-agent NOT found in process list"
Display --indent 4 --text "- Checking wazuh-agent daemon status" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
#################################################################################
#
# Test : LOGG-2146
# Description : Check for logrotate (/etc/logrotate.conf and logrotate.d)
Register --test-no LOGG-2146 --weight L --os Linux --network NO --category security --description "Checking logrotate.conf and logrotate.d"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking for ${ROOTDIR}etc/logrotate.conf"
if [ -f ${ROOTDIR}etc/logrotate.conf ]; then
LOGROTATE_CONFIG_FOUND=1
LOGROTATE_TOOL="logrotate"
LogText "Result: ${ROOTDIR}etc/logrotate.conf found (file)"
else
LogText "Result: ${ROOTDIR}etc/logrotate.conf NOT found"
fi
LogText "Test: Checking for ${ROOTDIR}etc/logrotate.d (directory)"
if [ -d ${ROOTDIR}etc/logrotate.d ]; then
LOGROTATE_CONFIG_FOUND=1
LOGROTATE_TOOL="logrotate"
LogText "Result: ${ROOTDIR}etc/logrotate.d found"
else
LogText "Result: ${ROOTDIR}etc/logrotate.conf found"
fi
if [ ${LOGROTATE_CONFIG_FOUND} -eq 1 ]; then
Display --indent 2 --text "- Checking logrotate presence" --result "${STATUS_OK}" --color GREEN
LogText "Result: logrotate configuration found"
else
Display --indent 2 --text "- Checking logrotate presence" --result "${STATUS_WARNING}" --color RED
LogText "Result: No logrotate configuration found"
ReportSuggestion "${TEST_NO}" "Check if log files are properly rotated"
fi
fi
#
#################################################################################
#
# Test : LOGG-2148
# Description : Checking log files rotated with logrotate
if [ -n "${LOGROTATEBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no LOGG-2148 --weight L --preqs-met ${PREQS_MET} --network NO --category security --description "Checking logrotated files"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking which files are rotated with logrotate and if they exist"
FIND=$(${LOGROTATEBINARY} -d -v ${ROOTDIR}etc/logrotate.conf 2>&1 | ${GREPBINARY} -E "considering log|skipping" | ${GREPBINARY} -v '*' | ${SORTBINARY} -u | ${AWKBINARY} '{ if ($2!="log") { print "File:"$2":does_not_exist" } else { print "File:"$3":exists" } }')
if [ -z "${FIND}" ]; then
LogText "Result: nothing found"
else
LogText "Result: found one or more files which are rotated via logrotate"
for I in ${FIND}; do
LogText "Output: ${I}"
done
fi
fi
#
#################################################################################
#
# Test : LOGG-2150
# Description : Checking log directories rotated with logrotate
if HasData "${LOGROTATEBINARY}"; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no LOGG-2150 --weight L --preqs-met ${PREQS_MET} --network NO --category security --description "Checking directories in logrotate configuration"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking which directories can be found in logrotate configuration"
FIND=$(${LOGROTATEBINARY} -d -v ${ROOTDIR}etc/logrotate.conf 2>&1 | ${GREPBINARY} -E "considering log|skipping" | ${GREPBINARY} -v '*' | ${SORTBINARY} -u | ${AWKBINARY} '{ if ($2=="log") { print $3 } }' | ${SEDBINARY} 's@/[^/]*$@@g' | ${SORTBINARY} -u)
if IsEmpty "${FIND}"; then
LogText "Result: nothing found"
else
LogText "Result: found one or more directories (via logrotate configuration)"
for DIR in ${FIND}; do
if [ -d ${DIR} ]; then
LogText "Directory found: ${DIR}"
Report "log_directory[]=${DIR}"
else
LogText "Result: Directory could not be found: ${DIR}"
fi
done
fi
fi
#
#################################################################################
#
# Test : LOGG-2152
# Description : Check for Solaris 'loghost' entry in /etc/inet/hosts, or
# successful resolving via DNS or any other name service.
Register --test-no LOGG-2152 --weight L --os Solaris --network NO --category security --description "Checking loghost"
if [ ${SKIPTEST} -eq 0 ]; then
# Try local hosts file
LogText "Result: Checking for loghost in /etc/inet/hosts"
FIND=$(${GREPBINARY} loghost /etc/inet/hosts | ${GREPBINARY} -v "^#")
if [ -n "${FIND}" ]; then
SOLARIS_LOGHOST="${FIND}"
SOLARIS_LOGHOST_FOUND=1
LogText "Result: Found loghost entry in /etc/inet/hosts"
else
LogText "Result: No loghost entry found in /etc/inet/hosts"
# Try name resolving if no entry is present in local host file
LogText "Result: Checking for loghost via name resolving"
FIND=$(getent hosts loghost | ${GREPBINARY} loghost)
if [ -n "${FIND}" ]; then
SOLARIS_LOGHOST="${FIND}"
SOLARIS_LOGHOST_FOUND=1
LogText "Result: name resolving was successful"
LogText "Output: ${FIND}"
else
LogText "Result: name resolving didn't find results"
fi
fi
if [ ${SOLARIS_LOGHOST_FOUND} -eq 1 ]; then
LogText "Result: loghost entry found and most likely used to send syslog messages"
Display --indent 2 --text "- Checking loghost entry" --result "${STATUS_OK}" --color GREEN
else
Display --indent 2 --text "- Checking loghost entry" --result "${STATUS_WARNING}" --color RED
LogText "Result: No loghost entry found"
ReportWarning "${TEST_NO}" "No loghost entry found"
ReportSuggestion "${TEST_NO}" "Add a loghost entry to /etc/inet/hosts or other name services"
fi
fi
#
#################################################################################
#
# Test : LOGG-2153
# Description : Check Solaris 'loghost' entry is not localhost, meaning
# remote logging is not configured.
if [ ${SOLARIS_LOGHOST_FOUND} -eq 1 ] && [ -n "${SOLARIS_LOGHOST}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no LOGG-2153 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking loghost is localhost"
if [ ${SKIPTEST} -eq 0 ]; then
FIND=$(echo "${SOLARIS_LOGHOST}" | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} -E "::1|127.0.0.1|127.1")
if [ -n "${FIND}" ]; then
SOLARIS_LOGHOST_LOCALHOST=1
LogText "Result: loghost entry is localhost (default)"
Display --indent 4 --text "- Checking loghost entry is localhost" --result "${STATUS_YES}" --color YELLOW
ReportSuggestion "${TEST_NO}" "Set loghost entry to a remote location to enable remote logging."
else
Display --indent 4 --text "- Checking loghost entry is localhost" --result "${STATUS_NO}" --color GREEN
fi
fi
#
#################################################################################
#
# Test : LOGG-2154
# Description : Check to see if remote logging is enabled
# Notes : prevent lines showing up with commands in it (like |mail)
if [ ${SYSLOG_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no LOGG-2154 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking syslog configuration file"
if [ ${SKIPTEST} -eq 0 ]; then
if [ ${RSYSLOG_RUNNING} -eq 1 ]; then
DATA=""
TARGET="${ROOTDIR}etc/rsyslog.conf"
if [ -f ${TARGET} ]; then
LogText "Test: analyzing file ${TARGET} for remote target"
DATA=$(${GREPBINARY} -E "@@?([a-zA-Z0-9\-])+(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?" ${TARGET} | ${GREPBINARY} -v "#" | ${TRBINARY} -cd "[:print:]\n" | ${SEDBINARY} 's/[[:blank:]]\{1,\}/:space:/g')
if [ -z "${DATA}" ]; then
LogText "Result: no remote target found"
else
LogText "Result: found remote target"
REMOTE_LOGGING_ENABLED=1
for D in ${DATA}; do
if SafeInput "${D}"; then
D=$(echo ${D} | ${SEDBINARY} 's/:space:/ /g')
LogText "Data: ${D}"
fi
done
fi
fi
TARGET="${ROOTDIR}etc/rsyslog.d"
if [ -d ${TARGET} ]; then
FILES=$(${FINDBINARY} -L ${TARGET} -type f -print0 | ${TRBINARY} -cd '[:print:]\0' | ${SEDBINARY} 's/[[:blank:]]/:space:/g' | ${TRBINARY} '\0' ' ')
for F in ${FILES}; do
F=$(echo ${F} | ${SEDBINARY} 's/:space:/ /g')
LogText "Test: analyzing file ${F} for remote target"
DATA=$(${GREPBINARY} -E "@@?([a-zA-Z0-9\-])+(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?(\.)?(([a-zA-Z0-9-])+)?" ${F} | ${GREPBINARY} -v "#" | ${TRBINARY} -cd "[:print:]\n" | ${SEDBINARY} 's/[[:blank:]]\{1,\}/:space:/g')
if [ -n "${DATA}" ]; then
LogText "Result: found remote target"
REMOTE_LOGGING_ENABLED=1
for D in ${DATA}; do
if SafeInput "${D}"; then
D=$(echo ${D} | ${SEDBINARY} 's/:space:/ /g')
LogText "Data: ${D}"
fi
done
else
# Check new style configuration (omrelp/omfwd). This can be all on one line or even split over multiple lines.
DATA=$(${GREPBINARY} -E "target=\"([a-zA-Z0-9\-])" ${F})
if [ -n "${DATA}" ]; then
LogText "Result: most likely remote log host is used, as keyword 'target' is used"
REMOTE_LOGGING_ENABLED=1
else
LogText "Result: no remote target found"
fi
fi
done
fi
fi
# Test generic syslog files (syslog-ng and older syslog daemons)
if [ ${SYSLOG_NG_RUNNING} -eq 1 ]; then
SYSLOGD_CONF="${ROOTDIR}etc/syslog-ng/syslog-ng.conf"
else
SYSLOGD_CONF="${ROOTDIR}etc/syslog.conf"
fi
if [ -f ${SYSLOGD_CONF} ]; then
LogText "Test: check if logs are also logged to a remote logging host"
FIND=$(${GREPBINARY} -E "@[a-zA-Z0-9]|destination\s.+(udp|tcp).+\sport" ${SYSLOGD_CONF} | ${GREPBINARY} -v "^#" | ${GREPBINARY} -v "[a-zA-Z0-9]@")
if [ -n "${FIND}" ]; then
FIND2=$(echo "${FIND}" | ${GREPBINARY} -v "@loghost")
if [ ${SOLARIS_LOGHOST_LOCALHOST} -eq 1 ] && [ -z "${FIND2}" ]; then
LogText "Result: remote logging enabled to loghost, but loghost is localhost"
else
LogText "Result: remote logging enabled"
REMOTE_LOGGING_ENABLED=1
fi
else
# Search for configured destinations with an IP address or hostname, then determine which ones are used as a log destination
DESTINATIONS=$(${GREPBINARY} "^destination" ${SYSLOGD_CONF} | ${GREPBINARY} -E "(udp|tcp)" | ${GREPBINARY} "port" | ${AWKBINARY} '{print $2}')
for DESTINATION in ${DESTINATIONS}; do
FIND2=$(${GREPBINARY} "log" ${SYSLOGD_CONF} | ${GREPBINARY} "source" | ${GREPBINARY} -E "destination\(${DESTINATION}\)")
if [ -n "${FIND2}" ]; then
LogText "Result: found destination ${DESTINATION} configured for remote logging"
REMOTE_LOGGING_ENABLED=1
fi
done
fi
fi
# Test wazuh-agent configuration for syslog configuration
if [ ${WAZUH_AGENT_RUNNING} ]; then
WAZUH_AGENT_CONF="/var/ossec/etc/ossec.conf"
fi
if [ -f ${WAZUH_AGENT_CONF} ]; then
LogText "Test: Checking Wazuh agent configuration for remote syslog forwarding"
FIND=$(${EGREPBINARY} '