Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/CISOfy/lynis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md15
-rw-r--r--README.md7
-rw-r--r--db/languages/ru76
-rw-r--r--db/tests.db4
-rw-r--r--default.prf3
-rw-r--r--include/binaries19
-rw-r--r--include/consts4
-rw-r--r--include/functions67
-rw-r--r--include/profiles7
-rw-r--r--include/tests_authentication59
-rw-r--r--include/tests_crypto6
-rw-r--r--include/tests_filesystems37
-rw-r--r--include/tests_insecure_services22
-rw-r--r--include/tests_kernel105
-rw-r--r--include/tests_logging7
-rw-r--r--include/tests_memory_processes2
-rw-r--r--include/tests_networking87
-rw-r--r--include/tests_php36
-rw-r--r--include/tests_ports_packages2
-rw-r--r--include/tests_printers_spoolers (renamed from include/tests_printers_spools)16
-rw-r--r--include/tests_time22
-rwxr-xr-xlynis13
22 files changed, 437 insertions, 179 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1686e0db..b982ac53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,13 +55,16 @@ Using the relevant options, the scan will change base on the intended goal.
- New test: CRYP-8004 - presence of hardware random number generator
- New test: CRYP-8005 - presence of software random number generator
- New test: DBS-1828 - PostgreSQL configuration files
+- New test: FILE-6394 - test virtual memory swappiness (Linux)
- New test: FINT-4316 - presence of AIDE database and size test
- New test: FINT-4340 - check dm-integrity status (Linux)
- New test: FINT-4341 - verify status of dm-verity (Linux)
- New test: INSE-8314 - test for NIS client
- New test: INSE-8316 - test for NIS server
+- New test: NETW-2400 - test hostname for valid characters and length
- New test: NETW-2706 - check DNSSEC (systemd)
- New test: NETW-3200 - determine enabled network protocols
+- New test: PHP-2382 - detect listen option in PHP (FPM)
- New test: PROC-3802 - check presence of prelink tooling
- New test: TIME-3180 - report if ntpctl cannot communicate with OpenNTPD
- New test: TIME-3181 - check status of OpenNTPD time synchronisation
@@ -76,6 +79,7 @@ Using the relevant options, the scan will change base on the intended goal.
- Added end-of-life data for Arch Linux and Debian
- Detection and end-of-life data added for Amazon Linux
- Detection of linux-lts on Arch Linux
+- Translations: Russian added
### Changed
- Function: CheckItem() now returns only exit code (ITEM_FOUND is dropped)
@@ -89,12 +93,14 @@ Using the relevant options, the scan will change base on the intended goal.
- AUTH-9234 - NetBSD support
- AUTH-9252 - corrected permission check
- AUTH-9266 - skip .pam-old files in /etc/pam.d
-- AUTH-9268 - Perform test also on FreeBSD and NetBSD
+- AUTH-9268 - Perform test also on DragonFly, FreeBSD, and NetBSD
- AUTH-9282 - fix: temporary variable was overwritten
- AUTH-9408 - added support for pam_tally2 to log failed logins
+- AUTH-9489 - test removedd as it is merged with AUTH-9218
- BANN-7126 - additional words for login banner are accepted
- BOOT-5122 - check for defined password in all GRUB configuration files
- CONT-8106 - support newer 'docker info' output
+- CRYP-7902 - optionally check also certificates provided by packages
- CRYP-8002 - gather kernel entropy on Linux systems
- FILE-6310 - support for HP-UX
- FILE-6374 - changed log and allow root location to be changed
@@ -115,7 +121,9 @@ Using the relevant options, the scan will change base on the intended goal.
- KRNL-5788 - don't complain about missing /vmlinuz for Raspi
- KRNL-5820 - extended check to include limits.d directory
- KRNL-5830 - skip test partially when running non-privileged
+- KRNL-5830 - detect required reboots on Raspbian
- LOGG-2154 - added support for rsyslog configurations
+- LOGG-2190 - skip mysqld related entries
- MACF-6234 - SELinux tests extended
- MAIL-8804 - replaced static strings with translation-aware strings
- MALW-3280 - Kaspersky detection added
@@ -128,9 +136,11 @@ Using the relevant options, the scan will change base on the intended goal.
- PKGS-7388 - only perform check for Debian/Ubuntu/Mint
- PKGS-7410 - use multiple package managers when available
- PKGS-7410 - added support for Zypper to test number of kernels
+- PRNT-2308 - check also for Port and SSLListen statements
- PROC-3602 - allow different root directory
- PROC-3612 - show 'Not found' instead of 'OK'
- PROC-3614 - show 'Not found' instead of 'OK'
+- PROC-3802 - limit to Linux only (prelink package check)
- SCHD-7702 - removed hardening points
- SINT-7010 - limit test to only macOS systems
- SSH-7402 - detect other SSH daemons like dropbear
@@ -141,6 +151,7 @@ Using the relevant options, the scan will change base on the intended goal.
- SSH-7408 - corrected OpenSSH server version check
- STRG-1840 - renamed to USB-1000
- STRG-1842 - added default authorized devices and renamed to USB-2000
+- TIME-3104 - use find to discover files in cron directories
- TOOL-5002 - differentiate between a discovered binary and running process
- TOOL-5160 - added support for OSSEC agent daemon
- Perform additional check to ensure pacman package manager is used
@@ -151,9 +162,11 @@ Using the relevant options, the scan will change base on the intended goal.
- Several code cleanups, simplification of commands, and code standardization
- Tests using lsof may ignore individual threads (if supported)
- Corrected end-of-life detection for CentOS 7 and CentOS 8
+- Tests can require detected package manager (--package-manager-required)
- Do not show tool tips when quiet option is used
- Improved screen output in several tests
- Extended output of 'lynis update info'
+- Improved support for NetBSD
- Test if profiles are readable
- systemd service file adjusted
- bash completion script extended
diff --git a/README.md b/README.md
index c4e10b88..ccc5a4d3 100644
--- a/README.md
+++ b/README.md
@@ -55,11 +55,14 @@ Typical users of the software:
If you want to run the software as `root`, we suggest changing the ownership of the files. Use `chown -R 0:0` to recursively alter the owner and group and set it to user ID `0` (`root`).
-### Package
+### Software Package
-Stable releases of Lynis are packaged and made available as RPM or DEB package. The [CISOfy software repository](https://packages.cisofy.com) can be used to install Lynis on systems running:
+For Linux, BSD, macOS, there is typically a package available. The Lynis project also provides packages in RPM or DEB format. The [CISOfy software repository](https://packages.cisofy.com) can be used to install Lynis on systems running:
`CentOS`, `Debian`, `Fedora`, `OEL`, `openSUSE`, `RHEL`, `Ubuntu`, and others.
+Some distributions may also have Lynis in their software repository: [![Repology](https://repology.org/badge/tiny-repos/lynis.svg)](https://repology.org/project/lynis/versions)
+If they don't provide an up-to-date version, consider the CISOfy repository, tarball (website), or GitHub release.
+
### Enterprise Version
This software component is also part of an enterprise solution. Same quality, yet with more functionality.
diff --git a/db/languages/ru b/db/languages/ru
index e16f1062..5153a319 100644
--- a/db/languages/ru
+++ b/db/languages/ru
@@ -1,38 +1,38 @@
-GEN_CHECKING="Checking"
-GEN_CURRENT_VERSION="Current version"
-GEN_DEBUG_MODE="Debug mode"
-GEN_INITIALIZE_PROGRAM="Initializing program"
-GEN_PHASE="phase"
-GEN_PLUGINS_ENABLED="Plugins enabled"
-GEN_VERBOSE_MODE="Verbose mode"
-GEN_UPDATE_AVAILABLE="update available"
-GEN_WHAT_TO_DO="What to do"
-NOTE_EXCEPTIONS_FOUND="Exceptions found"
-NOTE_EXCEPTIONS_FOUND_DETAILED="Some exceptional events or information was found"
-NOTE_PLUGINS_TAKE_TIME="Note: plugins have more extensive tests and may take several minutes to complete"
-SECTION_CUSTOM_TESTS="Custom Tests"
-SECTION_MALWARE="Malware"
-SECTION_MEMORY_AND_PROCESSES="Memory and Processes"
-STATUS_DONE="DONE"
-STATUS_FOUND="FOUND"
-STATUS_YES="YES"
-STATUS_NO="NO"
-STATUS_OFF="OFF"
-STATUS_OK="OK"
-STATUS_ON="ON"
-STATUS_NONE="NONE"
-STATUS_NOT_FOUND="NOT FOUND"
-STATUS_NOT_RUNNING="NOT RUNNING"
-STATUS_RUNNING="RUNNING"
-STATUS_SKIPPED="SKIPPED"
-STATUS_SUGGESTION="SUGGESTION"
-STATUS_UNKNOWN="UNKNOWN"
-STATUS_WARNING="WARNING"
-TEXT_YOU_CAN_HELP_LOGFILE="You can help by providing your log file"
-TEXT_UPDATE_AVAILABLE="update available"
-NOTE_SKIPPED_TESTS_NON_PRIVILEGED="Skipped tests due to non-privileged mode"
-STATUS_DISABLED="DISABLED"
-STATUS_ENABLED="ENABLED"
-STATUS_ERROR="ERROR"
-ERROR_NO_LICENSE="No license key configured"
-ERROR_NO_UPLOAD_SERVER="No upload server configured"
+GEN_CHECKING="Проверка"
+GEN_CURRENT_VERSION="Текущая версия"
+GEN_DEBUG_MODE="Режим отладки"
+GEN_INITIALIZE_PROGRAM="Инициализация программы"
+GEN_PHASE="Стадия"
+GEN_PLUGINS_ENABLED="Плагины включены"
+GEN_VERBOSE_MODE="Подробный режим"
+GEN_UPDATE_AVAILABLE="доступно обновление"
+GEN_WHAT_TO_DO="Что сделать"
+NOTE_EXCEPTIONS_FOUND="Найдены исключения"
+NOTE_EXCEPTIONS_FOUND_DETAILED="Были найдены некоторые исключительные события или информация"
+NOTE_PLUGINS_TAKE_TIME="Примечание: плагины имеют более обширные тесты и могут занять несколько минут до завершения"
+SECTION_CUSTOM_TESTS="Пользовательские тесты"
+SECTION_MALWARE="Вредоносное ПО"
+SECTION_MEMORY_AND_PROCESSES="Память и процессы"
+STATUS_DONE="Завершено"
+STATUS_FOUND="Найдено"
+STATUS_YES="ДА"
+STATUS_NO="НЕТ"
+STATUS_OFF="Выключено"
+STATUS_OK="ОК"
+STATUS_ON="Включено"
+STATUS_NONE="Отсутствует"
+STATUS_NOT_FOUND="НЕ НАЙДЕНО"
+STATUS_NOT_RUNNING="НЕ ЗАПУЩЕНО"
+STATUS_RUNNING="ЗАПУЩЕНО"
+STATUS_SKIPPED="ПРОПУЩЕНО"
+STATUS_SUGGESTION="ПРЕДЛОЖЕНИЕ"
+STATUS_UNKNOWN="НЕИЗВЕСТНО"
+STATUS_WARNING="ПРЕДУПРЕЖДЕНИЕ"
+TEXT_YOU_CAN_HELP_LOGFILE="Вы можете помочь предоставив ваш лог-файл"
+TEXT_UPDATE_AVAILABLE="доступно обновление"
+NOTE_SKIPPED_TESTS_NON_PRIVILEGED="Тесты пропущены из-за использования непривилегированного режима"
+STATUS_DISABLED="ОТКЛЮЧЕНО"
+STATUS_ENABLED="ВКЛЮЧЕНО"
+STATUS_ERROR="ОШИБКА"
+ERROR_NO_LICENSE="Лицензионный ключ не настроен"
+ERROR_NO_UPLOAD_SERVER="Загрузочный сервер не настроен"
diff --git a/db/tests.db b/db/tests.db
index 9b978fa5..32347102 100644
--- a/db/tests.db
+++ b/db/tests.db
@@ -49,7 +49,6 @@ AUTH-9406:test:security:authentication::Query LDAP servers in client configurati
AUTH-9408:test:security:authentication::Logging of failed login attempts via /etc/login.defs:
AUTH-9409:test:security:authentication:OpenBSD:Check for doas file:
AUTH-9410:test:security:authentication:OpenBSD:Check for doas file permissions:
-AUTH-9489:test:security:authentication:DragonFly:Check login shells for passwordless accounts:
BANN-7113:test:security:banners:FreeBSD:Check COPYRIGHT banner file:
BANN-7124:test:security:banners::Check issue banner file:
BANN-7126:test:security:banners::Check issue banner file contents:
@@ -123,6 +122,7 @@ FILE-6368:test:security:filesystems:Linux:Checking ACL support on root file syst
FILE-6372:test:security:filesystems:Linux:Checking / mount options:
FILE-6374:test:security:filesystems:Linux:Linux mount options:
FILE-6376:test:security:filesystems:Linux:Determine if /var/tmp is bound to /tmp:
+FILE-6394:test:performance:filesystems:Linux:Test swappiness of virtual memory:
FILE-6410:test:security:filesystems::Checking Locate database:
FILE-6430:test:security:filesystems::Disable mounting of some filesystems:
FILE-6439:test:security:filesystems:DragonFly:Checking HAMMER PFS mounts:
@@ -288,6 +288,7 @@ NAME-4402:test:security:nameservices::Check duplicate line in /etc/hosts:
NAME-4404:test:security:nameservices::Check /etc/hosts contains an entry for this server name:
NAME-4406:test:security:nameservices::Check server hostname mapping:
NAME-4408:test:security:nameservices::Check localhost to IP mapping:
+NETW-2400:test:basics:networking::Test hostname for valid characters and length:
NETW-2600:test:security:networking:Linux:Checking IPv6 configuration:
NETW-2704:test:security:networking::Basic nameserver configuration tests:
NETW-2705:test:security:networking::Check availability two nameservers:
@@ -311,6 +312,7 @@ PHP-2374:test:security:php::Check PHP enable_dl option:
PHP-2376:test:security:php::Check PHP allow_url_fopen option:
PHP-2378:test:security:php::Check PHP allow_url_include option:
PHP-2379:test:security:php::Check PHP suhosin extension status:
+PHP-2382:test:security:php::Check PHP listen option:
PKGS-7301:test:security:ports_packages::Query NetBSD pkg:
PKGS-7302:test:security:ports_packages::Query FreeBSD/NetBSD pkg_info:
PKGS-7303:test:security:ports_packages::Query brew package manager:
diff --git a/default.prf b/default.prf
index f59e50c2..6ff3eac2 100644
--- a/default.prf
+++ b/default.prf
@@ -93,8 +93,9 @@ skip-plugins=no
#skip-upgrade-test=yes
# Locations where to search for SSL certificates (separate paths with a colon)
-ssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc/pki:/etc/postfix:/etc/ssl:/opt/psa/var/certificates:/usr/local/psa/var/certificates:/usr/local/share/ca-certificates:/var/www:/srv/www
+ssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc/pki:/etc/postfix:/etc/ssl:/opt/psa/var/certificates:/usr/local/psa/var/certificates:/usr/local/share/ca-certificates:/usr/share/ca-certificates:/usr/share/gnupg:/var/www:/srv/www
ssl-certificate-paths-to-ignore=/etc/letsencrypt/archive:
+ssl-certificate-include-packages=no
# Scan type - how deep the audit should be (light, normal or full)
test-scan-mode=full
diff --git a/include/binaries b/include/binaries
index 08b9b4d4..6bbea4af 100644
--- a/include/binaries
+++ b/include/binaries
@@ -74,6 +74,10 @@
fi
done
+ NSUID_BINARIES=0
+ NSGID_BINARIES=0
+ SUID_BINARIES=
+ SGID_BINARIES=
# Now perform binary detection
for SCANDIR in ${BIN_PATHS}; do
SCANDIR=$(echo "${SCANDIR}" | sed 's/!!space!!/ /g')
@@ -115,6 +119,14 @@
COUNT=$((COUNT + 1))
BINARY="${SCANDIR}/${FILENAME}"
DISCOVERED_BINARIES="${DISCOVERED_BINARIES}${BINARY} "
+ if [ -u ${BINARY} ]; then
+ NSUID_BINARIES=$((NSUID_BINARIES + 1))
+ SUID_BINARIES="${SUID_BINARIES}${BINARY} "
+ fi
+ if [ -g ${BINARY} ]; then
+ NSGID_BINARIES=$((NSGID_BINARIES + 1))
+ SGID_BINARIES="${SGID_BINARIES}${BINARY} "
+ fi
# Optimized, much quicker (limited file access needed)
case ${FILENAME} in
aa-status) AASTATUSBINARY=${BINARY}; LogText " Found known binary: aa-status (apparmor component) - ${BINARY}" ;;
@@ -230,6 +242,7 @@
php) PHPBINARY="${BINARY}"; PHPVERSION=$(${BINARY} -v | awk '{ if ($1=="PHP") { print $2 }}' | head -1); LogText "Found known binary: php (programming language interpreter) - ${BINARY} (version ${PHPVERSION})" ;;
pkg) PKG_BINARY="${BINARY}"; LogText " Found known binary: pkg (software package administration) - ${BINARY}" ;;
pkg_admin) PKGADMINBINARY="${BINARY}"; LogText " Found known binary: pkg_admin (software package administration) - ${BINARY}" ;;
+ pkg_info) PKGINFOBINARY="${BINARY}"; LogText " Found known binary: pkg_info (software package information) - ${BINARY}" ;;
postconf) POSTCONFBINARY="${BINARY}"; LogText " Found known binary: postconf (postfix configuration) - ${BINARY}" ;;
postfix) POSTFIXBINARY="${BINARY}"; LogText " Found known binary: postfix (postfix binary) - ${BINARY}" ;;
prelink) PRELINKBINARY="${BINARY}"; LogText " Found known binary: prelink (system optimizer) - ${BINARY}" ;;
@@ -311,8 +324,12 @@
BINARY_SCAN_FINISHED=1
BINARY_PATHS_FOUND=$(echo ${BINARY_PATHS_FOUND} | sed 's/^, //g' | sed 's/, /,/g')
LogText "Discovered directories: ${BINARY_PATHS_FOUND}"
- LogText "Result: found ${COUNT} binaries"
+ LogText "Result: found ${COUNT} binaries including ${NSUID_BINARIES} set-uid and ${NSGID_BINARIES} set-gid"
+ LogText "Result: set-uid binaries: ${SUID_BINARIES}"
+ LogText "Result: set-gid binaries: ${SGID_BINARIES}"
Report "binaries_count=${COUNT}"
+ Report "binaries_suid_count=${SUID_BINARIES}"
+ Report "binaries_sgid_count=${SGID_BINARIES}"
Report "binary_paths=${BINARY_PATHS_FOUND}"
# Test if the basic system tools are defined. These will be used during the audit.
diff --git a/include/consts b/include/consts
index 3969aad5..7968ef1f 100644
--- a/include/consts
+++ b/include/consts
@@ -125,6 +125,7 @@ unset LANG
GRSEC_FOUND=0
GRUBCONFFILE=""
GRUB2INSTALLBINARY=""
+ HAS_PACKAGE_MANAGER=0
HAS_SYSTEMD=0
HEADBINARY=""
HELPER=""
@@ -222,6 +223,7 @@ unset LANG
PGREPBINARY=""
PIDFILE=""
PKG_BINARY=""
+ PKGINFOBINARY=""
PKGADMINBINARY=""
PLUGINDIR=""
PLUGIN_PHASE=0
@@ -279,6 +281,7 @@ unset LANG
SNORTBINARY=""
SSHKEYSCANBINARY=""
SSHKEYSCANFOUND=0
+ SSL_CERTIFICATE_INCLUDE_PACKAGES=0
SSL_CERTIFICATE_PATHS=""
SSL_CERTIFICATE_PATHS_TO_IGNORE=""
STUNNELBINARY=""
@@ -324,6 +327,7 @@ unset LANG
VULNERABLE_PACKAGES_FOUND=0
WCBINARY=""
XARGSBINARY=""
+ XBPSBINARY=""
YUMBINARY=""
ZYPPERBINARY=""
diff --git a/include/functions b/include/functions
index ed1a58eb..58ddabe9 100644
--- a/include/functions
+++ b/include/functions
@@ -1516,6 +1516,7 @@
# Returns : 0 (process is running), 1 (process not running)
# RUNNING (1 = running, 0 = not running) - will be deprecated
# Notes : PSOPTIONS are declared globally, to prevent testing each call
+ # Fallback is used on binaries as IsRunning is used for 'show' command
################################################################################
IsRunning() {
@@ -1546,43 +1547,43 @@
if [ -z "${search}" ]; then ExitFatal "Missing process to search for when using IsRunning function"; fi
RUNNING=0
# AIX does not fully support pgrep options, so using ps instead
- if [ -n "${PGREPBINARY}" ] && [ "${OS}" != "AIX" ]; then
+ if [ "${OS}" != "AIX" ]; then
# When --user is used, perform a search using the -u option
- # Initialize users for strict mode
+ # Initialize users for strict mode
if [ -n "${users:-}" ]; then
for u in ${users}; do
- user_uid=$(getent passwd "${u}" 2> /dev/null | ${AWKBINARY} -F: '{print $3}')
+ user_uid=$(getent passwd "${u}" 2> /dev/null | ${AWKBINARY:-awk} -F: '{print $3}')
# Only perform search if user exists and we had no match yet
if [ -n "${user_uid}" ]; then
if [ -z "${FIND}" ]; then
LogText "Performing pgrep scan using uid ${user_uid}"
- FIND=$(${PGREPBINARY} ${pgrep_options} -u "${user_uid}" "${search}" | ${TRBINARY} '\n' ' ')
+ FIND=$(${PGREPBINARY:-pgrep} ${pgrep_options} -u "${user_uid}" "${search}" | ${TRBINARY:-tr} '\n' ' ')
fi
fi
done
else
LogText "Performing pgrep scan without uid"
- FIND=$(${PGREPBINARY} ${pgrep_options} "${search}" | ${TRBINARY} '\n' ' ')
+ FIND=$(${PGREPBINARY:-pgrep} ${pgrep_options} "${search}" | ${TRBINARY:-tr} '\n' ' ')
fi
else
if [ "${SHELL_IS_BUSYBOX}" -eq 1 ]; then
# This search is not foolproof
LogText "Performing simple ps scan (busybox)"
PSOPTIONS=" -o args="
- FIND=$(${PSBINARY} ${PSOPTIONS} | ${EGREPBINARY} "( |/)${search}" | ${GREPBINARY} -v "grep")
+ FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${EGREPBINARY:-egrep} "( |/)${search}" | ${GREPBINARY:-grep} -v "grep")
else
if [ -n "${users}" ]; then
for u in ${users}; do
- user_uid=$(getent passwd "${u}" 2> /dev/null | ${AWKBINARY} -F: '{print $3}')
+ user_uid=$(getent passwd "${u}" 2> /dev/null | ${AWKBINARY:-awk} -F: '{print $3}')
# Only perform search if user exists and we had no match yet
if [ -n "${user_uid}" ]; then
if [ -z "${FIND}" ]; then
if [ ${PARTIAL_SEARCH} -eq 1 ]; then
LogText "Performing ps scan using partial match and for uid ${user_uid}"
- FIND=$(${PSBINARY} -u "${user_uid}" -o comm= "${search}" | ${AWKBINARY} -v pattern="${search}" '$0 ~ pattern {print}')
+ FIND=$(${PSBINARY:-ps} -u "${user_uid}" -o comm= "${search}" | ${AWKBINARY:-awk} -v pattern="${search}" '$0 ~ pattern {print}')
else
LogText "Performing ps scan using exact match and for uid ${user_uid}"
- FIND=$(${PSBINARY} -u "${user_uid}" -o comm= "${search}" | ${AWKBINARY} -v pattern="^${search}$" '$0 ~ pattern {print}')
+ FIND=$(${PSBINARY:-ps} -u "${user_uid}" -o comm= "${search}" | ${AWKBINARY:-awk} -v pattern="^${search}$" '$0 ~ pattern {print}')
fi
fi
fi
@@ -1595,10 +1596,10 @@
esac
if [ ${PARTIAL_SEARCH} -eq 1 ]; then
LogText "Performing ps scan using partial match and without uid"
- FIND=$(${PSBINARY} ${PSOPTIONS} | ${AWKBINARY} -v pattern="${search}" '$0 ~ pattern {print}')
+ FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${AWKBINARY:-awk} -v pattern="${search}" '$0 ~ pattern {print}')
else
LogText "Performing ps scan using exact match and without uid"
- FIND=$(${PSBINARY} ${PSOPTIONS} | ${AWKBINARY} -v pattern="^${search}$" '$0 ~ pattern {print}')
+ FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${AWKBINARY:-awk} -v pattern="^${search}$" '$0 ~ pattern {print}')
fi
fi
fi
@@ -1774,14 +1775,11 @@
# dmidecode
# Values: VMware Virtual Platform / VirtualBox
if [ -z "${SHORT}" ]; then
- if [ -x /usr/bin/dmidecode ]; then DMIDECODE_BINARY="/usr/bin/dmidecode"
- elif [ -x /usr/sbin/dmidecode ]; then DMIDECODE_BINARY="/usr/sbin/dmidecode"
- else
- DMIDECODE_BINARY=""
- fi
- if [ ! "${DMIDECODE_BINARY}" = "" -a ${PRIVILEGED} -eq 1 ]; then
+ # Try to find dmidecode in case we did not check binaries (e.g. lynis show environment)
+ if [ ${CHECK_BINARIES} -eq 0 ]; then DMIDECODEBINARY=$(command -v dmidecode 2> /dev/null); fi
+ if [ -n "${DMIDECODEBINARY}" -a -x "${DMIDECODEBINARY}" -a ${PRIVILEGED} -eq 1 ]; then
LogText "Test: trying to guess virtualization with dmidecode"
- FIND=$(/usr/sbin/dmidecode -s system-product-name | awk '{ print $1 }')
+ FIND=$(${DMIDECODEBINARY} -s system-product-name | awk '{ print $1 }')
if [ -n "${FIND}" ]; then
LogText "Result: found ${FIND}"
SHORT="${FIND}"
@@ -1794,6 +1792,7 @@
else
LogText "Result: skipped dmidecode test, as we already found machine type"
fi
+
# Other options
# SaltStack: salt-call grains.get virtual
# < needs snippet >
@@ -1864,7 +1863,7 @@
fi
# Check if we caught some string along all tests
- if [ ! "${SHORT}" = "" ]; then
+ if [ -n "${SHORT}" ]; then
# Lowercase and see if we found a match
SHORT=$(echo ${SHORT} | awk '{ print $1 }' | tr '[:upper:]' '[:lower:]')
@@ -2020,6 +2019,7 @@
PackageIsInstalled() {
exit_code=255
+ # First parameter is package name (or __dummy__ for initial test to see if package manager is available and works as expected)
if [ $# -eq 1 ]; then
package="$1"
else
@@ -2041,6 +2041,9 @@
elif [ -n "${PKG_BINARY}" ]; then
output=$(${PKG_BINARY} -N info ${package} >/dev/null 2>&1)
exit_code=$? # 0=package installed, 70=invalid package
+ elif [ -n "${PKGINFOBINARY}" ]; then
+ output=$(${PKGINFOBINARY} -q -e ${package} >/dev/null 2>&1)
+ exit_code=$? # 0=package installed, 1=package not installed
elif [ -n "${RPMBINARY}" ]; then
output=$(${RPMBINARY} --quiet -q ${package} > /dev/null 2>&1)
exit_code=$?
@@ -2054,7 +2057,21 @@
output=$(${XBPSBINARY} ${package} 2> /dev/null | ${GREPBINARY} "^ii")
exit_code=$?
else
- ReportException "PackageIsInstalled:01"
+ if [ "${package}" != "__dummy__" ]; then
+ ReportException "PackageIsInstalled:01 (test=${TEST_NO:-unknown})"
+ fi
+ fi
+
+ # Give thumbs up if dummy package is used during initial test for package manager availability
+ if [ "${package}" = "__dummy__" ]; then
+ # There should be no positive match on this dummy package
+ if [ ${exit_code} -eq 0 ]; then
+ exit_code=1
+ elif [ ${exit_code} -eq 255 ]; then
+ exit_code=1
+ else
+ exit_code=0
+ fi
fi
return ${exit_code}
@@ -2497,8 +2514,8 @@
Register() {
# Do not insert a log break, if previous test was not logged
if [ ${SKIPLOGTEST} -eq 0 ]; then LogTextBreak; fi
- ROOT_ONLY=0; SKIPTEST=0; SKIPLOGTEST=0; SKIPREASON=""; TEST_NEED_OS=""; PREQS_MET=""
- TEST_CATEGORY=""; TEST_NEED_NETWORK=""; TEST_NEED_PLATFORM=""
+ ROOT_ONLY=0; SKIPTEST=0; SKIPLOGTEST=0; SKIPREASON=""; PREQS_MET=""
+ TEST_CATEGORY=""; TEST_NEED_NETWORK=""; TEST_NEED_OS=""; TEST_NEED_PKG_MGR=0; TEST_NEED_PLATFORM=""
TOTAL_TESTS=$((TOTAL_TESTS + 1))
while [ $# -ge 1 ]; do
case $1 in
@@ -2522,6 +2539,9 @@
shift
TEST_NEED_OS=$1
;;
+ --package-manager-required)
+ TEST_NEED_PKG_MGR=1
+ ;;
--preqs-met)
shift
PREQS_MET=$1
@@ -2634,6 +2654,9 @@
# Check for correct hardware platform
if [ ${SKIPTEST} -eq 0 -a -n "${TEST_NEED_PLATFORM}" -a ! "${HARDWARE}" = "${TEST_NEED_PLATFORM}" ]; then SKIPTEST=1; SKIPREASON="Incorrect hardware platform"; fi
+ # Check for required (and discovered) package manager
+ if [ ${SKIPTEST} -eq 0 -a ${TEST_NEED_PKG_MGR} -eq 1 -a ${HAS_PACKAGE_MANAGER} -eq 0 ]; then SKIPTEST=1; SKIPREASON="Requires a known package manager to test presence of a particular package"; fi
+
# Not all prerequisites met, like missing tool
if [ ${SKIPTEST} -eq 0 -a "${PREQS_MET}" = "NO" ]; then SKIPTEST=1; if [ -z "${SKIPREASON}" ]; then SKIPREASON="Prerequisites not met (ie missing tool, other type of Linux distribution)"; fi; fi
diff --git a/include/profiles b/include/profiles
index 328d4d49..da2124f7 100644
--- a/include/profiles
+++ b/include/profiles
@@ -376,6 +376,13 @@
AddSetting "ssl-certificate-paths-to-ignore" "${SSL_CERTIFICATE_PATHS_TO_IGNORE}" "Paths that should be ignored for SSL certificates"
;;
+ # Check also certificates provided by packages?
+ ssl-certificate-include-packages)
+ FIND=$(echo "${VALUE}" | grep -E "^(1|true|yes)") && SSL_CERTIFICATE_INCLUDE_PACKAGES=1
+ Debug "Check also certificates provided by packages set to ${SSL_CERTIFICATE_INCLUDE_PACKAGES}"
+ ;;
+
+
# Set strict mode for development and quality purposes
strict)
FIND=$(echo "${VALUE}" | grep -E "^(1|true|yes)") && SET_STRICT=1
diff --git a/include/tests_authentication b/include/tests_authentication
index ce821fba..bf8cabe8 100644
--- a/include/tests_authentication
+++ b/include/tests_authentication
@@ -157,51 +157,7 @@
# Test : AUTH-9218
# Description : Check login shells for passwordless accounts
# Notes : Results should be checked
- Register --test-no AUTH-9218 --os FreeBSD --weight L --network NO --category security --description "Check login shells for passwordless accounts"
- if [ ${SKIPTEST} -eq 0 ]; then
- FOUND=0
- LogText "Test: Checking login shells"
- if [ -f ${ROOTDIR}etc/master.passwd ]; then
- # Check for all shells, except: (/usr)/sbin/nologin /nonexistent
- FIND=$(${GREPBINARY} "[a-z]:\*:" /etc/master.passwd | ${EGREPBINARY} -v '^#|/sbin/nologin|/usr/sbin/nologin|/nonexistent' | ${SEDBINARY} 's/ /!space!/g')
- if [ "${FIND}" = "" ]; then
- Display --indent 2 --text "- Login shells" --result "${STATUS_OK}" --color GREEN
- else
- Display --indent 2 --text "- Login shells" --result "${STATUS_WARNING}" --color RED
- for LINE in ${FIND}; do
- LINE=$(echo ${LINE} | ${SEDBINARY} 's/!space!/ /g')
- SHELL=$(echo ${LINE} | ${AWKBINARY} -F: '{ print $10 }')
- LogText "Output: ${LINE}"
- if [ -z "${SHELL}" ]; then
- LogText "Result: found no shell on line"
- else
- LogText "Result: found possible harmful shell ${SHELL}"
- if [ -f ${SHELL} ]; then
- LogText "Result: shell ${SHELL} does exist"
- FOUND=1
- else
- LogText "Result: shell ${SHELL} does not exist"
- ReportSuggestion "${TEST_NO}" "Determine if account is needed, as shell ${SHELL} does not exist"
- fi
- fi
- done
- if [ ${FOUND} -eq 1 ]; then
- ReportWarning "${TEST_NO}" "Possible harmful shell found (for passwordless account!)"
- fi
- fi
- else
- Display --indent 2 --text "- Login shells" --result "${STATUS_SKIPPED}" --color WHITE
- LogText "Result: No /etc/master.passwd file found"
- fi
- unset LINE SHELL
- fi
-#
-#################################################################################
-#
- # Test : AUTH-9489
- # Description : Check login shells for passwordless accounts
- # Notes : Results should be checked
- Register --test-no AUTH-9489 --os DragonFly --weight L --network NO --category security --description "Check login shells for passwordless accounts"
+ Register --test-no AUTH-9218 --os "DragonFly FreeBSD NetBSD OpenBSD" --root-only YES --weight L --network NO --category security --description "Check login shells for passwordless accounts"
if [ ${SKIPTEST} -eq 0 ]; then
FOUND=0
LogText "Test: Checking login shells"
@@ -374,7 +330,7 @@
echo "Unknown password hashing method ${METHOD}. Please report to lynis-dev@cisofy.com"
;;
esac
- done | ${SORTBINARY} --unique | ${TRBINARY} '\n' ' ')
+ done | ${SORTBINARY} -u | ${TRBINARY} '\n' ' ')
if [ -z "${FIND}" ]; then
Display --indent 2 --text "- Password hashing methods" --result "${STATUS_OK}" --color GREEN
LogText "Result: no poor password hashing methods found"
@@ -396,7 +352,7 @@
if [ -f ${ROOTDIR}etc/login.defs ]; then
PREQS_MET="YES"
fi
- Register --test-no AUTH-9230 --root-only NO --weight L --network NO --category security --description "Check group password hashing rounds"
+ Register --test-no AUTH-9230 --preqs-met ${PREQS_MET} --root-only NO --weight L --network NO --category security --description "Check group password hashing rounds"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking SHA_CRYPT_MIN_ROUNDS option in ${ROOTDIR}etc/login.defs"
FIND=$(${GREPBINARY} "^SHA_CRYPT_MIN_ROUNDS" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="SHA_CRYPT_MIN_ROUNDS") { print $2 } }')
@@ -817,13 +773,8 @@
# Test : AUTH-9268
# Description : Searching available PAM files
# Notes : PAM is used on AIX, FreeBSD, Linux, HPUX, NetBSD, Solaris
- case "${OS}" in
- "AIX"|"FreeBSD"|"Linux"|"HPUX"|"NetBSD"|"Solaris")
- PREQS_MET="YES" ;;
- *)
- PREQS_MET="NO" ;;
- esac
- Register --test-no AUTH-9268 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking presence pam.d files"
+ OS_USES_PAM="AIX DragonFly FreeBSD Linux HPUX NetBSD Solaris"
+ Register --test-no AUTH-9268 --os "${OS_USES_PAM}" --weight L --network NO --category security --description "Checking presence pam.d files"
if [ ${SKIPTEST} -eq 0 ]; then
FOUND=0
LogText "Test: Searching pam modules"
diff --git a/include/tests_crypto b/include/tests_crypto
index 47c03451..02fa0a80 100644
--- a/include/tests_crypto
+++ b/include/tests_crypto
@@ -63,7 +63,7 @@
SKIP=0
# Now check if this path is on the to-be-ignored list
for D in ${SSL_CERTIFICATE_PATHS_TO_IGNORE}; do
- if Equals "${D}" "${SUBDIR}"; then
+ if ContainsString "${D}" "${SUBDIR}"; then
SKIP=1
LogText "Result: skipping directory (${SUBDIR}) as it is on ignore list"
fi
@@ -74,8 +74,8 @@
COUNT_DIR=$((COUNT_DIR + 1))
FileIsReadable "${FILE}"
if [ ${CANREAD} -eq 1 ]; then
- # Only check the files that are not installed by a package
- if ! FileInstalledByPackage "${FILE}"; then
+ # Only check the files that are not installed by a package, unless enabled by profile
+ if [ ${SSL_CERTIFICATE_INCLUDE_PACKAGES} -eq 1 ] || ! FileInstalledByPackage "${FILE}"; then
OUTPUT=$(${GREPBINARY} -q 'BEGIN CERT' "${FILE}")
if [ $? -eq 0 ]; then
LogText "Result: file is a certificate file"
diff --git a/include/tests_filesystems b/include/tests_filesystems
index 38b4c0d0..aabdc2be 100644
--- a/include/tests_filesystems
+++ b/include/tests_filesystems
@@ -580,7 +580,7 @@
FS_FSTAB=""
fi
fi
- if [ -z "${FS_FSTAB}" ]; then # not found in fstab, check if mounted otherwise
+ if [ -z "${FS_FSTAB}" ]; then # not found in fstab, check if mounted otherwise
FS_FSTAB=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($3==fs) { print $6 } }')
FOUND_FLAGS=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($1~"[^#]" && $3==fs) { print $6 } }' | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\n' ' ')
else
@@ -668,7 +668,6 @@
# Description : Check for nodirtime option
# Want to contribute to Lynis? Create this test
-
#
#################################################################################
#
@@ -676,7 +675,6 @@
# Description : Check for relatime
# Want to contribute to Lynis? Create this test
-
#
#################################################################################
#
@@ -689,11 +687,36 @@
#
#################################################################################
#
- # Test : FILE-6394 TODO
+ # Test : FILE-6394
# Description : Check vm.swappiness (Linux)
-
- # Want to contribute to Lynis? Create this test
-
+ Register --test-no FILE-6394 --os Linux --weight L --network NO --category security --description "Determine level of swappiness."
+ if [ ${SKIPTEST} -eq 0 ]; then
+ SWAPLEVEL=$(${CAT_BINARY} /proc/sys/vm/swappiness)
+ LogText "Test: checking level of vm.swappiness: ${SWAPLEVEL}"
+ PHYSDISK=$(${LSBLKBINARY} | ${GREPBINARY} -E 'disk|SWAP' | ${GREPBINARY} -B1 SWAP | ${HEADBINARY} -n1 | ${AWKBINARY} '{print $1}')
+ if [ ${SWAPLEVEL} -gt 60 ]; then
+ LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is more frequent than default."
+ # Check if swap is on a HDD or SDD for frequent swapping
+ if [ -d "/sys/block/${PHYSDISK}" ]; then
+ HDDORSDD=$(${CAT_BINARY} "/sys/block/${PHYSDISK}/queue/rotational")
+ if [ ${HDDORSDD} -eq 1 ]; then
+ ReportSuggestion "${TEST_NO}" "vm.swappiness set to: ${SWAPLEVEL} > 60 (default) - consider installing an SSD for swap partition for better performance."
+ fi
+ fi
+ elif [ ${SWAPLEVEL} -eq 0 ]; then
+ LogText "Result: vm.swappiness=${SWAPLEVEL} meaning swapping is disabled."
+ ReportSuggestion "${TEST_NO}" "vm.swappiness set to: ${SWAPLEVEL}. Consider setting value to minimum of 1 for minimizing swappiness, but not quite disabling it. Will prevent OOM killer from killing processes when running out of physical memory."
+ elif [ ${SWAPLEVEL} -eq 1 ]; then
+ LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping can still occur but at very minimum."
+ elif [ ${SWAPLEVEL} -eq 10 ]; then
+ LogText "Result: vm.swappiness=${SWAPLEVEL} which is the preferred setting for database servers."
+ elif [ ${SWAPLEVEL} -lt 60 ]; then
+ LogText "Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is less frequent than default. This is only recommended for servers."
+ else
+ LogText "Result: vm.swappiness=${SWAPLEVEL} which is the standard level of swappiness and works well for desktop systems."
+ fi
+ if IsVerbose; then Display --indent 2 --text "- Swappiness: ${SWAPLEVEL}" --result "INFO" --color WHITE; fi
+ fi
#
#################################################################################
#
diff --git a/include/tests_insecure_services b/include/tests_insecure_services
index 3bc8dfdf..5c8af1fc 100644
--- a/include/tests_insecure_services
+++ b/include/tests_insecure_services
@@ -37,7 +37,7 @@
#
# Test : INSE-8000
# Description : Check for installed inetd package
- Register --test-no INSE-8000 --weight L --network NO --category security --description "Installed inetd package"
+ Register --test-no INSE-8000 --package-manager-required --weight L --network NO --category security --description "Installed inetd package"
if [ ${SKIPTEST} -eq 0 ]; then
# Check for installed inetd daemon
LogText "Test: Checking if inetd is installed"
@@ -134,7 +134,7 @@
#
# Test : INSE-8100
# Description : Check for installed xinetd daemon
- Register --test-no INSE-8100 --weight L --network NO --category security --description "Check for installed xinetd daemon"
+ Register --test-no INSE-8100 --package-manager-required --weight L --network NO --category security --description "Check for installed xinetd daemon"
if [ ${SKIPTEST} -eq 0 ]; then
# Check for installed xinetd daemon
LogText "Test: Checking for installed xinetd daemon"
@@ -250,7 +250,7 @@
# Test : INSE-8200
# Description : Check if tcp_wrappers is installed when inetd/xinetd is active
if [ ${INETD_ACTIVE} -eq 1 -o ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
- Register --test-no INSE-8200 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check if tcp_wrappers is installed when inetd/xinetd is active"
+ Register --test-no INSE-8200 --package-manager-required --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check if tcp_wrappers is installed when inetd/xinetd is active"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking if tcp_wrappers is installed"
FOUND=0
@@ -272,7 +272,7 @@
#
# Test : INSE-8300
# Description : Check if rsh client is installed
- Register --test-no INSE-8300 --weight L --network NO --category security --description "Check if rsh client is installed"
+ Register --test-no INSE-8300 --package-manager-required --weight L --network NO --category security --description "Check if rsh client is installed"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking if rsh client is installed"
FOUND=0
@@ -328,7 +328,7 @@
#
# Test : INSE-8304
# Description : Check if rsh server is installed
- Register --test-no INSE-8304 --weight L --network NO --category security --description "Check if rsh server is installed"
+ Register --test-no INSE-8304 --package-manager-required --weight L --network NO --category security --description "Check if rsh server is installed"
if [ ${SKIPTEST} -eq 0 ]; then
# Check if rsh server is installed
LogText "Test: Checking if rsh server is installed"
@@ -352,7 +352,7 @@
#
# Test : INSE-8310
# Description : Check if telnet client is installed
- Register --test-no INSE-8310 --weight L --network NO --category security --description "Check if telnet client is installed"
+ Register --test-no INSE-8310 --package-manager-required --weight L --network NO --category security --description "Check if telnet client is installed"
if [ ${SKIPTEST} -eq 0 ]; then
# Check if telnet client is installed
LogText "Test: Checking if telnet client is installed"
@@ -373,7 +373,7 @@
#
# Test : INSE-8312
# Description : Check if telnet server is installed
- Register --test-no INSE-8322 --weight L --network NO --category security --description "Check if telnet server is installed"
+ Register --test-no INSE-8322 --package-manager-required --weight L --network NO --category security --description "Check if telnet server is installed"
if [ ${SKIPTEST} -eq 0 ]; then
# Check if TFTP server is installed
LogText "Test: Checking if telnet server is installed"
@@ -398,7 +398,7 @@
#
# Test : INSE-8314
# Description : Check if NIS client is installed
- Register --test-no INSE-8314 --weight L --network NO --category security --description "Check if NIS client is installed"
+ Register --test-no INSE-8314 --package-manager-required --weight L --network NO --category security --description "Check if NIS client is installed"
if [ ${SKIPTEST} -eq 0 ]; then
FOUND=""
LogText "Test: Checking if NIS client is installed"
@@ -422,7 +422,7 @@
#
# Test : INSE-8316
# Description : Check if NIS server is installed
- Register --test-no INSE-8316 --weight L --network NO --category security --description "Check if NIS server is installed"
+ Register --test-no INSE-8316 --package-manager-required --weight L --network NO --category security --description "Check if NIS server is installed"
if [ ${SKIPTEST} -eq 0 ]; then
FOUND=""
LogText "Test: Checking if NIS server is installed"
@@ -446,7 +446,7 @@
#
# Test : INSE-8318
# Description : Check if TFTP client is installed
- Register --test-no INSE-8318 --weight L --network NO --category security --description "Check if TFTP client is installed"
+ Register --test-no INSE-8318 --package-manager-required --weight L --network NO --category security --description "Check if TFTP client is installed"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking if TFTP client is installed"
FOUND=""
@@ -470,7 +470,7 @@
#
# Test : INSE-8320
# Description : Check if TFTP server is installed
- Register --test-no INSE-8320 --weight L --network NO --category security --description "Check if TFTP server is installed"
+ Register --test-no INSE-8320 --package-manager-required --weight L --network NO --category security --description "Check if TFTP server is installed"
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: Checking if TFTP server is installed"
FOUND=""
diff --git a/include/tests_kernel b/include/tests_kernel
index 4948e0dd..72e5082b 100644
--- a/include/tests_kernel
+++ b/include/tests_kernel
@@ -31,6 +31,7 @@
LINUXCONFIGFILE=""
LINUXCONFIGFILE_ZIPPED=0
LIMITS_DIRECTORY="${ROOTDIR}etc/security/limits.d"
+ APT_ARCHIVE_DIRECTORY="${ROOTDIR}var/cache/apt/archives"
#
#################################################################################
#
@@ -102,8 +103,7 @@
# Description : Check CPU options and support (PAE, No eXecute, eXecute Disable)
# More info : pae and nx bit are both visible on AMD and Intel CPU's if supported
- if [ "${HARDWARE}" = "x86_64" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
- Register --test-no KRNL-5677 --preqs-met "${PREQS_MET}" --os Linux --weight L --network NO --category security --description "Check CPU options and support"
+ Register --test-no KRNL-5677 --platform x86_64 --os Linux --weight L --network NO --category security --description "Check CPU options and support"
if [ ${SKIPTEST} -eq 0 ]; then
Display --indent 2 --text "- Checking CPU support (NX/PAE)"
LogText "Test: Checking /proc/cpuinfo"
@@ -773,6 +773,107 @@
LogText "Result: /boot does not exist or not privileged to read files"
fi
+ # Attempt to check for Raspbian if reboot is needed
+ # This check searches for apt package "raspberrypi-kernel-[package-date]", trys to extract the date of packaging from the filename
+ # and compares that date with the currently running kernel's build date (uname -v).
+ # Of course there can be a time difference between kernel build and kernel packaging, therefor a time difference of
+ # 3 days is accepted and it is assumed with only 3 days apart, this must be the same kernel version.
+ if [ ${REBOOT_NEEDED} -eq 2 ] && [ -d "${APT_ARCHIVE_DIRECTORY}" ]; then
+ LogText "Result: found folder ${APT_ARCHIVE_DIRECTORY}; assuming this is a debian based distribution"
+ LogText "Check: try to find raspberrypi-kernel file in ${APT_ARCHIVE_DIRECTORY} and extract package date from file name"
+
+ FOUND_KERNEL_DATE=$(${FINDBINARY} ${APT_ARCHIVE_DIRECTORY} -name "raspberrypi-kernel*" -printf "%T@ %Tc %p\n" 2> /dev/null \
+ | ${SORTBINARY} -nr | ${HEADBINARY} -1 | ${GREPBINARY} -o "raspberrypi-kernel.*deb" | ${EGREPBINARY} -o "\.[0-9]+" | ${SEDBINARY} 's/\.//g')
+
+ if [ -n "${FOUND_KERNEL_DATE}" ]; then
+ FOUND_KERNEL_IN_SECONDS=$(date -d "${FOUND_KERNEL_DATE}" "+%s" 2> /dev/null)
+ else
+ LogText "Result: Skipping this test, as there was no package date to extract"
+ fi
+
+ if [ -n "${FOUND_KERNEL_IN_SECONDS}" ] && [ ${FOUND_KERNEL_IN_SECONDS} -gt 1 ]; then
+ LogText "Result: Got package date: ${FOUND_KERNEL_DATE} (= ${FOUND_KERNEL_IN_SECONDS} seconds)"
+ UNAME_OUTPUT="$(${UNAMEBINARY} -v 2> /dev/null)"
+ else
+ LogText "Result: Skipping this test, as extracting the seconds of package date failed"
+ fi
+
+ if [ -n "${UNAME_OUTPUT}" ]; then
+ LogText "Result: Got an output from 'uname -v'"
+ LogText "Check: Trying to extract kernel build date from 'uname -v' output"
+ next=""
+ for part in ${UNAME_OUTPUT}; do
+ if [ -z "$next" ]; then
+ if [ "${part}" = "Mon" ] || [ "${part}" = "Tue" ] || [ "${part}" = "Wed" ] || [ "${part}" = "Thu" ] || [ "${part}" = "Fri" ] || [ "${part}" = "Sat" ] || [ "${part}" = "Sun" ]; then
+ next="month"
+ fi
+ elif [ "$next" = "month" ]; then
+ if [ $(${ECHOCMD} "${part}" | ${EGREPBINARY} -c "[A-Z][a-z]") -ge 1 ]; then
+ UNAME_DATE_MONTH="${part}"
+ next="day"
+ fi
+ elif [ "${next}" = "day" ]; then
+ if [ $(${ECHOCMD} ${part} | ${EGREPBINARY} -c "[0-9][0-9]") -ge 1 ]; then
+ UNAME_DATE_DAY="${part}"
+ next="time"
+ fi
+ elif [ "${next}" = "time" ]; then
+ if [ $(${ECHOCMD} ${part} | ${EGREPBINARY} -c ":[0-9][0-9]:") -ge 1 ]; then
+ next="year"
+ fi
+ elif [ "${next}" = "year" ]; then
+ if [ $(${ECHOCMD} ${part} | ${EGREPBINARY} -c "[0-9][0-9]") -ge 1 ]; then
+ UNAME_DATE_YEAR="${part}"
+ break
+ fi
+ fi
+ done
+ if [ -n "${UNAME_DATE_MONTH}" ] && [ -n "${UNAME_DATE_DAY}" ] && [ -n "${UNAME_DATE_YEAR}" ]; then
+ LogText "Result: Extracted kernel build date is: ${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}"
+ UNAME_DATE_IN_SECONDS=$(date -d "${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}" "+%s" 2> /dev/null)
+ LogText "Check: Comparing kernel build date in seconds (${UNAME_DATE_IN_SECONDS}s) with package date in seconds (${FOUND_KERNEL_IN_SECONDS}s)"
+ if [ -n "${UNAME_DATE_IN_SECONDS}" ] && [ ${FOUND_KERNEL_IN_SECONDS} -ge ${UNAME_DATE_IN_SECONDS} ]; then
+ LogText "Result: package creation date is older than running kernel. Hence, this check should be valid."
+ LogText "Check if package create date and kernel build date are not more than 3 days apart."
+
+ SECONDS_APART=$(( ${FOUND_KERNEL_IN_SECONDS} - ${UNAME_DATE_IN_SECONDS} ))
+ if [ ${SECONDS_APART} -ge 60 ]; then
+ MINUTES_APART=$(( ${SECONDS_APART} / 60 ))
+ if [ ${MINUTES_APART} -ge 60 ]; then
+ DAYS_APART=$(( ${MINUTES_APART} / 60 ))
+ if [ ${DAYS_APART} -ge 24 ]; then DAYS_APART=$(( ${DAYS_APART} / 24 )); else DAYS_APART=0; fi
+ else
+ DAYS_APART=0
+ fi
+ else
+ DAYS_APART=0
+ fi
+ # assuming kernels are packaged definitely within 3 days. ACCEPTED_TIME_DIFF needs a value in seconds
+ ACCEPTED_TIME_DIFF=$((3 * 24 * 60 * 60))
+ if [ ${FOUND_KERNEL_IN_SECONDS} -le $((${UNAME_DATE_IN_SECONDS} + ${ACCEPTED_TIME_DIFF})) ]; then
+ LogText "Result: package create date and kernel build date are only ${DAYS_APART} day(s) apart."
+ LogText "Result: Assuming no reboot needed."
+ REBOOT_NEEDED=0
+ else
+ LogText "Result: package create date and kernel build date are ${DAYS_APART} day(s) apart."
+ LogText "Result: Assuming reboot is needed."
+ REBOOT_NEEDED=1
+ fi
+ else
+ LogText "Result: Package's create date is older than running kernel, which is unexpected. Might not be a valid test. Skipping..."
+ fi
+ else
+ LogText "Result: Could not extract Day, Month and Year from 'uname -v' output"
+ fi
+ else
+ LogText "Result: Did not get output from 'uname -v'. Skipping test."
+ fi
+
+
+ else
+ LogText "Result: /var/cache/apt/archives/ does not exist"
+ fi
+
# Display discovered status
if [ ${REBOOT_NEEDED} -eq 0 ]; then
Display --indent 2 --text "- Check if reboot is needed" --result "${STATUS_NO}" --color GREEN
diff --git a/include/tests_logging b/include/tests_logging
index 7f254147..292940e3 100644
--- a/include/tests_logging
+++ b/include/tests_logging
@@ -534,12 +534,7 @@
LSOF_GREP="WARNING|Output information"
# MySQL versions prior to 5.6 leave lots of deleted in-use files in /tmp, ignoring those
- if [ -n "${DPKGBINARY}" ]; then
- EARLY_MYSQL=$(${DPKGBINARY} -l | ${EGREPBINARY} mysql-server-5.[0-5])
- elif [ -n "${RPMBINARY}" ]; then
- EARLY_MYSQL=$(${RPMBINARY} -qa mariadb | ${EGREPBINARY} mariadb-5.[0-5])
- fi
- if [ -n "${EARLY_MYSQL}" ]; then LSOF_GREP="${LSOF_GREP}|mysqld"; fi
+ LSOF_GREP="${LSOF_GREP}|mysqld"
# grsecurity causes Fail2Ban to hold onto deleted in-use files in /var/tmp
if [ ${GRSEC_FOUND} -eq 1 ]; then LSOF_GREP="${LSOF_GREP}|fail2ban"; fi
diff --git a/include/tests_memory_processes b/include/tests_memory_processes
index 0b0fff6f..2454f320 100644
--- a/include/tests_memory_processes
+++ b/include/tests_memory_processes
@@ -118,7 +118,7 @@
#
# Test : PROC-3802
# Description : Check presence of prelink tooling
- Register --test-no PROC-3802 --weight L --network NO --category security --description "Check presence of prelink tooling"
+ Register --test-no PROC-3802 --package-manager-required --os Linux --weight L --network NO --category security --description "Check presence of prelink tooling"
if [ ${SKIPTEST} -eq 0 ]; then
if PackageIsInstalled "prelink"; then
LogText "Result: prelink packages is installed"
diff --git a/include/tests_networking b/include/tests_networking
index b182f605..83a7aae0 100644
--- a/include/tests_networking
+++ b/include/tests_networking
@@ -35,6 +35,55 @@
#
#################################################################################
#
+ # Test : NETW-2400
+ # Description : Test hostname for valid characters and length
+ # Notes : FQDN: max 253 characters
+ # : component: a-z, 0-9, hyphen, not start with hyphen, max 63 characters
+ # dots allowed as separator
+ Register --test-no NETW-2400 --weight L --network YES --category basics --description "Hostname length and value check"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Test first the fully qualified domain name
+ if [ ${#FQDN} -gt 253 ]; then
+ # Too long
+ LogText "Result: FQDN is more than 253 characters"
+ Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_WARNING}" --color RED
+ ReportWarning "${TEST_NO}" "Hostname is too long (more than 253 characters)"
+ elif [ ${#FQDN} -eq 0 ]; then
+ # FQDN not defined
+ LogText "Result: FQDN is not defined"
+ if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_UNKNOWN}" --color YELLOW; fi
+ else
+ # Fine
+ LogText "Result: FQDN is defined and not longer than 253 characters (${#FQDN} characters)"
+ if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_OK}" --color GREEN; fi
+ fi
+ # Now test short hostname
+ if [ ${#HOSTNAME} -eq 0 ]; then
+ if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_NONE}" --color RED; fi
+ LogText "Result: hostname is not defined"
+ else
+ # Test length
+ if [ ${#HOSTNAME} -gt 63 ]; then
+ LogText "Result: hostname is more than 63 characters"
+ Display --indent 2 --text "- Hostname (length)" --result "${STATUS_WARNING}" --color RED
+ else
+ LogText "Result: hostnamed is defined and not longer than 63 characters"
+ fi
+ # Test valid characters (normally a dot should not be in the name, but we can't be 100% sure we have short name)
+ FIND=$(echo "${HOSTNAME}" | ${TRBINARY} -d '[a-z0-9\.\-]')
+ if [ -z "${FIND}" ]; then
+ LogText "Result: good, no unexpected characters discovered in hostname"
+ if IsVerbose; then Display --indent 2 --text "- Hostname (allowed characters)" --result "${STATUS_OK}" --color GREEN; fi
+ else
+ LogText "Result: unexpected characters discovered in hostname (characters: ${FIND}), which may impact network connectivity"
+ Display --indent 2 --text "- Hostname (allowed characters)" --result "${STATUS_WARNING}" --color RED
+ ReportWarning "${TEST_NO}" "Hostname contains invalid characters" "hostname" "text:See log file for invalid characters"
+ fi
+ fi
+ fi
+#
+#################################################################################
+#
# Test : NETW-2600
# Description : Gather IPv6 configuration
Register --test-no NETW-2600 --os "Linux" --weight L --network YES --category security --description "Checking IPv6 configuration"
@@ -191,23 +240,32 @@
#################################################################################
#
# Test : NETW-2706
- # Description : Check systemd-resolved and upstream DNSSEC status
- if [ -n "${RESOLVECTLBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
- Register --test-no NETW-2706 --preqs-met ${PREQS_MET} --weight L --network YES --category security --description "Check systemd-resolved and upstream DNSSEC status"
+ # Description : Check systemd-resolve output and upstream DNSSEC status
+ # Notes : Ubuntu 16.04 uses systemd-resolve, newer ones most likely resolvectl
+ if [ -n "${RESOLVECTLBINARY}" ]; then
+ PREQS_MET="YES"
+ RESOLVE_CMD="${RESOLVECTLBINARY}"
+ RESOLVE_CMD_PARAM="statistics"
+ elif [ -n "$(command -v systemd-resolve 2> /dev/null)" ]; then
+ PREQS_MET="YES"
+ RESOLVE_CMD="$(command -v systemd-resolve 2> /dev/null)"
+ RESOLVE_CMD_PARAM="--statistics"
+ else
+ PREQS_MET="NO"
+ fi
+ Register --test-no NETW-2706 --preqs-met "${PREQS_MET}" --weight L --network YES --category security --description "Check systemd-resolved and upstream DNSSEC status"
if [ ${SKIPTEST} -eq 0 ]; then
SKIP=0
- if [ -n "${RESOLVECTLBINARY}" ]; then
- DNSSEC_STATUS=$(${RESOLVECTLBINARY} statistics | ${AWKBINARY} -F ":" '/DNSSEC supported/ { print $2 }' | ${TRBINARY} -d ' ')
- if [ "${DNSSEC_STATUS}" = "yes" ]; then
- Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_OK}" --color GREEN
- LogText "Result: DNSSEC supported by systemd-resolved and upstream DNS servers"
- else
- Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_WARNING}" --color RED
- LogText "Result: DNSSEC not supported by systemd-resolved or upstream DNS servers"
- fi
+ DNSSEC_STATUS=$(${RESOLVE_CMD} ${RESOLVE_CMD_PARAM} 2> /dev/null | ${AWKBINARY} -F ":" '/DNSSEC supported/ { print $2 }' | ${TRBINARY} -d ' ')
+ if [ "${DNSSEC_STATUS}" = "yes" ]; then
+ Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_YES}" --color GREEN
+ LogText "Result: DNSSEC supported by systemd-resolved and upstream DNS servers"
+ elif [ "${DNSSEC_STATUS}" = "no" ]; then
+ Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_NO}" --color YELLOW
+ LogText "Result: DNSSEC not supported by systemd-resolved or upstream DNS servers"
else
- Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_SKIPPED}" --color YELLOW
- LogText "Result: resolvectl not installed, test can't be fully performed"
+ Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_UNKNOWN}" --color RED
+ LogText "Result: command '${RESOLVE_CMD} ${RESOLVE_CMD_PARAM}' returned an error. Please run command manually to check for details."
fi
else
LogText "Result: Test most likely skipped due to not having resolvectl"
@@ -727,7 +785,6 @@
#################################################################################
#
-
WaitForKeyPress
#
diff --git a/include/tests_php b/include/tests_php
index a452781a..0f498fff 100644
--- a/include/tests_php
+++ b/include/tests_php
@@ -464,6 +464,42 @@
#
#################################################################################
#
+ # Test : PHP-2382
+ # Description : Check listen option
+ # Background : https://github.com/CISOfy/lynis/issues/837
+ if [ -n "${PHPINI_ALLFILES}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no PHP-2382 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP expose_php option"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ FOUND=0
+ for FILE in ${PHPINI_ALLFILES}; do
+ # Don't look at this setting in cli configuration
+ case "${FILE}" in
+ */cli/*)
+ continue
+ ;;
+ esac
+ LogText "Test: Checking file ${FILE}"
+ FIND=$(${EGREPBINARY} -i "^listen = [0-9]{1,5}$" ${FILE})
+ if HasData "${FIND}"; then
+ LogText "Result: found listen on just a port number"
+ LogText "Data: ${FIND}"
+ LogText "Note: when possible, limit access to just localhost, so it can't be accessed from outside"
+ FOUND=1
+ fi
+ done
+
+ if [ ${FOUND} -eq 1 ]; then
+ Display --indent 4 --text "- Checking listen option" --result "${STATUS_SUGGESTION}" --color YELLOW
+ #ReportSuggestion "${TEST_NO}" "Limit the listening of FastCGI to just localhost or a local socket" "listen = 127.0.0.1:9000" "-"
+ AddHP 1 3
+ else
+ Display --indent 4 --text "- Checking listen option" --result "${STATUS_OK}" --color GREEN
+ AddHP 2 2
+ fi
+ fi
+#
+#################################################################################
+#
WaitForKeyPress
diff --git a/include/tests_ports_packages b/include/tests_ports_packages
index f63f2793..286da608 100644
--- a/include/tests_ports_packages
+++ b/include/tests_ports_packages
@@ -38,7 +38,7 @@
# Test : PKGS-7301
# Description : Query FreeBSD pkg
if [ -x ${ROOTDIR}usr/sbin/pkg ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
- Register --test-no PKGS-7301 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Query NetBSD pkg"
+ Register --test-no PKGS-7301 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Query FreeBSD pkg"
if [ ${SKIPTEST} -eq 0 ]; then
FIND=$(pkg -N 2>&1; echo $?)
if [ "${FIND}" = "0" ]; then
diff --git a/include/tests_printers_spools b/include/tests_printers_spoolers
index 161c9fb3..b8435493 100644
--- a/include/tests_printers_spools
+++ b/include/tests_printers_spoolers
@@ -134,23 +134,31 @@
#
# Test : PRNT-2308
# Description : Check CUPS daemon network configuration
+ # Notes : Listen and SSLListen can be used
if [ ${CUPSD_FOUND} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no PRNT-2308 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check CUPSd network configuration"
if [ ${SKIPTEST} -eq 0 ]; then
FOUND=0
# Checking network addresses
LogText "Test: Checking CUPS daemon listening network addresses"
- FIND=$(${GREPBINARY} "^Listen" ${CUPSD_CONFIG_FILE} | ${GREPBINARY} -v "/" | ${AWKBINARY} '{ print $2 }')
+ FIND=$(${EGREPBINARY} "^(SSL)?Listen" ${CUPSD_CONFIG_FILE} | ${GREPBINARY} -v "/" | ${AWKBINARY} '{ print $2 }')
COUNT=0
for ITEM in ${FIND}; do
- LogText "Found network address: ${ITEM}"
+ LogText "Result: found network address: ${ITEM}"
COUNT=$((COUNT + 1))
FOUND=1
done
- # Check if daemon is only running on localhost
+ # Search for Port statement
+ FIND=$(${EGREPBINARY} "^Port 631" ${CUPSD_CONFIG_FILE})
+ if [ -n "${FIND}" ]; then
+ LogText "Result: found CUPS listening on port 631 (most likely all interfaces)"
+ FOUND=1
+ fi
+
+ # Check if daemon might be running on localhost
if [ ${FOUND} -eq 0 ]; then
- LogText "Result: no listen statement found in CUPS configuration file"
+ LogText "Result: CUPS does not look to be listening on a network port"
elif [ ${COUNT} -eq 1 ]; then
if [ "${FIND}" = "localhost:631" -o "${FIND}" = "127.0.0.1:631" ]; then
LogText "Result: CUPS daemon only running on localhost"
diff --git a/include/tests_time b/include/tests_time
index 23fd0965..7c15d0a3 100644
--- a/include/tests_time
+++ b/include/tests_time
@@ -163,22 +163,28 @@
fi
done
- # Don't run check in cron job directory on Solaris
- # /etc/cron.d/FIFO is a special file and test get stuck at this file
+ # Notes: only test for normal files. File /etc/cron.d/FIFO on solaris is a special file and test may hang
+ # Linux systems may have a .placeholder file
FOUND_IN_CRON=0
# Check cron jobs
for I in ${CRON_DIRS}; do
if [ -d ${I} ]; then
if FileIsReadable ${I}; then
- FIND=$(${LSBINARY} ${I} | ${GREPBINARY} -v FIFO)
+ FIND=$(${FINDBINARY} ${I} -type f -a ! -name ".placeholder" -print 2> /dev/null | ${SEDBINARY} 's/ /__space__/g' | ${TRBINARY} '\n' '\0' | ${TRBINARY} -cd '[:print:]\0' | ${TRBINARY} '\0' ' ')
if [ -n "${FIND}" ]; then
for J in ${FIND}; do
- LogText "Test: checking for ntpdate or rdate in ${I}/${J}"
- FIND2=$(${EGREPBINARY} "rdate|ntpdate" ${I}/${J} | ${GREPBINARY} -v "^#")
- if [ -n "${FIND2}" ]; then
- LogText "Positive match found: ${FIND2}"
- FOUND=1; FOUND_IN_CRON=1; NTP_CONFIG_TYPE_SCHEDULED=1
+ # Place back spaces if needed
+ J=$(echo ${J} | ${SEDBINARY} 's/__space__/ /g')
+ LogText "Test: checking for ntpdate or rdate in ${J}"
+ if FileIsReadable ${J}; then
+ FIND2=$(${EGREPBINARY} "rdate|ntpdate" "${J}" | ${GREPBINARY} -v "^#")
+ if [ -n "${FIND2}" ]; then
+ LogText "Positive match found: ${FIND2}"
+ FOUND=1; FOUND_IN_CRON=1; NTP_CONFIG_TYPE_SCHEDULED=1
+ fi
+ else
+ LogText "Result: could not test in file '${J}' as it is not readable"
fi
done
else
diff --git a/lynis b/lynis
index 12eea7fb..d5dca003 100755
--- a/lynis
+++ b/lynis
@@ -524,6 +524,7 @@ ${NORMAL}
if [ "${OS}" = "Linux" -a "${HOSTNAME}" = "${FQDN}" ]; then
FQDN=$(hostname -f 2> /dev/null)
fi
+
#
#################################################################################
#
@@ -568,6 +569,7 @@ ${NORMAL}
fi
Report "test_category=${TEST_CATEGORY_TO_CHECK}"
Report "test_group=${TEST_GROUP_TO_CHECK}"
+
#
#################################################################################
#
@@ -630,6 +632,7 @@ ${NORMAL}
echo "Make sure to execute ${PROGRAM_NAME} from untarred directory or check your installation."
exit 1
fi
+
#
#################################################################################
#
@@ -817,6 +820,14 @@ ${NORMAL}
#
#################################################################################
#
+ # Test if we have a package manager available by testing for a dummy package (should not exist)
+ if PackageIsInstalled "__dummy__"; then
+ HAS_PACKAGE_MANAGER=1
+ LogText "Informational: package manager is used"
+ else
+ LogText "Informational: no known package manager for this system"
+ fi
+
# Use hardware detection capabilities
IsVirtualMachine
if IsContainer; then
@@ -980,7 +991,7 @@ ${NORMAL}
LogText "Info: perform tests from all categories"
INCLUDE_TESTS="boot_services kernel memory_processes authentication shells \
- filesystems usb storage storage_nfs nameservices dns ports_packages networking printers_spools \
+ filesystems usb storage storage_nfs nameservices dns ports_packages networking printers_spoolers \
mail_messaging firewalls webservers ssh snmp databases ldap php squid logging \
insecure_services banners scheduling accounting time crypto virtualization containers \
mac_frameworks file_integrity tooling malware file_permissions homedirs \