Compare commits

...

13 Commits

Author SHA1 Message Date
1733d1f460 build(deps): bump luizm/action-sh-checker from 0.8.0 to 0.9.0
Bumps [luizm/action-sh-checker](https://github.com/luizm/action-sh-checker) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/luizm/action-sh-checker/releases)
- [Commits](https://github.com/luizm/action-sh-checker/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: luizm/action-sh-checker
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-16 22:28:53 +00:00
9a225c6157 build(deps): bump dev-drprasad/delete-tag-and-release from 1.0.1 to 1.1 (#238)
Bumps [dev-drprasad/delete-tag-and-release](https://github.com/dev-drprasad/delete-tag-and-release) from 1.0.1 to 1.1.
- [Release notes](https://github.com/dev-drprasad/delete-tag-and-release/releases)
- [Commits](https://github.com/dev-drprasad/delete-tag-and-release/compare/v1.0.1...v1.1)

---
updated-dependencies:
- dependency-name: dev-drprasad/delete-tag-and-release
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-10 17:47:36 +02:00
6079b16611 fix: invalid behavior on sid/alternative in 5.3.4/99.5.4.5.1 (#237) 2024-04-09 17:12:31 +02:00
f7cdf438d4 build(deps): bump metcalfc/changelog-generator from 4.2.0 to 4.3.1 (#234)
Bumps [metcalfc/changelog-generator](https://github.com/metcalfc/changelog-generator) from 4.2.0 to 4.3.1.
- [Release notes](https://github.com/metcalfc/changelog-generator/releases)
- [Changelog](https://github.com/metcalfc/changelog-generator/blob/main/release-notes.png)
- [Commits](https://github.com/metcalfc/changelog-generator/compare/v4.2.0...v4.3.1)

---
updated-dependencies:
- dependency-name: metcalfc/changelog-generator
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2024-03-05 09:33:10 +01:00
43fc23ee40 fix: catch cidr network in ssh keys (#236)
Co-authored-by: Ismaël Tanguy <ismael.tanguy@ovhcloud.com>
2024-02-22 17:55:03 +01:00
3bd4078e70 fix: allow set-hardening-level option usage (#232)
Was broken since 2020, fixes #230
2024-02-01 17:09:35 +01:00
a45aa40ce4 bump to 4.1.4 2024-01-18 09:16:00 +00:00
730ab47437 allow multiple users in 5.2.18 (#228)
* allow multiple exception users for 99.5.2.4

* move clean up part of previous commit

* split clean up part of previous commit

* add tests for multiple allowed and denied ssh users

* fix script to correctly set multiple allowed and denied ssh users

* add cleanup resolved check to 5.2.18

* apply shellfmt to 5.2.18

---------

Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2024-01-10 17:07:02 +01:00
5313799193 Allow multiple exception users to be defined for 99.5.2.4_ssh_keys_from (#221)
* allow multiple exception users for 99.5.2.4
2023-12-27 13:42:10 +01:00
73616af4eb Syslog-ng fixes and enhancements (#226)
* syslog-ng : fix remote host test and enhance Regex

fixes #124

* enh: add test for 4.2.1.6
2023-12-27 10:27:06 +01:00
c391723fe5 fix: Allow --only option to be called multiple times (#225)
--only option was affected with a grep bug since 2017.
the regex was not able to parse more than the first passed argument.

fixes #224
2023-12-26 17:08:53 +01:00
71019a5512 fix: update Readme to clarify project usage (#223)
fixes: #219
2023-12-26 09:57:15 +01:00
fb4df82fc4 fix: typo in README. Update example of --audit usage (#222)
fixes #220
fixes #217
2023-12-26 09:19:55 +01:00
18 changed files with 299 additions and 42 deletions

View File

@ -21,7 +21,7 @@ jobs:
find ../ -name "*.deb" -exec mv {} cis-hardening.deb \;
# DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE
- name: Delete the tag latest and the release latest
uses: dev-drprasad/delete-tag-and-release@v1.0.1
uses: dev-drprasad/delete-tag-and-release@v1.1
with:
delete_release: true
tag_name: latest
@ -34,7 +34,7 @@ jobs:
# GENERATE CHANGELOG CORRESPONDING TO COMMIT BETWEEN HEAD AND COMPUTED LAST TAG
- name: Generate changelog
id: changelog
uses: metcalfc/changelog-generator@v4.2.0
uses: metcalfc/changelog-generator@v4.3.1
with:
myToken: ${{ secrets.GITHUB_TOKEN }}
head-ref: ${{ github.sha }}

View File

@ -10,7 +10,7 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v4
- name: Run the sh-checker
uses: luizm/action-sh-checker@v0.8.0
uses: luizm/action-sh-checker@v0.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Optional if sh_checker_comment is false.
SHFMT_OPTS: -l -i 4 -w # Optional: pass arguments to shfmt.

View File

@ -33,7 +33,7 @@ jobs:
find ../ -name "*.deb" -exec mv {} cis-hardening.deb \;
# DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE
- name: Delete the tag latest and the release latest
uses: dev-drprasad/delete-tag-and-release@v1.0.1
uses: dev-drprasad/delete-tag-and-release@v1.1
with:
delete_release: true
tag_name: latest

View File

@ -16,6 +16,9 @@
Modular Debian 10/11/12 security hardening scripts based on [cisecurity.org](https://www.cisecurity.org)
recommendations. We use it at [OVHcloud](https://www.ovhcloud.com) to harden our PCI-DSS infrastructure.
NB : Although Debian 12 CIS Hardening guide is still in development, we do use this set of scripts
in production at OVHcloud on Debian 12 Operating Systems.
```console
$ bin/hardening.sh --audit-all
[...]
@ -40,12 +43,11 @@ hardening [INFO] Treating /opt/cis-hardening/bin/hardening/6.2.19_check_duplicat
```console
$ git clone https://github.com/ovh/debian-cis.git && cd debian-cis
$ cp debian/default /etc/default/cis-hardening
$ sed -i "s#CIS_LIB_DIR=.*#CIS_LIB_DIR='$(pwd)'/lib#" etc/default/cis-hardening
$ sed -i "s#CIS_CHECKS_DIR=.*#CIS_CHECKS_DIR='$(pwd)'/bin/hardening#" etc/default/cis-hardening
$ sed -i "s#CIS_CONF_DIR=.*#CIS_CONF_DIR='$(pwd)'/etc#" etc/default/cis-hardening
$ sed -i "s#CIS_TMP_DIR=.*#CIS_TMP_DIR='$(pwd)'/tmp#" etc/default/cis-hardening
$ bin/hardening/1.1.1.1_disable_freevxfs.sh --audit-all
hardening [INFO] Treating /opt/cis-hardening/bin/hardening/1.1.1.1_disable_freevxfs.sh
$ sed -i "s#CIS_LIB_DIR=.*#CIS_LIB_DIR='$(pwd)'/lib#" /etc/default/cis-hardening
$ sed -i "s#CIS_CHECKS_DIR=.*#CIS_CHECKS_DIR='$(pwd)'/bin/hardening#" /etc/default/cis-hardening
$ sed -i "s#CIS_CONF_DIR=.*#CIS_CONF_DIR='$(pwd)'/etc#" /etc/default/cis-hardening
$ sed -i "s#CIS_TMP_DIR=.*#CIS_TMP_DIR='$(pwd)'/tmp#" /etc/default/cis-hardening
$ ./bin/hardening/1.1.1.1_disable_freevxfs.sh --audit
1.1.1.1_disable_freevxfs [INFO] Working on 1.1.1.1_disable_freevxfs
1.1.1.1_disable_freevxfs [INFO] [DESCRIPTION] Disable mounting of freevxfs filesystems.
1.1.1.1_disable_freevxfs [INFO] Checking Configuration
@ -244,6 +246,20 @@ built a secure environment. While we use it at OVHcloud to harden our PCI-DSS co
infrastructure, we can not guarantee that it will work for you. It will not
magically secure any random host.
A word about numbering, implementation and sustainability over time of this repository:
This project is born with the Debian 7 distribution in 2016. Over time, CIS Benchmark PDF
has evolved, changing it's numbering, deleting obsolete checks.
In order to keep retro-compatiblity with the last maintained Debian, the numbering
has not been changed along with the PDF, because the configuration scripts are named after it.
Changing the numbering might break automation for admins using it for years, and handling
this issue without breaking anything would require a huge refactoring.
As a consequence, please do not worry about numbering, the checks are there,
but the numbering accross PDFs might differ.
Please also note that all the check inside CIS Benchmark PDF might not be implemented
in this set of scripts.
We did choose the most relevant to us at OVHcloud, do not hesitate to make a
Pull Request in order to add the missing script you might find relevant for you.
Additionally, quoting the License:
> THIS SOFTWARE IS PROVIDED BY OVH SAS AND CONTRIBUTORS ``AS IS'' AND ANY
@ -257,6 +273,7 @@ Additionally, quoting the License:
> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## :satellite: Reference
- **Center for Internet Security**: https://www.cisecurity.org/

View File

@ -192,7 +192,7 @@ while [[ $# -gt 0 ]]; do
done
# if no RUN_MODE was passed, usage and quit
if [ "$AUDIT" -eq 0 ] && [ "$AUDIT_ALL" -eq 0 ] && [ "$AUDIT_ALL_ENABLE_PASSED" -eq 0 ] && [ "$APPLY" -eq 0 ] && [ "$CREATE_CONFIG" -eq 0 ]; then
if [ "$AUDIT" -eq 0 ] && [ "$AUDIT_ALL" -eq 0 ] && [ "$AUDIT_ALL_ENABLE_PASSED" -eq 0 ] && [ "$APPLY" -eq 0 ] && [ "$CREATE_CONFIG" -eq 0 ] && [ "$SET_HARDENING_LEVEL" -eq 0 ]; then
usage
fi
@ -299,7 +299,7 @@ for SCRIPT in $(find "${CIS_CHECKS_DIR}"/ -name "*.sh" | sort -V); do
SCRIPT_PREFIX=$(grep -Eo '^[0-9.]+' <<<"$(basename "$SCRIPT")")
# shellcheck disable=SC2001
SCRIPT_PREFIX_RE=$(sed -e 's/\./\\./g' <<<"$SCRIPT_PREFIX")
if ! grep -qwE "(^| )$SCRIPT_PREFIX_RE" <<<"${TEST_LIST[@]}"; then
if ! grep -qE "(^|[[:space:]])$SCRIPT_PREFIX_RE([[:space:]]|$)" <<<"${TEST_LIST[@]}"; then
# not in the list
continue
fi

View File

@ -16,10 +16,9 @@ set -u # One variable unset, it's over
HARDENING_LEVEL=3
# shellcheck disable=2034
DESCRIPTION="Configure syslog-ng to send logs to a remote log host."
PACKAGE='syslog-ng'
PATTERN='destination[[:alnum:][:space:]*{]+(tcp|udp)[[:space:]]*\(\"[[:alnum:].]+\".'
SYSLOG_BASEDIR='/etc/syslog-ng'
PATTERN='destination[[:alnum:][:space:]*_*{]+(tcp|network|udp)[[:space:]]*\([[:space:]]*\"?[[:alnum:]\-.]+\"?.'
# This function will be called if the script status is on enabled / audit mode
audit() {

View File

@ -18,9 +18,9 @@ HARDENING_LEVEL=3
DESCRIPTION="Configure syslog to accept remote syslog messages only on designated log hosts."
PACKAGE='syslog-ng'
SYSLOG_BASEDIR='/etc/syslog-ng'
REMOTE_HOST=""
PATTERN='source[[:alnum:][:space:]*{]+(tcp|udp)[[:space:]]*\(\"[[:alnum:].]+\".'
PATTERN='source[[:alnum:][:space:]*_*{]+(tcp|network|udp)[[:space:]]*\([[:space:]]*\"?[[:alnum:]\-.]+\"?.'
# This function will be called if the script status is on enabled / audit mode
audit() {
@ -37,7 +37,7 @@ audit() {
fi
done
if [[ "$REMOTE_HOST" ]]; then
if [[ "$REMOTE_HOST" ]] && [[ "$REMOTE_HOST" != 'false' ]]; then
info "This is the remote host, checking that it only accepts logs from specified zone"
if [ "$FOUND" = 1 ]; then
ok "$PATTERN is present in $FILES"
@ -70,7 +70,7 @@ apply() {
fi
done
if [[ "$REMOTE_HOST" ]]; then
if [[ "$REMOTE_HOST" ]] && [[ "$REMOTE_HOST" != 'false' ]]; then
info "This is the remote host, checking that it only accepts logs from specified zone"
if [ "$FOUND" = 1 ]; then
ok "$PATTERN is present in $FILES"

View File

@ -22,13 +22,13 @@ FILE='/etc/ssh/sshd_config'
# This function will be called if the script status is on enabled / audit mode
audit() {
OPTIONS="AllowUsers='$ALLOWED_USERS' AllowGroups='$ALLOWED_GROUPS' DenyUsers='$DENIED_USERS' DenyGroups='$DENIED_GROUPS'"
OPTIONS=("AllowUsers='$ALLOWED_USERS'" "AllowGroups='$ALLOWED_GROUPS'" "DenyUsers='$DENIED_USERS'" "DenyGroups='$DENIED_GROUPS'")
is_pkg_installed "$PACKAGE"
if [ "$FNRET" != 0 ]; then
ok "$PACKAGE is not installed!"
else
ok "$PACKAGE is installed"
for SSH_OPTION in $OPTIONS; do
for SSH_OPTION in "${OPTIONS[@]}"; do
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
# shellcheck disable=SC2001
@ -53,7 +53,7 @@ apply() {
crit "$PACKAGE is absent, installing it"
apt_install "$PACKAGE"
fi
for SSH_OPTION in $OPTIONS; do
for SSH_OPTION in "${OPTIONS[@]}"; do
SSH_PARAM=$(echo "$SSH_OPTION" | cut -d= -f 1)
SSH_VALUE=$(echo "$SSH_OPTION" | cut -d= -f 2)
# shellcheck disable=SC2001

View File

@ -49,7 +49,7 @@ apply() {
ok "$CONF_LINE is present in $CONF_FILE"
else
warn "$CONF_LINE is not present in $CONF_FILE"
if [ "$DEB_MAJ_VER" -ge "11" ]; then
if [ "$DEB_MAJ_VER" = "sid" ] || [ "$DEB_MAJ_VER" -ge "11" ]; then
add_line_file_before_pattern "$CONF_FILE" "password [success=1 default=ignore] pam_unix.so yescrypt" "# pam-auth-update(8) for details."
else
add_line_file_before_pattern "$CONF_FILE" "password [success=1 default=ignore] pam_unix.so sha512" "# pam-auth-update(8) for details."
@ -67,12 +67,11 @@ check_config() {
# We need to call this in the subs called by main.sh when it is sourced, otherwise it would
# either be too soon (DEB_MAJ_VER not defined) or too late (test has already been run)
_set_vars_jit() {
if [ "$DEB_MAJ_VER" -ge "11" ]; then
if [ "$DEB_MAJ_VER" = "sid" ] || [ "$DEB_MAJ_VER" -ge "11" ]; then
CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*(sha512|yescrypt)" # https://github.com/ovh/debian-cis/issues/158
else
CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*sha512"
fi
unset -f _set_vars_jit
}
# Source Root Dir Parameter

View File

@ -19,14 +19,14 @@ DESCRIPTION="Check <from> field in ssh authorized keys files for users with logi
# Regex looking for empty, hash starting lines, or 'from="127.127.127,127.127.127" ssh'
# shellcheck disable=2089
REGEX_FROM_IP="from=(?:'|\")(,?(\d{1,3}(\.\d{1,3}){3}))+(?:'|\")"
REGEX_FROM_IP="from=(?:'|\")(,?(\d{1,3}(\.\d{1,3}){3})(\/\d{1,2})?)+(?:'|\")"
REGEX_OK_LINES="(^(#|$)|($REGEX_FROM_IP))"
AUTHKEYFILE_PATTERN=""
AUTHKEYFILE_PATTERN_DEFAULT=".ssh/authorized_keys .ssh/authorized_keys2"
ALLOWED_IPS=""
USERS_TO_CHECK=""
EXCEPTION_USER=""
EXCEPTION_USERS=""
ALLOWED_NOLOGIN_SHELLS="/bin/false /usr/sbin/nologin"
@ -137,7 +137,10 @@ audit() {
continue
else
info "User $user has a valid shell ($shell)."
if [ "$user" = "root" ] && [ "$user" != "$EXCEPTION_USER" ]; then
if grep -qw "$user" <<<"$EXCEPTION_USERS"; then
info "User $user is named in EXEPTION_USERS and is thus skipped from check."
continue
elif [ "$user" = "root" ]; then
check_dir /root
continue
elif $SUDO_CMD [ ! -d /home/"$user" ]; then
@ -164,7 +167,7 @@ status=audit
# Put authorized IPs you want to allow in "from" field of authorized_keys
ALLOWED_IPS=""
USERS_TO_CHECK=""
EXCEPTION_USER=""
EXCEPTION_USERS=""
EOF
}

View File

@ -48,7 +48,7 @@ apply() {
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"
info "Parameter $CONF_LINE is present but with the wrong value -- Fixing"
replace_in_file "$CONF_FILE" "^$(echo "$CONF_LINE" | cut -d ' ' -f1)[[:space:]]*.*" "$CONF_LINE"
fi
fi
@ -63,14 +63,13 @@ check_config() {
# We need to call this in the subs called by main.sh when it is sourced, otherwise it would
# either be too soon (DEB_MAJ_VER not defined) or too late (test has already been run)
_set_vars_jit() {
if [ "$DEB_MAJ_VER" -ge "11" ]; then
if [ "$DEB_MAJ_VER" = "sid" ] || [ "$DEB_MAJ_VER" -ge "11" ]; then
CONF_LINE_REGEX="ENCRYPT_METHOD (SHA512|yescrypt|YESCRYPT)"
CONF_LINE="ENCRYPT_METHOD YESCRYPT"
else
CONF_LINE_REGEX="ENCRYPT_METHOD SHA512"
CONF_LINE="ENCRYPT_METHOD SHA512"
fi
unset -f _set_vars_jit
}
# Source Root Dir Parameter

11
debian/changelog vendored
View File

@ -1,3 +1,14 @@
cis-hardening (4.1-4) unstable; urgency=medium
* allow multiple users in 5.2.18 (#228)
* Allow multiple exception users to be defined for 99.5.2.4_ssh_keys_from (#221)
* Syslog-ng fixes and enhancements (#226)
* fix: Allow --only option to be called multiple times (#225)
* fix: update Readme to clarify project usage (#223)
* fix: typo in README. Update example of --audit usage (#222)
-- Thibault Dewailly <thibault.dewailly@ovhcloud.com> Thu, 18 Jan 2024 09:13:15 +0000
cis-hardening (4.1-3) unstable; urgency=medium
* Adapt all scripts to yescrypt (#216)

View File

@ -38,6 +38,6 @@ EOF
run subfile "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# Cleanup
rm /etc/syslog-ng/conf.d/1_tcp_destination
rm -f /etc/syslog-ng/conf.d/1_tcp_destination
}

View File

@ -2,10 +2,37 @@
# run-shellcheck
test_audit() {
describe Running on blank host
register_test retvalshouldbe 0
dismiss_count_for_test
register_test retvalshouldbe 1
# shellcheck disable=2154
echo 'REMOTE_HOST="true"' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# TODO fill comprehensive tests
cp -a /etc/syslog-ng/syslog-ng.conf /tmp/syslog-ng.conf.bak
echo "source mySyslog tcp (\"127.0.0.1\")" >>/etc/syslog-ng/syslog-ng.conf
describe Checking one line conf
register_test retvalshouldbe 0
run oneline "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
cp -a /tmp/syslog-ng.conf.bak /etc/syslog-ng/syslog-ng.conf
cat >>/etc/syslog-ng/syslog-ng.conf <<EOF
source mySyslog {
tcp ("127.0.0.1"),
port(1234),
EOF
describe Checking mutliline conf
register_test retvalshouldbe 0
run multiline "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
mv /tmp/syslog-ng.conf.bak /etc/syslog-ng/syslog-ng.conf
echo "source mySyslog tcp (\"127.0.0.1\")" >>/etc/syslog-ng/conf.d/1_tcp_source
cat /etc/syslog-ng/conf.d/1_tcp_source
describe Checking file in subdirectory
register_test retvalshouldbe 0
run subfile "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
rm -f /etc/syslog-ng/conf.d/1_tcp_source
}

View File

@ -22,4 +22,109 @@ test_audit() {
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Check and report mismatch for allowed user
useradd -s /bin/bash johnallow
sed -i "s/ALLOWED_USERS=''/ALLOWED_USERS='johnallow'/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
register_test retvalshouldbe 1
register_test contain "^AllowUsers[[:space:]]*johnallow is not present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run allowed_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correctly apply allowed user
# the previous test checked that ALLOWED_USERS is set but not correctly applied in sshd_config so we apply it now
"${CIS_CHECKS_DIR}/${script}.sh" || true
# and check again that the fix was correctly applied
register_test retvalshouldbe 0
register_test contain "^AllowUsers[[:space:]]*johnallow is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run fix_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --apply-all
describe Check and report mismatch for multiple allowed users
useradd -s /bin/bash janeallow
sed -i "s/johnallow/johnallow janeallow/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
register_test retvalshouldbe 1
register_test contain "^AllowUsers[[:space:]]*johnallow janeallow is not present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run multi_allowed_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correctly apply multiple allowed users
# the previous test checked that ALLOWED_USERS is set but not correctly applied in sshd_config so we apply it now
"${CIS_CHECKS_DIR}/${script}.sh" || true
# and check again that the fix was correctly applied
tail -n 5 /etc/ssh/sshd_config
register_test retvalshouldbe 0
register_test contain "^AllowUsers[[:space:]]*johnallow janeallow is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run fix_multi_allowed_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# reset allowed users to default before continuing
sed -i "s/ALLOWED_USERS='johnallow janeallow'/ALLOWED_USERS=''/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
describe Check and report mismatch for denied user
useradd -s /bin/bash peterdeny
sed -i "s/DENIED_USERS=''/DENIED_USERS='peterdeny'/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
register_test retvalshouldbe 1
register_test contain "^AllowUsers[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*peterdeny is not present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run denied_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correctly apply denied user
# the previous test checked that DENIED_USERS is set but not correctly applied in sshd_config so we apply it now
"${CIS_CHECKS_DIR}/${script}.sh" || true
# and check again that the fix was correctly applied
register_test retvalshouldbe 0
register_test contain "^AllowUsers[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*peterdeny is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run fix_denied_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --apply-all
describe Check and report mismatch for multiple denied users
useradd -s /bin/bash marrydeny
sed -i "s/peterdeny/peterdeny marrydeny/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
register_test retvalshouldbe 1
register_test contain "^AllowUsers[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*peterdeny marrydeny is not present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run multi_denied_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correctly apply multiple denied users
# the previous test checked that DENIED_USERS is set but not correctly applied in sshd_config so we apply it now
"${CIS_CHECKS_DIR}/${script}.sh" || true
# and check again that the fix was correctly applied
register_test retvalshouldbe 0
register_test contain "^AllowUsers[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*peterdeny marrydeny is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run fix_multi_denied_user_mismatch "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# reset to prevent other test from possibly failing in the future
sed -i "s/DENIED_USERS='peterdeny marrydeny'/DENIED_USERS=''/" "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "^AllowUsers[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^AllowGroups[[:space:]]** is present in /etc/ssh/sshd_config"
register_test contain "^DenyUsers[[:space:]]*nobody is present in /etc/ssh/sshd_config"
register_test contain "^DenyGroups[[:space:]]*nobody is present in /etc/ssh/sshd_config"
run cleanup_resolved "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# Cleanup
userdel johnallow
userdel janeallow
userdel peterdeny
userdel marrydeny
}

View File

@ -6,4 +6,50 @@ test_audit() {
register_test contain "is present in /etc/pam.d/common-password"
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Tests purposely failing
sed -i '/pam_unix.so/ s/sha512/sha256/' "/etc/pam.d/common-password" # Debian 10
sed -i '/pam_unix.so/ s/yescrypt/sha256/' "/etc/pam.d/common-password" # Debian 11+
register_test retvalshouldbe 1
register_test contain "is not present"
run noncompliant "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe correcting situation
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" --apply || true
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "is present in /etc/pam.d/common-password"
run solvedsid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# DEB_MAJ_VER cannot be overwritten here;
# therefore we need to trick get_debian_major_version
ORIGINAL_DEB_VER="$(cat /etc/debian_version)"
echo "sid" >/etc/debian_version
describe Running on blank host as sid
register_test retvalshouldbe 0
register_test contain "(sha512|yescrypt)"
run blanksid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Tests purposely failing as sid
sed -i '/pam_unix.so/ s/sha512/sha256/' "/etc/pam.d/common-password" # Debian 10
sed -i '/pam_unix.so/ s/yescrypt/sha256/' "/etc/pam.d/common-password" # Debian 11+
register_test retvalshouldbe 1
register_test contain "is not present"
run noncompliantsid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe correcting situation as sid
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" --apply || true
describe Checking resolved state as sid
register_test retvalshouldbe 0
register_test contain "is present in /etc/pam.d/common-password"
run solvedsid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# Cleanup
echo -n "$ORIGINAL_DEB_VER" >/etc/debian_version
unset ORIGINAL_DEB_VER
}

View File

@ -2,7 +2,7 @@
# run-shellcheck
test_audit() {
# shellcheck disable=2154
echo 'EXCEPTION_USER="root"' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
echo 'EXCEPTION_USERS=""' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
skip_tests
# shellcheck disable=2154
@ -12,12 +12,29 @@ test_audit() {
describe Running on blank host
register_test retvalshouldbe 0
dismiss_count_for_test
register_test contain "[INFO] User root has a valid shell"
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 "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
mkdir -p /root/.ssh
ssh-keygen -N "" -t ed25519 -f /tmp/rootkey1
cat /tmp/rootkey1.pub >>/root/.ssh/authorized_keys
describe Check /root is used for root user instead of home by placing key without from field
register_test retvalshouldbe 1
run rootcheck "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
echo 'EXCEPTION_USERS="root exceptiontestuser"' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
useradd -s /bin/bash exceptiontestuser
describe Check multiple exception users are skipped
register_test retvalshouldbe 0
register_test contain "[INFO] User root is named in EXEPTION_USERS and is thus skipped from check."
register_test contain "[INFO] User exceptiontestuser is named in EXEPTION_USERS and is thus skipped from check."
# shellcheck disable=2154
run exceptionusers "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
mkdir -p /home/secaudit/.ssh
touch /home/secaudit/.ssh/authorized_keys2
describe empty authorized keys file
@ -55,11 +72,11 @@ test_audit() {
run allwdfromip "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# shellcheck disable=2016
echo 'ALLOWED_IPS="$ALLOWED_IPS 127.0.0.1,10.2.3.1"' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
echo 'ALLOWED_IPS="$ALLOWED_IPS 127.0.0.1,10.2.3.1/8"' >>"${CIS_CONF_DIR}/conf.d/${script}.cfg"
{
echo -n 'from="10.0.1.2",command="echo bla" '
cat /tmp/key1.pub
echo -n 'command="echo bla,from="10.0.1.2,10.2.3.1"" '
echo -n 'command="echo bla,from="10.0.1.2,10.2.3.1/8"" '
cat /tmp/key1.pub
} >>/home/secaudit/.ssh/authorized_keys2
describe Key with from and command options
@ -74,7 +91,9 @@ test_audit() {
run checkuser "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# Cleanup
userdel exceptiontestuser
userdel jeantestuser
userdel -r jeantest2
rm -f /tmp/key1 /tmp/key1.pub
rm -f /tmp/key1 /tmp/key1.pub /tmp/rootkey1.pub
rm -rf /root/.ssh
}

View File

@ -28,11 +28,43 @@ test_audit() {
run wrongconf "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correcting situation
sed -i 's/disabled/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved state
mv /tmp/login.defs.bak /etc/login.defs
register_test retvalshouldbe 0
register_test contain "is present in /etc/login.defs"
run sha512pass "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# DEB_MAJ_VER cannot be overwritten here;
# therefore we need to trick get_debian_major_version
ORIGINAL_DEB_VER="$(cat /etc/debian_version)"
echo "sid" >/etc/debian_version
describe Running on blank host as sid
register_test retvalshouldbe 0
register_test contain "(SHA512|yescrypt|YESCRYPT)"
# shellcheck disable=2154
run blanksid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
cp /etc/login.defs /tmp/login.defs.bak
sed -ir 's/ENCRYPT_METHOD[[:space:]]\+.*/ENCRYPT_METHOD MD5/' /etc/login.defs
describe Fail: wrong hash function configuration as sid
register_test retvalshouldbe 1
register_test contain "(SHA512|yescrypt|YESCRYPT)"
run wrongconfsid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
describe Correcting situation as sid
sed -i 's/audit/enabled/' "${CIS_CONF_DIR}/conf.d/${script}.cfg"
"${CIS_CHECKS_DIR}/${script}.sh" || true
describe Checking resolved state as sid
register_test retvalshouldbe 0
register_test contain "(SHA512|yescrypt|YESCRYPT)"
run sha512passsid "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
# Cleanup
echo -n "$ORIGINAL_DEB_VER" >/etc/debian_version
unset ORIGINAL_DEB_VER
}