debian-cis/README.md

299 lines
14 KiB
Markdown
Raw Normal View History

2024-03-25 03:48:23 +01:00
██████╗██╗███████╗ ██████╗ ███████╗██████╗ ██╗ █████╗ ███╗ ██╗
██╔════╝██║██╔════╝ ██╔══██╗██╔════╝██╔══██╗██║██╔══██╗████╗ ██║
██║ ██║███████╗ ██║ ██║█████╗ ██████╔╝██║███████║██╔██╗ ██║
██║ ██║╚════██║ ██║ ██║██╔══╝ ██╔══██╗██║██╔══██║██║╚██╗██║
╚██████╗██║███████║ ██████╔╝███████╗██████╔╝██║██║ ██║██║ ╚████║
╚═════╝╚═╝╚══════╝ ╚═════╝ ╚══════╝╚═════╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝
██╗ ██╗ █████╗ ██████╗ ██████╗ ███████╗███╗ ██╗██╗███╗ ██╗ ██████╗
██║ ██║██╔══██╗██╔══██╗██╔══██╗██╔════╝████╗ ██║██║████╗ ██║██╔════╝
███████║███████║██████╔╝██║ ██║█████╗ ██╔██╗ ██║██║██╔██╗ ██║██║ ███╗
██╔══██║██╔══██║██╔══██╗██║ ██║██╔══╝ ██║╚██╗██║██║██║╚██╗██║██║ ██║
██║ ██║██║ ██║██║ ██║██████╔╝███████╗██║ ╚████║██║██║ ╚████║╚██████╔╝
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝
2024-03-25 03:47:36 +01:00
# :lock: CIS Debian 10/11/12 Hardening
2021-01-13 11:14:26 +01:00
2021-01-15 11:51:53 +01:00
<p align="center">
<img src="https://repository-images.githubusercontent.com/56690366/bbe7c380-55b2-11eb-84ba-d06bf153fe8b" width="300px">
</p>
2021-01-18 14:26:34 +01:00
![Shell-linter](https://github.com/ovh/debian-cis/workflows/Run%20shell-linter/badge.svg)
![Functionnal tests](https://github.com/ovh/debian-cis/workflows/Run%20functionnal%20tests/badge.svg)
![Release](https://github.com/ovh/debian-cis/workflows/Create%20Release/badge.svg)
2021-01-15 11:51:53 +01:00
![Realease](https://img.shields.io/github/v/release/ovh/debian-cis)
![License](https://img.shields.io/github/license/ovh/debian-cis)
---
Modular Debian 10/11/12 security hardening scripts based on [cisecurity.org](https://www.cisecurity.org)
2021-01-15 11:51:53 +01:00
recommendations. We use it at [OVHcloud](https://www.ovhcloud.com) to harden our PCI-DSS infrastructure.
2016-04-20 18:56:28 +02:00
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.
2016-04-20 18:56:28 +02:00
```console
2016-04-21 12:00:20 +02:00
$ bin/hardening.sh --audit-all
[...]
2021-01-13 11:14:26 +01:00
hardening [INFO] Treating /opt/cis-hardening/bin/hardening/6.2.19_check_duplicate_groupname.sh
6.2.19_check_duplicate_gr [INFO] Working on 6.2.19_check_duplicate_groupname
6.2.19_check_duplicate_gr [INFO] Checking Configuration
6.2.19_check_duplicate_gr [INFO] Performing audit
6.2.19_check_duplicate_gr [ OK ] No duplicate GIDs
6.2.19_check_duplicate_gr [ OK ] Check Passed
2016-04-21 12:00:20 +02:00
[...]
################### SUMMARY ###################
2021-01-13 11:14:26 +01:00
Total Available Checks : 232
Total Runned Checks : 166
Total Passed Checks : [ 142/166 ]
Total Failed Checks : [ 24/166 ]
Enabled Checks Percentage : 71.00 %
Conformity Percentage : 85.00 %
2016-04-20 18:56:28 +02:00
```
2021-01-15 11:51:53 +01:00
## :dizzy: Quickstart
2016-04-20 18:56:28 +02:00
```console
2016-04-21 12:00:20 +02:00
$ git clone https://github.com/ovh/debian-cis.git && cd debian-cis
2016-04-21 15:18:36 +02:00
$ 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
2021-01-13 11:14:26 +01:00
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
1.1.1.1_disable_freevxfs [INFO] Performing audit
1.1.1.1_disable_freevxfs [ OK ] CONFIG_VXFS_FS is disabled
1.1.1.1_disable_freevxfs [ OK ] Check Passed
2016-04-20 18:56:28 +02:00
```
2021-01-15 11:51:53 +01:00
## :hammer: Usage
2016-04-20 18:56:28 +02:00
### Configuration
Hardening scripts are in ``bin/hardening``. Each script has a corresponding
configuration file in ``etc/conf.d/[script_name].cfg``.
Each hardening script can be individually enabled from its configuration file.
For example, this is the default configuration file for ``disable_system_accounts``:
```
# Configuration for script of same name
status=disabled
# Put here your exceptions concerning admin accounts shells separated by spaces
EXCEPTIONS=""
```
``status`` parameter may take 3 values:
- ``disabled`` (do nothing): The script will not run.
- ``audit`` (RO): The script will check if any change *should* be applied.
- ``enabled`` (RW): The script will check if any change should be done and automatically apply what it can.
Global configuration is in ``etc/hardening.cfg``. This file controls the log level
as well as the backup directory. Whenever a script is instructed to edit a file, it
will create a timestamped backup in this directory.
### Run aka "Harden your distro"
To run the checks and apply the fixes, run ``bin/hardening.sh``.
This command has 2 main operation modes:
- ``--audit``: Audit your system with all enabled and audit mode scripts
- ``--apply``: Audit your system with all enabled and audit mode scripts and apply changes for enabled scripts
2021-01-13 11:14:26 +01:00
Additionally, some options add more granularity:
``--audit-all`` can be used to force running all auditing scripts,
2016-04-20 18:56:28 +02:00
including disabled ones. this will *not* change the system.
``--audit-all-enable-passed`` can be used as a quick way to kickstart your
configuration. It will run all scripts in audit mode. If a script passes,
it will automatically be enabled for future runs. Do NOT use this option
if you have already started to customize your configuration.
2021-01-13 11:14:26 +01:00
``--sudo``: audit your system as a normal user, but allow sudo escalation to read
specific root read-only files. You need to provide a sudoers file in /etc/sudoers.d/
with NOPASWD option, since checks are executed with ``sudo -n`` option, that will
not prompt for a password.
2021-01-13 11:14:26 +01:00
``--batch``: while performing system audit, this option sets LOGLEVEL to 'ok' and
captures all output to print only one line once the check is done, formatted like :
OK|KO OK|KO|WARN{subcheck results} [OK|KO|WARN{...}]
2021-01-13 11:14:26 +01:00
``--only <check_number>``: run only the selected checks.
``--set-hardening-level``: run all checks that are lower or equal to the selected level.
Do NOT use this option if you have already started to customize your configuration.
``--allow-service <service>``: use with --set-hardening-level. Modifies the policy
to allow a certain kind of services on the machine, such as http, mail, etc.
Can be specified multiple times to allow multiple services.
Use --allow-service-list to get a list of supported services.
``--set-log-level <level>``: This option sets LOGLEVEL, you can choose : info, warning, error, ok, debug.
Default value is : info
2021-01-13 11:14:26 +01:00
``--create-config-files-only``: create the config files in etc/conf.d. Must be run as root,
before running the audit with user secaudit, to have the rights setup well on the conf files.
``--allow-unsupported-distribution``: must be specified manually in the command line to allow
the run on non compatible version or distribution. If you want to mute the warning change the
LOGLEVEL in /etc/hardening.cfg
2021-01-15 11:51:53 +01:00
## :computer: Hacking
2016-04-20 18:56:28 +02:00
**Getting the source**
```console
2016-04-21 12:00:20 +02:00
$ git clone https://github.com/ovh/debian-cis.git
2016-04-20 18:56:28 +02:00
```
**Building a debian Package** (the hacky way)
```console
2016-04-21 12:00:20 +02:00
$ debuild -us -uc
2016-04-20 18:56:28 +02:00
```
**Adding a custom hardening script**
2016-04-21 12:00:20 +02:00
```console
$ cp src/skel bin/hardening/99.99_custom_script.sh
$ chmod +x bin/hardening/99.99_custom_script.sh
$ cp src/skel.cfg etc/conf.d/99.99_custom_script.cfg
```
2021-01-13 11:14:26 +01:00
Every custom check numerotation begins with 99. The numbering after it depends on the section the check refers to.
If the check replace somehow one that is in the CIS specifications,
you can use the numerotation of the check it replaces inplace. For example we check
the config of OSSEC (file integrity) in `1.4.x` whereas CIS recommends AIDE.
2021-01-15 11:51:53 +01:00
Do not forget to specify in comment if it's a bonus check (suggested by CIS but not in the CIS numerotation), a legacy check (part from previous CIS specification but deleted in more recents one) or an OVHcloud security check.
(part of OVHcloud security policy)
2021-01-13 11:14:26 +01:00
2016-04-21 12:00:20 +02:00
Code your check explaining what it does then if you want to test
```console
$ sed -i "s/status=.+/status=enabled/" etc/conf.d/99.99_custom_script.cfg
$ ./bin/hardening/99.99_custom_script.sh
```
2021-01-15 11:51:53 +01:00
## :sparkles: Functional testing
IMP(test): Add feature to run functional tests in docker instance Add usecase in basename Add test files for checks with find command Always show logs FIX: run void script to generate config and avoid sed failure Update README with functional test description Add skeleton for functional test Add argument to launch only specific test suite Add support for debian8 and compulsory mention of debian version at launch Improve README Simplify test file syntax to avoid copy/paste mistake Add script that runs tests on all debian targets Improve run_all_target script with nowait and nodel options Add dockerfile for Buster pre-version Chore: Use getopt for options and reviewed code by shellcheck Add trap to ensure cleanup on exit/interrupt Remove quotes that lead to `less` misinterpretation of the filenames Set `local` for variables inside `test_audit` func Move functional assertion functions to dedicated file Add cleanup for logs and containers Improve cleanup, and now exits Apply shellcheck recommendations FIX: allow script to be run from anywhere (dirname $0) Changes to be committed: modified: README.md new file: src/skel.test new file: tests/docker/Dockerfile.debian10_20181226 new file: tests/docker/Dockerfile.debian8 new file: tests/docker/Dockerfile.debian9 new file: tests/docker_build_and_run_tests.sh new file: tests/hardening/12.10_find_suid_files.sh new file: tests/hardening/12.11_find_sgid_files.sh new file: tests/hardening/12.7_find_world_writable_file.sh new file: tests/hardening/12.8_find_unowned_files.sh new file: tests/hardening/12.9_find_ungrouped_files.sh new file: tests/hardening/2.17_sticky_bit_world_writable_folder.sh new file: tests/launch_tests.sh new file: tests/lib.sh new file: tests/run_all_targets.sh
2018-12-24 14:12:59 +01:00
Functional tests are available. They are to be run in a Docker environment.
```console
$ ./tests/docker_build_and_run_tests.sh <target> [name of test script...]
```
With `target` being like `debian10` or `debian11`.
IMP(test): Add feature to run functional tests in docker instance Add usecase in basename Add test files for checks with find command Always show logs FIX: run void script to generate config and avoid sed failure Update README with functional test description Add skeleton for functional test Add argument to launch only specific test suite Add support for debian8 and compulsory mention of debian version at launch Improve README Simplify test file syntax to avoid copy/paste mistake Add script that runs tests on all debian targets Improve run_all_target script with nowait and nodel options Add dockerfile for Buster pre-version Chore: Use getopt for options and reviewed code by shellcheck Add trap to ensure cleanup on exit/interrupt Remove quotes that lead to `less` misinterpretation of the filenames Set `local` for variables inside `test_audit` func Move functional assertion functions to dedicated file Add cleanup for logs and containers Improve cleanup, and now exits Apply shellcheck recommendations FIX: allow script to be run from anywhere (dirname $0) Changes to be committed: modified: README.md new file: src/skel.test new file: tests/docker/Dockerfile.debian10_20181226 new file: tests/docker/Dockerfile.debian8 new file: tests/docker/Dockerfile.debian9 new file: tests/docker_build_and_run_tests.sh new file: tests/hardening/12.10_find_suid_files.sh new file: tests/hardening/12.11_find_sgid_files.sh new file: tests/hardening/12.7_find_world_writable_file.sh new file: tests/hardening/12.8_find_unowned_files.sh new file: tests/hardening/12.9_find_ungrouped_files.sh new file: tests/hardening/2.17_sticky_bit_world_writable_folder.sh new file: tests/launch_tests.sh new file: tests/lib.sh new file: tests/run_all_targets.sh
2018-12-24 14:12:59 +01:00
Running without script arguments will run all tests in `./tests/hardening/` directory.
Or you can specify one or several test script to be run.
This will build a new Docker image from the current state of the projet and run
a container that will assess a blank Debian system compliance for each check.
For hardening audit points the audit is expected to fail, then be fixed so that
running the audit a second time will succeed.
For vulnerable items, the audit is expected to succeed on a blank
system, then the functional tests will introduce a weak point, that is expected
to be detected when running the audit test a second time. Finally running the `apply`
part of debian-cis script will restore a compliance state that is expected to be
assed by running the audit check a third time.
Functional tests can make use of the following helper functions :
* `describe <test description>`
* `run <usecase> <audit_script> <audit_script_options>`
* `register_test <test content (see below)>`
* `retvalshoudbe <integer>` check the script return value
* `contain "<SAMPLE TEXT>"` check that the output contains the following text
In order to write your own functional test, you will find a code skeleton in
`./src/skel.test`.
2016-04-20 18:56:28 +02:00
2021-01-13 11:14:26 +01:00
Some tests ar labelled with a disclaimer warning that we only test on a blank host
and that we will not test the apply function. It's because the check is very basic
(like a package install) and that a test on it is not really necessary.
Furthermore, some tests are disabled on docker because there not pertinent (kernel
modules, grub, partitions, ...)
You can disable a check on docker with:
```bash
if [ -f "/.dockerenv" ]; then
skip "SKIPPED on docker"
else
...
fi
```
2021-01-15 11:51:53 +01:00
## :art: Coding style
2021-01-13 11:14:26 +01:00
### Shellcheck
We use [Shellcheck](https://github.com/koalaman/shellcheck) to check the
correctness of the scripts and to respect best practices.
It can be used directly with the docker environnment to check all scripts
compliancy. By default it runs on every `.sh` it founds.
```console
$ ./shellcheck/launch_shellcheck.sh [name of script...]
```
### Shellfmt
We use [Shellfmt](https://github.com/mvdan/sh) to check the styling and to keep a
consistent style in every script.
Identically to shellcheck, it can be run through a script with the following:
```console
$ ./shellfmt/launch_shellfmt.sh
```
It will automatically fix any styling problem on every script.
2021-01-15 11:51:53 +01:00
## :heavy_exclamation_mark: Disclaimer
2016-04-20 18:56:28 +02:00
This project is a set of tools. They are meant to help the system administrator
2021-01-15 11:51:53 +01:00
built a secure environment. While we use it at OVHcloud to harden our PCI-DSS compliant
2016-04-20 18:56:28 +02:00
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.
2016-04-20 18:56:28 +02:00
Additionally, quoting the License:
2021-01-18 11:58:38 +01:00
> THIS SOFTWARE IS PROVIDED BY OVH SAS AND CONTRIBUTORS ``AS IS'' AND ANY
2016-04-20 18:56:28 +02:00
> EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2021-01-15 11:51:53 +01:00
> DISCLAIMED. IN NO EVENT SHALL OVHcloud SAS AND CONTRIBUTORS BE LIABLE FOR ANY
2016-04-20 18:56:28 +02:00
> DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2021-01-15 11:51:53 +01:00
## :satellite: Reference
2016-04-20 18:56:28 +02:00
2016-04-21 12:00:20 +02:00
- **Center for Internet Security**: https://www.cisecurity.org/
2021-01-13 11:14:26 +01:00
- **CIS recommendations**: https://learn.cisecurity.org/benchmarks
2016-04-20 18:56:28 +02:00
2021-01-15 11:51:53 +01:00
## :page_facing_up: License
2016-04-20 18:56:28 +02:00
2021-01-18 11:58:38 +01:00
Apache, Version 2.0