mirror of
https://github.com/ovh/debian-cis.git
synced 2024-11-22 05:27:01 +01:00
Migrate generic checks from secaudit to cis-hardening
new file: 99.3.1_acc_shadow_sha512.sh new file: 99.3.2_acc_sudoers_no_all.sh new file: 99.4_net_fw_default_policy_drop.sh new file: 99.5.1_ssh_auth_pubk_only.sh new file: 99.5.2.1_ssh_cry_kex.sh new file: 99.5.2.2_ssh_cry_mac.sh new file: 99.5.2.3_ssh_cry_rekey.sh new file: 99.5.3_ssh_disable_features.sh new file: 99.5.4_ssh_keys_from.sh new file: 99.5.5_ssh_strict_modes.sh new file: 99.5.6_ssh_sys_accept_env.sh new file: 99.5.7_ssh_sys_no_legacy.sh new file: 99.5.8_ssh_sys_sandbox.sh new file: 99.5.9_ssh_log_level.sh Fix descriptions in comment section for 99.* secaudit checks Remove duplicated legacy services that are already taken care of by vanilla cis Enable custom configuration of checks in config-file, no more hard coded conf Add test to disable check if debian version is too old Add excused IPs while checking "from" field of authorized_keys Escaping dots in IPs Manage Kex for different debian versions Add tests for generic checks and add apply for ssh config Apply shellcheck recommendations on audit/hardening scripts Update script to check for allowed IPs only, remove bastion related Fill `apply` func for ssh config related scripts Add and update tests scenarii Disable shellcheck test for external source 1091 As of today, the entire project is not shellcheck compliant, I prefer disabling the test that warns about not finding external source (that arent compliant). I will enable it again when the project library will be shellchecked https://github.com/koalaman/shellcheck/wiki/SC1091 Refactor password policy check with one check by feature Previous file will now only look for bad passwords in /etc/shadow I added two checks that look for the compliant configuration lines in conf files /etc/logins.defs and /etc/pam.d/common-passwords FIX: merge chained sed and fix regex FIX: update regex to capture more output FIX: fix pattern to ignore commented lines, add apply Also add tests to ensure that commented lines are not detected as valid configuration CHORE: cleanup test situation with file and users removal IMP: add case insensitive option when looking for patterns in files CHORE: removed duplicated line in test file
This commit is contained in:
parent
ba93159a00
commit
810fee4c8f
79
bin/hardening/99.3.1_acc_shadow_sha512.sh
Executable file
79
bin/hardening/99.3.1_acc_shadow_sha512.sh
Executable file
@ -0,0 +1,79 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check that any password that may exist in /etc/shadow is SHA512 hashed and salted
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Check that any password that may exist in /etc/shadow is SHA512 hashed and salted"
|
||||||
|
FILE="/etc/shadow"
|
||||||
|
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
# Review shadow file for existing passwords
|
||||||
|
pw_found=""
|
||||||
|
users_reviewed=""
|
||||||
|
if $SUDO_CMD [ ! -r "$FILE" ]; then
|
||||||
|
crit "$FILE is not readable"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
for line in $($SUDO_CMD cut -d ":" -f 1,2 /etc/shadow); do
|
||||||
|
users_reviewed+="$line "
|
||||||
|
user=$(echo "$line" | cut -d ":" -f 1)
|
||||||
|
passwd=$(echo "$line" | cut -d ":" -f 2)
|
||||||
|
if [[ $passwd = '!' || $passwd = '*' ]]; then
|
||||||
|
continue
|
||||||
|
# Check password against $6$<salt>$<encrypted>, see `man 3 crypt`
|
||||||
|
elif [[ $passwd =~ ^\$6\$[a-zA-Z0-9./]{2,16}\$[a-zA-Z0-9./]{86}$ ]]; then
|
||||||
|
pw_found+="$user "
|
||||||
|
ok "User $user has suitable SHA512 hashed password."
|
||||||
|
else
|
||||||
|
pw_found+="$user "
|
||||||
|
crit "User $user has a password that is not SHA512 hashed."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -z "$users_reviewed" ]]; then
|
||||||
|
crit "No users were reviewed in $FILE !"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ -z "$pw_found" ]]; then
|
||||||
|
ok "There is no password in $FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
99
bin/hardening/99.3.2_acc_sudoers_no_all.sh
Executable file
99
bin/hardening/99.3.2_acc_sudoers_no_all.sh
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checks there are no carte-blanche authorization in sudoers file(s).
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Checks there are no carte-blanche authorization in sudoers file(s)."
|
||||||
|
|
||||||
|
FILE="/etc/sudoers"
|
||||||
|
DIRECTORY="/etc/sudoers.d"
|
||||||
|
# spaces will be expanded to [:space:]* when using the regex
|
||||||
|
# improves readability in audit report
|
||||||
|
REGEX="ALL = \( ALL( : ALL)? \)( NOPASSWD:)? ALL"
|
||||||
|
EXCEPT=""
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
FILES=""
|
||||||
|
if $SUDO_CMD [ ! -r "$FILE" ]; then
|
||||||
|
crit "$FILE is not readable"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
FILES="$FILE"
|
||||||
|
if $SUDO_CMD [ ! -d "$DIRECTORY" ]; then
|
||||||
|
debug "$DIRECTORY does not exist"
|
||||||
|
elif $SUDO_CMD [ ! -x "$DIRECTORY" ]; then
|
||||||
|
crit "Cannot browse $DIRECTORY"
|
||||||
|
else
|
||||||
|
FILES="$FILES $($SUDO_CMD ls -1 $DIRECTORY | sed s=^=$DIRECTORY/= )"
|
||||||
|
fi
|
||||||
|
for file in $FILES; do
|
||||||
|
if $SUDO_CMD [ ! -r "$file" ]; then
|
||||||
|
crit "$file is not readable"
|
||||||
|
else
|
||||||
|
# shellcheck disable=2001
|
||||||
|
if ! $SUDO_CMD grep -E "$(echo "$REGEX" | sed 's/ /[[:space:]]*/g')" "$file" &> /dev/null ; then
|
||||||
|
ok "There is no carte-blanche sudo permission in $file"
|
||||||
|
else
|
||||||
|
# shellcheck disable=2001
|
||||||
|
RET=$($SUDO_CMD grep -E "$(echo "$REGEX" | sed 's/ /[[:space:]]*/g')" "$file" | sed 's/\t/#/g;s/ /#/g' )
|
||||||
|
for line in $RET; do
|
||||||
|
if grep -q "$(echo "$line" | cut -d '#' -f 1)" <<< "$EXCEPT" ; then
|
||||||
|
# shellcheck disable=2001
|
||||||
|
ok "$(echo "$line" | sed 's/#/ /g') is present in $file but was EXCUSED because $(echo "$line" | cut -d '#' -f 1) is part of exceptions."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# shellcheck disable=2001
|
||||||
|
crit "$(echo "$line" | sed 's/#/ /g') is present in $file"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will create the config file for this check with default values
|
||||||
|
create_config() {
|
||||||
|
cat <<EOF
|
||||||
|
status=disabled
|
||||||
|
# Put EXCEPTION account names here, space separated
|
||||||
|
EXCEPT="root %root %sudo %wheel"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
62
bin/hardening/99.3.3_acc_pam_sha512.sh
Executable file
62
bin/hardening/99.3.3_acc_pam_sha512.sh
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check that any password that may exist in /etc/shadow is SHA512 hashed and salted
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Check that any password that may exist in /etc/shadow is SHA512 hashed and salted"
|
||||||
|
|
||||||
|
CONF_FILE="/etc/pam.d/common-password"
|
||||||
|
CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*sha512"
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
# Check conf file for default SHA512 hash
|
||||||
|
if $SUDO_CMD [ ! -r $CONF_FILE ]; then
|
||||||
|
crit "$CONF_FILE is not readable"
|
||||||
|
else
|
||||||
|
does_pattern_exist_in_file $CONF_FILE "$(sed 's/ /[[:space:]]+/g' <<< "$CONF_LINE")"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$CONF_LINE is present in $CONF_FILE"
|
||||||
|
else
|
||||||
|
crit "$CONF_LINE is not present in $CONF_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
76
bin/hardening/99.3.4_acc_logindefs_sha512.sh
Executable file
76
bin/hardening/99.3.4_acc_logindefs_sha512.sh
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check that any password that may exist in /etc/shadow is SHA512 hashed and salted
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Check that any password that may exist in /etc/shadow is SHA512 hashed and salted"
|
||||||
|
|
||||||
|
CONF_FILE="/etc/login.defs"
|
||||||
|
CONF_LINE="ENCRYPT_METHOD SHA512"
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
# Check conf file for default SHA512 hash
|
||||||
|
if $SUDO_CMD [ ! -r $CONF_FILE ]; then
|
||||||
|
crit "$CONF_FILE is not readable"
|
||||||
|
else
|
||||||
|
does_pattern_exist_in_file $CONF_FILE "^ *${CONF_LINE/ /[[:space:]]+}"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$CONF_LINE is present in $CONF_FILE"
|
||||||
|
else
|
||||||
|
crit "$CONF_LINE is not present in $CONF_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
does_pattern_exist_in_file $CONF_FILE "^ *${CONF_LINE/ /[[:space:]]+}"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$CONF_LINE is present in $CONF_FILE"
|
||||||
|
else
|
||||||
|
warn "$CONF_LINE is not present in $CONF_FILE, adding it"
|
||||||
|
does_pattern_exist_in_file "$CONF_FILE" "^$(echo "$CONF_LINE" | cut -d ' ' -f1)"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $CONF_FILE "$CONF_LINE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file "$CONF_FILE" "^$(echo "$CONF_LINE" | cut -d ' ' -f1)[[:space:]]*.*" "$CONF_LINE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
78
bin/hardening/99.4_net_fw_default_policy_drop.sh
Executable file
78
bin/hardening/99.4_net_fw_default_policy_drop.sh
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check iptables firewall default policy for DROP on INPUT and FORWARD.
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Check iptables firewall default policy for DROP on INPUT and FORWARD."
|
||||||
|
|
||||||
|
PACKAGE="iptables"
|
||||||
|
FW_CHAINS="INPUT FORWARD"
|
||||||
|
FW_POLICY="DROP"
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ipt=$($SUDO_CMD $PACKAGE -nL || true )
|
||||||
|
if [[ -z $ipt ]]; then
|
||||||
|
crit "Empty return from $PACKAGE command. Aborting..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
for chain in $FW_CHAINS; do
|
||||||
|
regex="Chain $chain \(policy ([A-Z]+)\)"
|
||||||
|
# previous line will capture actual policy
|
||||||
|
if [[ $ipt =~ $regex ]]; then
|
||||||
|
actual_policy=${BASH_REMATCH[1]}
|
||||||
|
if [[ $actual_policy == "$FW_POLICY" ]]; then
|
||||||
|
ok "Policy correctly set to $FW_POLICY for chain $chain"
|
||||||
|
else
|
||||||
|
crit "Policy set to $actual_policy for chain $chain, should be ${FW_POLICY}."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "cant find chain $chain"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
97
bin/hardening/99.5.1_ssh_auth_pubk_only.sh
Executable file
97
bin/hardening/99.5.1_ssh_auth_pubk_only.sh
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ensure that sshd only allows authentication through public key.
|
||||||
|
#
|
||||||
|
|
||||||
|
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 that sshd only allows authentication through public key."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
OPTIONS='PubkeyAuthentication=yes PasswordAuthentication=no KbdInteractiveAuthentication=no KerberosAuthentication=no ChallengeResponseAuthentication=no HostbasedAuthentication=no GSSAPIAuthentication=no GSSAPIKeyExchange=no '
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]+$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]+$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]+.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
117
bin/hardening/99.5.2.1_ssh_cry_kex.sh
Executable file
117
bin/hardening/99.5.2.1_ssh_cry_kex.sh
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checking key exchange ciphers.
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Checking key exchange ciphers."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS=''
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
create_config() {
|
||||||
|
get_debian_major_version
|
||||||
|
set +u
|
||||||
|
debug "Debian version : $DEB_MAJ_VER "
|
||||||
|
if [[ -z $DEB_MAJ_VER ]] || [[ 7 -eq $DEB_MAJ_VER ]]; then
|
||||||
|
KEX='diffie-hellman-group-exchange-sha256'
|
||||||
|
elif [[ 8 -eq $DEB_MAJ_VER ]] || [[ 9 -eq $DEB_MAJ_VER ]]; then
|
||||||
|
KEX='curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256'
|
||||||
|
else
|
||||||
|
KEX='diffie-hellman-group-exchange-sha256'
|
||||||
|
fi
|
||||||
|
set -u
|
||||||
|
cat <<EOF
|
||||||
|
status=disabled
|
||||||
|
# Put your KexAlgorithms
|
||||||
|
OPTIONS="KexAlgorithms=$KEX"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
107
bin/hardening/99.5.2.2_ssh_cry_mac.sh
Executable file
107
bin/hardening/99.5.2.2_ssh_cry_mac.sh
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checking Message Authentication Code ciphers for preferred UMAC and SHA-256|512 with Encrypt-Then-Mac (etm) setting.
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Checking Message Authentication Code ciphers for preferred UMAC and SHA-256|512 with Encrypt-Then-Mac (etm) setting."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS=''
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will create the config file for this check with default values
|
||||||
|
create_config() {
|
||||||
|
cat <<EOF
|
||||||
|
status=disabled
|
||||||
|
# Put your MACs
|
||||||
|
OPTIONS="MACs=umac-128-etm@openssh.com,umac-64-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128@openssh.com,umac-64@openssh.com,hmac-sha2-512,hmac-sha2-256"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
113
bin/hardening/99.5.2.3_ssh_cry_rekey.sh
Executable file
113
bin/hardening/99.5.2.3_ssh_cry_rekey.sh
Executable file
@ -0,0 +1,113 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checking rekey limit for time (6 hours) or volume (512Mio) whichever comes first.
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Checking rekey limit for time (6 hours) or volume (512Mio) whichever comes first."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS='RekeyLimit=512M\s+6h'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
get_debian_major_version
|
||||||
|
set +u
|
||||||
|
debug "Debian version : $DEB_MAJ_VER "
|
||||||
|
if [[ -z $DEB_MAJ_VER ]]; then
|
||||||
|
set -u
|
||||||
|
crit "Cannot get Debian version. Aborting..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "${DEB_MAJ_VER}" -lt "8" ]]; then
|
||||||
|
set -u
|
||||||
|
warn "Debian version too old (${DEB_MAJ_VER}), check does not apply, you should disable this check."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
set -u
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
SSH_VALUE=$(sed 's/\\s+/ /' <<< "$SSH_VALUE")
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
96
bin/hardening/99.5.3_ssh_disable_features.sh
Executable file
96
bin/hardening/99.5.3_ssh_disable_features.sh
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check all special features in sshd_config are disabled
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Check all special features in sshd_config are disabled"
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
OPTIONS='AllowAgentForwarding=no AllowTcpForwarding=no AllowStreamLocalForwarding=no PermitTunnel=no PermitUserRC=no GatewayPorts=no'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
174
bin/hardening/99.5.4_ssh_keys_from.sh
Executable file
174
bin/hardening/99.5.4_ssh_keys_from.sh
Executable file
@ -0,0 +1,174 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check <from> field in ssh authorized keys files for users with login shell, and bastions IP if available.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it is over
|
||||||
|
set -u # One variable unset, it is over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Check <from> field in ssh authorized keys files for users with login shell, and allowed IP if available."
|
||||||
|
|
||||||
|
# Regex looking for empty, hash starting lines, or 'from="127.127.127,127.127.127" ssh'
|
||||||
|
# shellcheck disable=2089
|
||||||
|
REGEX="^(from=(?:'|\")(,?(\d{1,3}(\.\d{1,3}){3}))+(?:'|\")\s+ssh|#|$)"
|
||||||
|
AUTHKEYFILE_PATTERN=""
|
||||||
|
AUTHKEYFILE_PATTERN_DEFAULT=".ssh/authorized_keys .ssh/authorized_keys2"
|
||||||
|
|
||||||
|
ALLOWED_IPS=""
|
||||||
|
|
||||||
|
ALLOWED_NOLOGIN_SHELLS="/bin/false /usr/sbin/nologin"
|
||||||
|
|
||||||
|
# Check functions
|
||||||
|
check_ip() {
|
||||||
|
file=$1
|
||||||
|
if [ -z "$ALLOWED_IPS" ]; then
|
||||||
|
warn "No allowed IPs to treat";
|
||||||
|
return ;
|
||||||
|
fi
|
||||||
|
for line in $($SUDO_CMD grep -ne "from" "$file" | tr -s " " | sed 's/ /_/g' ); do
|
||||||
|
linum=$(echo "$line" | cut -d ':' -f 1)
|
||||||
|
ips=$(echo "$line" | cut -d '"' -f 2 | tr ',' ' ')
|
||||||
|
ok_ips_allowed=""
|
||||||
|
bad_ips=""
|
||||||
|
for ip in $ips; do
|
||||||
|
ip_escaped=$(sed 's/\./\\./g' <<< "$ip")
|
||||||
|
if grep -qw "$ip_escaped" <<< $ALLOWED_IPS ; then
|
||||||
|
debug "Line $linum of $file allows access from exused IP (${ip})."
|
||||||
|
ok_ips_allowed+="$ip "
|
||||||
|
else
|
||||||
|
debug "Line $linum of $file allows access from ip ($ip) that is not allowed."
|
||||||
|
bad_ips+="$ip "
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
ok_ips=$( sed 's/ $//' <<< "${ok_ips_allowed}")
|
||||||
|
bad_ips=$( sed 's/ $//' <<< "${bad_ips}")
|
||||||
|
if [[ -z $bad_ips ]]; then
|
||||||
|
if [[ ! -z $ok_ips ]]; then
|
||||||
|
ok "Line $linum of $file allows ssh access only from allowed IPs ($ok_ips)."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
crit "Line $linum of $file allows ssh access from (${bad_ips}) that are not allowed."
|
||||||
|
if [[ ! -z $ok_ips ]]; then
|
||||||
|
ok "Line $linum of $file allows ssh access from at least allowed IPs ($ok_ips)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
check_file() {
|
||||||
|
file=$1
|
||||||
|
if $SUDO_CMD [ ! -e "$file" ]; then debug "$file does not exist"; return; fi
|
||||||
|
if $SUDO_CMD [ -r "$file" ]; then
|
||||||
|
debug "Treating $file"
|
||||||
|
FOUND_AUTHKF=1
|
||||||
|
if $SUDO_CMD grep -vqP "$REGEX" "${file}" ; then
|
||||||
|
bad_lines="$(grep -vnP "$REGEX" "${file}" | cut -d ':' -f 1 | tr '\n' ' ' | sed 's/ $//' )"
|
||||||
|
crit "There are anywhere access keys in ${file} at lines (${bad_lines})."
|
||||||
|
else
|
||||||
|
ok "File ${file} is cleared from anywhere access keys."
|
||||||
|
check_ip "$file"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
crit "Cannot read ${file} for ${user}."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dir() {
|
||||||
|
directory=$1
|
||||||
|
if $SUDO_CMD [ ! -x "$directory" ]; then
|
||||||
|
crit "Cannot read ${directory}."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
for file in $AUTHKEYFILE_PATTERN; do
|
||||||
|
check_file "${directory}"/${file}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
# Retrieve authorized_key file pattern from sshd_config
|
||||||
|
if $SUDO_CMD [ ! -r /etc/ssh/sshd_config ]; then
|
||||||
|
crit "/etc/ssh/sshd_config is not readable."
|
||||||
|
else
|
||||||
|
ret=$($SUDO_CMD grep -iP "^AuthorizedKeysFile" /etc/ssh/sshd_config || echo '#KO' )
|
||||||
|
if [ "x$ret" = "x#KO" ]; then
|
||||||
|
debug "No AuthorizedKeysFile defined in sshd_config."
|
||||||
|
else
|
||||||
|
AUTHKEYFILE_PATTERN=$(echo "$ret" | sed 's/AuthorizedKeysFile//i' | sed 's#%h/##' | tr -s "[:space:]")
|
||||||
|
debug "Found pattern in sshdconfig : ${AUTHKEYFILE_PATTERN}."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$AUTHKEYFILE_PATTERN" ] ; then
|
||||||
|
AUTHKEYFILE_PATTERN=$AUTHKEYFILE_PATTERN_DEFAULT
|
||||||
|
debug "Set default pattern for authorized_keys file."
|
||||||
|
fi
|
||||||
|
|
||||||
|
for line in $($SUDO_CMD cat /etc/passwd | cut -d ":" -f 1,7); do
|
||||||
|
# Checking if at least one AuthKeyFile has been found for this user
|
||||||
|
FOUND_AUTHKF=0
|
||||||
|
user=$(echo "$line" | cut -d ":" -f 1);
|
||||||
|
shell=$(echo "$line" | cut -d ':' -f 2);
|
||||||
|
if grep -q "$shell" <<< "$ALLOWED_NOLOGIN_SHELLS" ; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
info "User $user has a valid shell.";
|
||||||
|
if [ "x$user" = "xroot" ]; then
|
||||||
|
check_dir /root
|
||||||
|
continue
|
||||||
|
elif $SUDO_CMD [ ! -d /home/"$user" ]; then
|
||||||
|
info "User $user has no home directory."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
check_dir /home/"${user}"
|
||||||
|
if [ $FOUND_AUTHKF = 0 ]; then
|
||||||
|
warn "$user has a valid shell but no authorized_keys file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
create_config() {
|
||||||
|
cat <<EOF
|
||||||
|
status=disabled
|
||||||
|
# Put authorized IPs you want to allow in "from" field of authorized_keys
|
||||||
|
ALLOWED_IPS=""
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
96
bin/hardening/99.5.5_ssh_strict_modes.sh
Executable file
96
bin/hardening/99.5.5_ssh_strict_modes.sh
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# OVH Security audit
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ensure home directory and ssh sensitive files are verified (not publicly readable) before connecting.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Ensure home directory and ssh sensitive files are verified (not publicly readable) before connecting."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS='StrictModes=yes'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
88
bin/hardening/99.5.6_ssh_sys_accept_env.sh
Executable file
88
bin/hardening/99.5.6_ssh_sys_accept_env.sh
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# 9Restrict which user's variables are accepted by ssh daemon
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Restrict which user's variables are accepted by ssh daemon"
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
PATTERN='^\s*AcceptEnv\s+LANG LC_\*'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$PATTERN"
|
||||||
|
PATTERN=$( sed 's/\^//' <<< "$PATTERN" | sed -r 's/\\s\*//' | sed -r 's/\\s\+/ /g' | sed 's/\\//g')
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$PATTERN"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$PATTERN"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
66
bin/hardening/99.5.7_ssh_sys_no_legacy.sh
Executable file
66
bin/hardening/99.5.7_ssh_sys_no_legacy.sh
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
# CIS Debian 7 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ensure that legacy services rlogin, rlogind and rcp are disabled and not installed
|
||||||
|
#
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="Ensure that legacy services rlogin, rlogind and rcp are disabled and not installed"
|
||||||
|
# shellcheck disable=2034
|
||||||
|
SERVICES="rlogin rlogind rcp"
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
for SERVICE in $SERVICES
|
||||||
|
do
|
||||||
|
info "Checking if $SERVICE is enabled and installed"
|
||||||
|
is_service_enabled "$SERVICE"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
ok "$SERVICE is disabled"
|
||||||
|
else
|
||||||
|
crit "$SERVICE is enabled"
|
||||||
|
fi
|
||||||
|
is_pkg_installed "$SERVICE"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
ok "$SERVICE is not installed"
|
||||||
|
else
|
||||||
|
warn "$SERVICE is installed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment, cannot source CIS_ROOT_DIR variable, aborting"
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
98
bin/hardening/99.5.8_ssh_sys_sandbox.sh
Executable file
98
bin/hardening/99.5.8_ssh_sys_sandbox.sh
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check UsePrivilegeSeparation set to sandbox.
|
||||||
|
#
|
||||||
|
|
||||||
|
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="Check UsePrivilegeSeparation set to sandbox."
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS='UsePrivilegeSeparation=sandbox'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
97
bin/hardening/99.5.9_ssh_loglevel.sh
Executable file
97
bin/hardening/99.5.9_ssh_loglevel.sh
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run-shellcheck
|
||||||
|
|
||||||
|
#
|
||||||
|
# CIS Debian 7/8 Hardening
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# SSH log level is set to VERBOSE
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e # One error, it's over
|
||||||
|
set -u # One variable unset, it's over
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
DESCRIPTION="SSH log level is set to VERBOSE"
|
||||||
|
# shellcheck disable=2034
|
||||||
|
HARDENING_LEVEL=2
|
||||||
|
|
||||||
|
PACKAGE='openssh-server'
|
||||||
|
OPTIONS='LogLevel=VERBOSE'
|
||||||
|
FILE='/etc/ssh/sshd_config'
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled / audit mode
|
||||||
|
audit () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
crit "$PACKAGE is not installed!"
|
||||||
|
else
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
crit "$PATTERN is not present in $FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will be called if the script status is on enabled mode
|
||||||
|
apply () {
|
||||||
|
is_pkg_installed $PACKAGE
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PACKAGE is installed"
|
||||||
|
else
|
||||||
|
crit "$PACKAGE is absent, installing it"
|
||||||
|
apt_install $PACKAGE
|
||||||
|
fi
|
||||||
|
for SSH_OPTION in $OPTIONS; do
|
||||||
|
SSH_PARAM=$(echo $SSH_OPTION | cut -d= -f 1)
|
||||||
|
SSH_VALUE=$(echo $SSH_OPTION | cut -d= -f 2)
|
||||||
|
PATTERN="^$SSH_PARAM[[:space:]]*$SSH_VALUE"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "$PATTERN"
|
||||||
|
if [ "$FNRET" = 0 ]; then
|
||||||
|
ok "$PATTERN is present in $FILE"
|
||||||
|
else
|
||||||
|
warn "$PATTERN is not present in $FILE, adding it"
|
||||||
|
does_pattern_exist_in_file_nocase $FILE "^$SSH_PARAM"
|
||||||
|
if [ "$FNRET" != 0 ]; then
|
||||||
|
add_end_of_file $FILE "$SSH_PARAM $SSH_VALUE"
|
||||||
|
else
|
||||||
|
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing"
|
||||||
|
replace_in_file $FILE "^$SSH_PARAM[[:space:]]*.*" "$SSH_PARAM $SSH_VALUE"
|
||||||
|
fi
|
||||||
|
/etc/init.d/ssh reload > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function will check config parameters required
|
||||||
|
check_config() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
# Source Root Dir Parameter
|
||||||
|
if [ -r /etc/default/cis-hardening ]; then
|
||||||
|
. /etc/default/cis-hardening
|
||||||
|
fi
|
||||||
|
if [ -z "$CIS_ROOT_DIR" ]; then
|
||||||
|
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
|
||||||
|
echo "Cannot source CIS_ROOT_DIR variable, aborting."
|
||||||
|
exit 128
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
|
||||||
|
if [ -r "$CIS_ROOT_DIR"/lib/main.sh ]; then
|
||||||
|
# shellcheck source=/opt/debian-cis/lib/main.sh
|
||||||
|
. "$CIS_ROOT_DIR"/lib/main.sh
|
||||||
|
else
|
||||||
|
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_ROOT_DIR in /etc/default/cis-hardening"
|
||||||
|
exit 128
|
||||||
|
fi
|
34
lib/utils.sh
34
lib/utils.sh
@ -95,14 +95,25 @@ has_file_correct_permissions() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
does_pattern_exist_in_file_nocase() {
|
||||||
|
_does_pattern_exist_in_file "-Ei" $*
|
||||||
|
}
|
||||||
|
|
||||||
does_pattern_exist_in_file() {
|
does_pattern_exist_in_file() {
|
||||||
local FILE=$1
|
_does_pattern_exist_in_file "-E" $*
|
||||||
local PATTERN=$2
|
}
|
||||||
|
|
||||||
|
_does_pattern_exist_in_file() {
|
||||||
|
local OPTIONS="$1"
|
||||||
|
shift
|
||||||
|
local FILE="$1"
|
||||||
|
shift
|
||||||
|
local PATTERN="$*"
|
||||||
|
|
||||||
debug "Checking if $PATTERN is present in $FILE"
|
debug "Checking if $PATTERN is present in $FILE"
|
||||||
if $SUDO_CMD [ -r "$FILE" ] ; then
|
if $SUDO_CMD [ -r "$FILE" ] ; then
|
||||||
debug "$SUDO_CMD grep -qE -- '$PATTERN' $FILE"
|
debug "$SUDO_CMD grep -q $OPTIONS -- '$PATTERN' $FILE"
|
||||||
if $($SUDO_CMD grep -qE -- "$PATTERN" $FILE); then
|
if $($SUDO_CMD grep -q $OPTIONS -- "$PATTERN" $FILE); then
|
||||||
FNRET=0
|
FNRET=0
|
||||||
else
|
else
|
||||||
FNRET=1
|
FNRET=1
|
||||||
@ -382,3 +393,18 @@ is_pkg_installed()
|
|||||||
FNRET=1
|
FNRET=1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns Debian major version
|
||||||
|
|
||||||
|
get_debian_major_version()
|
||||||
|
{
|
||||||
|
DEB_MAJ_VER=""
|
||||||
|
does_file_exist /etc/debian_version
|
||||||
|
if [ $FNRET ]; then
|
||||||
|
DEB_MAJ_VER=$(cut -d '.' -f1 /etc/debian_version)
|
||||||
|
else
|
||||||
|
DEB_MAJ_VER=$(lsb_release -r | cut -f2 | cut -d '.' -f 1)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ fi
|
|||||||
for f in $files; do
|
for f in $files; do
|
||||||
if head "$f" | grep -qE "^# run-shellcheck$"; then
|
if head "$f" | grep -qE "^# run-shellcheck$"; then
|
||||||
printf "\e[1;36mRunning shellcheck on: %s \e[0m\n" "$f"
|
printf "\e[1;36mRunning shellcheck on: %s \e[0m\n" "$f"
|
||||||
if ! /usr/bin/shellcheck --color=always --shell=bash "$f"; then
|
if ! /usr/bin/shellcheck --color=always --shell=bash -e SC1091 "$f"; then
|
||||||
retval=$((retval + 1))
|
retval=$((retval + 1))
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
25
tests/hardening/99.3.1_acc_shadow_sha512.sh
Normal file
25
tests/hardening/99.3.1_acc_shadow_sha512.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "There is no password in /etc/shadow"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
cp -a /etc/shadow /tmp/shadow.bak
|
||||||
|
sed -i 's/secaudit:!/secaudit:mypassword/' /etc/shadow
|
||||||
|
describe Fail: Found unsecure password
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "User secaudit has a password that is not SHA512 hashed"
|
||||||
|
run unsecpasswd /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
mv /tmp/shadow.bak /etc/shadow
|
||||||
|
chpasswd << EOF
|
||||||
|
secaudit:mypassword
|
||||||
|
EOF
|
||||||
|
describe Pass: Found properly hashed password
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "User secaudit has suitable SHA512 hashed password"
|
||||||
|
run sha512pass /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
28
tests/hardening/99.3.2_acc_sudoers_no_all.sh
Normal file
28
tests/hardening/99.3.2_acc_sudoers_no_all.sh
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "There is no carte-blanche sudo permission in"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
# Proceed to operation that will end up to a non compliant system
|
||||||
|
useradd -s /bin/bash jeantestuser
|
||||||
|
echo 'jeantestuser ALL = (ALL) NOPASSWD:ALL' >> /etc/sudoers.d/jeantestuser
|
||||||
|
describe Fail: Not compliant system
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "[ KO ] jeantestuser ALL = (ALL) NOPASSWD:ALL is present in /etc/sudoers.d/jeantestuser"
|
||||||
|
run userallcmd /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
|
||||||
|
# shellcheck disable=2016
|
||||||
|
echo 'EXCEPT="$EXCEPT jeantestuser"' >> /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
describe Adding jeantestuser to exceptions
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] jeantestuser ALL = (ALL) NOPASSWD:ALL is present in /etc/sudoers.d/jeantestuser but was EXCUSED because jeantestuser is part of exceptions"
|
||||||
|
run userexcept /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
rm -f /etc/sudoers.d/jeantestuser
|
||||||
|
userdel jeantestuser
|
||||||
|
}
|
||||||
|
|
9
tests/hardening/99.3.3_acc_pam_sha512.sh
Normal file
9
tests/hardening/99.3.3_acc_pam_sha512.sh
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^\s*password\s.+\s+pam_unix\.so\s+.*sha512 is present in /etc/pam.d/common-password"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
38
tests/hardening/99.3.4_acc_logindefs_sha512.sh
Normal file
38
tests/hardening/99.3.4_acc_logindefs_sha512.sh
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "ENCRYPT_METHOD SHA512 is present in /etc/login.defs"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
cp /etc/login.defs /tmp/login.defs.bak
|
||||||
|
describe Line as comment
|
||||||
|
sed -i 's/\(ENCRYPT_METHOD SHA512\)/# \1/' /etc/login.defs
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "SHA512 is not present"
|
||||||
|
run commented /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
rm /etc/login.defs
|
||||||
|
describe Fail: missing conf file
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "/etc/login.defs is not readable"
|
||||||
|
run missconffile /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
cp /tmp/login.defs.bak /etc/login.defs
|
||||||
|
sed -ir 's/ENCRYPT_METHOD[[:space:]]\+SHA512/ENCRYPT_METHOD MD5/' /etc/login.defs
|
||||||
|
describe Fail: wrong hash function configuration
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "SHA512 is not present"
|
||||||
|
run wrongconf /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
mv /tmp/login.defs.bak /etc/login.defs
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run sha512pass /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
29
tests/hardening/99.5.1_ssh_auth_pubk_only.sh
Normal file
29
tests/hardening/99.5.1_ssh_auth_pubk_only.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^PubkeyAuthentication[[:space:]]+yes is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^PasswordAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^KbdInteractiveAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^KerberosAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^ChallengeResponseAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^HostbasedAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^GSSAPIAuthentication[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^GSSAPIKeyExchange[[:space:]]+no is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
29
tests/hardening/99.5.2.1_ssh_cry_kex.sh
Normal file
29
tests/hardening/99.5.2.1_ssh_cry_kex.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
cp -a /etc/ssh/sshd_config /tmp/sshd_config.bak
|
||||||
|
|
||||||
|
describe Change case of config line
|
||||||
|
sed -i 's/\(KexAlgorithms\)/\U\1/' /etc/ssh/sshd_config
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run uppercase /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
mv /tmp/sshd_config.bak /etc/ssh/sshd_config
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
22
tests/hardening/99.5.2.2_ssh_cry_mac.sh
Normal file
22
tests/hardening/99.5.2.2_ssh_cry_mac.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^MACs[[:space:]]*umac-128-etm@openssh.com,umac-64-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128@openssh.com,umac-64@openssh.com,hmac-sha2-512,hmac-sha2-256 is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
22
tests/hardening/99.5.2.3_ssh_cry_rekey.sh
Normal file
22
tests/hardening/99.5.2.3_ssh_cry_rekey.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^RekeyLimit[[:space:]]*512M\s+6h is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
28
tests/hardening/99.5.3_ssh_disable_features.sh
Normal file
28
tests/hardening/99.5.3_ssh_disable_features.sh
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^AllowAgentForwarding[[:space:]]*no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^AllowTcpForwarding[[:space:]]*no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^AllowStreamLocalForwarding[[:space:]]*no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^PermitTunnel[[:space:]]*no is present in /etc/ssh/sshd_config
|
||||||
|
"
|
||||||
|
register_test contain "[ OK ] ^PermitUserRC[[:space:]]*no is present in /etc/ssh/sshd_config"
|
||||||
|
register_test contain "[ OK ] ^GatewayPorts[[:space:]]*no is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
50
tests/hardening/99.5.4_ssh_keys_from.sh
Normal file
50
tests/hardening/99.5.4_ssh_keys_from.sh
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
dismiss_test
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run genconf /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
useradd -s /bin/bash jeantestuser
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[WARN] secaudit has a valid shell but no authorized_keys file"
|
||||||
|
register_test contain "[INFO] User jeantestuser has a valid shell"
|
||||||
|
register_test contain "[INFO] User jeantestuser has no home directory"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
mkdir -p /home/secaudit/.ssh
|
||||||
|
touch /home/secaudit/.ssh/authorized_keys2
|
||||||
|
describe empty authorized keys file
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run emptyauthkey /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
ssh-keygen -t ed25519 -f /tmp/key1
|
||||||
|
cat /tmp/key1.pub >> /home/secaudit/.ssh/authorized_keys2
|
||||||
|
describe Key without from field
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
run keynofrom /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
echo -n 'from="127.0.0.1" ' > /home/secaudit/.ssh/authorized_keys2
|
||||||
|
cat /tmp/key1.pub >> /home/secaudit/.ssh/authorized_keys2
|
||||||
|
describe Key with from, no ip check
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run keyfrom /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
# shellcheck disable=2016
|
||||||
|
echo 'ALLOWED_IPS="$ALLOWED_IPS 127.0.0.1"' >> /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
echo -n 'from="10.0.1.2" ' >> /home/secaudit/.ssh/authorized_keys2
|
||||||
|
cat /tmp/key1.pub >> /home/secaudit/.ssh/authorized_keys2
|
||||||
|
describe Key with from, filled allowed IPs, one bad ip
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
run badfromip /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
# shellcheck disable=2016
|
||||||
|
echo 'ALLOWED_IPS="$ALLOWED_IPS 10.0.1.2"' >> /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
describe Key with from, filled allowed IPs, all IPs allowed
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
run allwdfromip /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
userdel jeantestuser
|
||||||
|
}
|
||||||
|
|
23
tests/hardening/99.5.5_ssh_strict_modes.sh
Normal file
23
tests/hardening/99.5.5_ssh_strict_modes.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
dismiss_count_for_test
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^StrictModes[[:space:]]*yes is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
30
tests/hardening/99.5.6_ssh_sys_accept_env.sh
Normal file
30
tests/hardening/99.5.6_ssh_sys_accept_env.sh
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
# Proceed to operation that will end up to a non compliant system
|
||||||
|
describe Tests purposely failing
|
||||||
|
sed -ri 's/^\s*AcceptEnv\s+LANG LC_\*//' /etc/ssh/sshd_config
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "[ KO ] ^\s*AcceptEnv\s+LANG LC_\* is not present in /etc/ssh/sshd_config"
|
||||||
|
run noncompliant /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^\s*AcceptEnv\s+LANG LC_\* is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
8
tests/hardening/99.5.7_ssh_sys_no_legacy.sh
Normal file
8
tests/hardening/99.5.7_ssh_sys_no_legacy.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
22
tests/hardening/99.5.8_ssh_sys_sandbox.sh
Normal file
22
tests/hardening/99.5.8_ssh_sys_sandbox.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^UsePrivilegeSeparation[[:space:]]*sandbox is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
22
tests/hardening/99.5.9_ssh_loglevel.sh
Normal file
22
tests/hardening/99.5.9_ssh_loglevel.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# run-shellcheck
|
||||||
|
test_audit() {
|
||||||
|
describe Running on blank host
|
||||||
|
register_test retvalshouldbe 1
|
||||||
|
register_test contain "openssh-server is installed"
|
||||||
|
# shellcheck disable=2154
|
||||||
|
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
|
||||||
|
describe Correcting situation
|
||||||
|
# `apply` performs a service reload after each change in the config file
|
||||||
|
# the service needs to be started for the reload to succeed
|
||||||
|
service ssh start
|
||||||
|
# if the audit script provides "apply" option, enable and run it
|
||||||
|
sed -i 's/disabled/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
|
||||||
|
/opt/debian-cis/bin/hardening/"${script}".sh || true
|
||||||
|
|
||||||
|
describe Checking resolved state
|
||||||
|
register_test retvalshouldbe 0
|
||||||
|
register_test contain "[ OK ] ^LogLevel[[:space:]]*VERBOSE is present in /etc/ssh/sshd_config"
|
||||||
|
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,6 @@
|
|||||||
set -e
|
set -e
|
||||||
# stop on undefined variable
|
# stop on undefined variable
|
||||||
set -u
|
set -u
|
||||||
# debug
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
mytmpdir=$(mktemp -d -t debian-cis-test.XXXXXX)
|
mytmpdir=$(mktemp -d -t debian-cis-test.XXXXXX)
|
||||||
totalerrors=255
|
totalerrors=255
|
||||||
|
Loading…
Reference in New Issue
Block a user