Compare commits

..

33 Commits

Author SHA1 Message Date
d1bd1eb2e7 bump to 3.4-1 (#150) 2022-03-18 16:49:25 +01:00
ad5c71c3ce fix: allow passwd-, group- and shadow- debian default permissions (#149) 2022-03-18 16:41:49 +01:00
33964c0a3d Bump EndBug/add-and-commit from 8.0.2 to 9 (#148)
Bumps [EndBug/add-and-commit](https://github.com/EndBug/add-and-commit) from 8.0.2 to 9.
- [Release notes](https://github.com/EndBug/add-and-commit/releases)
- [Changelog](https://github.com/EndBug/add-and-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/EndBug/add-and-commit/compare/v8.0.2...v9)

---
updated-dependencies:
- dependency-name: EndBug/add-and-commit
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 15:36:48 +01:00
8320d0eecc CI: Fix release action (#147)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
2022-03-03 12:02:12 +01:00
a0d33ab158 Update changelog for release 3.3-1 (#146)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
2022-03-03 10:26:42 +01:00
a6a22084e1 missing shadowtools backup files is ok (#132)
* missing shadowtools backup files is ok

* update corresponding test cases
2022-03-02 18:05:37 +01:00
b962155a3c fix: Avoid find failures on too many files (#144)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2022-03-02 17:49:28 +01:00
20bf51f65b Bump actions/checkout from 2 to 3 (#145)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-02 00:14:50 +01:00
adfe28470a Bump metcalfc/changelog-generator from 1.0.0 to 3.0.0 (#133)
Bumps [metcalfc/changelog-generator](https://github.com/metcalfc/changelog-generator) from 1.0.0 to 3.0.0.
- [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/v1.0.0...v3.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 23:48:57 +01:00
c94ee10afe Bump EndBug/add-and-commit from 7 to 8.0.2 (#142)
Bumps [EndBug/add-and-commit](https://github.com/EndBug/add-and-commit) from 7 to 8.0.2.
- [Release notes](https://github.com/EndBug/add-and-commit/releases)
- [Changelog](https://github.com/EndBug/add-and-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/EndBug/add-and-commit/compare/v7...v8.0.2)

---
updated-dependencies:
- dependency-name: EndBug/add-and-commit
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 20:39:39 +01:00
453a72b8c8 Bump actions-ecosystem/action-get-latest-tag from 1.4.1 to 1.5.0 (#143)
Bumps [actions-ecosystem/action-get-latest-tag](https://github.com/actions-ecosystem/action-get-latest-tag) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/actions-ecosystem/action-get-latest-tag/releases)
- [Commits](https://github.com/actions-ecosystem/action-get-latest-tag/compare/v1.4.1...v1.5.0)

---
updated-dependencies:
- dependency-name: actions-ecosystem/action-get-latest-tag
  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>
2022-03-01 20:28:33 +01:00
bb03764918 fix: Catch unexpected failures (#140)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
2022-01-31 15:38:38 +01:00
17d272420a feat: Dissociate iptables pkg name from command (#137)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
2021-12-27 15:40:55 +01:00
f1c1517bd2 Update changelog for release 3.2-2 (#135)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Tarik Megzari <tarik.megzari@corp.ovh.com>
2021-12-13 16:06:57 +01:00
1341622335 Fix empty fstab test (#134)
Signed-off-by: Tarik Megzari <tarik.megzari@corp.ovh.com>

Co-authored-by: Thibault Dewailly <thibault.dewailly@corp.ovh.com>
2021-12-08 08:42:22 +01:00
c8fcfed248 Update changelog for release 3.2-1 2021-12-01 11:04:56 +00:00
97914976c8 Skip NTP and Chrony config check if they are not installed (#120)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-12-01 10:49:08 +01:00
66c8ccf495 Fix 3.4.2 audit rule (#123)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-12-01 10:23:11 +01:00
b53bf1795c Fix grub detection (#119)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-12-01 08:58:32 +01:00
1a874b2b35 Allow grub.cfg permission to be 600 (#121)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-11-30 18:47:19 +01:00
7266ec7cb4 Honor --set-log-level parameter (#127)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-11-30 18:42:33 +01:00
8f855ac159 fix: kernel module detection (#129)
* fix: add filter to hfs

* fix is_kernel_option_enabled check

as the module in question could have dependencies which have been blacklisted as well we need to make sure that the comparison only checks for the module in question - the last line in the output.

Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-10-20 14:51:29 +02:00
ad192c9457 Add silent mode and json summary (#128)
Co-authored-by: GoldenKiwi <thibault.dewailly@corp.ovh.com>
2021-10-20 13:22:59 +02:00
3d2d97a727 FIX(1.7.1.4): don't abort script in case of unconfined processes (#130) 2021-10-20 13:14:36 +02:00
6e2fb1570c FIX(2.2.1.4): Validate debian default ntp config (#118) 2021-10-15 16:19:51 +02:00
faf5b155e5 Bump metcalfc/changelog-generator from v0.4.4 to v1.0.0 (#81)
Bumps [metcalfc/changelog-generator](https://github.com/metcalfc/changelog-generator) from v0.4.4 to v1.0.0.
- [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/v0.4.4...e5306b306fa2e34f05258789e0e5c526c1bd4352)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thibault Ayanides <thibault.ayanides@ovhcloud.com>
2021-08-10 13:57:13 +02:00
43887d4165 Bump luizm/action-sh-checker from 0.1.13 to 0.3.0 (#111)
Bumps [luizm/action-sh-checker](https://github.com/luizm/action-sh-checker) from 0.1.13 to 0.3.0.
- [Release notes](https://github.com/luizm/action-sh-checker/releases)
- [Commits](https://github.com/luizm/action-sh-checker/compare/v0.1.13...v0.3.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>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-10 13:47:31 +02:00
499ebf2f9b Bump dev-drprasad/delete-tag-and-release from v0.1.3 to v0.2.0 (#72)
Bumps [dev-drprasad/delete-tag-and-release](https://github.com/dev-drprasad/delete-tag-and-release) from v0.1.3 to v0.2.0.
- [Release notes](https://github.com/dev-drprasad/delete-tag-and-release/releases)
- [Commits](https://github.com/dev-drprasad/delete-tag-and-release/compare/v0.1.3...085c6969f18bad0de1b9f3fe6692a3cd01f64fe5)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thibault Ayanides <thibault.ayanides@ovhcloud.com>
2021-08-10 10:39:53 +02:00
afed5a9dce 99.5.4.5.2: fix bug where sha512 option rounds provoke KO (#112) 2021-08-10 10:30:35 +02:00
01c3d1b98c Bump luizm/action-sh-checker from v0.1.12 to v0.1.13 (#73)
Bumps [luizm/action-sh-checker](https://github.com/luizm/action-sh-checker) from v0.1.12 to v0.1.13.
- [Release notes](https://github.com/luizm/action-sh-checker/releases)
- [Commits](https://github.com/luizm/action-sh-checker/compare/v0.1.12...164368daf52a9126460854f9c0de00abc079a350)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thibault Ayanides <thibault.ayanides@ovhcloud.com>
2021-08-10 09:43:59 +02:00
25e899168f Bump actions-ecosystem/action-get-latest-tag from 1 to 1.4.1 (#101)
Bumps [actions-ecosystem/action-get-latest-tag](https://github.com/actions-ecosystem/action-get-latest-tag) from 1 to 1.4.1.
- [Release notes](https://github.com/actions-ecosystem/action-get-latest-tag/releases)
- [Commits](https://github.com/actions-ecosystem/action-get-latest-tag/compare/v1...v1.4.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thibault Ayanides <thibault.ayanides@ovhcloud.com>
2021-08-10 09:36:28 +02:00
9a2e3a0e0d Fix 5.4.5 pattern search (#108)
fix #107
2021-08-09 10:49:56 +02:00
334d743125 fix EXCEPTIONS management (#104)
* FIX(1.1.21, 6.1.10) fix EXCEPTIONS management
* Update changelog
* Refactor test for 6.1.10-14
2021-06-02 13:47:19 +02:00
46 changed files with 482 additions and 319 deletions

View File

@ -7,10 +7,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Produce debian man - name: Produce debian man
run: 'docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/latex:2.6 MANUAL.md -s -t man > debian/cis-hardening.8' run: 'docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/latex:2.6 MANUAL.md -s -t man > debian/cis-hardening.8'
- uses: EndBug/add-and-commit@v7 - uses: EndBug/add-and-commit@v9
with: with:
add: 'debian/cis-hardening.8' add: 'debian/cis-hardening.8'
message: 'Regenerate man pages (Github action)' message: 'Regenerate man pages (Github action)'

View File

@ -8,20 +8,20 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run the tests debian9 - name: Run the tests debian9
run: ./tests/docker_build_and_run_tests.sh debian9 run: ./tests/docker_build_and_run_tests.sh debian9
functionnal-tests-docker-debian10: functionnal-tests-docker-debian10:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run the tests debian10 - name: Run the tests debian10
run: ./tests/docker_build_and_run_tests.sh debian10 run: ./tests/docker_build_and_run_tests.sh debian10
functionnal-tests-docker-debian11: functionnal-tests-docker-debian11:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run the tests debian11 - name: Run the tests debian11
run: ./tests/docker_build_and_run_tests.sh debian11 run: ./tests/docker_build_and_run_tests.sh debian11

View File

@ -11,7 +11,7 @@ jobs:
steps: steps:
# CHECKOUT CODE # CHECKOUT CODE
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
# BUILD THE .DEB PACKAGE # BUILD THE .DEB PACKAGE
- name: Build - name: Build
run: | run: |
@ -21,7 +21,7 @@ jobs:
find ../ -name "*.deb" -exec mv {} cis-hardening.deb \; find ../ -name "*.deb" -exec mv {} cis-hardening.deb \;
# DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE # DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE
- name: Delete the tag latest and the release latest - name: Delete the tag latest and the release latest
uses: dev-drprasad/delete-tag-and-release@v0.1.3 uses: dev-drprasad/delete-tag-and-release@v0.2.0
with: with:
delete_release: true delete_release: true
tag_name: latest tag_name: latest
@ -29,12 +29,12 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# GET LATEST VERSION TAG # GET LATEST VERSION TAG
- name: Get latest version tag - name: Get latest version tag
uses: actions-ecosystem/action-get-latest-tag@v1 uses: actions-ecosystem/action-get-latest-tag@v1.5.0
id: get-latest-tag id: get-latest-tag
# GENERATE CHANGELOG CORRESPONDING TO COMMIT BETWEEN HEAD AND COMPUTED LAST TAG # GENERATE CHANGELOG CORRESPONDING TO COMMIT BETWEEN HEAD AND COMPUTED LAST TAG
- name: Generate changelog - name: Generate changelog
id: changelog id: changelog
uses: metcalfc/changelog-generator@v0.4.4 uses: metcalfc/changelog-generator@v3.0.0
with: with:
myToken: ${{ secrets.GITHUB_TOKEN }} myToken: ${{ secrets.GITHUB_TOKEN }}
head-ref: ${{ github.sha }} head-ref: ${{ github.sha }}

View File

@ -8,9 +8,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run the sh-checker - name: Run the sh-checker
uses: luizm/action-sh-checker@v0.1.12 uses: luizm/action-sh-checker@v0.3.0
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Optional if sh_checker_comment is false. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Optional if sh_checker_comment is false.
SHFMT_OPTS: -l -i 4 -w # Optional: pass arguments to shfmt. SHFMT_OPTS: -l -i 4 -w # Optional: pass arguments to shfmt.
@ -24,6 +24,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run shellcheck - name: Run shellcheck
run: ./shellcheck/docker_build_and_run_shellcheck.sh run: ./shellcheck/docker_build_and_run_shellcheck.sh

View File

@ -7,8 +7,6 @@ on:
jobs: jobs:
build: build:
name: Create Release name: Create Release
# only runs on master
if: github.event.base_ref == 'refs/heads/master'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# GET VERSION TAG # GET VERSION TAG
@ -17,7 +15,7 @@ jobs:
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
# CHECKOUT CODE # CHECKOUT CODE
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
ref: ${{ steps.vars.outputs.tag }} ref: ${{ steps.vars.outputs.tag }}
# GENERATE CHANGELOG CORRESPONDING TO ENTRY IN DEBIAN/CHANGELOG # GENERATE CHANGELOG CORRESPONDING TO ENTRY IN DEBIAN/CHANGELOG
@ -35,7 +33,7 @@ jobs:
find ../ -name "*.deb" -exec mv {} cis-hardening.deb \; find ../ -name "*.deb" -exec mv {} cis-hardening.deb \;
# DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE # DELETE THE TAG NAMED LATEST AND THE CORRESPONDING RELEASE
- name: Delete the tag latest and the release latest - name: Delete the tag latest and the release latest
uses: dev-drprasad/delete-tag-and-release@v0.1.3 uses: dev-drprasad/delete-tag-and-release@v0.2.0
with: with:
delete_release: true delete_release: true
tag_name: latest tag_name: latest

View File

@ -26,6 +26,7 @@ ALLOW_SERVICE_LIST=0
SET_HARDENING_LEVEL=0 SET_HARDENING_LEVEL=0
SUDO_MODE='' SUDO_MODE=''
BATCH_MODE='' BATCH_MODE=''
SUMMARY_JSON=''
ASK_LOGLEVEL='' ASK_LOGLEVEL=''
ALLOW_UNSUPPORTED_DISTRIBUTION=0 ALLOW_UNSUPPORTED_DISTRIBUTION=0
@ -80,7 +81,7 @@ $LONG_SCRIPT_NAME <RUN_MODE> [OPTIONS], where RUN_MODE is one of:
Modifies the policy to allow a certain kind of services on the machine, such 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. as http, mail, etc. Can be specified multiple times to allow multiple services.
Use --allow-service-list to get a list of supported services. Use --allow-service-list to get a list of supported services.
--create-config-files-only --create-config-files-only
Create the config files in etc/conf.d Create the config files in etc/conf.d
Must be run as root, before running the audit with user secaudit Must be run as root, before running the audit with user secaudit
@ -101,14 +102,18 @@ OPTIONS:
Finally note that '--sudo' mode only works for audit mode. Finally note that '--sudo' mode only works for audit mode.
--set-log-level <level> --set-log-level <level>
This option sets LOGLEVEL, you can choose : info, warning, error, ok, debug. This option sets LOGLEVEL, you can choose : info, warning, error, ok, debug or silent.
Default value is : info Default value is : info
--summary-json
While performing system audit, this option sets LOGLEVEL to silent and
only output a json summary at the end
--batch --batch
While performing system audit, this option sets LOGLEVEL to 'ok' and 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 : 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{...}] OK|KO OK|KO|WARN{subcheck results} [OK|KO|WARN{...}]
--allow-unsupported-distribution --allow-unsupported-distribution
Must be specified manually in the command line to allow the run on non compatible 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 version or distribution. If you want to mute the warning change the LOGLEVEL
@ -165,6 +170,10 @@ while [[ $# -gt 0 ]]; do
--sudo) --sudo)
SUDO_MODE='--sudo' SUDO_MODE='--sudo'
;; ;;
--summary-json)
SUMMARY_JSON='--summary-json'
ASK_LOGLEVEL=silent
;;
--batch) --batch)
BATCH_MODE='--batch' BATCH_MODE='--batch'
ASK_LOGLEVEL=ok ASK_LOGLEVEL=ok
@ -299,19 +308,19 @@ for SCRIPT in $(find "$CIS_ROOT_DIR"/bin/hardening/ -name "*.sh" | sort -V); do
info "Treating $SCRIPT" info "Treating $SCRIPT"
if [ "$CREATE_CONFIG" = 1 ]; then if [ "$CREATE_CONFIG" = 1 ]; then
debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --create-config-files-only" debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --create-config-files-only"
"$SCRIPT" --create-config-files-only "$BATCH_MODE" LOGLEVEL=$LOGLEVEL "$SCRIPT" --create-config-files-only "$BATCH_MODE"
elif [ "$AUDIT" = 1 ]; then elif [ "$AUDIT" = 1 ]; then
debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit $SUDO_MODE $BATCH_MODE" debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit $SUDO_MODE $BATCH_MODE"
"$SCRIPT" --audit "$SUDO_MODE" "$BATCH_MODE" LOGLEVEL=$LOGLEVEL "$SCRIPT" --audit "$SUDO_MODE" "$BATCH_MODE"
elif [ "$AUDIT_ALL" = 1 ]; then elif [ "$AUDIT_ALL" = 1 ]; then
debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit-all $SUDO_MODE $BATCH_MODE" debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit-all $SUDO_MODE $BATCH_MODE"
"$SCRIPT" --audit-all "$SUDO_MODE" "$BATCH_MODE" LOGLEVEL=$LOGLEVEL "$SCRIPT" --audit-all "$SUDO_MODE" "$BATCH_MODE"
elif [ "$AUDIT_ALL_ENABLE_PASSED" = 1 ]; then elif [ "$AUDIT_ALL_ENABLE_PASSED" = 1 ]; then
debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit-all $SUDO_MODE $BATCH_MODE" debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT --audit-all $SUDO_MODE $BATCH_MODE"
"$SCRIPT" --audit-all "$SUDO_MODE" "$BATCH_MODE" LOGLEVEL=$LOGLEVEL "$SCRIPT" --audit-all "$SUDO_MODE" "$BATCH_MODE"
elif [ "$APPLY" = 1 ]; then elif [ "$APPLY" = 1 ]; then
debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT" debug "$CIS_ROOT_DIR/bin/hardening/$SCRIPT"
"$SCRIPT" LOGLEVEL=$LOGLEVEL "$SCRIPT"
fi fi
SCRIPT_EXITCODE=$? SCRIPT_EXITCODE=$?
@ -355,6 +364,18 @@ if [ "$BATCH_MODE" ]; then
BATCH_SUMMARY+=" CONFORMITY_PERCENTAGE:N.A" # No check runned, avoid division by 0 BATCH_SUMMARY+=" CONFORMITY_PERCENTAGE:N.A" # No check runned, avoid division by 0
fi fi
becho "$BATCH_SUMMARY" becho "$BATCH_SUMMARY"
elif [ "$SUMMARY_JSON" ]; then
if [ "$TOTAL_TREATED_CHECKS" != 0 ]; then
CONFORMITY_PERCENTAGE=$(div $((PASSED_CHECKS * 100)) $TOTAL_TREATED_CHECKS)
else
CONFORMITY_PERCENTAGE=0 # No check runned, avoid division by 0
fi
printf '{'
printf '"available_checks": %s, ' "$TOTAL_CHECKS"
printf '"run_checks": %s, ' "$TOTAL_TREATED_CHECKS"
printf '"passed_checks": %s, ' "$PASSED_CHECKS"
printf '"conformity_percentage": %s' "$CONFORMITY_PERCENTAGE"
printf '}\n'
else else
printf "%40s\n" "################### SUMMARY ###################" printf "%40s\n" "################### SUMMARY ###################"
printf "%30s %s\n" "Total Available Checks :" "$TOTAL_CHECKS" printf "%30s %s\n" "Total Available Checks :" "$TOTAL_CHECKS"

View File

@ -26,7 +26,7 @@ audit() {
# In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it # In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it
ok "Container detected, consider host enforcing or disable this check!" ok "Container detected, consider host enforcing or disable this check!"
else else
is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" "($MODULE_NAME|install)"
if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated
crit "$MODULE_NAME is enabled!" crit "$MODULE_NAME is enabled!"
else else
@ -41,7 +41,7 @@ apply() {
# In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it # In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it
ok "Container detected, consider host enforcing!" ok "Container detected, consider host enforcing!"
else else
is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" "($MODULE_NAME|install)"
if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated
warn "I cannot fix $MODULE_NAME, recompile your kernel or blacklist module $MODULE_NAME (/etc/modprobe.d/blacklist.conf : +install $MODULE_NAME /bin/true)" warn "I cannot fix $MODULE_NAME, recompile your kernel or blacklist module $MODULE_NAME (/etc/modprobe.d/blacklist.conf : +install $MODULE_NAME /bin/true)"
else else

View File

@ -26,7 +26,7 @@ audit() {
# In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it # In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it
ok "Container detected, consider host enforcing or disable this check!" ok "Container detected, consider host enforcing or disable this check!"
else else
is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" "($MODULE_NAME|install)"
if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated
crit "$MODULE_NAME is enabled!" crit "$MODULE_NAME is enabled!"
else else
@ -41,7 +41,7 @@ apply() {
# In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it # In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it
ok "Container detected, consider host enforcing!" ok "Container detected, consider host enforcing!"
else else
is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" "($MODULE_NAME|install)"
if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated
warn "I cannot fix $MODULE_NAME, recompile your kernel or blacklist module $MODULE_NAME (/etc/modprobe.d/blacklist.conf : +install $MODULE_NAME /bin/true)" warn "I cannot fix $MODULE_NAME, recompile your kernel or blacklist module $MODULE_NAME (/etc/modprobe.d/blacklist.conf : +install $MODULE_NAME /bin/true)"
else else

View File

@ -23,21 +23,14 @@ EXCEPTIONS=''
audit() { audit() {
info "Checking if setuid is set on world writable Directories" info "Checking if setuid is set on world writable Directories"
FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}') FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}')
# shellcheck disable=SC2086 if [ -n "$EXCEPTIONS" ]; then
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print 2>/dev/null) # shellcheck disable=SC2086
IFS_BAK=$IFS RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type d \( -perm -0002 -a ! -perm -1000 \) -regextype 'egrep' ! -regex $EXCEPTIONS -print 2>/dev/null)
IFS=$'\n' else
for LINE in $RESULT; do # shellcheck disable=SC2086
debug "line : $LINE" RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type d \( -perm -0002 -a ! -perm -1000 \) -print 2>/dev/null)
if echo "$EXCEPTIONS" | grep -q "$LINE"; then fi
debug "$LINE is confirmed as an exception"
# shellcheck disable=SC2001
RESULT=$(sed "s!$LINE!!" <<<"$RESULT")
else
debug "$LINE not found in exceptions"
fi
done
IFS=$IFS_BAK
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
crit "Some world writable directories are not on sticky bit mode!" crit "Some world writable directories are not on sticky bit mode!"
# shellcheck disable=SC2001 # shellcheck disable=SC2001
@ -50,42 +43,25 @@ audit() {
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print 2>/dev/null) if [ -n "$EXCEPTIONS" ]; then
IFS_BAK=$IFS # shellcheck disable=SC2086
IFS=$'\n' RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type d \( -perm -0002 -a ! -perm -1000 \) -regextype 'egrep' ! -regex $EXCEPTIONS -print 2>/dev/null)
for LINE in $RESULT; do else
debug "line : $LINE" RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type d \( -perm -0002 -a ! -perm -1000 \) -print 2>/dev/null)
if echo "$EXCEPTIONS" | grep -q "$ACCOUNT"; then fi
debug "$ACCOUNT is confirmed as an exception"
# shellcheck disable=SC2001
RESULT=$(sed "s!$LINE!!" <<<"$RESULT")
else
debug "$ACCOUNT not found in exceptions"
fi
done
IFS=$IFS_BAK
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
warn "Setting sticky bit on world writable directories" warn "Setting sticky bit on world writable directories"
df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type d -perm -0002 2>/dev/null | xargs chmod a+t
else else
ok "All world writable directories have a sticky bit, nothing to apply" ok "All world writable directories have a sticky bit, nothing to apply"
fi fi
} }
# This function will create the config file for this check with default values
create_config() {
cat <<EOF
status=audit
# Put here your exceptions separated by spaces
EXCEPTIONS=""
EOF
}
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
if [ -z "$EXCEPTIONS" ]; then # No param for this function
EXCEPTIONS="@" :
fi
} }
# Source Root Dir Parameter # Source Root Dir Parameter

View File

@ -23,6 +23,7 @@ FILE='/boot/grub/grub.cfg'
USER='root' USER='root'
GROUP='root' GROUP='root'
PERMISSIONS='400' PERMISSIONS='400'
PERMISSIONSOK='400 600'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
@ -33,7 +34,7 @@ audit() {
crit "$FILE ownership was not set to $USER:$GROUP" crit "$FILE ownership was not set to $USER:$GROUP"
fi fi
has_file_correct_permissions "$FILE" "$PERMISSIONS" has_file_one_of_permissions "$FILE" "$PERMISSIONSOK"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" = 0 ]; then
ok "$FILE has correct permissions" ok "$FILE has correct permissions"
else else
@ -51,7 +52,7 @@ apply() {
chown "$USER":"$GROUP" "$FILE" chown "$USER":"$GROUP" "$FILE"
fi fi
has_file_correct_permissions "$FILE" "$PERMISSIONS" has_file_one_of_permissions "$FILE" "$PERMISSIONSOK"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" = 0 ]; then
ok "$FILE has correct permissions" ok "$FILE has correct permissions"
else else
@ -63,7 +64,7 @@ apply() {
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
is_pkg_installed "grub-pc" is_pkg_installed "grub-common"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
warn "Grub is not installed, not handling configuration" warn "Grub is not installed, not handling configuration"
exit 2 exit 2

View File

@ -55,9 +55,9 @@ apply() {
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
is_pkg_installed "grub-pc" is_pkg_installed "grub-common"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
warn "grub-pc is not installed, not handling configuration" warn "Grub is not installed, not handling configuration"
exit 2 exit 2
fi fi
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then

View File

@ -33,7 +33,7 @@ audit() {
done done
if [ "$ERROR" = 0 ]; then if [ "$ERROR" = 0 ]; then
is_pkg_installed "grub-pc" is_pkg_installed "grub-common"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
if [ "$IS_CONTAINER" -eq 1 ]; then if [ "$IS_CONTAINER" -eq 1 ]; then
ok "Grub is not installed in container" ok "Grub is not installed in container"

View File

@ -32,8 +32,8 @@ audit() {
fi fi
done done
if [ "$ERROR" = 0 ]; then if [ "$ERROR" = 0 ]; then
RESULT_UNCONFINED=$($SUDO_CMD apparmor_status | grep "^0 processes are unconfined but have a profile defined") RESULT_UNCONFINED=$($SUDO_CMD apparmor_status | grep "^0 processes are unconfined but have a profile defined" || true)
RESULT_COMPLAIN=$($SUDO_CMD apparmor_status | grep "^0 profiles are in complain mode.") RESULT_COMPLAIN=$($SUDO_CMD apparmor_status | grep "^0 profiles are in complain mode." || true)
if [ -n "$RESULT_UNCONFINED" ]; then if [ -n "$RESULT_UNCONFINED" ]; then
ok "No profiles are unconfined" ok "No profiles are unconfined"
@ -61,8 +61,8 @@ apply() {
fi fi
done done
RESULT_UNCONFINED=$(apparmor_status | grep "^0 processes are unconfined but have a profile defined") RESULT_UNCONFINED=$(apparmor_status | grep "^0 processes are unconfined but have a profile defined" || true)
RESULT_COMPLAIN=$(apparmor_status | grep "^0 profiles are in complain mode.") RESULT_COMPLAIN=$(apparmor_status | grep "^0 profiles are in complain mode." || true)
if [ -n "$RESULT_UNCONFINED" ]; then if [ -n "$RESULT_UNCONFINED" ]; then
ok "No profiles are unconfined" ok "No profiles are unconfined"

View File

@ -25,17 +25,11 @@ CONF_FILE='/etc/chrony/chrony.conf'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
is_pkg_installed "$PACKAGE" does_pattern_exist_in_file "$CONF_FILE" "$CONF_DEFAULT_PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
crit "$PACKAGE is not installed!" crit "$CONF_DEFAULT_PATTERN not found in $CONF_FILE"
else else
ok "$PACKAGE is installed, checking configuration" ok "$CONF_DEFAULT_PATTERN found in $CONF_FILE"
does_pattern_exist_in_file "$CONF_FILE" "$CONF_DEFAULT_PATTERN"
if [ "$FNRET" != 0 ]; then
crit "$CONF_DEFAULT_PATTERN not found in $CONF_FILE"
else
ok "$CONF_DEFAULT_PATTERN found in $CONF_FILE"
fi
fi fi
} }
@ -46,7 +40,11 @@ apply() {
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
: is_pkg_installed "$PACKAGE"
if [ "$FNRET" != 0 ]; then
warn "$PACKAGE is not installed, not handling configuration"
exit 2
fi
} }
# Source Root Dir Parameter # Source Root Dir Parameter

View File

@ -20,30 +20,24 @@ DESCRIPTION="Configure Network Time Protocol (ntp). Check restrict parameters an
HARDENING_EXCEPTION=ntp HARDENING_EXCEPTION=ntp
PACKAGE='ntp' PACKAGE='ntp'
NTP_CONF_DEFAULT_PATTERN='^restrict -4 default (kod nomodify notrap nopeer noquery|ignore)' NTP_CONF_DEFAULT_PATTERN='^restrict -4 default (kod nomodify notrap nopeer noquery|kod notrap nomodify nopeer noquery|ignore)'
NTP_CONF_FILE='/etc/ntp.conf' NTP_CONF_FILE='/etc/ntp.conf'
NTP_INIT_PATTERN='RUNASUSER=ntp' NTP_INIT_PATTERN='RUNASUSER=ntp'
NTP_INIT_FILE='/etc/init.d/ntp' NTP_INIT_FILE='/etc/init.d/ntp'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
is_pkg_installed "$PACKAGE" does_pattern_exist_in_file "$NTP_CONF_FILE" "$NTP_CONF_DEFAULT_PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
crit "$PACKAGE is not installed!" crit "$NTP_CONF_DEFAULT_PATTERN not found in $NTP_CONF_FILE"
else else
ok "$PACKAGE is installed, checking configuration" ok "$NTP_CONF_DEFAULT_PATTERN found in $NTP_CONF_FILE"
does_pattern_exist_in_file "$NTP_CONF_FILE" "$NTP_CONF_DEFAULT_PATTERN" fi
if [ "$FNRET" != 0 ]; then does_pattern_exist_in_file "$NTP_INIT_FILE" "^$NTP_INIT_PATTERN"
crit "$NTP_CONF_DEFAULT_PATTERN not found in $NTP_CONF_FILE" if [ "$FNRET" != 0 ]; then
else crit "$NTP_INIT_PATTERN not found in $NTP_INIT_FILE"
ok "$NTP_CONF_DEFAULT_PATTERN found in $NTP_CONF_FILE" else
fi ok "$NTP_INIT_PATTERN found in $NTP_INIT_FILE"
does_pattern_exist_in_file "$NTP_INIT_FILE" "^$NTP_INIT_PATTERN"
if [ "$FNRET" != 0 ]; then
crit "$NTP_INIT_PATTERN not found in $NTP_INIT_FILE"
else
ok "$NTP_INIT_PATTERN found in $NTP_INIT_FILE"
fi
fi fi
} }
@ -77,7 +71,11 @@ apply() {
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
: is_pkg_installed "$PACKAGE"
if [ "$FNRET" != 0 ]; then
warn "$PACKAGE is not installed, not handling configuration"
exit 2
fi
} }
# Source Root Dir Parameter # Source Root Dir Parameter

View File

@ -28,7 +28,7 @@ audit() {
# In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it # In an unprivileged container, the kernel modules are host dependent, so you should consider enforcing it
ok "Container detected, consider host enforcing or disable this check!" ok "Container detected, consider host enforcing or disable this check!"
else else
is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" is_kernel_option_enabled "$KERNEL_OPTION" "$MODULE_NAME" "($MODULE_NAME|install)"
if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated if [ "$FNRET" = 0 ]; then # 0 means true in bash, so it IS activated
crit "$MODULE_NAME is enabled!" crit "$MODULE_NAME is enabled!"
else else

View File

@ -20,6 +20,7 @@ DESCRIPTION="Check iptables firewall default policy for DROP on INPUT and FORWAR
PACKAGE="iptables" PACKAGE="iptables"
FW_CHAINS="INPUT FORWARD" FW_CHAINS="INPUT FORWARD"
FW_POLICY="DROP" FW_POLICY="DROP"
FW_CMD="iptables"
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
@ -27,9 +28,9 @@ audit() {
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
crit "$PACKAGE is not installed!" crit "$PACKAGE is not installed!"
else else
ipt=$($SUDO_CMD "$PACKAGE" -nL 2>/dev/null || true) ipt=$($SUDO_CMD "$FW_CMD" -nL 2>/dev/null || true)
if [[ -z "$ipt" ]]; then if [[ -z "$ipt" ]]; then
crit "Empty return from $PACKAGE command. Aborting..." crit "Empty return from $FW_CMD command. Aborting..."
return return
fi fi
for chain in $FW_CHAINS; do for chain in $FW_CHAINS; do

View File

@ -19,7 +19,7 @@ DESCRIPTION="Collect use of privileged commands."
SUDO_CMD='sudo -n' SUDO_CMD='sudo -n'
# Find all files with setuid or setgid set # Find all files with setuid or setgid set
AUDIT_PARAMS=$($SUDO_CMD find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | AUDIT_PARAMS=$($SUDO_CMD find / -xdev -ignore_readdir_race \( -perm -4000 -o -perm -2000 \) -type f |
awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged" }') awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged" }')
FILE='/etc/audit/audit.rules' FILE='/etc/audit/audit.rules'

View File

@ -31,7 +31,7 @@ audit() {
debug "$FILE_SEARCHED is a directory" debug "$FILE_SEARCHED is a directory"
# shellcheck disable=2044 # shellcheck disable=2044
for file_in_dir in $(find "$FILE_SEARCHED" -type f); do for file_in_dir in $(find "$FILE_SEARCHED" -type f); do
does_pattern_exist_in_file "$file_in_dir" "^$PATTERN" does_pattern_exist_in_file "$file_in_dir" "$PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
debug "$PATTERN is not present in $FILE_SEARCHED/$file_in_dir" debug "$PATTERN is not present in $FILE_SEARCHED/$file_in_dir"
else else
@ -41,7 +41,7 @@ audit() {
fi fi
done done
else else
does_pattern_exist_in_file "$FILE_SEARCHED" "^$PATTERN" does_pattern_exist_in_file "$FILE_SEARCHED" "$PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
debug "$PATTERN is not present in $FILE_SEARCHED" debug "$PATTERN is not present in $FILE_SEARCHED"
else else
@ -64,7 +64,7 @@ apply() {
debug "$FILE_SEARCHED is a directory" debug "$FILE_SEARCHED is a directory"
# shellcheck disable=2044 # shellcheck disable=2044
for file_in_dir in $(find "$FILE_SEARCHED" -type f); do for file_in_dir in $(find "$FILE_SEARCHED" -type f); do
does_pattern_exist_in_file "$FILE_SEARCHED/$file_in_dir" "^$PATTERN" does_pattern_exist_in_file "$FILE_SEARCHED/$file_in_dir" "$PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
debug "$PATTERN is not present in $FILE_SEARCHED/$file_in_dir" debug "$PATTERN is not present in $FILE_SEARCHED/$file_in_dir"
else else
@ -74,7 +74,7 @@ apply() {
fi fi
done done
else else
does_pattern_exist_in_file "$FILE_SEARCHED" "^$PATTERN" does_pattern_exist_in_file "$FILE_SEARCHED" "$PATTERN"
if [ "$FNRET" != 0 ]; then if [ "$FNRET" != 0 ]; then
debug "$PATTERN is not present in $FILE_SEARCHED" debug "$PATTERN is not present in $FILE_SEARCHED"
else else
@ -87,8 +87,7 @@ apply() {
warn "$PATTERN is not present in $FILES_TO_SEARCH" warn "$PATTERN is not present in $FILES_TO_SEARCH"
touch "$FILE" touch "$FILE"
chmod 644 "$FILE" chmod 644 "$FILE"
add_end_of_file "$FILE" "$PATTERN$VALUE" add_end_of_file "$FILE" "readonly $PATTERN$VALUE"
add_end_of_file "$FILE" "readonly TMOUT"
add_end_of_file "$FILE" "export TMOUT" add_end_of_file "$FILE" "export TMOUT"
else else
ok "$PATTERN is present in $FILES_TO_SEARCH" ok "$PATTERN is present in $FILES_TO_SEARCH"

View File

@ -17,27 +17,21 @@ HARDENING_LEVEL=3
# shellcheck disable=2034 # shellcheck disable=2034
DESCRIPTION="Ensure no world writable files exist" DESCRIPTION="Ensure no world writable files exist"
EXCEPTIONS='' EXCLUDED=''
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
info "Checking if there are world writable files" info "Checking if there are world writable files"
FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}') FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}')
# shellcheck disable=SC2086
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -type f -perm -0002 -print 2>/dev/null) if [ -n "$EXCLUDED" ]; then
IFS_BAK=$IFS # shellcheck disable=SC2086
IFS=$'\n' RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -0002 -regextype 'egrep' ! -regex $EXCLUDED -print 2>/dev/null)
for LINE in $RESULT; do else
debug "line : $LINE" # shellcheck disable=SC2086
if echo "$EXCEPTIONS" | grep -q "$LINE"; then RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -0002 -print 2>/dev/null)
debug "$LINE is confirmed as an exception" fi
# shellcheck disable=SC2001
RESULT=$(sed "s!$LINE!!" <<<"$RESULT")
else
debug "$LINE not found in exceptions"
fi
done
IFS=$IFS_BAK
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
crit "Some world writable files are present" crit "Some world writable files are present"
# shellcheck disable=SC2001 # shellcheck disable=SC2001
@ -50,42 +44,25 @@ audit() {
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 -print 2>/dev/null) if [ -n "$EXCLUDED" ]; then
IFS_BAK=$IFS # shellcheck disable=SC2086
IFS=$'\n' RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type f -perm -0002 -regextype 'egrep' ! -regex $EXCLUDED -print 2>/dev/null)
for LINE in $RESULT; do else
debug "line : $LINE" RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type f -perm -0002 -print 2>/dev/null)
if echo "$EXCEPTIONS" | grep -q "$ACCOUNT"; then fi
debug "$ACCOUNT is confirmed as an exception"
# shellcheck disable=SC2001
RESULT=$(sed "s!$LINE!!" <<<"$RESULT")
else
debug "$ACCOUNT not found in exceptions"
fi
done
IFS=$IFS_BAK
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
warn "chmoding o-w all files in the system" warn "chmoding o-w all files in the system"
df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 -print 2>/dev/null | xargs chmod o-w df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -type f -perm -0002 -print 2>/dev/null | xargs chmod o-w
else else
ok "No world writable files found, nothing to apply" ok "No world writable files found, nothing to apply"
fi fi
} }
# This function will create the config file for this check with default values
create_config() {
cat <<EOF
status=audit
# Put here your exceptions separated by spaces
EXCEPTIONS=""
EOF
}
# This function will check config parameters required # This function will check config parameters required
check_config() { check_config() {
if [ -z "$EXCEPTIONS" ]; then # No param for this function
EXCEPTIONS="@" :
fi
} }
# Source Root Dir Parameter # Source Root Dir Parameter

View File

@ -26,10 +26,10 @@ audit() {
FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}') FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}')
if [ -n "$EXCLUDED" ]; then if [ -n "$EXCLUDED" ]; then
# shellcheck disable=SC2086 # shellcheck disable=SC2086
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -nouser -regextype 'egrep' ! -regex "$EXCLUDED" -print 2>/dev/null) RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -nouser -regextype 'egrep' ! -regex $EXCLUDED -print 2>/dev/null)
else else
# shellcheck disable=SC2086 # shellcheck disable=SC2086
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -nouser -print 2>/dev/null) RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -nouser -print 2>/dev/null)
fi fi
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
crit "Some unowned files are present" crit "Some unowned files are present"
@ -44,13 +44,14 @@ audit() {
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
if [ -n "$EXCLUDED" ]; then if [ -n "$EXCLUDED" ]; then
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser -regextype 'egrep' ! -regex "$EXCLUDED" -ls 2>/dev/null) # shellcheck disable=SC2086
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nouser -regextype 'egrep' ! -regex $EXCLUDED -ls 2>/dev/null)
else else
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser -ls 2>/dev/null) RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nouser -ls 2>/dev/null)
fi fi
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
warn "Applying chown on all unowned files in the system" warn "Applying chown on all unowned files in the system"
df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser -print 2>/dev/null | xargs chown "$USER" df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nouser -print 2>/dev/null | xargs chown "$USER"
else else
ok "No unowned files found, nothing to apply" ok "No unowned files found, nothing to apply"
fi fi

View File

@ -26,10 +26,10 @@ audit() {
FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}') FS_NAMES=$(df --local -P | awk '{if (NR!=1) print $6}')
if [ -n "$EXCLUDED" ]; then if [ -n "$EXCLUDED" ]; then
# shellcheck disable=SC2086 # shellcheck disable=SC2086
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -nogroup -regextype 'egrep' ! -regex "$EXCLUDED" -print 2>/dev/null) RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -nogroup -regextype 'egrep' ! -regex $EXCLUDED -print 2>/dev/null)
else else
# shellcheck disable=SC2086 # shellcheck disable=SC2086
RESULT=$($SUDO_CMD find $FS_NAMES -xdev -nogroup -print 2>/dev/null) RESULT=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -nogroup -print 2>/dev/null)
fi fi
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
crit "Some ungrouped files are present" crit "Some ungrouped files are present"
@ -44,13 +44,14 @@ audit() {
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
if [ -n "$EXCLUDED" ]; then if [ -n "$EXCLUDED" ]; then
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup -regextype 'egrep' ! -regex "$EXCLUDED" -ls 2>/dev/null) # shellcheck disable=SC2086
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nogroup -regextype 'egrep' ! -regex $EXCLUDED -ls 2>/dev/null)
else else
RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup -ls 2>/dev/null) RESULT=$(df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nogroup -ls 2>/dev/null)
fi fi
if [ -n "$RESULT" ]; then if [ -n "$RESULT" ]; then
warn "Applying chgrp on all ungrouped files in the system" warn "Applying chgrp on all ungrouped files in the system"
df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup -print 2>/dev/null | xargs chgrp "$GROUP" df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -ignore_readdir_race -nogroup -print 2>/dev/null | xargs chgrp "$GROUP"
else else
ok "No ungrouped files found, nothing to apply" ok "No ungrouped files found, nothing to apply"
fi fi

View File

@ -24,9 +24,9 @@ audit() {
FS_NAMES=$(df --local -P | awk '{ if (NR!=1) print $6 }') FS_NAMES=$(df --local -P | awk '{ if (NR!=1) print $6 }')
# shellcheck disable=2086 # shellcheck disable=2086
if [ -n "$IGNORED_PATH" ]; then if [ -n "$IGNORED_PATH" ]; then
FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -type f -perm -4000 -regextype 'egrep' ! -regex "$IGNORED_PATH" -print) FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -4000 -regextype 'egrep' ! -regex $IGNORED_PATH -print)
else else
FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -type f -perm -4000 -print) FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -4000 -print)
fi fi
BAD_BINARIES="" BAD_BINARIES=""
for BINARY in $FOUND_BINARIES; do for BINARY in $FOUND_BINARIES; do

View File

@ -24,9 +24,9 @@ audit() {
FS_NAMES=$(df --local -P | awk '{ if (NR!=1) print $6 }') FS_NAMES=$(df --local -P | awk '{ if (NR!=1) print $6 }')
# shellcheck disable=2086 # shellcheck disable=2086
if [ -n "$IGNORED_PATH" ]; then if [ -n "$IGNORED_PATH" ]; then
FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -type f -perm -2000 -regextype 'egrep' ! -regex "$IGNORED_PATH" -print) FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -2000 -regextype 'egrep' ! -regex $IGNORED_PATH -print)
else else
FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -type f -perm -2000 -print) FOUND_BINARIES=$($SUDO_CMD find $FS_NAMES -xdev -ignore_readdir_race -type f -perm -2000 -print)
fi fi
BAD_BINARIES="" BAD_BINARIES=""
for BINARY in $FOUND_BINARIES; do for BINARY in $FOUND_BINARIES; do

View File

@ -25,35 +25,45 @@ GROUPSOK='root shadow'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
crit "$FILE permissions were not set to $PERMISSIONS" has_file_correct_permissions "$FILE" "$PERMISSIONS"
fi if [ "$FNRET" = 0 ]; then
has_file_one_of_ownership "$FILE" "$USER" "$GROUPSOK" ok "$FILE has correct permissions"
if [ "$FNRET" = 0 ]; then else
ok "$FILE has correct ownership" crit "$FILE permissions were not set to $PERMISSIONS"
else fi
crit "$FILE ownership was not set to $USER:$GROUPSOK" has_file_one_of_ownership "$FILE" "$USER" "$GROUPSOK"
if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
crit "$FILE ownership was not set to $USER:$GROUPSOK"
fi
fi fi
} }
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
info "fixing $FILE permissions to $PERMISSIONS" has_file_correct_permissions "$FILE" "$PERMISSIONS"
chmod 0"$PERMISSIONS" "$FILE" if [ "$FNRET" = 0 ]; then
fi ok "$FILE has correct permissions"
has_file_one_of_ownership "$FILE" "$USER" "$GROUPSOK" else
if [ "$FNRET" = 0 ]; then info "fixing $FILE permissions to $PERMISSIONS"
ok "$FILE has correct ownership" chmod 0"$PERMISSIONS" "$FILE"
else fi
info "fixing $FILE ownership to $USER:$GROUP" has_file_one_of_ownership "$FILE" "$USER" "$GROUPSOK"
chown "$USER":"$GROUP" "$FILE" if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
info "fixing $FILE ownership to $USER:$GROUP"
chown "$USER":"$GROUP" "$FILE"
fi
fi fi
} }

View File

@ -19,40 +19,51 @@ DESCRIPTION="Check 600 permissions and root:root ownership on /etc/passwd-"
FILE='/etc/passwd-' FILE='/etc/passwd-'
PERMISSIONS='600' PERMISSIONS='600'
PERMISSIONSOK='644 640 600'
USER='root' USER='root'
GROUP='root' GROUP='root'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
crit "$FILE permissions were not set to $PERMISSIONS" has_file_one_of_permissions "$FILE" "$PERMISSIONSOK"
fi if [ "$FNRET" = 0 ]; then
has_file_correct_ownership "$FILE" "$USER" "$GROUP" ok "$FILE has correct permissions"
if [ "$FNRET" = 0 ]; then else
ok "$FILE has correct ownership" crit "$FILE permissions were not set to $PERMISSIONS"
else fi
crit "$FILE ownership was not set to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
crit "$FILE ownership was not set to $USER:$GROUP"
fi
fi fi
} }
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
info "fixing $FILE permissions to $PERMISSIONS" has_file_correct_permissions "$FILE" "$PERMISSIONS"
chmod 0"$PERMISSIONS" "$FILE" if [ "$FNRET" = 0 ]; then
fi ok "$FILE has correct permissions"
has_file_correct_ownership "$FILE" "$USER" "$GROUP" else
if [ "$FNRET" = 0 ]; then info "fixing $FILE permissions to $PERMISSIONS"
ok "$FILE has correct ownership" chmod 0"$PERMISSIONS" "$FILE"
else fi
info "fixing $FILE ownership to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
chown "$USER":"$GROUP" "$FILE" if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
info "fixing $FILE ownership to $USER:$GROUP"
chown "$USER":"$GROUP" "$FILE"
fi
fi fi
} }

View File

@ -19,40 +19,51 @@ DESCRIPTION="Check 600 permissions and root:shadow ownership on /etc/shadow-"
FILE='/etc/shadow-' FILE='/etc/shadow-'
PERMISSIONS='600' PERMISSIONS='600'
PERMISSIONSOK='640 600'
USER='root' USER='root'
GROUP='shadow' GROUP='shadow'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
crit "$FILE permissions were not set to $PERMISSIONS" has_file_one_of_permissions "$FILE" "$PERMISSIONSOK"
fi if [ "$FNRET" = 0 ]; then
has_file_correct_ownership "$FILE" "$USER" "$GROUP" ok "$FILE has correct permissions"
if [ "$FNRET" = 0 ]; then else
ok "$FILE has correct ownership" crit "$FILE permissions were not set to $PERMISSIONS"
else fi
crit "$FILE ownership was not set to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
crit "$FILE ownership was not set to $USER:$GROUP"
fi
fi fi
} }
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
info "fixing $FILE permissions to $PERMISSIONS" has_file_correct_permissions "$FILE" "$PERMISSIONS"
chmod 0"$PERMISSIONS" "$FILE" if [ "$FNRET" = 0 ]; then
fi ok "$FILE has correct permissions"
has_file_correct_ownership "$FILE" "$USER" "$GROUP" else
if [ "$FNRET" = 0 ]; then info "fixing $FILE permissions to $PERMISSIONS"
ok "$FILE has correct ownership" chmod 0"$PERMISSIONS" "$FILE"
else fi
info "fixing $FILE ownership to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
chown "$USER":"$GROUP" "$FILE" if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
info "fixing $FILE ownership to $USER:$GROUP"
chown "$USER":"$GROUP" "$FILE"
fi
fi fi
} }

View File

@ -19,40 +19,51 @@ DESCRIPTION="Check 600 permissions and root:root ownership on /etc/group-"
FILE='/etc/group-' FILE='/etc/group-'
PERMISSIONS='600' PERMISSIONS='600'
PERMISSIONSOK='644 640 600'
USER='root' USER='root'
GROUP='root' GROUP='root'
# This function will be called if the script status is on enabled / audit mode # This function will be called if the script status is on enabled / audit mode
audit() { audit() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
crit "$FILE permissions were not set to $PERMISSIONS" has_file_one_of_permissions "$FILE" "$PERMISSIONSOK"
fi if [ "$FNRET" = 0 ]; then
has_file_correct_ownership "$FILE" "$USER" "$GROUP" ok "$FILE has correct permissions"
if [ "$FNRET" = 0 ]; then else
ok "$FILE has correct ownership" crit "$FILE permissions were not set to $PERMISSIONS"
else fi
crit "$FILE ownership was not set to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
crit "$FILE ownership was not set to $USER:$GROUP"
fi
fi fi
} }
# This function will be called if the script status is on enabled mode # This function will be called if the script status is on enabled mode
apply() { apply() {
has_file_correct_permissions "$FILE" "$PERMISSIONS" does_file_exist "$FILE"
if [ "$FNRET" = 0 ]; then if [ "$FNRET" != 0 ]; then
ok "$FILE has correct permissions" ok "$FILE does not exist"
else else
info "fixing $FILE permissions to $PERMISSIONS" has_file_correct_permissions "$FILE" "$PERMISSIONS"
chmod 0"$PERMISSIONS" "$FILE" if [ "$FNRET" = 0 ]; then
fi ok "$FILE has correct permissions"
has_file_correct_ownership "$FILE" "$USER" "$GROUP" else
if [ "$FNRET" = 0 ]; then info "fixing $FILE permissions to $PERMISSIONS"
ok "$FILE has correct ownership" chmod 0"$PERMISSIONS" "$FILE"
else fi
info "fixing $FILE ownership to $USER:$GROUP" has_file_correct_ownership "$FILE" "$USER" "$GROUP"
chown "$USER":"$GROUP" "$FILE" if [ "$FNRET" = 0 ]; then
ok "$FILE has correct ownership"
else
info "fixing $FILE ownership to $USER:$GROUP"
chown "$USER":"$GROUP" "$FILE"
fi
fi fi
} }

View File

@ -49,7 +49,6 @@ apply() {
info "Parameter $SSH_PARAM is present but with the wrong value -- Fixing" 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" replace_in_file "$CONF_FILE" "^$(echo "$CONF_LINE" | cut -d ' ' -f1)[[:space:]]*.*" "$CONF_LINE"
fi fi
/etc/init.d/ssh reload >/dev/null 2>&1
fi fi
} }

View File

@ -37,7 +37,7 @@ audit() {
pw_found+="$user " pw_found+="$user "
ok "User $user has a disabled password." ok "User $user has a disabled password."
# Check password against $6$<salt>$<encrypted>, see `man 3 crypt` # 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 elif [[ $passwd =~ ^\$6(\$rounds=[0-9]+)?\$[a-zA-Z0-9./]{2,16}\$[a-zA-Z0-9./]{86}$ ]]; then
pw_found+="$user " pw_found+="$user "
ok "User $user has suitable SHA512 hashed password." ok "User $user has suitable SHA512 hashed password."
else else

44
debian/changelog vendored
View File

@ -1,3 +1,47 @@
cis-hardening (3.4-1) unstable; urgency=medium
* fix: allow passwd-, group- and shadow- debian default permissions (#149)
-- Thibault Dewailly <thibault.dewailly@ovhcloud.com> Fri, 18 Mar 2022 15:43:24 +0000
cis-hardening (3.3-1) unstable; urgency=medium
* fix: missing shadowtools backup files is ok (#132)
* feat: Dissociate iptables pkg name from command (#137)
* fix: Catch unexpected failures (#140)
* fix: Avoid find failures on too many files (#144)
-- Tarik Megzari <tarik.megzari@corp.ovh.com> Wed, 02 Mar 2022 13:25:33 +0100
cis-hardening (3.2-2) unstable; urgency=medium
* Fix empty fstab test
-- Tarik Megzari <tarik.megzari@corp.ovh.com> Wed, 08 Dec 2021 13:59:49 +0100
cis-hardening (3.2-1) unstable; urgency=medium
- Skip NTP and Chrony config check if they are not installed (#120)
- Fix 3.4.2 audit rule (#123)
- Fix grub detection (#119)
- Allow grub.cfg permission to be 600 (#121)
- Honor --set-log-level parameter (#127)
- fix: kernel module detection (#129)
- Add silent mode and json summary (#128)
- FIX(1.7.1.4): don't abort script in case of unconfined processes (#130)
- FIX(2.2.1.4): Validate debian default ntp config (#118)
- 99.5.4.5.2: fix bug where sha512 option rounds provoke KO (#112)
- Fix 5.4.5 pattern search (#108)
-- Thibault Dewailly <thibault.dewailly@ovhcloud.com> Wed, 01 Dec 2021 10:56:47 +0000
cis-hardening (3.1-6) unstable; urgency=medium
* Improve EXCEPTIONS management (1.1.21,6.1.10)
* Fix bug linked with regex quoting (6.1.10-11-12-13-14)
-- Thibault Ayanides <thibault.ayanides@ovhcloud.com> Wed, 02 Jun 2021 09:45:40 +0200
cis-hardening (3.1-5) unstable; urgency=medium cis-hardening (3.1-5) unstable; urgency=medium
* Fix unbound EXCEPTIONS variable in some cases * Fix unbound EXCEPTIONS variable in some cases

View File

@ -25,6 +25,9 @@ backup_file() {
# #
case $LOGLEVEL in case $LOGLEVEL in
silent)
MACHINE_LOG_LEVEL=0
;;
error) error)
MACHINE_LOG_LEVEL=1 MACHINE_LOG_LEVEL=1
;; ;;
@ -100,6 +103,20 @@ debug() {
if [ "$MACHINE_LOG_LEVEL" -ge 5 ]; then _logger "$GRAY" "[DBG ] $*"; fi if [ "$MACHINE_LOG_LEVEL" -ge 5 ]; then _logger "$GRAY" "[DBG ] $*"; fi
} }
exception() {
# Trap exit code is the same as the trapped one unless we call an explicit exit
TRAP_CODE=$?
if [ "$ACTIONS_DONE" -ne 1 ]; then
if [ "$BATCH_MODE" -eq 1 ]; then
BATCH_OUTPUT="KO $SCRIPT_NAME $BATCH_OUTPUT KO{Unexpected exit code: $TRAP_CODE}"
becho "$BATCH_OUTPUT"
else
crit "Check failed with unexpected exit code: $TRAP_CODE"
fi
exit 1 # Means critical status
fi
}
# #
# sudo wrapper # sudo wrapper
# issue crit state if not allowed to perform sudo # issue crit state if not allowed to perform sudo

View File

@ -10,9 +10,17 @@ BATCH_OUTPUT=""
status="" status=""
forcedstatus="" forcedstatus=""
SUDO_CMD="" SUDO_CMD=""
SAVED_LOGLEVEL=""
ACTIONS_DONE=0
if [ -n "${LOGLEVEL:-}" ]; then
SAVED_LOGLEVEL=$LOGLEVEL
fi
# shellcheck source=../etc/hardening.cfg # shellcheck source=../etc/hardening.cfg
[ -r "$CIS_ROOT_DIR"/etc/hardening.cfg ] && . "$CIS_ROOT_DIR"/etc/hardening.cfg [ -r "$CIS_ROOT_DIR"/etc/hardening.cfg ] && . "$CIS_ROOT_DIR"/etc/hardening.cfg
if [ -n "$SAVED_LOGLEVEL" ]; then
LOGLEVEL=$SAVED_LOGLEVEL
fi
# shellcheck source=../lib/common.sh # shellcheck source=../lib/common.sh
[ -r "$CIS_ROOT_DIR"/lib/common.sh ] && . "$CIS_ROOT_DIR"/lib/common.sh [ -r "$CIS_ROOT_DIR"/lib/common.sh ] && . "$CIS_ROOT_DIR"/lib/common.sh
# shellcheck source=../lib/utils.sh # shellcheck source=../lib/utils.sh
@ -104,6 +112,9 @@ if [ -z "$status" ]; then
exit 2 exit 2
fi fi
# We want to trap unexpected failures in check scripts
trap exception EXIT
case $status in case $status in
enabled | true) enabled | true)
info "Checking Configuration" info "Checking Configuration"
@ -121,6 +132,7 @@ audit)
;; ;;
disabled | false) disabled | false)
info "$SCRIPT_NAME is disabled, ignoring" info "$SCRIPT_NAME is disabled, ignoring"
ACTIONS_DONE=1
exit 2 # Means unknown status exit 2 # Means unknown status
;; ;;
*) *)
@ -128,6 +140,8 @@ disabled | false)
;; ;;
esac esac
ACTIONS_DONE=1
if [ "$CRITICAL_ERRORS_NUMBER" -eq 0 ]; then if [ "$CRITICAL_ERRORS_NUMBER" -eq 0 ]; then
if [ "$BATCH_MODE" -eq 1 ]; then if [ "$BATCH_MODE" -eq 1 ]; then
BATCH_OUTPUT="OK $SCRIPT_NAME $BATCH_OUTPUT" BATCH_OUTPUT="OK $SCRIPT_NAME $BATCH_OUTPUT"

View File

@ -384,9 +384,9 @@ is_kernel_option_enabled() {
fi fi
else else
if [ "$MODPROBE_FILTER" != "" ]; then if [ "$MODPROBE_FILTER" != "" ]; then
DEF_MODULE="$($SUDO_CMD modprobe -n -v "$MODULE_NAME" 2>/dev/null | grep -E "$MODPROBE_FILTER" | xargs)" DEF_MODULE="$($SUDO_CMD modprobe -n -v "$MODULE_NAME" 2>/dev/null | grep -E "$MODPROBE_FILTER" | tail -1 | xargs)"
else else
DEF_MODULE="$($SUDO_CMD modprobe -n -v "$MODULE_NAME" 2>/dev/null | xargs)" DEF_MODULE="$($SUDO_CMD modprobe -n -v "$MODULE_NAME" 2>/dev/null | tail -1 | xargs)"
fi fi
if [ "$DEF_MODULE" == "install /bin/true" ] || [ "$DEF_MODULE" == "install /bin/false" ]; then if [ "$DEF_MODULE" == "install /bin/true" ] || [ "$DEF_MODULE" == "install /bin/false" ]; then
@ -415,9 +415,9 @@ is_kernel_option_enabled() {
is_a_partition() { is_a_partition() {
local PARTITION=$1 local PARTITION=$1
FNRET=128 FNRET=128
if [ ! -f /etc/fstab ] || [ -n "$(sed '/^#/d' /etc/fstab)" ]; then if [ ! -f /etc/fstab ] || [ -z "$(sed '/^#/d' /etc/fstab)" ]; then
debug "/etc/fstab not found or empty, searching mountpoint" debug "/etc/fstab not found or empty, searching mountpoint"
if mountpoint "$PARTITION" | grep -qE ".*is a mountpoint.*"; then if mountpoint -q "$PARTITION"; then
FNRET=0 FNRET=0
fi fi
else else
@ -448,8 +448,8 @@ is_mounted() {
has_mount_option() { has_mount_option() {
local PARTITION=$1 local PARTITION=$1
local OPTION=$2 local OPTION=$2
if [ ! -f /etc/fstab ] || [ -n "$(sed '/^#/d' /etc/fstab)" ]; then if [ ! -f /etc/fstab ] || [ -z "$(sed '/^#/d' /etc/fstab)" ]; then
debug "/etc/fstab not found or empty, readin current mount options" debug "/etc/fstab not found or empty, reading current mount options"
has_mounted_option "$PARTITION" "$OPTION" has_mounted_option "$PARTITION" "$OPTION"
else else
if grep "[[:space:]]${PARTITION}[[:space:]]" /etc/fstab | grep -vE "^#" | awk '{print $4}' | grep -q "bind"; then if grep "[[:space:]]${PARTITION}[[:space:]]" /etc/fstab | grep -vE "^#" | awk '{print $4}' | grep -q "bind"; then

View File

@ -2,15 +2,14 @@
# run-shellcheck # run-shellcheck
test_audit() { test_audit() {
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 1 register_test retvalshouldbe 0
dismiss_count_for_test
# shellcheck disable=2154 # shellcheck disable=2154
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
ln -s /dev/shm /run/shm ln -s /dev/shm /run/shm
describe Partition symlink describe Partition symlink
register_test retvalshouldbe 1 register_test retvalshouldbe 0
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup

View File

@ -3,14 +3,13 @@
test_audit() { test_audit() {
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 0 register_test retvalshouldbe 0
dismiss_count_for_test
# shellcheck disable=2154 # shellcheck disable=2154
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
ln -s /dev/shm /run/shm ln -s /dev/shm /run/shm
describe Partition symlink describe Partition symlink
register_test retvalshouldbe 1 register_test retvalshouldbe 0
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup

View File

@ -3,14 +3,13 @@
test_audit() { test_audit() {
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 0 register_test retvalshouldbe 0
dismiss_count_for_test
# shellcheck disable=2154 # shellcheck disable=2154
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
ln -s /dev/shm /run/shm ln -s /dev/shm /run/shm
describe Partition symlink describe Partition symlink
register_test retvalshouldbe 1 register_test retvalshouldbe 0
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup

View File

@ -1,29 +1,35 @@
# shellcheck shell=bash # shellcheck shell=bash
# run-shellcheck # run-shellcheck
test_audit() { test_audit() {
describe Running void to generate the conf file that will later be edited
# shellcheck disable=2154
/opt/debian-cis/bin/hardening/"${script}".sh || true
# shellcheck disable=2016
echo 'EXCEPTIONS="$EXCEPTIONS /home/secaudit/exception"' >>/opt/debian-cis/etc/conf.d/"${script}".cfg
mkdir /home/secaudit/exception
chmod 777 /home/secaudit/exception
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 0 register_test retvalshouldbe 0
register_test contain "All world writable directories have a sticky bit" register_test contain "All world writable directories have a sticky bit"
# shellcheck disable=2154 # shellcheck disable=2154
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
if [ -f "/.dockerenv" ]; then
skip "SKIPPED on docker"
else
describe Tests purposely failing
local targetdir="/home/secaudit/world_writable_folder"
mkdir $targetdir || true
chmod 777 "$targetdir"
register_test retvalshouldbe 1
register_test contain "Some world writable directories are not on sticky bit mode"
run noncompliant /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe correcting situation describe Tests purposely failing
sed -i 's/audit/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg local targetdir="/home/secaudit/world_writable_folder"
/opt/debian-cis/bin/hardening/"${script}".sh --apply || true mkdir $targetdir || true
chmod 777 "$targetdir"
register_test retvalshouldbe 1
register_test contain "Some world writable directories are not on sticky bit mode"
run noncompliant /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe correcting situation
sed -i 's/audit/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
/opt/debian-cis/bin/hardening/"${script}".sh --apply || true
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "All world writable directories have a sticky bit"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "All world writable directories have a sticky bit"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
fi
} }

View File

@ -1,32 +1,33 @@
# shellcheck shell=bash # shellcheck shell=bash
# run-shellcheck # run-shellcheck
test_audit() { test_audit() {
describe Running void to generate the conf file that will later be edited
# shellcheck disable=2154
/opt/debian-cis/bin/hardening/"${script}".sh || true
# shellcheck disable=2016
echo 'EXCLUDED="$EXCLUDED ^/dev/.*"' >>/opt/debian-cis/etc/conf.d/"${script}".cfg
#run this test only if we're not in docker describe Running on blank host
if [ -f "/.dockerenv" ]; then register_test retvalshouldbe 0
skip "SKIPPED on docker" register_test contain "No world writable files found"
else # shellcheck disable=2154
describe Running on blank host run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
register_test retvalshouldbe 0
register_test contain "No world writable files found"
# shellcheck disable=2154
run blank /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Tests purposely failing describe Tests purposely failing
local targetfile="/home/secaudit/worldwritable" local targetfile="/home/secaudit/worldwritable"
touch "$targetfile" touch "$targetfile"
chmod 777 "$targetfile" chmod 777 "$targetfile"
register_test retvalshouldbe 1 register_test retvalshouldbe 1
register_test contain "Some world writable files are present" register_test contain "Some world writable files are present"
run noncompliant /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run noncompliant /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe correcting situation describe correcting situation
sed -i 's/audit/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg sed -i 's/audit/enabled/' /opt/debian-cis/etc/conf.d/"${script}".cfg
/opt/debian-cis/bin/hardening/"${script}".sh --apply || true /opt/debian-cis/bin/hardening/"${script}".sh --apply || true
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "No world writable files found"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Checking resolved state
register_test retvalshouldbe 0
register_test contain "No world writable files found"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
fi
} }

View File

@ -1,6 +1,15 @@
# shellcheck shell=bash # shellcheck shell=bash
# run-shellcheck # run-shellcheck
test_audit() { test_audit() {
describe Running void to generate the conf file that will later be edited
# shellcheck disable=2154
/opt/debian-cis/bin/hardening/"${script}".sh || true
# shellcheck disable=2016
echo 'EXCLUDED="$EXCLUDED ^/home/secaudit/6.1.11/.*"' >>/opt/debian-cis/etc/conf.d/"${script}".cfg
mkdir /home/secaudit/6.1.11/
touch /home/secaudit/6.1.11/test
chown 1200 /home/secaudit/6.1.11/test
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 0 register_test retvalshouldbe 0
register_test contain "No unowned files found" register_test contain "No unowned files found"

View File

@ -1,6 +1,15 @@
# shellcheck shell=bash # shellcheck shell=bash
# run-shellcheck # run-shellcheck
test_audit() { test_audit() {
describe Running void to generate the conf file that will later be edited
# shellcheck disable=2154
/opt/debian-cis/bin/hardening/"${script}".sh || true
# shellcheck disable=2016
echo 'EXCLUDED="$EXCLUDED ^/home/secaudit/6.1.12/.*"' >>/opt/debian-cis/etc/conf.d/"${script}".cfg
mkdir /home/secaudit/6.1.12/
touch /home/secaudit/6.1.12/test
chown 1200:1200 /home/secaudit/6.1.12/test
describe Running on blank host describe Running on blank host
register_test retvalshouldbe 0 register_test retvalshouldbe 0
register_test contain "No ungrouped files found" register_test contain "No ungrouped files found"

View File

@ -37,6 +37,12 @@ test_audit() {
register_test contain "has correct ownership" register_test contain "has correct ownership"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Missing File should be OK as well
rm "$test_file"
register_test retvalshouldbe 0
register_test contain "does not exist"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup
userdel "$test_user" userdel "$test_user"
} }

View File

@ -10,6 +10,13 @@ test_audit() {
local test_user="testetcpasswd-user" local test_user="testetcpasswd-user"
local test_file="/etc/passwd-" local test_file="/etc/passwd-"
describe Debian default right shall be accepted
chmod 644 "$test_file"
chown root:root "$test_file"
register_test retvalshouldbe 0
register_test contain "has correct permissions"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Tests purposely failing describe Tests purposely failing
chmod 777 "$test_file" chmod 777 "$test_file"
register_test retvalshouldbe 1 register_test retvalshouldbe 1
@ -37,6 +44,12 @@ test_audit() {
register_test contain "has correct ownership" register_test contain "has correct ownership"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Missing File should be OK as well
rm "$test_file"
register_test retvalshouldbe 0
register_test contain "does not exist"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup
userdel "$test_user" userdel "$test_user"
} }

View File

@ -10,6 +10,13 @@ test_audit() {
local test_user="testetcshadow-user" local test_user="testetcshadow-user"
local test_file="/etc/shadow-" local test_file="/etc/shadow-"
describe Debian default right shall be accepted
chmod 640 "$test_file"
chown root:shadow "$test_file"
register_test retvalshouldbe 0
register_test contain "has correct permissions"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Tests purposely failing describe Tests purposely failing
chmod 777 "$test_file" chmod 777 "$test_file"
register_test retvalshouldbe 1 register_test retvalshouldbe 1
@ -37,6 +44,12 @@ test_audit() {
register_test contain "has correct ownership" register_test contain "has correct ownership"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Missing File should be OK as well
rm "$test_file"
register_test retvalshouldbe 0
register_test contain "does not exist"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup
userdel "$test_user" userdel "$test_user"
} }

View File

@ -10,6 +10,13 @@ test_audit() {
local test_user="testetcgroup--user" local test_user="testetcgroup--user"
local test_file="/etc/group-" local test_file="/etc/group-"
describe Debian default right shall be accepted
chmod 644 "$test_file"
chown root:root "$test_file"
register_test retvalshouldbe 0
register_test contain "has correct permissions"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Tests purposely failing describe Tests purposely failing
chmod 777 "$test_file" chmod 777 "$test_file"
register_test retvalshouldbe 1 register_test retvalshouldbe 1
@ -37,6 +44,12 @@ test_audit() {
register_test contain "has correct ownership" register_test contain "has correct ownership"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
describe Missing File should be OK as well
rm "$test_file"
register_test retvalshouldbe 0
register_test contain "does not exist"
run resolved /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
# Cleanup # Cleanup
userdel "$test_user" userdel "$test_user"
} }

View File

@ -29,4 +29,12 @@ EOF
register_test retvalshouldbe 0 register_test retvalshouldbe 0
register_test contain "User secaudit has suitable SHA512 hashed password" register_test contain "User secaudit has suitable SHA512 hashed password"
run sha512pass /opt/debian-cis/bin/hardening/"${script}".sh --audit-all run sha512pass /opt/debian-cis/bin/hardening/"${script}".sh --audit-all
chpasswd -c SHA512 -s 1000 <<EOF
secaudit:mypassword
EOF
describe Pass: Found properly hashed password with custom round number
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
} }