feat: add debian12 scripts

- nftables_is_enabled.sh 	-> 4.2.9
- nftables_has_table.sh 	-> 4.2.4
- nftables_has_base_chains.sh 	-> 4.2.5
- nftables_rules_permanent.sh	-> 4.2.10
This commit is contained in:
damien cavagnini
2025-08-01 16:20:58 +02:00
parent 0cf11ca4cf
commit dfd3773129
9 changed files with 419 additions and 1 deletions

View File

@@ -0,0 +1,94 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure nftables base chains exist (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 nftables base chains exist"
# This function will be called if the script status is on enabled / audit mode
audit() {
INPUT_CHAIN=1
OUTPUT_CHAIN=1
FORWARD_CHAIN=1
if $SUDO_CMD nft list ruleset 2>/dev/null | grep 'hook input'; then
INPUT_CHAIN=0
ok "nft base input chain exist"
else
crit "nft base input chain does not exist"
fi
if $SUDO_CMD nft list ruleset 2>/dev/null | grep 'hook output'; then
OUTPUT_CHAIN=0
ok "nft base output chain exist"
else
crit "nft base output chain does not exist"
fi
if $SUDO_CMD nft list ruleset 2>/dev/null | grep 'hook forward'; then
FORWARD_CHAIN=0
ok "nft base forward chain exist"
else
crit "nft base forward chain does not exist"
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
if [ "$INPUT_CHAIN" -eq 1 ]; then
info "adding nft base input chain"
# shellcheck disable=1083
nft create chain inet filter input { type filter hook input priority 0 \; }
fi
if [ "$OUTPUT_CHAIN" -eq 1 ]; then
info "adding nft base output chain"
# shellcheck disable=1083
nft create chain inet filter output { type filter hook output priority 0 \; }
fi
if [ "$FORWARD_CHAIN" -eq 1 ]; then
info "adding nft base forward chain"
# shellcheck disable=1083
nft create chain inet filter forward { type filter hook forward priority 0 \; }
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,67 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure a nftables table exists (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 a nftables table exists"
# This function will be called if the script status is on enabled / audit mode
audit() {
NFTABLES_HAS_TABLES=0
local tables
tables=$($SUDO_CMD nft list tables 2>/dev/null | wc -l)
if [ "$tables" -eq 0 ]; then
crit "There are no nft tables"
NFTABLES_HAS_TABLES=1
else
ok "There are $tables nft tables"
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
if [ "$NFTABLES_HAS_TABLES" -eq 1 ]; then
info "Adding 'filter' nft table"
nft create table inet filter
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,68 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure nftables service is enabled (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 nftables service is enabled"
SERVICE="nftables.service"
# This function will be called if the script status is on enabled / audit mode
audit() {
SERVICE_ENABLED=1
is_service_enabled "$SERVICE"
if [ "$FNRET" -eq 0 ]; then
ok "$SERVICE is enabled"
SERVICE_ENABLED=0
else
crit "$SERVICE is not enabled"
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
}
# 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,111 @@
#!/bin/bash
# run-shellcheck
#
# CIS Debian Hardening
#
#
# Ensure nftables rules are permanent (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 nftables rules are permanent"
NFTABLES_CONF="/etc/nftables.conf"
# default to "/etc/nftables.rules"
# May be changed in config, see "create_config" below
NFTABLES_RULES=""
# This function will be called if the script status is on enabled / audit mode
audit() {
NFTABLES_INCLUDE=1
NFTABLES_INCLUDE_INPUT=1
NFTABLES_INCLUDE_OUTPUT=1
NFTABLES_INCLUDE_FORWARD=1
# the CIS recommendation is to have one or many nftables rules outside nftables.conf
if grep -E '^\s*include' "$NFTABLES_CONF" >/dev/null; then
NFTABLES_INCLUDE=0
ok "There is an included file in $NFTABLES_CONF"
# shellcheck disable=2046
if [ $(awk '/hook input/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' $NFTABLES_CONF) | wc -l) -gt 0 ]; then
NFTABLES_INCLUDE_INPUT=0
ok "nftables input is configured to be persistent"
else
crit "nftables input is not configured to be persistent"
fi
# shellcheck disable=2046
if [ $(awk '/hook forward/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' $NFTABLES_CONF) | wc -l) -gt 0 ]; then
NFTABLES_INCLUDE_FORWARD=0
ok "nftables forward is configured to be persistent"
else
crit "nftables forward is not configured to be persistent"
fi
# shellcheck disable=2046
if [ $(awk '/hook output/,/}/' $(awk '$1 ~ /^\s*include/ { gsub("\"","",$2);print $2 }' $NFTABLES_CONF) | wc -l) -gt 0 ]; then
NFTABLES_INCLUDE_OUTPUT=0
ok "nftables output is configured to be persistent"
else
crit "nftables output is not configured to be persistent"
fi
else
crit "There is no 'include' in $NFTABLES_CONF"
fi
}
# This function will be called if the script status is on enabled mode
apply() {
audit
if [ "$NFTABLES_INCLUDE" -ne 0 ]; then
add_end_of_file "$NFTABLES_CONF" "include \"$NFTABLES_RULES\""
fi
if [ "$NFTABLES_INCLUDE_INPUT" -ne 0 ] || [ "$NFTABLES_INCLUDE_FORWARD" -ne 0 ] || [ "$NFTABLES_INCLUDE_OUTPUT" -ne 0 ]; then
info "some basic chains are not persisted in $NFTABLES_RULES, please review them manually"
fi
}
create_config() {
cat <<EOF
# shellcheck disable=2034
status=audit
# Put here the nftables rules file for persistent rules
NFTABLES_RULES="/etc/nftables.rules"
EOF
}
# 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/sbin/nft list *
cisharden ALL = (root) NOPASSWD: SCL_CMD cisharden ALL = (root) NOPASSWD: SCL_CMD

View File

@@ -0,0 +1,15 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Prepare test
apt install -y nftables
# running on a non privilieged container, wont test much...
describe Running on blank host
register_test retvalshouldbe 1
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe clean test
apt remove -y nftables
}

View File

@@ -0,0 +1,16 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Prepare test
apt install -y nftables
# running on a non privilieged container, wont test much...
describe Running on blank host
register_test retvalshouldbe 1
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe clean test
apt remove -y nftables
}

View File

@@ -0,0 +1,10 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Running on blank host
register_test retvalshouldbe 0
dismiss_count_for_test
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
}

View File

@@ -0,0 +1,36 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe prepare failing test
rm -f /etc/nftables.conf
touch /etc/nftables.conf
touch /etc/nftables.rules
describe Running failed 'missing include'
register_test retvalshouldbe 1
# shellcheck disable=2154
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Fixing first situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
# the 'include' part is fixed, but configuration is missing
# this has to be fixed manually, so for now, sill a failing test
describe Running failed 'missing basic chains'
register_test retvalshouldbe 1
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Fixing final situation
echo 'hook input' >/etc/nftables.rules
echo 'hook output' >>/etc/nftables.rules
echo 'hook forward' >>/etc/nftables.rules
describe Running success
register_test retvalshouldbe 0
run failed "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe clean test
rm -f /etc/nftables.conf /etc/nftables.rules
}