From c2598e484e8375daf24cd651f4093a3d28cfc8cf Mon Sep 17 00:00:00 2001 From: damien cavagnini Date: Mon, 28 Jul 2025 14:47:41 +0200 Subject: [PATCH] feat: add debian12 scripts ufw_is_installed.sh -> 4.1.1 iptables_persistent_is_not_installed.sh -> 4.1.2 ufw_is_enabled -> 4.1.3 nftables_is_not_installed.sh -> 4.3.1.2 libpam_runtime_is_version -> 5.3.1.1 --- .../iptables_persistent_is_not_installed.sh | 65 +++++++++++++ bin/hardening/libpam_runtime_is_version.sh | 78 +++++++++++++++ .../nftables_not_installed_with_iptables.sh | 75 ++++++++++++++ bin/hardening/ufw_is_enabled.sh | 97 +++++++++++++++++++ bin/hardening/ufw_is_installed.sh | 73 ++++++++++++++ .../iptables_persistent_is_not_installed.sh | 23 +++++ tests/hardening/libpam_runtime_is_version.sh | 10 ++ .../nftables_not_installed_with_iptables.sh | 23 +++++ tests/hardening/ufw_is_enabled.sh | 11 +++ tests/hardening/ufw_is_installed.sh | 39 ++++++++ 10 files changed, 494 insertions(+) create mode 100755 bin/hardening/iptables_persistent_is_not_installed.sh create mode 100755 bin/hardening/libpam_runtime_is_version.sh create mode 100755 bin/hardening/nftables_not_installed_with_iptables.sh create mode 100755 bin/hardening/ufw_is_enabled.sh create mode 100755 bin/hardening/ufw_is_installed.sh create mode 100644 tests/hardening/iptables_persistent_is_not_installed.sh create mode 100644 tests/hardening/libpam_runtime_is_version.sh create mode 100644 tests/hardening/nftables_not_installed_with_iptables.sh create mode 100644 tests/hardening/ufw_is_enabled.sh create mode 100644 tests/hardening/ufw_is_installed.sh 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..6a9a3c0 --- /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" -ne 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..0196595 --- /dev/null +++ b/bin/hardening/libpam_runtime_is_version.sh @@ -0,0 +1,78 @@ +#!/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 + + # 1.5.2-6+deb12u1 -> 1.5.2-6 + version=$(dpkg-query -s "$PACKAGE" | awk '/Version/ {print $2}' | sed 's/+.*$//') + if [[ "$version" > "$MIN_VERSION" ]] || [[ "$version" == "$MIN_VERSION" ]]; then + ok "$PACKAGE is $version" + else + crit "$PACKAGE is $version" + PACKAGE_IS_VERSION=1 + fi +} + +# This function will be called if the script status is on enabled mode +apply() { + audit + if [ "$PACKAGE_IS_VERSION" -eq 1 ]; then + apt upgrade -y libpam-runtime + fi +} + +create_config() { + if [ "$DEB_MAJ_VER" -eq 12 ]; then + cat <:: +MIN_VERSION="1.5.2-6" +EOF + 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/nftables_not_installed_with_iptables.sh b/bin/hardening/nftables_not_installed_with_iptables.sh new file mode 100755 index 0000000..ef6e8b0 --- /dev/null +++ b/bin/hardening/nftables_not_installed_with_iptables.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# run-shellcheck +# +# CIS Debian Hardening +# + +# +# Ensure nftables is not installed with iptables (Automated) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +# shellcheck disable=2034 +HARDENING_LEVEL=2 +DESCRIPTION="Ensure nftables is not installed with iptables" +PACKAGE='nftables' +CONFLICT_PACKAGE='iptables' + +# This function will be called if the script status is on enabled / audit mode +audit() { + PACKAGE_INSTALLED=1 + CONFLICT_PACKAGE_INSTALLED=1 + + is_pkg_installed "$PACKAGE" + if [ "$FNRET" -eq 0 ]; then + PACKAGE_INSTALLED=0 + fi + + is_pkg_installed "$CONFLICT_PACKAGE" + if [ "$FNRET" -eq 0 ]; then + CONFLICT_PACKAGE_INSTALLED=0 + fi + + if [ "$PACKAGE_INSTALLED" -eq 0 ] && [ "$CONFLICT_PACKAGE_INSTALLED" -eq 0 ]; then + crit "'$PACKAGE' is installed with '$CONFLICT_PACKAGE'" + else + ok "'$PACKAGE' is not installed with '$CONFLICT_PACKAGE'" + fi +} + +# This function will be called if the script status is on enabled mode +apply() { + audit + if [ "$PACKAGE_INSTALLED" -eq 0 ] && [ "$CONFLICT_PACKAGE_INSTALLED" -eq 0 ]; then + info "Trying to remove $PACKAGE" + DEBIAN_FRONTEND='noninteractive' apt remove "$PACKAGE" -y + 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/ufw_is_enabled.sh b/bin/hardening/ufw_is_enabled.sh new file mode 100755 index 0000000..22a3494 --- /dev/null +++ b/bin/hardening/ufw_is_enabled.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +# run-shellcheck +# +# CIS Debian Hardening +# + +# +# Ensure ufw service is enabled (Automated) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +# shellcheck disable=2034 +HARDENING_LEVEL=3 +# shellcheck disable=2034 +DESCRIPTION="Ensure ufw service is enabled (Automated)" +SERVICE="ufw.service" +CREATE_SSH_RULE="" +SSH_RULE="allow proto tcp from any to any port 22" + +# This function will be called if the script status is on enabled / audit mode +audit() { + SERVICE_ENABLED=1 + SERVICE_ACTIVE=1 + + is_service_enabled "$SERVICE" + if [ "$FNRET" -eq 0 ]; then + ok "$SERVICE is enabled" + SERVICE_ENABLED=0 + else + crit "$SERVICE is not enabled" + fi + + is_service_active "$SERVICE" + if [ "$FNRET" -eq 0 ]; then + ok "$SERVICE is active" + SERVICE_ACTIVE=0 + else + crit "$SERVICE is not active" + fi +} + +# This function will be called if the script status is on enabled mode +apply() { + audit + if [ "$SERVICE_ENABLED" -ne 0 ]; then + manage_service unmask "$SERVICE" + manage_service enable "$SERVICE" + fi + + if [ "$SERVICE_ACTIVE" -ne 0 ]; then + # When running ufw enable or starting ufw via its initscript, ufw will flush its chains. + # This is required so ufw can maintain a consistent state, but it may drop existing + # connections (eg ssh). ufw does support adding rules before enabling the firewall. + if [[ "$CREATE_SSH_RULE" == "true" ]]; then + info "we are going to modify ufw rules to ensure ssh stays allowed" + ufw "$SSH_RULE" + fi + manage_service start "$SERVICE" + fi + +} + +create_config() { + cat <