feat: add debian12 scripts

- auditd_logs_full_halt.sh			-> 6.3.2.3
- systemd_journal_upload_remote_auth.sh		-> 6.2.1.2.2
- sudo_auth_timeout.sh 				-> 5.2.6
- libpam_modules_is_installed.sh 		-> 5.3.1.2
- ufw_not_installed_with_nftables.sh 		-> 4.2.2
- ufw_not_installed_with_iptables.sh 		-> 4.3.1.3
This commit is contained in:
damien cavagnini
2025-08-01 09:49:21 +02:00
parent ffab7bcb3e
commit c22ce20f9d
13 changed files with 614 additions and 1 deletions

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure system is disabled when audit logs are full (Automated)
#
set -e # One error, it's over
set -u # One variable unset, it's over
# shellcheck disable=2034
HARDENING_LEVEL=4
# shellcheck disable=2034
DESCRIPTION="Ensure system is disabled when audit logs are full"
AUDIT_CONF="/etc/audit/auditd.conf"
# This function will be called if the script status is on enabled / audit mode
# shellcheck disable=2120
audit() {
local disk_full_action=""
local disk_error_action=""
DISK_FULL_ACTION_IS_VALID=0
DISK_ERROR_ACTION_IS_VALID=0
# shellcheck disable=2016
# otherwise $2 will interpreted in awk, this is not what is intended
disk_full_action=$($SUDO_CMD awk -F '=' '/^[[:space:]]?disk_full_action/ {print $2}' "$AUDIT_CONF" | sed 's/\ //g')
# shellcheck disable=2016
disk_error_action=$($SUDO_CMD awk -F '=' '/^[[:space:]]?disk_error_action/ {print $2}' "$AUDIT_CONF" | sed 's/\ //g')
if [ "$disk_full_action" != "halt" ] && [ "$disk_full_action" != 'single' ]; then
DISK_FULL_ACTION_IS_VALID=1
crit "'disk_full_action' is not configured to 'halt' or 'single'"
warn "The recommendation is to stop the system when the logs disk is full. Make sure to understand the consequences before applying it"
else
ok "'disk_full_action' is configured to 'halt' or 'single'"
fi
if [ "$disk_error_action" != "halt" ] && [ "$disk_error_action" != 'single' ] && [ "$disk_error_action" != 'syslog' ]; then
DISK_ERROR_ACTION_IS_VALID=1
crit "'disk_error_action' is not configured to 'syslog', 'halt' or 'single'"
warn "The recommendation is to stop the system when there are errors on the logs disk. Make sure to understand the consequences before applying it"
else
ok "'disk_error_action' is configured to 'syslog', 'halt' or 'single'"
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
if [ "$DISK_FULL_ACTION_IS_VALID" -eq 1 ]; then
replace_in_file "$AUDIT_CONF" "^[[:space:]]\?disk_full_action" "disk_full_action = halt"
fi
if [ "$DISK_ERROR_ACTION_IS_VALID" -eq 1 ]; then
replace_in_file "$AUDIT_CONF" "^[[:space:]]\?disk_error_action" "disk_error_action = halt"
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

View File

@@ -0,0 +1,64 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure libpam-modules 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 libpam-modules is installed"
PACKAGE='libpam-modules'
# This function will be called if the script status is on enabled / audit mode
audit() {
is_pkg_installed "$PACKAGE"
if [ "$FNRET" -eq 0 ]; then
ok "$PACKAGE is installed"
else
crit "$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
info "Installing $PACKAGE"
apt_install "$PACKAGE"
fi
audit
}
# 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

View File

@@ -0,0 +1,93 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure sudo authentication timeout is configured correctly (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 sudo authentication timeout is configured correctly"
TIMEOUT_VALUE=15
# This function will be called if the script status is on enabled / audit mode
# shellcheck disable=2120
audit() {
SUDO_TIMEOUT_IS_VALID=0
local timestamp_timeout
local sudo_files
sudo_files="/etc/sudoers $(find /etc/sudoers.d -type f ! -name README | paste -s)"
# shellcheck disable=2016
# shellcheck disable=2086
timestamp_timeout=$($SUDO_CMD awk -F '=' '/timestamp_timeout/ {print $2}' $sudo_files)
if [ "$(wc -l <<<"$timestamp_timeout")" -eq 0 ]; then
# look for the default
# shellcheck disable=2016
timestamp_timeout=$(sudo -V | awk -F ':' '/Authentication timestamp timeout/ {print $2}' | sed -e 's/\..*$//' -e 's/\ //g')
if [ "$timestamp_timeout" -le "$TIMEOUT_VALUE" ]; then
ok "sudo timestamp timeout is $timestamp_timeout"
else
crit "sudo timestamp timeout is $timestamp_timeout"
SUDO_TIMEOUT_IS_VALID=1
fi
else
for timeout in $timestamp_timeout; do
if [ "$timeout" -le "$TIMEOUT_VALUE" ]; then
ok "sudo timestamp timeout is $timeout"
else
crit "sudo timestamp timeout is $timeout"
SUDO_TIMEOUT_IS_VALID=1
fi
done
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
if [ "$SUDO_TIMEOUT_IS_VALID" -ne 0 ]; then
sudo_files="/etc/sudoers $(find /etc/sudoers.d -type f ! -name README | paste -s)"
for file in $sudo_files; do
delete_line_in_file "$file" "timestamp_timeout"
done
add_end_of_file /etc/sudoers "Defaults timestamp_timeout=$TIMEOUT_VALUE"
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

View File

@@ -0,0 +1,63 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure systemd-journal-remote authentication is configured (Manual)
#
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 systemd-journal-remote authentication is configured"
JOURNAL_CONF="/etc/systemd/journal-upload.conf"
# This function will be called if the script status is on enabled / audit mode
# shellcheck disable=2120
audit() {
local conf_lines
# We are looking for URL, ServerKeyFile, ServerCertificateFile, TrustedCertificateFile
# shellcheck disable=2126
conf_lines=$(grep -P "^ *URL=|^ *ServerKeyFile=|^ *ServerCertificateFile=|^ *TrustedCertificateFile=" "$JOURNAL_CONF" | wc -l)
if [ "$conf_lines" -eq 4 ]; then
ok "remote authentication is configured, review it manually to ensure it is the expected one"
else
crit "remote authentication is not configured. Either configure it, or disable this recommendation if not needed."
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
}
# 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

View File

@@ -0,0 +1,75 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure ufw is uninstalled or disabled 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 ufw is uninstalled or disabled with iptables"
PACKAGE='ufw'
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

View File

@@ -0,0 +1,76 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure ufw is uninstalled or disabled with iptables (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 ufw is uninstalled or disabled with iptables"
PACKAGE='ufw'
CONFLICT_PACKAGE='nftables'
# 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

View File

@@ -24,6 +24,7 @@ Cmnd_Alias SCL_CMD = /bin/grep ,\
/sbin/lsmod,\ /sbin/lsmod,\
/sbin/modprobe,\ /sbin/modprobe,\
/usr/sbin/modprobe -n -v*,\ /usr/sbin/modprobe -n -v*,\
/usr/sbin/apparmor_status /usr/sbin/apparmor_status,\
/usr/bin/awk *
cisharden ALL = (root) NOPASSWD: SCL_CMD cisharden ALL = (root) NOPASSWD: SCL_CMD

View File

@@ -0,0 +1,46 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe prepare failing test disk_full
apt install -y auditd
sed -i -e '/disk_full_action/d' -e '/disk_error_action/d' /etc/audit/auditd.conf
echo "disk_full_action = SUSPEND" >>/etc/audit/auditd.conf
echo "disk_error_action = halt" >>/etc/audit/auditd.conf
describe Running failed 'disk_full_action'
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correcting situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
# shellcheck disable=2154
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved state
register_test retvalshouldbe 0
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe prepare failing test disk_error
apt install -y auditd
sed -i -e '/disk_full_action/d' -e '/disk_error_action/d' /etc/audit/auditd.conf
echo "disk_full_action = halt" >>/etc/audit/auditd.conf
echo "disk_error_action = suspend" >>/etc/audit/auditd.conf
describe Running failed 'disk_error_action'
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correcting situation
# shellcheck disable=2154
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved state
register_test retvalshouldbe 0
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
apt purge -y auditd
apt autoremove -y
}

View File

@@ -0,0 +1,10 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
# it should be installed by default
describe Checking blank host
register_test retvalshouldbe 0
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
}

View File

@@ -0,0 +1,27 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe prepare test
echo "Defaults timestamp_timeout=15" >/etc/sudoers.d/test_1
echo "Defaults timestamp_timeout=20" >/etc/sudoers.d/test_2
# by default authentication should not be configured
describe Running failed
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Fix the situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
# by default authentication should not be configured
describe Running resolved
register_test retvalshouldbe 0
# shellcheck disable=2154
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe clean test
rm -f /etc/sudoers.d/test_1 /etc/sudoers.d/test_2
}

View File

@@ -0,0 +1,27 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe prepare test
apt install systemd-journal-remote -y
# by default authentication should not be configured
describe Running failed
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Fix situation
for i in "URL" "ServerKeyFile" "ServerCertificateFile" "TrustedCertificateFile"; do
echo "$i=" >>/etc/systemd/journal-upload.conf
done
describe Running resolved
register_test retvalshouldbe 0
# shellcheck disable=2154
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe clean test
apt purge systemd-journal-remote -y
apt autoremove -y
}

View File

@@ -0,0 +1,21 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Prepare test
apt install -y nftables ufw
describe Checking failed
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe fix situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved
register_test retvalshouldbe 0
# shellcheck disable=2154
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
}

View File

@@ -0,0 +1,21 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Prepare test
apt install -y nftables ufw
describe Checking failed
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe fix situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved
register_test retvalshouldbe 0
# shellcheck disable=2154
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
}