mirror of
https://github.com/CISOfy/lynis.git
synced 2025-04-08 17:15:25 +02:00
This test was previously measuring the number of bytes (wc -c) in the exported JSON which is likely not what was intended and will lead to false positives anytime the number of bytes exceeds 16. The export feature is poorly documented and requires the jansson package on the target system to export as JSON - which may not always be the case. Lastly, 16 is an arbitrary and uncessarily high number. A simple workstation firewall can have only 3 rules and be effective. This commit makes use of 'nft list ruleset' instead of the export command, strips out blank lines as well as table & chain headers before measuring the number of lines in the output. Any result with more than 3 rules is now considered non-empty. This is more consistent with the equivalent iptables test case.
615 lines
30 KiB
Bash
615 lines
30 KiB
Bash
#!/bin/sh
|
|
|
|
#################################################################################
|
|
#
|
|
# Lynis
|
|
# ------------------
|
|
#
|
|
# Copyright 2007-2013, Michael Boelen
|
|
# Copyright 2007-2019, 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.
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Firewalls
|
|
#
|
|
#################################################################################
|
|
#
|
|
InsertSection "Software: firewalls"
|
|
#
|
|
#################################################################################
|
|
#
|
|
IPTABLES_ACTIVE=0
|
|
IP6TABLES_ACTIVE=0
|
|
IPTABLES_INKERNEL_ACTIVE=0
|
|
IPTABLES_MODULE_ACTIVE=0
|
|
FIREWALL_ACTIVE=0
|
|
FIREWALL_EMPTY_RULESET=0
|
|
NFTABLES_ACTIVE=0
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4502
|
|
# Description : Check iptables kernel module
|
|
Register --test-no FIRE-4502 --os Linux --weight L --network NO --category security --description "Check iptables kernel module"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} "^ip*_tables")
|
|
if [ ! -z "${FIND}" ]; then
|
|
FIREWALL_ACTIVE=1
|
|
IPTABLES_ACTIVE=1
|
|
IPTABLES_MODULE_ACTIVE=1
|
|
Display --indent 2 --text "- Checking iptables kernel module" --result "${STATUS_FOUND}" --color GREEN
|
|
Report "firewall_software[]=iptables"
|
|
LogText "Result: Found iptables in loaded kernel modules"
|
|
for I in ${FIND}; do
|
|
if [ "${I}" = "ip6_tables" ]; then IP6TABLES_ACTIVE=1; Report "firewall_software[]=ip6tables"; fi
|
|
LogText "Found module: ${I}"
|
|
done
|
|
elif [ -f ${ROOTDIR}proc/net/ip_tables_names ]; then
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=iptables"
|
|
IPTABLES_ACTIVE=1
|
|
Display --indent 2 --text "- Checking iptables support" --result "${STATUS_FOUND}" --color GREEN
|
|
elif [ -f ${ROOTDIR}proc/net/ip6_tables_names ]; then
|
|
FIREWALL_ACTIVE=1
|
|
IP6TABLES_ACTIVE=1
|
|
Report "firewall_software[]=ip6tables"
|
|
Display --indent 2 --text "- Checking ip6tables support" --result "${STATUS_FOUND}" --color GREEN
|
|
else
|
|
Display --indent 2 --text "- Checking iptables kernel module" --result "${STATUS_NOT_FOUND}" --color WHITE
|
|
|
|
# If we can't find an active module, try to find the Linux configuration file and check that
|
|
if [ -f /proc/config.gz ]; then LINUXCONFIGFILE="/proc/config.gz"; tCATCMD="zcat"; fi
|
|
sLINUXCONFIGFILE="/boot/config-$(uname -r)"
|
|
if [ -f ${sLINUXCONFIGFILE} ]; then LINUXCONFIGFILE=${sLINUXCONFIGFILE}; tCATCMD="cat"; fi
|
|
|
|
# If we have a kernel configuration file, use it for testing
|
|
# Do not perform test if we already found it in kernel module list, to avoid triggered it in the upcoming
|
|
# tests, when using iptables --list
|
|
if [ ! -z "${LINUXCONFIGFILE}" ]; then
|
|
if [ -f ${LINUXCONFIGFILE} -a ${IPTABLES_MODULE_ACTIVE} -eq 0 ]; then
|
|
LogText "Result: found kernel configuration file (${LINUXCONFIGFILE})"
|
|
FIND=$(${tCATCMD} ${LINUXCONFIGFILE} | ${GREPBINARY} -v '^#' | ${GREPBINARY} "CONFIG_IP_NF_IPTABLES" | head -n 1)
|
|
if [ ! -z "${FIND}" ]; then
|
|
HAVEMOD=$(echo ${FIND} | ${CUTBINARY} -d '=' -f2)
|
|
# Do not use iptables if it's compiled as a module (=m), since we already tested for it in the
|
|
# active list.
|
|
if [ "${HAVEMOD}" = "y" ]; then
|
|
LogText "Result: iptables available as a module in the configuration"
|
|
IPTABLES_ACTIVE=1
|
|
IPTABLES_INKERNEL_ACTIVE=1
|
|
FIREWALL_ACTIVE=1
|
|
Display --indent 2 --text "- Checking iptables in config file" --result "${STATUS_FOUND}" --color GREEN
|
|
else
|
|
LogText "Result: no iptables found in Linux kernel config file"
|
|
fi
|
|
else
|
|
LogText "Result: no Linux configuration file found"
|
|
Display --indent 2 --text "- Checking iptables in config file" --result "${STATUS_NOT_FOUND}" --color WHITE
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4508
|
|
# Description : Check iptables chain policies
|
|
# Notes : Suggestions are currently disabled, until related page and documentation is available
|
|
# TODO : grep -z is not supported on BusyBox
|
|
if [ ! "${IPTABLESBINARY}" = "" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4508 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description "Check used policies of iptables chains"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
Display --indent 4 --text "- Checking iptables policies of chains" --result "${STATUS_FOUND}" --color GREEN
|
|
TABLES="filter"
|
|
for TABLE in ${TABLES}; do
|
|
LogText "Test: gathering information from table ${TABLE}"
|
|
FIND="$FIND""\n"$(${IPTABLESBINARY} -t ${TABLE} --numeric --list | ${EGREPBINARY} -z -o -w '[A-Z]+' | tr -d '\0' | ${AWKBINARY} -v t=${TABLE} 'NR%2 {printf "%s %s ",t, $0 ; next;}1')
|
|
done
|
|
|
|
echo "${FIND}" | while read line; do
|
|
table=$(echo ${line} | ${AWKBINARY} '{ print $1 }')
|
|
chainname=$(echo ${line} | ${AWKBINARY} '{ print $2 }')
|
|
policy=$(echo ${line} | ${AWKBINARY} '{ print $3 }')
|
|
LogText "Result: iptables ${table} -- ${chainname} policy is ${policy}."
|
|
LogText "Result: ${policy}"
|
|
|
|
if [ "${TABLE}" = "filter" ]; then
|
|
if [ "${chainname}" = "INPUT" ]; then
|
|
case ${policy} in
|
|
"ACCEPT")
|
|
LogText "Result: Found ACCEPT for ${chainname} (table: ${table})"
|
|
Display --indent 6 --text "- Checking chain ${chainname} (table: ${table}, policy ${policy})" --result "ACCEPT" --color YELLOW
|
|
#ReportSuggestion ${TEST_NO} "Consider settings default chain policy to DROP (iptables chain ${chainname}, table: ${table})"
|
|
AddHP 1 3
|
|
;;
|
|
"DROP")
|
|
LogText "Result: Found DROP for ${chainname} (table: ${table})"
|
|
Display --indent 6 --text "- Checking chain ${chainname} (table: ${table}, policy ${policy})" --result "DROP" --color GREEN
|
|
AddHP 3 3
|
|
;;
|
|
*)
|
|
Display --indent 6 --text "- Checking chain ${chainname} (table: ${table}, policy ${policy})" --result "other" --color YELLOW
|
|
LogText "Result: Unknown policy: ${policy}"
|
|
#ReportSuggestion ${TEST_NO} "Check iptables ${chainname} (table: ${table}) chain policy"
|
|
;;
|
|
esac
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4512
|
|
# Description : Check iptables for empty ruleset (should have at least 5 or more rules)
|
|
if [ ! -z "${IPTABLESBINARY}" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4512 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description "Check iptables for empty ruleset"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(${IPTABLESBINARY} --list --numeric 2> /dev/null | ${EGREPBINARY} -v "^(Chain|target|$)" | ${WCBINARY} -l | ${TRBINARY} -d ' ')
|
|
if [ ! -z "${FIND}" ]; then
|
|
FIREWALL_ACTIVE=1
|
|
if [ ${FIND} -le 5 ]; then
|
|
# Firewall is active, but needs configuration
|
|
FIREWALL_EMPTY_RULESET=1
|
|
LogText "Result: iptables ruleset seems to be empty (found ${FIND} rules)"
|
|
Display --indent 4 --text "- Checking for empty ruleset" --result "${STATUS_WARNING}" --color RED
|
|
ReportWarning ${TEST_NO} "iptables module(s) loaded, but no rules active"
|
|
else
|
|
LogText "Result: one or more rules are available (${FIND} rules)"
|
|
Display --indent 4 --text "- Checking for empty ruleset" --result "${STATUS_OK}" --color GREEN
|
|
fi
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4513
|
|
# Description : Check iptables for unused rules
|
|
if [ ! -z "${IPTABLESBINARY}" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4513 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description "Check iptables for unused rules"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(${IPTABLESBINARY} --list --numeric --line-numbers --verbose | ${AWKBINARY} '{ if ($2=="0") print $1 }' | ${XARGSBINARY})
|
|
if IsEmpty "${FIND}"; then
|
|
Display --indent 4 --text "- Checking for unused rules" --result "${STATUS_OK}" --color GREEN
|
|
LogText "Result: There are no unused rules present"
|
|
else
|
|
Display --indent 4 --text "- Checking for unused rules" --result "${STATUS_FOUND}" --color YELLOW
|
|
LogText "Result: Found one or more possible unused rules"
|
|
LogText "Description: Unused rules can be a sign that the firewall rules aren't optimized or up-to-date"
|
|
LogText "Note: Sometimes rules aren't triggered but still in use. Keep this in mind before cleaning up rules."
|
|
LogText "Output: iptables rule numbers: ${FIND}"
|
|
ReportSuggestion ${TEST_NO} "Check iptables rules to see which rules are currently not used"
|
|
LogText "Tip: iptables --list --numeric --line-numbers --verbose"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4514
|
|
# Notes :
|
|
# Check if ipv6 is active on any network interface
|
|
# If ip_tables is active, and ip6_tables is not, show warning about missing filtering
|
|
#
|
|
#################################################################################
|
|
#
|
|
|
|
# Test : FIRE-4518
|
|
# Description : Checking status of pf firewall components
|
|
# Notes : Use /dev/pf as first detection method if pf is available
|
|
if [ -e /dev/pf ]; then PREQS_MET="YES"; SKIPREASON=""; else PREQS_MET="NO"; SKIPREASON="No /dev/pf device"; fi
|
|
Register --test-no FIRE-4518 --preqs-met ${PREQS_MET} --skip-reason "${SKIPREASON}" --weight L --network NO --root-only YES --category security --description "Check pf firewall components"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
PFFOUND=0; PFLOGDFOUND=0
|
|
|
|
# Check status with pfctl
|
|
LogText "Test: checking pf status via pfctl"
|
|
if [ ! -z "${PFCTLBINARY}" ]; then
|
|
FIND=$(${PFCTLBINARY} -sa 2>&1 | ${GREPBINARY} "^Status" | ${HEADBINARY} -1 | ${AWKBINARY} '{ print $2 }')
|
|
if [ "${FIND}" = "Disabled" ]; then
|
|
if IsVerbose; then Display --indent 2 --text "- Checking pf status (pfctl)" --result "${STATUS_DISABLED}" --color RED; fi
|
|
LogText "Result: pf is disabled"
|
|
AddHP 0 3
|
|
elif [ "${FIND}" = "Enabled" ]; then
|
|
Display --indent 2 --text "- Checking pf status (pfctl)" --result "${STATUS_ENABLED}" --color GREEN
|
|
LogText "Result: pf is enabled"
|
|
PFFOUND=1
|
|
AddHP 3 3
|
|
else
|
|
Display --indent 2 --text "- Checking pf status (pfctl)" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
ReportException ${TEST_NO} "Unknown status of pf firewall"
|
|
fi
|
|
fi
|
|
|
|
# If we didn't find the status to be enabled, stop searching
|
|
if [ ${PFFOUND} -eq 0 ]; then
|
|
# Check for pf kernel module (FreeBSD and similar)
|
|
LogText "Test: searching for pf kernel module"
|
|
if [ ! -z "${KLDSTATBINARY}" ]; then
|
|
FIND=$(${KLDSTATBINARY} | ${GREPBINARY} 'pf.ko')
|
|
if [ -z "${FIND}" ]; then
|
|
LogText "Result: Can not find pf KLD"
|
|
else
|
|
LogText "Result: pf KLD loaded"
|
|
PFFOUND=1
|
|
fi
|
|
else
|
|
LogText "Result: no kldstat binary, skipping this part"
|
|
fi
|
|
|
|
IsRunning pflogd
|
|
if [ ${RUNNING} -eq 1 ]; then
|
|
LogText "Result: found pflog daemon in process list"
|
|
Display --indent 4 --text "- Checking pflogd status" --result "ACTIVE" --color GREEN
|
|
PFFOUND=1
|
|
PFLOGDFOUND=1
|
|
else
|
|
LogText "Result: pflog daemon not found in process list"
|
|
fi
|
|
fi
|
|
|
|
if [ ${PFFOUND} -eq 1 ]; then
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=pf"
|
|
else
|
|
LogText "Result: pf not running on this system"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4520
|
|
# Description : Check pf configuration consistency
|
|
if [ ${PFFOUND} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4520 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check pf configuration consistency"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
LogText "Test: check /etc/pf.conf"
|
|
# Test for warnings (-n don't load the rules)
|
|
if [ -f /etc/pf.conf ]; then
|
|
LogText "Result: /etc/pf.conf exists"
|
|
# Check results from pfctl
|
|
PFWARNINGS=$(${PFCTLBINARY} -n -f /etc/pf.conf -vvv 2>&1 | ${GREPBINARY} -i 'warning')
|
|
if [ -z "${PFWARNINGS}" ]; then
|
|
Display --indent 4 --text "- Checking pf configuration consistency" --result "${STATUS_OK}" --color GREEN
|
|
LogText "Result: no pf filter warnings found"
|
|
else
|
|
Display --indent 4 --text "- Checking pf configuration consistency" --result "${STATUS_WARNING}" --color RED
|
|
LogText "Result: found one or more warnings in the pf filter rules"
|
|
ReportWarning ${TEST_NO} "Found one or more warnings in pf configuration file" "/etc/pf.conf" "text:Run 'pfctl -n -f /etc/pf.conf -vvv' to see available pf warnings"
|
|
fi
|
|
else
|
|
LogText "Result: /etc/pf.conf does NOT exist"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4522
|
|
# Description : Check ipchains
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4524
|
|
# Description : Check for CSF (ConfigServer Security & Firewall)
|
|
Register --test-no FIRE-4524 --weight L --network NO --category security --description "Check for CSF presence"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FILE="/etc/csf/csf.conf"
|
|
LogText "Test: check ${FILE}"
|
|
if [ -f ${FILE} ]; then
|
|
LogText "Result: ${FILE} exists"
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=csf"
|
|
Display --indent 2 --text "- Checking CSF status (configuration file)" --result "${STATUS_FOUND}" --color GREEN
|
|
|
|
LogText "Test: check if CSF testing mode is disabled"
|
|
FIND=$(${GREPBINARY} -P "^TESTING(\s|=)" ${FILE} | ${CUTBINARY} -d= -f2 | ${XARGSBINARY})
|
|
if [ "${FIND}" = "0" ]; then
|
|
Display --indent 4 --text "- Check if CSF testing mode is disabled" --result "${STATUS_OK}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "- Check if CSF testing mode is disabled" --result "${STATUS_WARNING}" --color RED
|
|
fi
|
|
|
|
LogText "Test: check if CSF is running"
|
|
if [ ! -f /etc/csf/csf.disable ]; then
|
|
Display --indent 4 --text "- Check if CSF is running" --result "${STATUS_OK}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "- Check if CSF is running" --result "${STATUS_WARNING}" --color RED
|
|
fi
|
|
else
|
|
LogText "Result: ${FILE} does NOT exist"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4526
|
|
# Description : Check ipf (Solaris)
|
|
if [ ! "${IPFBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4526 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check ipf status"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(${IPFBINARY} -n -V | ${GREPBINARY} "^Running" | ${AWKBINARY} '{ print $2 }')
|
|
if [ "${FIND}" = "yes" ]; then
|
|
Display --indent 4 --text "- Checking ipf status" --result "${STATUS_RUNNING}" --color GREEN
|
|
LogText "Result: ipf is enabled and running"
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=ipf"
|
|
else
|
|
Display --indent 4 --text "- Checking ipf status" --result "${STATUS_NOT_RUNNING}" --color YELLOW
|
|
LogText "Result: ipf is not running"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4530
|
|
# Description : Check IPFW (FreeBSD)
|
|
Register --test-no FIRE-4530 --os FreeBSD --weight L --network NO --category security --description "Check IPFW status"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
if [ ! -z "${SYSCTLBINARY}" ]; then
|
|
# For now, only check for IPv4.
|
|
FIND=$(${SYSCTLBINARY} net.inet.ip.fw.enable 2> /dev/null | ${AWKBINARY} '{ print $2 }')
|
|
if [ "${FIND}" = "1" ]; then
|
|
Display --indent 2 --text "- Checking IPFW status" --result "${STATUS_RUNNING}" --color GREEN
|
|
LogText "Result: IPFW is running for IPv4"
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=ipfw"
|
|
IPFW_ENABLED=$(service -e | ${GREPBINARY} -o ipfw)
|
|
if [ "${IPFW_ENABLED}" = "ipfw" ]; then
|
|
Display --indent 4 --text "- IPFW enabled in /etc/rc.conf" --result "${STATUS_YES}" --color GREEN
|
|
LogText "Result: IPFW is enabled at start-up for IPv4"
|
|
else
|
|
Display --indent 4 --text "- ipfw enabled in /etc/rc.conf" --result "${STATUS_NO}" --color YELLOW
|
|
LogText "Result: IPFW is disabled at start-up for IPv4"
|
|
fi
|
|
else
|
|
if IsVerbose; then Display --indent 2 --text "- Checking IPFW status" --result "${STATUS_NOT_RUNNING}" --color YELLOW; fi
|
|
LogText "Result: IPFW is not running for IPv4"
|
|
fi
|
|
else
|
|
ReportException "${TEST_NO}:1" "No IPFW test available (sysctl missing)"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4532
|
|
# Description : Check Application Firewall in macOS
|
|
if [ -x /usr/libexec/ApplicationFirewall/socketfilterfw ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4532 --weight L --os "macOS" --preqs-met ${PREQS_MET} --network NO --category security --description "Check macOS application firewall"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2> /dev/null | ${GREPBINARY} "Firewall is enabled")
|
|
if [ ! -z "${FIND}" ]; then
|
|
Display --indent 2 --text "- Checking macOS: Application Firewall" --result "${STATUS_ENABLED}" --color GREEN
|
|
AddHP 3 3
|
|
LogText "Result: application firewall of macOS is enabled"
|
|
FIREWALL_ACTIVE=1
|
|
APPLICATION_FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=macosx-app-fw"
|
|
Report "app_fw[]=macosx-app-fw"
|
|
else
|
|
if IsVerbose; then Display --indent 2 --text "- Checking macOS: Application Firewall" --result "${STATUS_DISABLED}" --color YELLOW; fi
|
|
AddHP 1 3
|
|
LogText "Result: application firewall of macOS is disabled"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4534
|
|
# Description : Check outbound firewalls on macOS
|
|
Register --test-no FIRE-4534 --weight L --os "macOS" --network NO --category security --description "Check for presence of outbound firewalls on macOS"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
|
|
# Little Snitch Daemon (macOS)
|
|
LogText "Test: checking process Little Snitch Daemon"
|
|
IsRunning --full "Little Snitch Daemon"
|
|
if [ ${RUNNING} -eq 1 ]; then
|
|
Display --indent 2 --text "- Checking Little Snitch Daemon" --result "${STATUS_ENABLED}" --color GREEN
|
|
LogText "Result: Little Snitch found"
|
|
FOUND=1
|
|
FIREWALL_ACTIVE=1
|
|
APPLICATION_FIREWALL_ACTIVE=1
|
|
Report "app_fw[]=little-snitch"
|
|
Report "firewall_software[]=little-snitch"
|
|
fi
|
|
|
|
# HandsOff! Daemon (macOS)
|
|
LogText "Test: checking process HandsOffDaemon"
|
|
IsRunning HandsOffDaemon
|
|
if [ ${RUNNING} -eq 1 ]; then
|
|
Display --indent 2 --text "- Checking Hands Off! Daemon" --result "${STATUS_ENABLED}" --color GREEN
|
|
LogText "Result: Hands Off! found"
|
|
FOUND=1
|
|
FIREWALL_ACTIVE=1
|
|
APPLICATION_FIREWALL_ACTIVE=1
|
|
Report "app_fw[]=hands-off"
|
|
Report "firewall_software[]=hands-off"
|
|
fi
|
|
|
|
# LuLu Daemon (macOS)
|
|
LogText "Test: checking process LuLu"
|
|
IsRunning LuLu
|
|
if [ ${RUNNING} -eq 1 ]; then
|
|
Display --indent 2 --text "- Checking LuLu Daemon" --result "${STATUS_ENABLED}" --color GREEN
|
|
LogText "Result: LuLu found"
|
|
FOUND=1
|
|
FIREWALL_ACTIVE=1
|
|
APPLICATION_FIREWALL_ACTIVE=1
|
|
Report "app_fw[]=lulu"
|
|
Report "firewall_software[]=lulu"
|
|
fi
|
|
|
|
# Radio Silence (macOS)
|
|
LogText "Test: checking process Radio Silence"
|
|
IsRunning --full "Radio Silence"
|
|
if [ ${RUNNING} -eq 1 ]; then
|
|
Display --indent 2 --text "- Checking Radio Silence" --result "${STATUS_ENABLED}" --color GREEN
|
|
LogText "Result: Radio Silence found"
|
|
FOUND=1
|
|
FIREWALL_ACTIVE=1
|
|
APPLICATION_FIREWALL_ACTIVE=1
|
|
Report "app_fw[]=radio-silence"
|
|
Report "firewall_software[]=radio-silence"
|
|
fi
|
|
|
|
if [ ${FOUND} -eq 0 ]; then
|
|
LogText "Result: outbound firewall not found"
|
|
AddHP 1 3
|
|
else
|
|
LogText "Result: found one or more macOS outbound firewall"
|
|
AddHP 3 3
|
|
fi
|
|
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4536
|
|
# Description : Check nftables kernel module
|
|
if HasData "${NFTBINARY}"; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4536 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check nftables status"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} "^nf*_tables")
|
|
if [ ! -z "${FIND}" ]; then
|
|
LogText "Result: found nftables kernel module"
|
|
FIREWALL_ACTIVE=1
|
|
NFTABLES_ACTIVE=1
|
|
Report "firewall_software[]=nftables"
|
|
else
|
|
LogText "Result: no nftables kernel module found"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4538
|
|
# Description : Check nftables configuration
|
|
if HasData "${NFTBINARY}"; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4538 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check nftables basic configuration"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
# Retrieve nft version
|
|
NFT_VERSION=$(${NFTBINARY} --version 2> /dev/null | ${AWKBINARY} '{ if ($1=="nftables") { print $2 }}' | ${TRBINARY} -d 'v')
|
|
Report "nft_version=${NFT_VERSION}"
|
|
LogText "Result: found version ${NFT_VERSION} of nft"
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4540
|
|
# Description : Check nftables configuration
|
|
if HasData "${NFTBINARY}"; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4540 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description "Check for empty nftables configuration"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
# Check for empty ruleset
|
|
NFT_RULES_LENGTH=$(${NFTBINARY} list ruleset --stateless 2> /dev/null | ${EGREPBINARY} -v "table|chain|;$|}$|^$" | ${WCBINARY} -l)
|
|
if [ ${NFT_RULES_LENGTH} -le 3 ]; then
|
|
FIREWALL_EMPTY_RULESET=1
|
|
LogText "Result: this firewall set has 3 rules or less and is considered to be empty"
|
|
else
|
|
LogText "Result: found ${NFT_RULES_LENGTH} rules in nftables configuration"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4586
|
|
# Description : Check firewall logging
|
|
if [ ${FIREWALL_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
Register --test-no FIRE-4586 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description "Check firewall logging"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
if [ ${IPTABLES_ACTIVE} -eq 1 ]; then
|
|
if [ ! -z "${IPTABLESSAVEBINARY}" ]; then
|
|
HAS_LOGGING=$(${IPTABLESSAVEBINARY} | ${GREPBINARY} "\-j LOG")
|
|
if [ -z "${HAS_LOGGING}" ]; then
|
|
Report "firewall_no_logging[]=iptables"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4590
|
|
# Description : Check if at least one firewall if active
|
|
Register --test-no FIRE-4590 --weight L --network NO --category security --description "Check firewall status"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
if [ ${FIREWALL_ACTIVE} -eq 1 ]; then
|
|
Display --indent 2 --text "- Checking host based firewall" --result "ACTIVE" --color GREEN
|
|
LogText "Result: host based firewall or packet filter is active"
|
|
Report "manual[]=Verify if there is a formal process for testing and applying firewall rules"
|
|
Report "manual[]=Verify all traffic is filtered the right way between the different security zones"
|
|
Report "manual[]=Verify if a list is available with all required services"
|
|
# YYY Solaris ipf (determine default policy)
|
|
Report "manual[]=Make sure an explicit deny all is the default policy for all unmatched traffic"
|
|
AddHP 5 5
|
|
else
|
|
Display --indent 2 --text "- Checking host based firewall" --result "NOT ACTIVE" --color YELLOW
|
|
LogText "Result: no host based firewall/packet filter found or configured"
|
|
ReportSuggestion ${TEST_NO} "Configure a firewall/packet filter to filter incoming and outgoing traffic"
|
|
AddHP 0 5
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : FIRE-4594
|
|
# Description : Check for APF (Advanced Policy Firewall)
|
|
Register --test-no FIRE-4594 --weight L --network NO --category security --description "Check for APF presence"
|
|
if [ ! -z "${IPTABLESBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FILE="/etc/apf/conf.apf"
|
|
LogText "Test: check ${FILE}"
|
|
if [ -f ${FILE} ]; then
|
|
LogText "Result: ${FILE} exists"
|
|
FIREWALL_ACTIVE=1
|
|
Report "firewall_software[]=apf"
|
|
Display --indent 2 --text "- Checking APF status (configuration file)" --result "${STATUS_FOUND}" --color GREEN
|
|
|
|
LogText "Test: check if APF testing mode is disabled"
|
|
FIND=$(${GREPBINARY} -P "^DEVEL_MODE(\s|=)" ${FILE} | ${CUTBINARY} -d= -f2 | ${XARGSBINARY})
|
|
if [ "${FIND}" = "0" ]; then
|
|
Display --indent 4 --text "- Check if APF testing mode is disabled" --result "${STATUS_OK}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "- Check if APF testing mode is disabled" --result "${STATUS_WARNING}" --color RED
|
|
fi
|
|
|
|
LogText "Test: check if APF is running"
|
|
FIND=$(${IPTABLESBINARY} -L -n | ${GREPBINARY} -iom1 sanity | ${WCBINARY} -l)
|
|
if [ "${FIND}" = "1" ]; then
|
|
Display --indent 4 --text "- Check if APF is running" --result "${STATUS_OK}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "- Check if APF is running" --result "${STATUS_WARNING}" --color RED
|
|
fi
|
|
else
|
|
LogText "Result: ${FILE} does NOT exist"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
|
|
# Report firewall installed for now, if we found one active. Next step would be determining binaries first and apply additional checks.
|
|
Report "firewall_active=${FIREWALL_ACTIVE}"
|
|
Report "firewall_empty_ruleset=${FIREWALL_EMPTY_RULESET}"
|
|
Report "firewall_installed=${FIREWALL_ACTIVE}"
|
|
|
|
WaitForKeyPress
|
|
|
|
#
|
|
#################################################################################
|
|
#
|
|
# TODO
|
|
# Suggestion to disable iptables if nftables is enabled
|
|
# Check for specific features in nftables releases
|
|
#
|
|
#================================================================================
|
|
# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
|