diff --git a/bin/hardening/iptables_persistent_is_not_installed.sh b/bin/hardening/iptables_persistent_is_not_installed.sh new file mode 100755 index 0000000..9ea3a34 --- /dev/null +++ b/bin/hardening/iptables_persistent_is_not_installed.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# run-shellcheck +# +# CIS Debian Hardening +# + +# +# Ensure iptables-persistent is not installed with ufw (Manual) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +# shellcheck disable=2034 +HARDENING_LEVEL=2 +# shellcheck disable=2034 +DESCRIPTION="Ensure iptables-persistent is not installed, requirement for ufw." + +PACKAGE='iptables-persistent' + +# This function will be called if the script status is on enabled / audit mode +audit() { + is_pkg_installed "$PACKAGE" + if [ "$FNRET" -eq 0 ]; then + crit "$PACKAGE is installed" + else + ok "$PACKAGE is not installed." + fi +} + +# This function will be called if the script status is on enabled mode +apply() { + is_pkg_installed "$PACKAGE" + if [ "$FNRET" -eq 0 ]; then + # Debian 12 CIS suggests to do it in an automated way, but this also conflicts with another recommendation: + # -> '4.1.2' wants to remove it while '4.3.1.1' wants to install it :/ + crit "'$PACKAGE' is installed. You should either disable this recommendation, or remove the package manually" + fi +} + +# This function will check config parameters required +check_config() { + : +} + +# Source Root Dir Parameter +if [ -r /etc/default/cis-hardening ]; then + # shellcheck source=../../debian/default + . /etc/default/cis-hardening +fi +if [ -z "$CIS_LIB_DIR" ]; then + echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment." + echo "Cannot source CIS_LIB_DIR variable, aborting." + exit 128 +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +if [ -r "${CIS_LIB_DIR}"/main.sh ]; then + # shellcheck source=../../lib/main.sh + . "${CIS_LIB_DIR}"/main.sh +else + echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_LIB_DIR in /etc/default/cis-hardening" + exit 128 +fi diff --git a/bin/hardening/libpam_runtime_is_version.sh b/bin/hardening/libpam_runtime_is_version.sh new file mode 100755 index 0000000..f077bce --- /dev/null +++ b/bin/hardening/libpam_runtime_is_version.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# run-shellcheck +# +# CIS Debian Hardening +# + +# +# Ensure latest version of pam is installed (Automated) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +# shellcheck disable=2034 +HARDENING_LEVEL=2 +# shellcheck disable=2034 +DESCRIPTION="Ensure latest version of pam is installed." +PACKAGE='libpam-runtime' +MIN_VERSION='' + +# This function will be called if the script status is on enabled / audit mode +audit() { + PACKAGE_IS_VERSION=0 + if [ "$DEB_MAJ_VER" -ge 12 ]; then + + version=$(dpkg-query --show --showformat '${Version}' "$PACKAGE") + if dpkg --compare-versions "$version" ge "$MIN_VERSION"; then + ok "$PACKAGE is $version" + else + crit "$PACKAGE is $version" + PACKAGE_IS_VERSION=1 + fi + + else + info "This recommendation requires at least a debian 12 system" + fi +} + +# This function will be called if the script status is on enabled mode +apply() { + if [ "$PACKAGE_IS_VERSION" -eq 1 ]; then + apt upgrade -y libpam-runtime + fi +} + +create_config() { + local PACKAGE_VERSION="" + if [ "$DEB_MAJ_VER" -eq 12 ]; then + PACKAGE_VERSION="1.5.2-6" + elif [ "$DEB_MAJ_VER" -eq 13 ]; then + PACKAGE_VERSION="1.7.0-5" + fi + cat </dev/null; then - debug "Service $SERVICE is enabled" + + if $SUDO_CMD systemctl -t "$SYSTEMD_OBJECT_TYPE" "$SYSTEMD_ACTION" "$SYSTEMD_OBJECT" >/dev/null; then FNRET=0 else - debug "Service $SERVICE is disabled" FNRET=1 fi + +} + +is_service_enabled() { + local SERVICE=$1 + + systemd_is_active_or_enabled "$SERVICE" 'service' 'is-enabled' + + if [ "$FNRET" -eq 0 ]; then + debug "Service $SERVICE is enabled" + else + debug "Service $SERVICE is not enabled" + fi + +} + +is_service_active() { + local SERVICE=$1 + + systemd_is_active_or_enabled "$SERVICE" 'service' 'is-active' + + if [ "$FNRET" -eq 0 ]; then + debug "Service $SERVICE is active" + else + debug "Service $SERVICE is not active" + fi } is_socket_enabled() { local SOCKET=$1 - # if running in a container, it does not make much sense to test for systemd / service - # the var "IS_CONTAINER" defined in lib/constant may not be enough, in case we are using systemd slices - # currently, did not find a unified way to manage all cases, so we check this only for systemctl usage - is_systemctl_running - if [ "$FNRET" -eq 1 ]; then - debug "host was not started using '/sbin/init', systemd should not be available" - FNRET=1 - return - fi - if $SUDO_CMD systemctl -t socket is-enabled "$SOCKET" >/dev/null; then + systemd_is_active_or_enabled "$SOCKET" 'socket' 'is-enabled' + + if [ "$FNRET" -eq 0 ]; then debug "Socket $SOCKET is enabled" - FNRET=0 else - debug "Socket $SOCKET is disabled" - FNRET=1 + debug "Socket $SOCKET is not enabled" + fi + +} + +is_socket_active() { + local SOCKET=$1 + + systemd_is_active_or_enabled "$SOCKET" 'socket' 'is-active' + + if [ "$FNRET" -eq 0 ]; then + debug "Socket $SOCKET is active" + else + debug "Socket $SOCKET is not active" + fi +} + +is_timer_active() { + local TIMER=$1 + + systemd_is_active_or_enabled "$TIMER" 'timer' 'is-active' + + if [ "$FNRET" -eq 0 ]; then + debug "Timer $TIMER is active" + else + debug "Timer $TIMER is not active" fi } diff --git a/tests/hardening/iptables_persistent_is_not_installed.sh b/tests/hardening/iptables_persistent_is_not_installed.sh new file mode 100644 index 0000000..211ad92 --- /dev/null +++ b/tests/hardening/iptables_persistent_is_not_installed.sh @@ -0,0 +1,23 @@ +# shellcheck shell=bash +# run-shellcheck +test_audit() { + describe set up successful check + apt remove -y ufw iptables-persistent + + describe Running success test + register_test retvalshouldbe 0 + # shellcheck disable=2154 + run failure "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + describe set up failed check + DEBIAN_FRONTEND='noninteractive' apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install iptables-persistent apt-utils -y + + describe running failed check + register_test retvalshouldbe 1 + # shellcheck disable=2154 + run success "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + apt remove -y iptables-persistent + apt autoremove -y + +} diff --git a/tests/hardening/libpam_runtime_is_version.sh b/tests/hardening/libpam_runtime_is_version.sh new file mode 100644 index 0000000..8b7f20c --- /dev/null +++ b/tests/hardening/libpam_runtime_is_version.sh @@ -0,0 +1,10 @@ +# shellcheck shell=bash +# run-shellcheck +test_audit() { + # at the time of writing, there is only one version of libpam-runtime available + describe Checking on blank host + register_test retvalshouldbe 0 + # shellcheck disable=2154 + run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + +} diff --git a/tests/hardening/nftables_not_installed_with_iptables.sh b/tests/hardening/nftables_not_installed_with_iptables.sh new file mode 100644 index 0000000..008256d --- /dev/null +++ b/tests/hardening/nftables_not_installed_with_iptables.sh @@ -0,0 +1,24 @@ +# shellcheck shell=bash +# run-shellcheck +test_audit() { + describe set up successful check + apt remove -y nftables + apt install -y iptables + + describe Running success test + register_test retvalshouldbe 0 + # shellcheck disable=2154 + run success "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + describe set up failed check + DEBIAN_FRONTEND='noninteractive' apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install nftables apt-utils -y + + describe running failed check + register_test retvalshouldbe 1 + # shellcheck disable=2154 + run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + apt remove -y nftables iptables + apt autoremove -y + +} diff --git a/tests/hardening/ufw_is_enabled.sh b/tests/hardening/ufw_is_enabled.sh new file mode 100644 index 0000000..c2dc702 --- /dev/null +++ b/tests/hardening/ufw_is_enabled.sh @@ -0,0 +1,11 @@ +# shellcheck shell=bash +# run-shellcheck +test_audit() { + + # not much to test here, we are running in a container, we wont check service state + describe Checking blank host + register_test retvalshouldbe 1 + # shellcheck disable=2154 + run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + +} diff --git a/tests/hardening/ufw_is_installed.sh b/tests/hardening/ufw_is_installed.sh new file mode 100644 index 0000000..83c86fb --- /dev/null +++ b/tests/hardening/ufw_is_installed.sh @@ -0,0 +1,39 @@ +# shellcheck shell=bash +# run-shellcheck +test_audit() { + describe set up failed check + apt remove -y ufw iptables-persistent + + describe Running failed test + register_test retvalshouldbe 1 + # shellcheck disable=2154 + run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + describe set up failed resolution + DEBIAN_FRONTEND='noninteractive' apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install iptables-persistent apt-utils -y + sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg" + + describe running failed resolution + # shellcheck disable=2154 + "${CIS_CHECKS_DIR}/${script}.sh" --apply || true + + describe running failed run after apply + register_test retvalshouldbe 1 + # shellcheck disable=2154 + run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + describe fix resolution + apt remove -y iptables-persistent + + describe running successfull resolution + # shellcheck disable=2154 + "${CIS_CHECKS_DIR}/${script}.sh" --apply || true + + describe running successfull audit + register_test retvalshouldbe 0 + # shellcheck disable=2154 + run success "${CIS_CHECKS_DIR}/${script}.sh" --audit-all + + apt remove -y ufw + apt autoremove -y +}