diff --git a/.ansible-lint b/.ansible-lint index 162b761..b717f67 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,15 +1,16 @@ +--- + parseable: true quiet: true skip_list: - 'schema' - 'no-changed-when' - 'var-spacing' - - 'fqcn-builtins' - 'experimental' - 'name[play]' - 'name[casing]' - 'name[template]' - - 'fqcn[action]' + - 'key-order[task]' - '204' - '305' - '303' diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index a1535e2..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Report Issue -about: Create a bug issue ticket to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the Issue** -A clear and concise description of what the bug is. - -**Expected Behavior** -A clear and concise description of what you expected to happen. - -**Actual Behavior** -A clear and concise description of what's happening. - -**Control(s) Affected** -What controls are being affected by the issue - -**Environment (please complete the following information):** - - Ansible Version: [e.g. 2.10] - - Host Python Version: [e.g. Python 3.7.6] - - Ansible Server Python Version: [e.g. Python 3.7.6] - - branch: [e.g. devel] - - Additional Details: - -**Additional Notes** -Anything additional goes here - -**Possible Solution** -Enter a suggested fix here diff --git a/.github/ISSUE_TEMPLATE/feature-request-or-enhancement.md b/.github/ISSUE_TEMPLATE/feature-request-or-enhancement.md deleted file mode 100644 index bf45700..0000000 --- a/.github/ISSUE_TEMPLATE/feature-request-or-enhancement.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Feature Request or Enhancement -about: Suggest an idea for this project -title: '' -labels: enhancement -assignees: '' - ---- - -**Feature Request or Enhancement** - - Feature [] - - Enhancement [] - -**Summary of Request** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Suggested Code** -Please provide any code you have in mind to fulfill the request diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 347d399..0000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Question -about: Ask away....... -title: '' -labels: question -assignees: '' - ---- - -**Question** -Pose question here. - -**Environment (please complete the following information):** - - Ansible Version: [e.g. 2.10] - - Host Python Version: [e.g. Python 3.7.6] - - Ansible Server Python Version: [e.g. Python 3.7.6] - - branch: [e.g. devel] - - Additional Details: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 05dadb6..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,12 +0,0 @@ -**Overall Review of Changes:** -A general description of the changes made that are being requested for merge - -**Issue Fixes:** -Please list (using linking) any open issues this PR addresses - -**Enhancements:** -Please list any enhancements/features that are not open issue tickets - -**How has this been tested?:** -Please give an overview of how these changes were tested. If they were not please use N/A - diff --git a/.github/workflows/AMAZON2.tfvars b/.github/workflows/AMAZON2.tfvars new file mode 100644 index 0000000..fc635fb --- /dev/null +++ b/.github/workflows/AMAZON2.tfvars @@ -0,0 +1,9 @@ +# Amazon Linux 2 +ami_id = "ami-03e0b06f01d45a4eb" +ami_os = "AmazonLinux2" +ami_username = "ec2-user" +ami_user_home = "/home/ec2-user" +benchmark_os = "Amazon2" +privsubnet_id = "subnet-0ce2cd3c739f6421c" +vpc_secgrp_id = "sg-0c0593968712e684d" +benchmark_type = "CIS" diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml new file mode 100644 index 0000000..e02fe1f --- /dev/null +++ b/.github/workflows/devel_pipeline_validation.yml @@ -0,0 +1,159 @@ +--- + + name: Devel pipeline + + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - devel + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + # Allow manual running of workflow + workflow_dispatch: + + # Allow permissions for AWS auth + permissions: + id-token: write + contents: read + pull-requests: read + + # A workflow run is made up of one or more jobs + # that can run sequentially or in parallel + jobs: + # This will create messages for first time contributers and direct them to the Discord server + welcome: + runs-on: self-hosted + + steps: + - uses: actions/first-interaction@main + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: |- + Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. + + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION: "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows + + steps: + + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi + + + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} + + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} + + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" + echo "VPC_ID" = $AWS_VPC_SECGRP_ID" + pwd + ls + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} + PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} + VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} + + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false + +## Debug Section + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml + + # Aws deployments taking a while to come up insert sleep or playbook fails + + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + + # Remove test system - User secrets to keep if necessary + + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/github_networks.tf b/.github/workflows/github_network.tf similarity index 98% rename from .github/workflows/github_networks.tf rename to .github/workflows/github_network.tf index 998cb76..5001dc2 100644 --- a/.github/workflows/github_networks.tf +++ b/.github/workflows/github_network.tf @@ -1,7 +1,7 @@ resource "aws_vpc" "Main" { cidr_block = var.main_vpc_cidr instance_tenancy = "default" - tags = { + tags = { Environment = "${var.environment}" Name = "${var.namespace}-VPC" } diff --git a/.github/workflows/github_vars.tfvars b/.github/workflows/github_vars.tfvars index 3ea5253..b8d1f5e 100644 --- a/.github/workflows/github_vars.tfvars +++ b/.github/workflows/github_vars.tfvars @@ -1,7 +1,7 @@ // github_actions variables // Resourced in github_networks.tf // Declared in variables.tf -// +// namespace = "github_actions" environment = "lockdown_github_repo_workflow" diff --git a/.github/workflows/linux_benchmark_testing.yml b/.github/workflows/linux_benchmark_testing.yml index d028118..9cc43d8 100644 --- a/.github/workflows/linux_benchmark_testing.yml +++ b/.github/workflows/linux_benchmark_testing.yml @@ -1,4 +1,4 @@ -# This is a basic workflow to help you get started with Actions +i# This is a basic workflow to help you get started with Actions name: linux_benchmark_pipeline diff --git a/.github/workflows/main.tf b/.github/workflows/main.tf index 16dfdf6..f39036f 100644 --- a/.github/workflows/main.tf +++ b/.github/workflows/main.tf @@ -25,7 +25,7 @@ resource "aws_security_group" "github_actions" { protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } - + ingress { from_port = 80 to_port = 80 @@ -77,6 +77,6 @@ resource "local_file" "inventory" { setup_audit: true run_audit: true system_is_ec2: true + amazon2cis_rule_4_5_2_4: false # Don't set root password EOF } - diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml new file mode 100644 index 0000000..4a5adc9 --- /dev/null +++ b/.github/workflows/main_pipeline_validation.yml @@ -0,0 +1,156 @@ +--- + + name: Main pipeline + + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - main + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + + # Allow permissions for AWS auth + permissions: + id-token: write + contents: read + pull-requests: read + + # A workflow run is made up of one or more jobs + # that can run sequentially or in parallel + jobs: + # This will create messages for first time contributers and direct them to the Discord server + welcome: + runs-on: self-hosted + + steps: + - uses: actions/first-interaction@main + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: |- + Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. + + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION : "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows + + steps: + + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi + + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} + + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} + + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" + echo "VPC_ID" = $AWS_VPC_SECGRP_ID" + pwd + ls + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} + PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} + VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} + + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false + +## Debug Section + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml + + # Aws deployments taking a while to come up insert sleep or playbook fails + + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + + # Remove test system - User secrets to keep if necessary + + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/update_galaxy.yml b/.github/workflows/update_galaxy.yml index 2052b0a..b6ee6a1 100644 --- a/.github/workflows/update_galaxy.yml +++ b/.github/workflows/update_galaxy.yml @@ -1,21 +1,19 @@ --- -# This is a basic workflow to help you get started with Actions + name: update galaxy -name: update galaxy + on: + push: + branches: + - main + jobs: + update_role: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 -# Controls when the action will run. -# Triggers the workflow on merge request events to the main branch -on: # yamllint disable-line rule:truthy - push: - branches: - - main -jobs: - update_role: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: robertdebock/galaxy-action@master - with: - galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} - git_branch: main + - name: Action Ansible Galaxy Release ${{ github.ref_name }} + uses: ansible-actions/ansible-galaxy-action@main + with: + galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} diff --git a/.gitignore b/.gitignore index 6aadd7e..2f4b6f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ .env *.log *.retry -.vagrant .cache +.vagrant tests/*redhat-subscription tests/Dockerfile *.iso @@ -10,6 +10,9 @@ tests/Dockerfile packer_cache delete* ignore* +test_inv +# temp remove doc while this is built up +doc/ # VSCode .vscode @@ -40,8 +43,13 @@ travis.env benchparse/ *xccdf.xml *.retry -test_inv -# ignore refactr pipeline test conf +# GitHub Action/Workflow files .github/ +# key types +*.pem +*.ppk +*.key +*.rsa +*.ecdsa diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..88d4f0d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,64 @@ +--- +##### CI for use by github no need for action to be added +##### Inherited +ci: + autofix_prs: false + skip: [detect-aws-credentials, ansible-lint ] + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + # Safety + - id: detect-aws-credentials + - id: detect-private-key + + # git checks + - id: check-merge-conflict + - id: check-added-large-files + - id: check-case-conflict + + # General checks + - id: trailing-whitespace + name: Trim Trailing Whitespace + description: This hook trims trailing whitespace. + entry: trailing-whitespace-fixer + language: python + types: [text] + args: [--markdown-linebreak-ext=md] + - id: end-of-file-fixer + +# Scan for passwords +- repo: https://github.com/Yelp/detect-secrets + rev: v1.4.0 + hooks: + - id: detect-secrets + +- repo: https://github.com/gitleaks/gitleaks + rev: v8.18.2 + hooks: + - id: gitleaks + +- repo: https://github.com/ansible-community/ansible-lint + rev: v24.2.1 + hooks: + - id: ansible-lint + name: Ansible-lint + description: This hook runs ansible-lint. + entry: python3 -m ansiblelint --force-color site.yml -c .ansible-lint + language: python + # do not pass files to ansible-lint, see: + # https://github.com/ansible/ansible-lint/issues/611 + pass_filenames: false + always_run: true + additional_dependencies: + # https://github.com/pre-commit/pre-commit/issues/1526 + # If you want to use specific version of ansible-core or ansible, feel + # free to override `additional_dependencies` in your own hook config + # file. + - ansible-core>=2.10.1 + +- repo: https://github.com/adrienverge/yamllint.git + rev: v1.35.1 # or higher tag + hooks: + - id: yamllint diff --git a/.yamllint b/.yamllint index 72ac645..65faae6 100644 --- a/.yamllint +++ b/.yamllint @@ -1,28 +1,33 @@ --- -# Based on ansible-lint config extends: default +ignore: | + tests/ + molecule/ + .github/ + .gitlab-ci.yml + *molecule.yml + rules: - braces: {max-spaces-inside: 1, level: error} - brackets: {max-spaces-inside: 1, level: error} - colons: {max-spaces-after: -1, level: error} - commas: {max-spaces-after: -1, level: error} - comments: disable - comments-indentation: disable - document-start: disable - empty-lines: {max: 3, level: error} - hyphens: {level: error} - indentation: - # Requiring 4 space indentation - spaces: 4 - # Requiring consistent indentation within a file, either indented or not - indent-sequences: consistent - key-duplicates: enable - line-length: disable - new-line-at-end-of-file: enable - new-lines: - type: unix - trailing-spaces: enable - truthy: - allowed-values: ['true', 'false'] - check-keys: true + indentation: + # Requiring 4 space indentation + spaces: 4 + # Requiring consistent indentation within a file, either indented or not + indent-sequences: consistent + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + empty-lines: + max: 1 + line-length: disable + key-duplicates: enable + new-line-at-end-of-file: enable + new-lines: + type: unix + trailing-spaces: enable + truthy: + allowed-values: ['true', 'false'] + check-keys: true diff --git a/README.md b/README.md index 1aa1f7e..a68bec9 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,37 @@ -# RHEL 7 CIS - -![Build Status](https://img.shields.io/github/workflow/status/ansible-lockdown/AMAZON2-CIS/CommunityToDevel?label=Devel%20Build%20Status&style=plastic) -![Build Status](https://img.shields.io/github/workflow/status/ansible-lockdown/AMAZON2-CIS/DevelToMain?label=Main%20Build%20Status&style=plastic) -![Release](https://img.shields.io/github/v/release/ansible-lockdown/AMAZON2-CIS?style=plastic) +# Amazon 2 Linux Configure Amazon Linux 2 machine to be [CIS](https://www.cisecurity.org/cis-benchmarks/) compliant Untested on OEL -Based on [CIS Amazon Linux 2 Benchmark v2.0.0 - 07-28-2021 ](https://www.cisecurity.org/cis-benchmarks/) +Based on [CIS Amazon Linux 2 Benchmark v3.0.0 - 12-22-2023 ](https://www.cisecurity.org/cis-benchmarks/) + + +![Org Stars](https://img.shields.io/github/stars/ansible-lockdown?label=Org%20Stars&style=social) +![Stars](https://img.shields.io/github/stars/ansible-lockdown/AMAZON2-CIS?label=Repo%20Stars&style=social) +![Forks](https://img.shields.io/github/forks/ansible-lockdown/AMAZON2-CIS?style=social) +![followers](https://img.shields.io/github/followers/ansible-lockdown?style=social) +[![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/AnsibleLockdown.svg?style=social&label=Follow%20%40AnsibleLockdown)](https://twitter.com/AnsibleLockdown) + +![Discord Badge](https://img.shields.io/discord/925818806838919229?logo=discord) + +![Release Branch](https://img.shields.io/badge/Release%20Branch-Main-brightgreen) +![Release Tag](https://img.shields.io/github/v/release/ansible-lockdown/AMAZON2-CIS) +![Release Date](https://img.shields.io/github/release-date/ansible-lockdown/AMAZON2-CIS) + +[![Main Pipeline Status](https://github.com/ansible-lockdown/AMAZON2-CIS/actions/workflows/main_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/AMAZON2-CIS/actions/workflows/main_pipeline_validation.yml) + +[![Devel Pipeline Status](https://github.com/ansible-lockdown/AMAZON2-CIS/actions/workflows/devel_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/AMAZON2-CIS/actions/workflows/devel_pipeline_validation.yml) +![Devel Commits](https://img.shields.io/github/commit-activity/m/ansible-lockdown/AMAZON2-CIS/devel?color=dark%20green&label=Devel%20Branch%20Commits) + +![Issues Open](https://img.shields.io/github/issues-raw/ansible-lockdown/AMAZON2-CIS?label=Open%20Issues) +![Issues Closed](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/AMAZON2-CIS?label=Closed%20Issues&&color=success) +![Pull Requests](https://img.shields.io/github/issues-pr/ansible-lockdown/AMAZON2-CIS?label=Pull%20Requests) + +![License](https://img.shields.io/github/license/ansible-lockdown/AMAZON2-CIS?label=License) ## Join us -On our [Discord Server](https://discord.gg/JFxpSgPFEJ) to ask questions, discuss features, or just chat with other Ansible-Lockdown users +On our [Discord Server](https://www.lockdownenterprise.com/discord) to ask questions, discuss features, or just chat with other Ansible-Lockdown users ## Caution(s) @@ -54,11 +74,12 @@ Further details can be seen in the [Changelog](./ChangeLog.md) **Technical Dependencies:** -- Running Ansible/Tower setup (this role is tested against Ansible version 2.9.1 and newer) +- Running Ansible/Tower setup (this role is tested against Ansible version 2.11.1 and newer) - Python3 Ansible run environment -- python-def (should be included in RHEL/CentOS 7) - First task sets up the prerequisites (Tag pre-reqs)for python3 and python2 (where required) +- python-def - First task sets up the prerequisites (Tag pre-reqs)for python3 and python2 (where required) - libselinux-python - python3-rpm (package used by py3 to use the rpm pkg) + - jmespath ## Role Variables @@ -84,8 +105,6 @@ Below is an example of the tag section from a control within this role. Using th - **devel** - This is the default branch and the working development branch. Community pull requests will pull into this branch - **main** - This is the release branch -- **reports** - This is a protected branch for our scoring reports, no code should ever go here -- **gh-pages** - This is the github pages branch - **all other branches** - Individual community member branches ## Community Contribution @@ -101,7 +120,7 @@ We encourage you (the community) to contribute to this role. Please read the rul uses: -- ansible-core 2.12 +- ansible-core 2.12+ - ansible collections - pulls in the latest version based on requirements file - runs the audit using the devel branch - This is an automated test that occurs on pull requests into devel @@ -115,6 +134,6 @@ If you would are interested in dedicated support to assist or provide bespoke se - [Ansible Counselor](https://www.mindpointgroup.com/products/ansible-counselor-on-demand-ansible-services-and-consulting/) - [Try us out](https://engage.mindpointgroup.com/try-ansible-counselor) -## Credits +## Credits and Thanks -This repo originated from work done by [Sam Doran](https://github.com/samdoran/ansible-role-stig) +Massive thanks to the fantastic community and all its members. diff --git a/collections/requirements.yml b/collections/requirements.yml index 4a418ef..996e799 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -1,8 +1,15 @@ --- collections: -- name: community.general -- name: community.crypto + - name: community.general + source: https://github.com/ansible-collections/community.general + type: git -- name: ansible.posix + - name: community.crypto + source: https://github.com/ansible-collections/community.crypto + type: git + + - name: ansible.posix + source: https://github.com/ansible-collections/ansible.posix + type: git diff --git a/defaults/main.yml b/defaults/main.yml index 61bff4b..6defeb2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,10 +8,6 @@ amazon2cis_section4: true amazon2cis_section5: true amazon2cis_section6: true -# 5.7 Group to be used for su -# this group needs to exists groups will not be created for remediation this is considered sys admins -# amazon2cis_sugroup: sugroup - ## Python Binary ## This is used for python3 Installations where python2 OS modules are used in ansible python2_bin: /bin/python2.7 @@ -19,139 +15,240 @@ python2_bin: /bin/python2.7 ## Benchmark name used by audting control role # The audit variable found at the base benchmark: AMAZON2-CIS -benchmark_version: v2.0.0 - -# If set true uses the tmp.mount service else using fstab configuration -amazon2cis_tmp_svc: true - -### Goss Audit run settings -# Goss audit configuration settings at bottom of file - -setup_audit: false -# How to retrive goss -# Options are copy or download - detailed settings at the bottom of this file -# you will need to access to either github or the file already dowmloaded -get_goss_file: download +benchmark_version: v3.0.0 -# how to get audit files onto host options -# options are git/copy/get_url -audit_content: git +## Ability to skip the os check +os_check: true -# Timeout for those cmds that take longer to run where timeout set -audit_cmd_timeout: 30000 - -# enable audits to run - this runs the audit and get the latest content -run_audit: false -### End Goss enablements #### +# Ability to stop reboot from occuring until convenient +# set to true if ok to reboot +skip_reboot: false # Change to false if using EFI boot changes 1.1.1.4 to stop vfat amazon2cis_legacy_boot: true +# SELinux policy # Enable/Disable SELinux amazon2cis_selinux_disable: false amazon2cis_selinux_state: enforcing +amazon2cis_selinux_pol: targeted # Misc. environment variables amazon2cis_skip_for_travis: false -amazon2cis_system_is_container: false system_is_ec2: true +# Some tasks can have a signifcant impact on a system ensure you agree +amazon2cis_disruption_high: true + +# Used for audit purposed only +amazon2cis_level_1: true +amazon2cis_level_2: true + +### +### Settings for associated Audit role using Goss +### + +########################################### +### Goss is required on the remote host ### +### vars/auditd.yml for other settings ### + +# Allow audit to setup the requirements including installing git (if option chosen and downloading and adding goss binary to system) +setup_audit: false + +# enable audits to run - this runs the audit and get the latest content +run_audit: false +# Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system +audit_run_heavy_tests: true + +## Only run Audit do not remediate +audit_only: false +### As part of audit_only ### +# This will enable files to be copied back to control node in audit_only mode +fetch_audit_files: false +# Path to copy the files to will create dir structure in audit_only mode +audit_capture_files_dir: /some/location to copy to on control node +############################# + +# How to retrieve audit binary +# Options are copy or download - detailed settings at the bottom of this file +# you will need to access to either github or the file already dowmloaded +get_audit_binary_method: download + +## if get_audit_binary_method - copy the following needs to be updated for your environment +## it is expected that it will be copied from somewhere accessible to the control node +## e.g copy from ansible control node to remote host +audit_bin_copy_location: /some/accessible/path + +# how to get audit files onto host options +# options are git/copy/archive/get_url other e.g. if you wish to run from already downloaded conf +audit_content: git + +# If using either archive, copy, get_url: +## Note will work with .tar files - zip will require extra configuration +### If using get_url this is expecting github url in tar.gz format e.g. +### https://github.com/ansible-lockdown/UBUNTU22-CIS-Audit/archive/refs/heads/benchmark-v1.0.0.tar.gz +audit_conf_source: "some path or url to copy from" + +# Destination for the audit content to be placed on managed node +# note may not need full path e.g. /opt with the directory being the {{ benchmark }}-Audit directory +audit_conf_dest: "/opt" + +# Where the audit logs are stored +audit_log_dir: '/opt' + +### Goss Settings ## +####### END ######## + # These variables correspond with the CIS rule IDs or paragraph numbers defined in # the CIS benchmark documents. # PLEASE NOTE: These work in coordination with the section # group variables and tags. # You must enable an entire section in order for the variables below to take effect. -# Section 1 rules + +## +## Section 1 rules +## # Section 1 is Initial Setup (Filesystem Configuration, Configure Software Updates, Configure Sudo, Filesystem Integrity Checking, Secure Boot Settings, Additional Process Hardening, Mandatory Access Control, and Warning Banners) +# Configure Filesystem Kernel Modules amazon2cis_rule_1_1_1_1: true amazon2cis_rule_1_1_1_2: true amazon2cis_rule_1_1_1_3: true -amazon2cis_rule_1_1_2: true -amazon2cis_rule_1_1_3: true -amazon2cis_rule_1_1_4: true -amazon2cis_rule_1_1_5: true -amazon2cis_rule_1_1_6: true -amazon2cis_rule_1_1_7: true -amazon2cis_rule_1_1_8: true -amazon2cis_rule_1_1_9: true -amazon2cis_rule_1_1_10: true -amazon2cis_rule_1_1_11: true -amazon2cis_rule_1_1_12: true -amazon2cis_rule_1_1_13: true -amazon2cis_rule_1_1_14: true -amazon2cis_rule_1_1_15: true -amazon2cis_rule_1_1_16: true -amazon2cis_rule_1_1_17: true -amazon2cis_rule_1_1_18: true -amazon2cis_rule_1_1_19: true -amazon2cis_rule_1_1_20: true -amazon2cis_rule_1_1_21: true -amazon2cis_rule_1_1_22: true -amazon2cis_rule_1_1_23: true -amazon2cis_rule_1_1_24: true +amazon2cis_rule_1_1_1_4: true +amazon2cis_rule_1_1_1_5: true +amazon2cis_rule_1_1_1_6: true +amazon2cis_rule_1_1_1_7: true +amazon2cis_rule_1_1_1_8: true + +# /tmp +amazon2cis_rule_1_1_2_1_1: true +amazon2cis_rule_1_1_2_1_2: true +amazon2cis_rule_1_1_2_1_3: true +amazon2cis_rule_1_1_2_1_4: true + +# /dev/shm +amazon2cis_rule_1_1_2_2_1: true +amazon2cis_rule_1_1_2_2_2: true +amazon2cis_rule_1_1_2_2_3: true +amazon2cis_rule_1_1_2_2_4: true + +# /home +amazon2cis_rule_1_1_2_3_1: true +amazon2cis_rule_1_1_2_3_2: true +amazon2cis_rule_1_1_2_3_3: true + +# /var +amazon2cis_rule_1_1_2_4_1: true +amazon2cis_rule_1_1_2_4_2: true +amazon2cis_rule_1_1_2_4_3: true + +# /var/tmp +amazon2cis_rule_1_1_2_5_1: true +amazon2cis_rule_1_1_2_5_2: true +amazon2cis_rule_1_1_2_5_3: true +amazon2cis_rule_1_1_2_5_4: true + +# /var/log +amazon2cis_rule_1_1_2_6_1: true +amazon2cis_rule_1_1_2_6_2: true +amazon2cis_rule_1_1_2_6_3: true +amazon2cis_rule_1_1_2_6_4: true + +# /var/log/audit +amazon2cis_rule_1_1_2_7_1: true +amazon2cis_rule_1_1_2_7_2: true +amazon2cis_rule_1_1_2_7_3: true +amazon2cis_rule_1_1_2_7_4: true + +# Software and Patch management amazon2cis_rule_1_2_1: true amazon2cis_rule_1_2_2: true amazon2cis_rule_1_2_3: true +amazon2cis_rule_1_2_4: true +amazon2cis_rule_1_2_5: true + +# Secure boot settings amazon2cis_rule_1_3_1: true -amazon2cis_rule_1_3_2: true + +# Additional Process Hardening amazon2cis_rule_1_4_1: true amazon2cis_rule_1_4_2: true -amazon2cis_rule_1_5_1: true -amazon2cis_rule_1_5_2: true -amazon2cis_rule_1_5_3: true -amazon2cis_rule_1_5_4: true -amazon2cis_rule_1_6_1_1: true -amazon2cis_rule_1_6_1_2: true -amazon2cis_rule_1_6_1_3: true -amazon2cis_rule_1_6_1_4: true -amazon2cis_rule_1_6_1_5: true -amazon2cis_rule_1_6_1_6: true -amazon2cis_rule_1_6_1_7: true -amazon2cis_rule_1_6_1_8: true -amazon2cis_rule_1_7_1: true -amazon2cis_rule_1_7_2: true -amazon2cis_rule_1_7_3: true -amazon2cis_rule_1_7_4: true -amazon2cis_rule_1_7_5: true -amazon2cis_rule_1_7_6: true -amazon2cis_rule_1_8: true - -# Section 2 rules +amazon2cis_rule_1_4_3: true +amazon2cis_rule_1_4_4: true + +# SElinux +amazon2cis_rule_1_5_1_1: true +amazon2cis_rule_1_5_1_2: true +amazon2cis_rule_1_5_1_3: true +amazon2cis_rule_1_5_1_4: true +amazon2cis_rule_1_5_1_5: true +amazon2cis_rule_1_5_1_6: true +amazon2cis_rule_1_5_1_7: true +amazon2cis_rule_1_5_1_8: true + +# Command line banner warnings +amazon2cis_rule_1_6_1: true +amazon2cis_rule_1_6_2: true +amazon2cis_rule_1_6_3: true +amazon2cis_rule_1_6_4: true +amazon2cis_rule_1_6_5: true +amazon2cis_rule_1_6_6: true + +## +## Section 2 rules +## # Section 2 is Services (inetd Services, Special Purpose Services, and Service Clients) + +# Time Service (Chrony) amazon2cis_rule_2_1_1: true amazon2cis_rule_2_1_2: true amazon2cis_rule_2_1_3: true -amazon2cis_rule_2_1_4: true -amazon2cis_rule_2_1_5: true -amazon2cis_rule_2_1_6: true -amazon2cis_rule_2_1_7: true -amazon2cis_rule_2_1_8: true -amazon2cis_rule_2_1_9: true -amazon2cis_rule_2_1_10: true -amazon2cis_rule_2_1_11: true -amazon2cis_rule_2_1_12: true -amazon2cis_rule_2_1_13: true -amazon2cis_rule_2_1_14: true -amazon2cis_rule_2_1_15: true -amazon2cis_rule_2_1_16: true -amazon2cis_rule_2_1_17: true -amazon2cis_rule_2_1_18: true -amazon2cis_rule_2_1_19: true -amazon2cis_rule_2_1_1_1: true -amazon2cis_rule_2_1_1_2: true -amazon2cis_rule_2_1_1_3: true + +# Special purpose services amazon2cis_rule_2_2_1: true amazon2cis_rule_2_2_2: true amazon2cis_rule_2_2_3: true amazon2cis_rule_2_2_4: true amazon2cis_rule_2_2_5: true -amazon2cis_rule_2_3: true - -# Section 3 rules +amazon2cis_rule_2_2_6: true +amazon2cis_rule_2_2_7: true +amazon2cis_rule_2_2_8: true +amazon2cis_rule_2_2_9: true +amazon2cis_rule_2_2_10: true +amazon2cis_rule_2_2_11: true +amazon2cis_rule_2_2_12: true +amazon2cis_rule_2_2_13: true +amazon2cis_rule_2_2_14: true +amazon2cis_rule_2_2_15: true +amazon2cis_rule_2_2_16: true +amazon2cis_rule_2_2_17: true +amazon2cis_rule_2_2_18: true +amazon2cis_rule_2_2_19: true +amazon2cis_rule_2_2_20: true +amazon2cis_rule_2_2_21: true +amazon2cis_rule_2_2_22: true + +# Client Services +amazon2cis_rule_2_3_1: true +amazon2cis_rule_2_3_2: true +amazon2cis_rule_2_3_3: true +amazon2cis_rule_2_3_4: true +amazon2cis_rule_2_3_5: true + +## +## Section 3 rules +## # Section 3 is Network Configuration (Disable unused network protocols, Network parameters (host), Network parameters (Host and Router), Uncommon Network Protocols, Firewall Configuration, and Configure iptables) +# ipv6, bluettoth and wireless amazon2cis_rule_3_1_1: true amazon2cis_rule_3_1_2: true +amazon2cis_rule_3_1_3: true + +# network kernel modules amazon2cis_rule_3_2_1: true amazon2cis_rule_3_2_2: true +amazon2cis_rule_3_2_3: true +amazon2cis_rule_3_2_4: true + +# network kernel parameters amazon2cis_rule_3_3_1: true amazon2cis_rule_3_3_2: true amazon2cis_rule_3_3_3: true @@ -161,117 +258,223 @@ amazon2cis_rule_3_3_6: true amazon2cis_rule_3_3_7: true amazon2cis_rule_3_3_8: true amazon2cis_rule_3_3_9: true -amazon2cis_rule_3_4_1: true -amazon2cis_rule_3_4_2: true -amazon2cis_rule_3_5_1_1: true -amazon2cis_rule_3_5_1_2: true -amazon2cis_rule_3_5_1_3: true -amazon2cis_rule_3_5_1_4: true -amazon2cis_rule_3_5_1_5: true -amazon2cis_rule_3_5_1_6: true -amazon2cis_rule_3_5_1_7: true -amazon2cis_rule_3_5_2_1: true -amazon2cis_rule_3_5_2_2: true -amazon2cis_rule_3_5_2_3: true -amazon2cis_rule_3_5_2_4: true -amazon2cis_rule_3_5_2_5: true -amazon2cis_rule_3_5_2_6: true -amazon2cis_rule_3_5_2_7: true -amazon2cis_rule_3_5_2_8: true -amazon2cis_rule_3_5_2_9: true -amazon2cis_rule_3_5_2_10: true -amazon2cis_rule_3_5_2_11: true -amazon2cis_rule_3_5_3_1_1: true -amazon2cis_rule_3_5_3_1_2: true -amazon2cis_rule_3_5_3_1_3: true - -# Section 4 rules -# Section 4 is Logging and Auditing (Configure System Accounting (auditd) and Configure Logging) +amazon2cis_rule_3_3_10: true +amazon2cis_rule_3_3_11: true + +# Configure firewall utility +amazon2cis_rule_3_4_1_1: true +amazon2cis_rule_3_4_1_2: true + +# firewalld +amazon2cis_rule_3_4_2_1: true +amazon2cis_rule_3_4_2_2: true +amazon2cis_rule_3_4_2_3: true +amazon2cis_rule_3_4_2_4: true + +# nftables +amazon2cis_rule_3_4_3_1: true +amazon2cis_rule_3_4_3_2: true +amazon2cis_rule_3_4_3_3: true +amazon2cis_rule_3_4_3_4: true +amazon2cis_rule_3_4_3_5: true +amazon2cis_rule_3_4_3_6: true +amazon2cis_rule_3_4_3_7: true +amazon2cis_rule_3_4_3_8: true +amazon2cis_rule_3_4_3_9: true + +# iptables +amazon2cis_rule_3_4_4_1_1: true + +# ip4tables +amazon2cis_rule_3_4_4_2_1: true +amazon2cis_rule_3_4_4_2_2: true +amazon2cis_rule_3_4_4_2_3: true +amazon2cis_rule_3_4_4_2_4: true +amazon2cis_rule_3_4_4_2_5: true +amazon2cis_rule_3_4_4_2_6: true + +# ip6tables +amazon2cis_rule_3_4_4_3_1: true +amazon2cis_rule_3_4_4_3_2: true +amazon2cis_rule_3_4_4_3_3: true +amazon2cis_rule_3_4_4_3_4: true +amazon2cis_rule_3_4_4_3_5: true +amazon2cis_rule_3_4_4_3_6: true + +## +## Section 4 rules +## +# Section 4 is Job Schedulers, SSH and privilege PAM +# Job Schedulers +## Cron amazon2cis_rule_4_1_1_1: true amazon2cis_rule_4_1_1_2: true amazon2cis_rule_4_1_1_3: true +amazon2cis_rule_4_1_1_4: true +amazon2cis_rule_4_1_1_5: true +amazon2cis_rule_4_1_1_6: true +amazon2cis_rule_4_1_1_7: true +amazon2cis_rule_4_1_1_8: true +# At amazon2cis_rule_4_1_2_1: true -amazon2cis_rule_4_1_2_2: true -amazon2cis_rule_4_1_2_3: true -amazon2cis_rule_4_1_2_4: true -amazon2cis_rule_4_1_3: true -amazon2cis_rule_4_1_4: true -amazon2cis_rule_4_1_5: true -amazon2cis_rule_4_1_6: true -amazon2cis_rule_4_1_7: true -amazon2cis_rule_4_1_8: true -amazon2cis_rule_4_1_9: true -amazon2cis_rule_4_1_10: true -amazon2cis_rule_4_1_11: true -amazon2cis_rule_4_1_12: true -amazon2cis_rule_4_1_13: true -amazon2cis_rule_4_1_14: true -amazon2cis_rule_4_1_15: true -amazon2cis_rule_4_1_16: true -amazon2cis_rule_4_1_17: true -amazon2cis_rule_4_2_1_1: true -amazon2cis_rule_4_2_1_2: true -amazon2cis_rule_4_2_1_3: true -amazon2cis_rule_4_2_1_4: true -amazon2cis_rule_4_2_1_5: true -amazon2cis_rule_4_2_1_6: true -amazon2cis_rule_4_2_2_1: true -amazon2cis_rule_4_2_2_2: true -amazon2cis_rule_4_2_2_3: true + +# SSH Server +amazon2cis_rule_4_2_1: true +amazon2cis_rule_4_2_2: true amazon2cis_rule_4_2_3: true amazon2cis_rule_4_2_4: true - -# Section 5 rules -# Section 5 is Access, Authentication, and Authorization (Configure time-based job schedulers, Configure SSH Server, Configure PAM, and User Accounts and Environment) -amazon2cis_rule_5_1_1: true -amazon2cis_rule_5_1_2: true +amazon2cis_rule_4_2_5: true +amazon2cis_rule_4_2_6: true +amazon2cis_rule_4_2_7: true +amazon2cis_rule_4_2_8: true +amazon2cis_rule_4_2_9: true +amazon2cis_rule_4_2_10: true +amazon2cis_rule_4_2_11: true +amazon2cis_rule_4_2_12: true +amazon2cis_rule_4_2_13: true +amazon2cis_rule_4_2_14: true +amazon2cis_rule_4_2_15: true +amazon2cis_rule_4_2_16: true +amazon2cis_rule_4_2_17: true +amazon2cis_rule_4_2_18: true +amazon2cis_rule_4_2_19: true +amazon2cis_rule_4_2_20: true +amazon2cis_rule_4_2_21: true +amazon2cis_rule_4_2_22: true + +# Privilege escalation +amazon2cis_rule_4_3_1: true +amazon2cis_rule_4_3_2: true +amazon2cis_rule_4_3_3: true +amazon2cis_rule_4_3_4: true +amazon2cis_rule_4_3_5: true +amazon2cis_rule_4_3_6: true +amazon2cis_rule_4_3_7: true + +## Configure Pluggable Authentication +# software packages +amazon2cis_rule_4_4_1_1: true +amazon2cis_rule_4_4_1_2: true + +# pam_faillock +amazon2cis_rule_4_4_2_1_1: true +amazon2cis_rule_4_4_2_1_2: true +amazon2cis_rule_4_4_2_1_3: true +amazon2cis_rule_4_4_2_1_4: true + +# pam_pwquality +amazon2cis_rule_4_4_2_2_1: true +amazon2cis_rule_4_4_2_2_2: true +amazon2cis_rule_4_4_2_2_3: true +amazon2cis_rule_4_4_2_2_4: true +amazon2cis_rule_4_4_2_2_5: true +amazon2cis_rule_4_4_2_2_6: true +amazon2cis_rule_4_4_2_2_7: true + +# pam pwhistory +amazon2cis_rule_4_4_2_3_1: true +amazon2cis_rule_4_4_2_3_2: true +amazon2cis_rule_4_4_2_3_3: true +amazon2cis_rule_4_4_2_3_4: true + +# pam pam_unix +amazon2cis_rule_4_4_2_4_1: true +amazon2cis_rule_4_4_2_4_2: true +amazon2cis_rule_4_4_2_4_3: true +amazon2cis_rule_4_4_2_4_4: true + +# shadow password +amazon2cis_rule_4_5_1_1: true +amazon2cis_rule_4_5_1_2: true +amazon2cis_rule_4_5_1_3: true +amazon2cis_rule_4_5_1_4: true +amazon2cis_rule_4_5_1_5: true + +# root and system accts +amazon2cis_rule_4_5_2_1: true +amazon2cis_rule_4_5_2_2: true +amazon2cis_rule_4_5_2_3: true +amazon2cis_rule_4_5_2_4: true + +# user default envs +amazon2cis_rule_4_5_3_1: true +amazon2cis_rule_4_5_3_2: true +amazon2cis_rule_4_5_3_3: true + +## +## Section 5 rules +## + +# Rsyslog +amazon2cis_rule_5_1_1_1: true +amazon2cis_rule_5_1_1_2: true +amazon2cis_rule_5_1_1_3: true +amazon2cis_rule_5_1_1_4: true +amazon2cis_rule_5_1_1_5: true +amazon2cis_rule_5_1_1_6: true +amazon2cis_rule_5_1_1_7: true + +# Journald +amazon2cis_rule_5_1_2_1_1: true +amazon2cis_rule_5_1_2_1_2: true +amazon2cis_rule_5_1_2_1_3: true +amazon2cis_rule_5_1_2_1_4: true +amazon2cis_rule_5_1_2_2: true +amazon2cis_rule_5_1_2_3: true +amazon2cis_rule_5_1_2_4: true +amazon2cis_rule_5_1_2_5: true +amazon2cis_rule_5_1_2_6: true amazon2cis_rule_5_1_3: true amazon2cis_rule_5_1_4: true -amazon2cis_rule_5_1_5: true -amazon2cis_rule_5_1_6: true -amazon2cis_rule_5_1_7: true -amazon2cis_rule_5_1_8: true -amazon2cis_rule_5_1_9: true -amazon2cis_rule_5_2_1: true -amazon2cis_rule_5_2_2: true -amazon2cis_rule_5_2_3: true + +# Auditd +amazon2cis_rule_5_2_1_1: true +amazon2cis_rule_5_2_1_2: true +amazon2cis_rule_5_2_1_3: true +amazon2cis_rule_5_2_1_4: true +amazon2cis_rule_5_2_2_1: true +amazon2cis_rule_5_2_2_2: true +amazon2cis_rule_5_2_2_3: true +amazon2cis_rule_5_2_2_4: true + +# auditd rules +amazon2cis_rule_5_2_3_1: true +amazon2cis_rule_5_2_3_2: true +amazon2cis_rule_5_2_3_3: true +amazon2cis_rule_5_2_3_4: true +amazon2cis_rule_5_2_3_5: true +amazon2cis_rule_5_2_3_6: true +amazon2cis_rule_5_2_3_7: true +amazon2cis_rule_5_2_3_8: true +amazon2cis_rule_5_2_3_9: true +amazon2cis_rule_5_2_3_10: true +amazon2cis_rule_5_2_3_11: true +amazon2cis_rule_5_2_3_12: true +amazon2cis_rule_5_2_3_13: true +amazon2cis_rule_5_2_3_14: true +amazon2cis_rule_5_2_3_15: true +amazon2cis_rule_5_2_3_16: true +amazon2cis_rule_5_2_3_17: true +amazon2cis_rule_5_2_3_18: true +amazon2cis_rule_5_2_3_19: true +amazon2cis_rule_5_2_3_20: true +amazon2cis_rule_5_2_3_21: true + +# auditd file access +amazon2cis_rule_5_2_4_1: true +amazon2cis_rule_5_2_4_2: true +amazon2cis_rule_5_2_4_3: true +amazon2cis_rule_5_2_4_4: true +amazon2cis_rule_5_2_4_5: true +amazon2cis_rule_5_2_4_6: true +amazon2cis_rule_5_2_4_7: true +amazon2cis_rule_5_2_4_8: true +amazon2cis_rule_5_2_4_9: true +amazon2cis_rule_5_2_4_10: true + +# Aide amazon2cis_rule_5_3_1: true amazon2cis_rule_5_3_2: true -amazon2cis_rule_5_3_3: true -amazon2cis_rule_5_3_4: true -amazon2cis_rule_5_3_5: true -amazon2cis_rule_5_3_6: true -amazon2cis_rule_5_3_7: true -amazon2cis_rule_5_3_8: true -amazon2cis_rule_5_3_9: true -amazon2cis_rule_5_3_10: true -amazon2cis_rule_5_3_12: true -amazon2cis_rule_5_3_11: true -amazon2cis_rule_5_3_13: true -amazon2cis_rule_5_3_14: true -amazon2cis_rule_5_3_15: true -amazon2cis_rule_5_3_16: true -amazon2cis_rule_5_3_17: true -amazon2cis_rule_5_3_18: true -amazon2cis_rule_5_3_19: true -amazon2cis_rule_5_3_20: true -amazon2cis_rule_5_3_21: true -amazon2cis_rule_5_3_22: true -amazon2cis_rule_5_4_1: true -amazon2cis_rule_5_4_2: true -amazon2cis_rule_5_4_3: true -amazon2cis_rule_5_4_4: true -amazon2cis_rule_5_5_1_1: true -amazon2cis_rule_5_5_1_2: true -amazon2cis_rule_5_5_1_3: true -amazon2cis_rule_5_5_1_4: true -amazon2cis_rule_5_5_1_5: true -amazon2cis_rule_5_5_2: true -amazon2cis_rule_5_5_3: true -amazon2cis_rule_5_5_4: true -amazon2cis_rule_5_5_5: true -amazon2cis_rule_5_6: true -amazon2cis_rule_5_7: true # Section 6 rules # Section 6 is System Maintenance (System File Permissions and User and Group Settings) @@ -307,49 +510,21 @@ amazon2cis_rule_6_2_15: true amazon2cis_rule_6_2_16: true amazon2cis_rule_6_2_17: true -# Service configuration booleans set true to keep service -amazon2cis_allow_autofs: false -amazon2cis_avahi_server: false -amazon2cis_cups_server: false -amazon2cis_dhcp_server: false -amazon2cis_ldap_server: false -amazon2cis_named_server: false -amazon2cis_vsftpd_server: false -amazon2cis_httpd_server: false -amazon2cis_dovecot_server: false -amazon2cis_smb_server: false -amazon2cis_squid_server: false -amazon2cis_snmp_server: false -amazon2cis_nis_server: false -amazon2cis_telnet_server: false -amazon2cis_is_mail_server: false -amazon2cis_nfs_rpc_server: false -amazon2cis_nfs_server: false -amazon2cis_rpc_server: false -amazon2cis_rsyncd_server: false +## Section 1 variables -# Service Clients -amazon2cis_ypbind_required: false -amazon2cis_rsh_required: false -amazon2cis_talk_required: false -amazon2cis_telnet_required: false -amazon2cis_openldap_clients_required: false - -# System network parameters (host only OR host and router) -amazon2cis_is_router: false - -# IPv6 required -amazon2cis_ipv6_required: false +# If set true uses the tmp.mount service else using fstab configuration +amazon2cis_tmp_svc: true -# Whether or not to run tasks related to auditing/patching the desktop environment -amazon2cis_gui: false +# cis 1.4.1 +kernel_sysctl_file: /etc/sysctl.d/60-kernel_sysctl.conf -# Set to 'true' if X Windows is needed in your environment -amazon2cis_xwindows_required: false +# Warning Banner Content (issue, issue.net, motd) +amazon2cis_warning_banner: | + Authorized uses only. All activity may be monitored and reported. +# End Banner -# Time Synchronization - Either chrony or ntp +## Section 2 variables amazon2cis_time_synchronization: chrony - amazon2cis_time_synchronization_servers: - 0.pool.ntp.org - 1.pool.ntp.org @@ -359,64 +534,122 @@ amazon2cis_time_synchronization_servers: amazon2cis_chrony_server_options: "minpoll 8" amazon2cis_ntp_server_options: "iburst" -# Firewall Service - either firewalld or iptables -amazon2cis_firewall: firewalld -amazon2cis_default_zone: public +## Optional settings not part of CIS but can assist systems +# Disable ipv6 on Chrony if ipv6 not required +amazon2cis_ipv6_chrony_disable: false -# AIDE -amazon2cis_config_aide: true -# AIDE cron settings -amazon2cis_aide_cron: - cron_user: root - cron_file: /etc/crontab - aide_job: '/usr/sbin/aide --check' - aide_minute: '0' - aide_hour: '5' - aide_day: '*' - aide_month: '*' - aide_weekday: '*' +# 2.2.x +# Service configuration booleans set true to keep service +# Service configuration +# Options are +# true to leave installed if exists not changes take place +# false - this removes the package +# mask - if a dependancy for product so cannot be removed +# Server Services +amazon2cis_autofs_services: false +amazon2cis_autofs_mask: true +amazon2cis_avahi_server: false +amazon2cis_avahi_mask: false +amazon2cis_dhcp_server: false +amazon2cis_dhcp_mask: false +amazon2cis_dns_server: false +amazon2cis_dns_mask: false +amazon2cis_dnsmasq_server: false +amazon2cis_dnsmasq_mask: false +amazon2cis_samba_server: false +amazon2cis_samba_mask: false +amazon2cis_ftp_server: false +amazon2cis_ftp_mask: false +amazon2cis_message_server: false # This is for messaging dovecot and cyrus-imap +amazon2cis_message_mask: false +amazon2cis_nfs_server: false +amazon2cis_nfs_mask: true +amazon2cis_nis_server: true # set to mask if nis client required +amazon2cis_nis_mask: false +amazon2cis_print_server: false # replaces cups +amazon2cis_print_mask: false +amazon2cis_rpc_server: false +amazon2cis_rpc_mask: true +amazon2cis_rsync_server: false +amazon2cis_rsync_mask: false +amazon2cis_net_snmp_server: false +amazon2cis_net_snmp_mask: false +amazon2cis_telnet_server: false +amazon2cis_telnet_mask: false +amazon2cis_tftp_server: false +amazon2cis_tftp_mask: false +amazon2cis_squid_server: false +amazon2cis_squid_mask: false +amazon2cis_httpd_server: false +amazon2cis_httpd_mask: false +amazon2cis_nginx_server: false +amazon2cis_nginx_mask: false +amazon2cis_xinetd_server: false +amazon2cis_xinetd_mask: false +amazon2cis_xwindow_server: false # will remove mask not an option +amazon2cis_is_mail_server: false -## Section 4 variables -# auditd settings -amazon2cis_auditd: - space_left_action: email - action_mail_acct: root - admin_space_left_action: halt - max_log_file_action: keep_logs +# Service Clients +# Client Services +amazon2cis_ftp_client: false +amazon2cis_openldap_clients_required: false +amazon2cis_ypbind_required: false # Same package as NIS server +amazon2cis_telnet_required: false +amazon2cis_tftp_client: false -# 4.2.3 -# amazon2cis_logrotate sets the daily, weekly, monthly, yearly value for the log rotation -# To conform to CIS standards this just needs to comply with your site policy -amazon2cis_logrotate: "daily" +## Section 3 Variables +# 3.1.x +# IPv6 required +amazon2cis_ipv6_required: false +amazon2cis_ipv6_sysctl_force: true +amazon2cis_ipv6_sysctl_file: /etc/sysctl.d/60-ipv6.conf +# Setting this will stop ipv6 listening on ::1 and will remove from /etc/hosts +amazon2cis_ipv6_disable_localhost: false -# AMZN LNX 2-4.1.2.4 -# amazon2cis_audit_backlog_limit value needs to be 8192 or larger to conform to CIS standards -amazon2cis_audit_backlog_limit: 8192 +# service = true removes package - mask = true will just mask package +amazon2cis_bluetooth_service: true +amazon2cis_bluetooth_mask: false -# AMZN LNX-4.2.1.4/4.2.1.5 remote and destation log server name -amazon2cis_remote_log_server: logagg.example.com +# 3.3.x +# System network parameters (host only OR host and router) +amazon2cis_is_router: false +amazon2cis_ipv4_sysctl_file: /etc/sysctl.d/60-ipv4.conf -# AMZN LNX-4.2.1.6 -amazon2cis_system_is_log_server: false +# Firewall Service - either firewalld, iptables or nftables +# multiple options for removal or masking of services +# The firewall to be configured +amazon2cis_system_firewall: firewalld +# Set the following to remove or mask - note will not effect system_firewall # set to none +amazon2cis_nftables: mask +amazon2cis_iptables: mask +amazon2cis_firewalld: none -# Maxium audit log size in MB -amazon2cis_maxauditlog_size: 10 +# Allow automated creation of nftables table +amazon2cis_nft_tables_autonewtable: false +# give that table a name +amazon2cis_nft_tables_tablename: cis +# Allow creation of chains +amazon2cis_nft_tables_autochaincreate: false -amazon2cis_rsyslog_ansibleManaged: true +## +## Section 4 Variables +## # SSH variables + +## Can be VERBOSE or INFO amazon2cis_ssh_loglevel: INFO # amazon2cis_ssh_maxsessions is the max number of sessions # To conform to CIS standards this value nees to be 10 or less -amazon2cis_ssh_maxsessions: 10 + amazon2cis_sshd: - clientalivecountmax: 0 + clientalivecountmax: 3 # clientaliveinterval shoudl be between 1 and 900 - clientaliveinterval: 300 + clientaliveinterval: 15 ciphers: "chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" macs: "hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256" - kex: "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256" + kex: "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256" # logingracetime value is in seconds and needs to be set to 1 minute or less logingracetime: 60 # WARNING: make sure you understand the precedence when working with these values!! @@ -425,9 +658,25 @@ amazon2cis_sshd: # denyusers: # denygroups: +amazon2cis_ssh_maxsessions: 10 +amazon2cis_ssh_maxauthtries: 4 + +## Optional settings not part of CIS but can assist systems +# Disable ipv6 on ssh if ipv6 not required +amazon2cis_ipv6_sshd_disable: false + +## Sudo +amazon2cis_sudolog_location: "/var/log/sudo.log" +amazon2cis_sudo_timestamp_timeout: 15 + +# Group to be used for su +# this group needs to exists groups will not be created for remediation this is considered sys admins + +amazon2cis_sugroup: wheel + # pam variables amazon2cis_pam_faillock: - attempts: 5 + deny: 5 interval: 900 unlock_time: 900 fail_for_root: "no" @@ -436,96 +685,140 @@ amazon2cis_pam_faillock: amazon2cis_inactivelock: lock_days: 30 +amazon2cis_pwquality_difok: 2 # 2 or more required +amazon2cis_pwquality_maxrepeat: 3 # 3 or less not 0 required +amazon2cis_pwquality_maxsequence: 3 # 3 or less not 0 required +amazon2cis_pwquality_minlen: 14 # 14 or more required +# Setting minclass true - mincalls used instead of seperated values +amazon2cis_pwquality_minclass: true +amazon2cis_pwquality_minclass_value: '4' # Not less than 4 +amazon2cis_pwquality: + - key: '#minclass' + value: "{{ ubtu22cis_pwquality_minclass_value }}" + - key: 'dcredit' + value: '-1' # not 0 or greater + - key: 'ucredit' + value: '-1' # not 0 or greater + - key: 'ocredit' + value: '-1' # not 0 or greater + - key: 'lcredit' + value: '-1' # not 0 or greater + +# pwhistory +amazon2cis_pwhistory_remember: 24 # 24 or more recommended + +## Users and environments +amazon2cis_encryption: sha512 +# If encryption method changes foce users to change password at next login +amazon2cis_force_user_passwd_change: false # Accounts listed below will not have INACTIVE field set in shadow file + +# Allow dynamic discovery of user accounts minimum and maximun from /etc/login.defs +# findings will override the uid_min|max below +amazon2cis_uid_info_dynamic: true +amazon2cis_uid_min: 1000 +amazon2cis_uid_max: 60000 + amazon2cis_inactive_whitelist: - root - vagrant +## 4.5.1.2 Add users to be skipped if required +amazon2cis_user_skip_list: + root + amazon2cis_pass: - max_days: 90 + max_days: 365 min_days: 1 warn_age: 7 + inactive: 30 # should not be 0 or -1 (little details in control) -# 5.3.7 -# amazon2_max_auth_tries is the number of max authorization attemps permitted per connection -# To conform to CIS standards this needs to be 4 or less -amazon2_max_auth_tries: 4 - -# 5.4.5 # Session timeout setting file (TMOUT setting can be set in multiple files) # Timeout value is in seconds. (60 seconds * 10 = 600) amazon2cis_shell_session_timeout: file: /etc/profile.d/tmout.sh timeout: 600 -# 5.4.1.5 Allow ansible to expire password for account with a last changed date in the future. False will just display users in violation, true will expire those users passwords +# Allow ansible to expire password for account with a last changed date in the future. False will just display users in violation, true will expire those users passwords amazon2cis_futurepwchgdate_autofix: true -# 5.4.2 -amazon2cis_int_gid: 1000 +amazon2cis_root_umask: '0027' # 0027 or more restrictive -# 5.6 Group to be used for su -# this group needs to exists groups will not be created for remediation this is considered sys admins +## +## Section 5 Variables +## + +# Preferred method of logging +# Whether rsyslog or journald preferred method for local logging +amazon2cis_syslog: rsyslog +amazon2cis_rsyslog_ansiblemanaged: true +# Set if system is the log server +amazon2cis_system_is_log_server: false + +# remote and destination log server name +amazon2cis_remote_log_server: false +amazon2cis_remote_log_host: logagg.example.com +amazon2cis_remote_log_port: 514 +amazon2cis_remote_log_protocol: tcp +amazon2cis_remote_log_retrycount: 100 +amazon2cis_remote_log_queuesize: 1000 + +# amazon2cis_logrotate sets the daily, weekly, monthly, yearly value for the log rotation +# To conform to CIS standards this just needs to comply with your site policy +amazon2cis_logrotate: "daily" + +# AuditD +# The audit_back_log_limit value should never be below 8192 +amazon2cis_audit_back_log_limit: 8192 +# The max_log_file parameter should be based on your sites policy size in MB +amazon2cis_max_log_file_size: 10 + +# auditd settings +amazon2cis_auditd: + disk_error_action: halt + disk_full_action: halt + action_mail_acct: root + space_left_action: email + admin_space_left_action: single + max_log_file_action: keep_logs -# amazon2cis_sugroup: sugroup +# This can be used to configure other keys in auditd.conf +amazon2cis_auditd_extra_conf: {} +# Example: +# amazon2cis_auditd_extra_conf: +# admin_space_left: '10%' -# amazon2_6.1.1 +# AIDE +# aide setup via - cron, timer +amazon2cis_aide_scan: cron +amazon2cis_config_aide: true +# AIDE cron settings +amazon2cis_aide_cron: + cron_user: root + cron_file: /etc/cron.d/cis_aide + aide_job: '/usr/sbin/aide --check' + aide_minute: 0 + aide_hour: 5 + aide_day: '*' + aide_month: '*' + aide_weekday: '*' + +## +## Section 6 variables +## + +# amazon2cis_rpm_audit_file: /var/tmp/rpm_file_check -# amazon2_6.2.12 +# Allow ansible to adjust world-writable files. False will just display world-writable files, True will remove world-writable amazon2cis_no_world_write_adjust: true amazon2cis_passwd_label: "{{ (this_item | default(item)).id }}: {{ (this_item | default(item)).dir }}" -amazon2cis_dotperm_ansibleManaged: true -# SELinux policy -amazon2cis_selinux_pol: targeted +## adjust files if ungrouped +amazon2cis_ungrouped_adjust: false -# Warning Banner Content (issue, issue.net, motd) -amazon2cis_warning_banner: | - Authorized uses only. All activity may be monitored and reported. -# End Banner +## Remove suid/sgid from files +amazon2cis_suid_adjust: false +amazon2cis_sgid_adjust: false -### Goss binary settings ### -goss_version: - release: v0.3.21 - checksum: 'sha256:9a9200779603acf0353d2c0e85ae46e083596c10838eaf4ee050c924678e4fe3' -audit_bin_path: /usr/local/bin/ -audit_bin: "{{ audit_bin_path }}goss" -audit_format: json - -# if get_goss_file == download change accordingly -goss_url: "https://github.com/goss-org/goss/releases/download/{{ goss_version.release }}/goss-linux-amd64" - -## if get_goss_file - copy the following needs to be updated for your environment -## it is expected that it will be copied from somewhere accessible to the control node -## e.g copy from ansible control node to remote host -copy_goss_from_path: /some/accessible/path - -### Goss Audit Benchmark file ### -## managed by the control audit_content -# git -audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" -audit_git_version: "benchmark_{{ benchmark_version }}_amazon2" - -# copy: -audit_local_copy: "some path to copy from" - -# get_url: -audit_files_url: "some url maybe s3?" - -# Where the goss audit configuration will be stored -audit_files: "/opt/{{ benchmark }}-Audit/" - -## Goss configuration information -# Where the goss configs and outputs are stored -audit_out_dir: '/opt' -audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" -pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}-{{ benchmark }}_pre_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}" -post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}-{{ benchmark }}_post_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}" - -## The following should not need changing -goss_file: "{{ audit_conf_dir }}goss.yml" -audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_hostname }}.yml" -audit_results: | - The pre remediation results are: {{ pre_audit_summary }}. - The post remediation results are: {{ post_audit_summary }}. - Full breakdown can be found in {{ audit_out_dir }} +# 6.2.12 +amazon2cis_dotperm_ansiblemanaged: true diff --git a/handlers/main.yml b/handlers/main.yml index f8c71c6..e19637d 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,78 +1,122 @@ --- - name: systemd restart tmp.mount - systemd: + ansible.builtin.systemd: name: tmp.mount daemon_reload: true enabled: true masked: false state: reloaded -- name: remount tmp - command: mount -o remount /tmp +- name: Remount dev_shm + ansible.posix.mount: + name: /dev/shm + state: remounted -- name: remount dev_shm - command: mount -o remount /dev/shm +- name: Remount home + ansible.posix.mount: + name: /home + state: remounted -- name: remount var_tmp - command: mount -o remount /var/tmp +- name: Remount var + ansible.posix.mount: + name: /var + state: remounted -- name: remount home - command: mount -o remount /home +- name: Remount var_tmp + ansible.posix.mount: + name: /var/tmp + state: remounted -- name: systemd daemon reload - systemd: +- name: Remount var_log + ansible.posix.mount: + name: /var/log + state: remounted + +- name: Remount var_log_audit + ansible.posix.mount: + name: /var/log/audit + state: remounted + +- name: Systemd_daemon_reload + ansible.builtin.systemd: daemon_reload: true -- name: grub2cfg - command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" +- name: Rebuild_grub + ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" -- name: restart postfix - service: +- name: Restart_postfix + ansible.builtin.service: name: postfix state: restarted -- name: sysctl flush ipv6 route table - sysctl: - name: net.ipv6.route.flush +- name: Sysctl_flush_ipv4_routes + ansible.posix.sysctl: + name: net.ipv4.route.flush value: '1' sysctl_set: true - when: ansible_virtualization_type != "docker" + ignore_errors: true # noqa ignore-errors -- name: sysctl flush ipv4 route table - sysctl: - name: net.ipv4.route.flush +- name: Sysctl_flush_ipv6_routes + ansible.posix.sysctl: + name: net.ipv6.route.flush value: '1' sysctl_set: true - when: ansible_virtualization_type != "docker" + ignore_errors: true # noqa ignore-errors + +- name: Restart_rsyslog + ansible.builtin.service: + name: rsyslog + state: restarted + +- name: Restart_journald + ansible.builtin.service: + name: systemd-journald + state: restarted + +- name: Restart_systemd_journal_upload + ansible.builtin.service: + name: systemd-journal-upload + state: restarted - name: update auditd - template: + ansible.builtin.template: src: audit/99_auditd.rules.j2 dest: /etc/audit/rules.d/99_auditd.rules owner: root group: root mode: 0600 - notify: restart auditd + notify: Restart_auditd + +- name: Auditd_immutable_check + ansible.builtin.shell: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules + changed_when: false + register: auditd_immutable_check -- name: restart auditd - command: /sbin/service auditd restart - check_mode: false - failed_when: false +- name: Audit_immutable_fact + ansible.builtin.debug: + msg: "Reboot required for auditd to apply new rules as immutable set" + notify: Change_requires_reboot when: - - not amazon2cis_skip_for_travis - tags: - - skip_ansible_lint + - auditd_immutable_check.stdout == '1' + +- name: Restart_auditd + ansible.builtin.shell: /sbin/service auditd restart - name: grub2cfg - command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" + ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" + notify: Change_requires_reboot - name: restart rsyslog - service: + ansible.builtin.service: name: rsyslog state: restarted - name: restart sshd - service: + ansible.builtin.service: name: sshd state: restarted + +- name: Change_requires_reboot + ansible.builtin.set_fact: + change_requires_reboot: true diff --git a/meta/main.yml b/meta/main.yml index c4042ae..42cde67 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,23 +1,25 @@ --- + galaxy_info: - author: "DFed, George Nalen, Mark Bolwell" + author: "George Nalen, Mark Bolwell" description: "Apply the Amazon Linux 2 CIS controls" company: "MindPoint Group" license: MIT namespace: mindpointgroup role_name: amazon2_cis - min_ansible_version: 2.10.1 + min_ansible_version: 2.11.1 platforms: - - name: Amazon + - name: Amazon Linux versions: - - "2017.03" - - "2017.09" + - "2" galaxy_tags: - system - security - cis - hardening - - Amazon + - benchmark + - compliance + - amazonlinux - complianceascode collections: - community.general diff --git a/site.yml b/site.yml index 52c4afc..40a9341 100644 --- a/site.yml +++ b/site.yml @@ -1,7 +1,7 @@ --- -- hosts: all +- name: Run the ansible-lockdown remediation role + hosts: all become: true - name: Run the ansible-lockdown remediation role roles: - - role: "{{ playbook_dir }}" + - role: "{{ playbook_dir }}" diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 8321a32..7ef94b4 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -1,22 +1,34 @@ --- -- name: Download audit binary - get_url: - url: "{{ goss_url }}" +- name: Pre Audit Setup | Set audit package name + block: + - name: Pre Audit Setup | Set audit package name | 64bit + ansible.builtin.set_fact: + audit_pkg_arch_name: AMD64 + when: ansible_facts.machine == "x86_64" + + - name: Pre Audit Setup | Set audit package name | ARM64 + ansible.builtin.set_fact: + audit_pkg_arch_name: ARM64 + when: ansible_facts.machine == "arm64" + +- name: Pre Audit Setup | Download audit binary + ansible.builtin.get_url: + url: "{{ audit_bin_url }}{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" owner: root group: root - checksum: "{{ goss_version.checksum }}" - mode: 0555 + checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" + mode: '0555' when: - - get_goss_file == 'download' + - get_audit_binary_method == 'download' -- name: copy audit binary - copy: - src: "{{ copy_goss_from_path }}" +- name: Pre Audit Setup | Copy audit binary + ansible.builtin.copy: + src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" - mode: 0555 + mode: '0555' owner: root group: root when: - - get_goss_file == 'copy' + - get_audit_binary_method == 'copy' diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml new file mode 100644 index 0000000..864f5bb --- /dev/null +++ b/tasks/audit_only.yml @@ -0,0 +1,30 @@ +--- + +- name: Audit_Only | Create local Directories for hosts + ansible.builtin.file: + mode: '0755' + path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" + recurse: true + state: directory + when: fetch_audit_files + delegate_to: localhost + become: false + +- name: Audit_only | Get audits from systems and put in group dir + ansible.builtin.fetch: + dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/" + flat: true + mode: '0644' + src: "{{ pre_audit_outfile }}" + when: fetch_audit_files + +- name: Audit_only | Show Audit Summary + when: + - audit_only + ansible.builtin.debug: + msg: "The Audit results are: {{ pre_audit_summary }}." + +- name: Audit_only | Stop Playbook Audit Only selected + when: + - audit_only + ansible.builtin.meta: end_play diff --git a/tasks/auditd.yml b/tasks/auditd.yml new file mode 100644 index 0000000..84f14f0 --- /dev/null +++ b/tasks/auditd.yml @@ -0,0 +1,14 @@ +--- + +- name: POST | AUDITD | Apply auditd template - only required rules will be added + ansible.builtin.template: + src: audit/99_auditd.rules.j2 + dest: /etc/audit/rules.d/99_auditd.rules + owner: root + group: root + mode: 0600 + register: audit_rules_updated + notify: + - Auditd_immutable_check + - Audit_immutable_fact + - Restart_auditd diff --git a/tasks/check_prereqs.yml b/tasks/check_prereqs.yml index ff1e7bc..9551852 100644 --- a/tasks/check_prereqs.yml +++ b/tasks/check_prereqs.yml @@ -1,7 +1,7 @@ --- - name: "PREREQ | Add the required packages installed | Python2" - package: + ansible.builtin.package: name: "{{ item }}" state: latest register: python2_packages @@ -12,7 +12,7 @@ ansible_python_interpreter: "{{ python2_bin }}" - name: "PREREQ | Check required packages installed | Python3 " - package: + ansible.builtin.package: name: "{{ item }}" state: present register: python3reqs_installed diff --git a/tasks/main.yml b/tasks/main.yml index 4b5d843..3aecdf3 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,112 +1,154 @@ --- - name: Check OS version and family - fail: - msg: "This role can only be run against Amazon Linux 2. {{ ansible_distribution }} {{ ansible_distribution_major_version }} is not supported." when: - - ansible_distribution != 'Amazon' - - ansible_distribution_major_version is version_compare('2', '!=') + - os_check + ansible.builtin.assert: + that: (ansible_facts.distribution == 'Amazon' and ansible_facts.distribution_major_version is version_compare('2', '==')) + fail_msg: "This role can only be run against Supported OSs. {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }} is not supported." + success_msg: "This role is running against a supported OS {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }}" tags: - always - name: Check ansible version - fail: - msg: You must use ansible 2.9 or greater - when: not ansible_version.full is version_compare('2.9', '>=') + ansible.builtin.assert: + that: ansible_version.full is version_compare(min_ansible_version, '>=') + fail_msg: "You must use Ansible {{ min_ansible_version }} or greater" + success_msg: "This role is running a supported version of ansible {{ ansible_version.full }} >= {{ min_ansible_version }}" tags: - always +- name: Ensure root password is set + when: + - amazon2cis_rule_4_5_2_4 + tags: + - always + block: + - name: Ensure root password is set + ansible.builtin.shell: passwd -S root | egrep -e "(Password set, SHA512 crypt|Password locked)" + changed_when: false + failed_when: false + register: root_passwd_set + + - name: Ensure root password is set + ansible.builtin.assert: + that: root_passwd_set.rc == 0 + fail_msg: "You have rule 4.5.2.4 enabled this requires that you have a root password set" + success_msg: "You have a root password set" + - name: "check sugroup exists if used" block: - name: "Check su group exists if defined" - command: grep -w "{{ amazon2cis_sugroup }}" /etc/group + ansible.builtin.command: grep -w "{{ amazon2cis_sugroup }}" /etc/group changed_when: false failed_when: sugroup_exists.rc >= 2 register: sugroup_exists - tags: - - skip_ansible_lint - name: Check sugroup if defined exists before continuing - assert: + ansible.builtin.assert: that: sugroup_exists.rc == 0 msg: "The variable amazon2cis_sugroup is defined but does not exist please rectify" when: - amazon2cis_sugroup is defined - - amazon2cis_rule_5_7 + - amazon2cis_rule_4_3_7 tags: - - rule_5.7 + - rule_4.3.7 -- include_tasks: check_prereqs.yml +- name: Run pre-reqs + ansible.builtin.import_tasks: + file: check_prereqs.yml tags: - always - prereqs -- include_tasks: prelim.yml +- name: Run prelim tasks + ansible.builtin.import_tasks: + file: prelim.yml tags: - prelim_tasks - always -- import_tasks: pre_remediation_audit.yml - when: - - run_audit - tags: - - run_audit - - name: Gather the package facts - package_facts: + ansible.builtin.package_facts: manager: auto tags: - always -- include_tasks: section_1/main.yml +- name: Import section 1 tasks + ansible.builtin.import_tasks: + file: section_1/main.yml when: amazon2cis_section1 tags: - amazon2cis_section1 -- include_tasks: section_2/main.yml +- name: Import section 2 tasks + ansible.builtin.import_tasks: + file: section_2/main.yml when: amazon2cis_section2 tags: - amazon2cis_section2 -- include_tasks: section_3/main.yml +- name: Import section 3 tasks + ansible.builtin.import_tasks: + file: section_3/main.yml when: amazon2cis_section3 tags: - amazon2cis_section3 -- include_tasks: section_4/main.yml +- name: Import section 4 tasks + ansible.builtin.import_tasks: + file: section_4/main.yml when: amazon2cis_section4 tags: - amazon2cis_section4 -- include_tasks: section_5/main.yml +- name: Import section 5 tasks + ansible.builtin.import_tasks: + file: section_5/main.yml when: amazon2cis_section5 tags: - amazon2cis_section5 -- include_tasks: section_6/main.yml +- name: Import section 6 tasks + ansible.builtin.import_tasks: + file: section_6/main.yml when: amazon2cis_section6 tags: - amazon2cis_section6 -# - include_tasks: post.yml -# tags: -# - post_tasks -# - always +- name: Run auditd logic + when: + - update_audit_template + tags: + - always + ansible.builtin.import_tasks: + file: auditd.yml -- name: flush handlers - meta: flush_handlers +- name: Run post remediation tasks + tags: + - post_tasks + - always + ansible.builtin.import_tasks: + file: post.yml -- name: run post_remediation audit - import_tasks: post_remediation_audit.yml +- name: Run post_remediation audit when: - run_audit tags: - run_audit + ansible.builtin.import_tasks: + file: post_remediation_audit.yml - name: Show Audit Summary - debug: - msg: "{{ audit_results.split('\n') }}" when: - run_audit tags: - run_audit + ansible.builtin.debug: + msg: "{{ audit_results.split('\n') }}" + +- name: Output Warning count and control IDs affected + tags: + - always + ansible.builtin.debug: + msg: "You have {{ warn_count }} warning(s) that require investigating that are related to the following benchmark ID(s) {{ warn_control_list }}" diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index a686a57..547b721 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -2,21 +2,21 @@ - name: "PRELIM | Parse Password Entries | Parse /etc/passwd" block: - name: "PRELIM | Parse /etc/passwd" - command: cat /etc/passwd + ansible.builtin.command: cat /etc/passwd changed_when: false failed_when: false check_mode: false register: amazon2cis_passwd_file_audit - name: "PRELIM | Parse Password EntriesSplit passwd entries" - set_fact: + ansible.builtin.set_fact: amazon2cis_passwd: "{{ amazon2cis_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" with_items: - "{{ amazon2cis_passwd_file_audit.stdout_lines }}" vars: ld_passwd_regex: >- ^(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*) - ld_passwd_yaml: | + ld_passwd_yaml: | # pragma: allowlist secret id: >-4 \g password: >-4 diff --git a/tasks/post.yml b/tasks/post.yml new file mode 100644 index 0000000..e8951b5 --- /dev/null +++ b/tasks/post.yml @@ -0,0 +1,43 @@ +--- +# Post tasks + +- name: POST | Perform yum package cleanup + ansible.builtin.package: + autoremove: true + changed_when: false + +- name: POST | flush handlers + ansible.builtin.meta: flush_handlers + +- name: POST | reboot system if changes require it and not skipped + block: + - name: POST | Reboot system if changes require it and not skipped + when: + - reboot_required + - not skip_reboot + ansible.builtin.reboot: + + - name: POST | Warning a reboot required but skip option set + when: + - reboot_required + - skip_reboot + ansible.builtin.debug: + msg: "Warning!! changes have been made that require a reboot to be implemented but skip reboot was set - Can affect compliance check results" + changed_when: true + + - name: "POST | Warning a reboot required but skip option set | warning count" + when: + - reboot_required + - skip_reboot + ansible.builtin.import_tasks: + file: warning_facts.yml + vars: + warn_control_id: Reboot_required + tags: + - always + +- name: If Warning count is 0 set fact + when: + - warn_count == '0' + ansible.builtin.set_fact: + control_number: "Congratulation None Found" diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index fd1e9ec..b3111c8 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,42 +1,46 @@ --- -- name: "Post Audit | Run post_remediation {{ benchmark }} audit" - shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" +- name: Post Audit | Run post_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" + AUDIT_FILE: goss.yml - name: Post Audit | ensure audit files readable by users - file: + ansible.builtin.file: path: "{{ item }}" - mode: 0644 + mode: '0644' state: file loop: - "{{ post_audit_outfile }}" - "{{ pre_audit_outfile }}" - name: Post Audit | Capture audit data if json format + when: + - audit_format == "json" block: - - name: "capture data {{ post_audit_outfile }}" - command: "cat {{ post_audit_outfile }}" + - name: capture data {{ post_audit_outfile }} + ansible.builtin.shell: "cat {{ post_audit_outfile }}" register: post_audit changed_when: false - name: Capture post-audit result - set_fact: - post_audit_summary: "{{ post_audit.stdout | from_json |json_query(summary) }}" + ansible.builtin.set_fact: + post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Post Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - name: "Post Audit | capture data {{ post_audit_outfile }}" - command: "tail -2 {{ post_audit_outfile }}" + - name: Post Audit | capture data {{ post_audit_outfile }} + ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" register: post_audit changed_when: false - name: Post Audit | Capture post-audit result - set_fact: + ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout_lines }}" - when: - - audit_format == "documentation" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 53e66f8..d0137e8 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,109 +1,121 @@ --- -- name: Pre Audit | Setup the audit - include_tasks: LE_audit_setup.yml +- name: Pre Audit Setup | Setup the LE audit when: - setup_audit tags: - setup_audit + ansible.builtin.include_tasks: + file: LE_audit_setup.yml -- name: "Pre Audit | Ensure {{ audit_conf_dir }} exists" - file: +- name: Pre Audit Setup | Ensure {{ audit_conf_dir }} exists + ansible.builtin.file: path: "{{ audit_conf_dir }}" state: directory mode: '0755' -- name: Pre Audit | If using git for content set up +- name: Pre Audit Setup | If using git for content set up + when: + - audit_content == 'git' block: - - name: Pre Audit | Install git - package: + - name: Pre Audit Setup | Install git + ansible.builtin.package: name: git state: present - vars: - ansible_python_interpreter: "{{ python2_bin }}" - - name: Pre Audit | retrieve audit content files from git - git: + - name: Pre Audit Setup | Retrieve audit content files from git + ansible.builtin.git: repo: "{{ audit_file_git }}" dest: "{{ audit_conf_dir }}" version: "{{ audit_git_version }}" - when: - - audit_content == 'git' -- name: Pre Audit | copy to audit content files to server - copy: - src: "{{ audit_local_copy }}" - dest: "{{ audit_conf_dir }}" +- name: Pre Audit Setup | Copy to audit content files to server when: - audit_content == 'copy' + ansible.builtin.copy: + src: "{{ audit_conf_source }}" + dest: "{{ audit_conf_dest }}" + mode: preserve + +- name: Pre Audit Setup | Unarchive audit content files on server + when: + - audit_content == 'archive' + ansible.builtin.unarchive: + src: "{{ audit_conf_source }}" + dest: "{{ audit_conf_dest }}" -- name: Pre Audit | get audit content from url - get_url: - url: "{{ audit_files_url }}" - dest: "{{ audit_conf_dir }}" +- name: Pre Audit Setup | Get audit content from url when: - audit_content == 'get_url' + ansible.builtin.unarchive: + src: "{{ audit_conf_source }}" + dest: "{{ audit_conf_dest }}/{{ benchmark }}-Audit" + remote_src: "{{ ( audit_conf_source is contains ('http'))| ternary(true, false ) }}" + extra_opts: "{{ (audit_conf_source is contains ('github')) | ternary('--strip-components=1', [] ) }}" -- name: Pre Audit | Check Goss is available +- name: Pre Audit Setup | Check Goss is available + when: + - run_audit block: - - name: Pre Audit | Check for goss file - stat: + - name: Pre Audit Setup | Check for goss file + ansible.builtin.stat: path: "{{ audit_bin }}" register: goss_available - - name: Pre Audit | If audit ensure goss is available - assert: - msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" + - name: Pre Audit Setup | If audit ensure goss is available when: - not goss_available.stat.exists - when: - - run_audit + ansible.builtin.assert: + msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" -- name: "Pre Audit | Check whether machine is UEFI-based" - stat: - path: /sys/firmware/efi - register: rhel8_efi_boot +- name: Pre Audit Setup | Copy ansible default vars values to test audit tags: - goss_template - -- name: Pre Audit | Copy ansible default vars values to test audit - template: - src: ansible_vars_goss.yml.j2 - dest: "{{ audit_vars_path }}" - mode: 0600 + - run_audit when: - run_audit - tags: - - goss_template + ansible.builtin.template: + src: ansible_vars_goss.yml.j2 + dest: "{{ audit_vars_path }}" + mode: '0600' -- name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" - shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" +- name: Pre Audit | Run pre_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" + AUDIT_FILE: goss.yml - name: Pre Audit | Capture audit data if json format + when: + - audit_format == "json" block: - - name: "Pre Audit | capture data {{ pre_audit_outfile }}" - command: "cat {{ pre_audit_outfile }}" - changed_when: false + - name: Pre Audit | Capture data {{ pre_audit_outfile }} + ansible.builtin.shell: "cat {{ pre_audit_outfile }}" register: pre_audit + changed_when: false - name: Pre Audit | Capture pre-audit result - set_fact: + ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Pre Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - name: "Pre Audit | capture data {{ pre_audit_outfile }}" - command: "tail -2 {{ pre_audit_outfile }}" + - name: Pre Audit | Capture data {{ pre_audit_outfile }} | documentation format + ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" register: pre_audit changed_when: false - - name: Pre Audit | Capture pre-audit result - set_fact: + - name: Pre Audit | Capture pre-audit result | documentation format + ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout_lines }}" + +- name: Audit_Only | Run Audit Only when: - - audit_format == "documentation" + - audit_only + ansible.builtin.import_tasks: audit_only.yml diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 3905a47..12974f1 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -1,35 +1,74 @@ --- +- name: Include audit specific variables + when: + - run_audit or audit_only + - setup_audit + tags: + - setup_audit + - run_audit + ansible.builtin.include_vars: + file: audit.yml + +- name: Include pre-remediation audit tasks + when: + - run_audit or audit_only + - setup_audit + tags: + - run_audit + ansible.builtin.import_tasks: + file: pre_remediation_audit.yml + # Preliminary tasks that should always be run # List users in order to look files inside each home directory -- include_tasks: parse_etc_password.yml - when: - - amazon2cis_section5 or - amazon2cis_section6 +- name: Parse etc password + ansible.builtin.import_tasks: + file: parse_etc_password.yml + tags: + - always - name: "PRELIM | List users accounts" - command: "awk -F: '{print $1}' /etc/passwd" + ansible.builtin.command: "awk -F: '{print $1}' /etc/passwd" changed_when: false check_mode: false register: users - name: "PRELIM | Gather accounts with empty password fields" - shell: "cat /etc/shadow | awk -F: '($2 == \"\" ) {j++;print $1; } END {exit j}'" + ansible.builtin.shell: "cat /etc/shadow | awk -F: '($2 == \"\" ) {j++;print $1; } END {exit j}'" changed_when: false check_mode: false register: empty_password_accounts - tags: - - skip_ansible_lint - name: "PRELIM | Gather UID 0 accounts other than root" - shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'" + ansible.builtin.shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'" changed_when: false check_mode: false - register: uid_zero_accounts_except_root + register: amazon2cis_uid_zero_accounts_except_root + +- name: "PRELIM | Gather interactive user ID min and max" + when: + - amazon2cis_uid_info_dynamic tags: - - skip_ansible_lint + - always + block: + - name: "PRELIM | Gather interactive user ID min" + ansible.builtin.shell: grep ^UID_MIN /etc/login.defs | awk '{print $2}' + changed_when: false + failed_when: false + register: amazon2cis_min_uid + + - name: "PRELIM | Gather interactive user ID max" + ansible.builtin.shell: grep ^UID_MAX /etc/login.defs | awk '{print $2}' + changed_when: false + failed_when: false + register: amazon2cis_max_uid + + - name: "PRELIM | Setting the fact" + ansible.builtin.set_fact: + amazon2cis_uid_min: "{{ amazon2cis_min_uid.stdout | string }}" + amazon2cis_uid_max: "{{ amazon2cis_max_uid.stdout | string }}" - name: "PRELIM | Check whether machine is UEFI-based" - stat: + ansible.builtin.stat: path: /sys/firmware/efi register: amazon2cis_efi_boot @@ -37,7 +76,7 @@ block: - name: "PRELIM | set fact if UEFI boot | Amazon Linux 2 " - set_fact: + ansible.builtin.set_fact: amazon2cis_bootloader_file: /boot/efi/EFI/amzn/grub.cfg amazon2cis_legacy_boot: false when: @@ -45,66 +84,166 @@ - ansible_distribution == 'Amazon' - name: "PRELIM | set if not UEFI boot" - set_fact: + ansible.builtin.set_fact: amazon2cis_bootloader_file: /boot/grub2/grub.cfg amazon2cis_legacy_boot: true when: not amazon2cis_efi_boot.stat.exists - name: output bootloader and efi state - debug: + ansible.builtin.debug: msg: - "bootloader file set to {{ amazon2cis_bootloader_file }}" - "legacy boot equals {{ amazon2cis_legacy_boot }}" - name: "PRELIM | Section 1.1 | Create list of mount points" - set_fact: + ansible.builtin.set_fact: mount_names: "{{ ansible_mounts | map(attribute='mount') | list }}" -- name: "PRELIM | Section 1.6 | SELinux" +- name: "PRELIM | Section 1.5 | SELinux" block: - - name: "PRELIM | Section 1.6 | Ensure SELinux is installed" - package: + - name: "PRELIM | Section 1.5 | Ensure SELinux is installed" + ansible.builtin.package: name: - libselinux - policycoreutils-python state: present - - name: "PRELIM | Section 1.6 | Ensure firewalld_t is set to permissive" - shell: semanage permissive -a firewalld_t + - name: "PRELIM | Section 1.5 | Check current firewalld_t semanage state" + ansible.builtin.shell: semanage permissive -l | grep firewalld_t + changed_when: false + failed_when: false + register: firewalld_t_sestate + + - name: "PRELIM | Section 1.5 | Ensure firewalld_t is set to permissive" + when: "'firewalld_t' not in firewalld_t_sestate.stdout" + ansible.builtin.shell: semanage permissive -a firewalld_t when: - not amazon2cis_selinux_disable vars: ansible_python_interpreter: /bin/python -- name: "PRELIM | Section 4.1 | Configure System Accounting (auditd)" - package: +- name: "PRELIM | Find all sudoers files." + when: + - amazon2cis_rule_4_3_4 or + amazon2cis_rule_4_3_5 + tags: + - always + ansible.builtin.shell: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'" + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_sudoers_files + +- name: "PRELIM | Section 5.2.x | Configure System Accounting (auditd)" + ansible.builtin.package: name: audit state: present vars: ansible_python_interpreter: /bin/python -- name: "PRELIM | Section 5.1 | Configure cron" - package: +- name: "PRELIM | 5.2.4.x | Ensure audit log files are mode 0640 or less permissive | discover file" + ansible.builtin.shell: "grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }'" + changed_when: false + failed_when: audit_discovered_logfile.rc not in [0, 1] + register: audit_discovered_logfile + when: + - amazon2cis_rule_5_2_4_1 + - amazon2cis_rule_5_2_4_2 + - amazon2cis_rule_5_2_4_3 + - amazon2cis_rule_5_2_4_4 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.1 + - rule_5.2.4.2 + - rule_5.2.4.3 + - rule_5.2.4.4 + +- name: "PRELIM | 5.2.4.5/6/7 | Audit conf and rules files | list files" + ansible.builtin.find: + path: /etc/audit + file_type: file + recurse: true + patterns: '*.conf,*.rules' + register: auditd_conf_files + when: + - amazon2cis_rule_5_2_4_5 or + amazon2cis_rule_5_2_4_6 or + amazon2cis_rule_5_2_4_7 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.5 + - rule_5.2.4.6 + - rule_5.2.4.7 + +- name: "PRELIM | Section 4.1.1.x | Configure cron" + ansible.builtin.package: name: cronie state: present vars: ansible_python_interpreter: /bin/python -### NOTE: You will need to adjust the UID range in parenthases below. -### ALSO NOTE: We weed out any user with a home dir not in standard locations because interactive users shouldn't have those paths as a home dir. Add or removed directory paths as needed below. -- name: "PRELIM | 6.2.8 | Gather local interactive user directories" - shell: "getent passwd {1000..65535} | cut -d: -f6 | sort -u | grep -v '/var/' | grep -v '/nonexistent/*' | grep -v '/run/*'" +- name: "PRELIM | Interactive User accounts home directories" + tags: + - always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/false") { print $6 }' changed_when: false - failed_when: false - register: amazon2cis_6_2_8_getent + register: interactive_users_home + +##### Optional ##### + +- name: "PRELIM | Optional | If IPv6 disable to stop ssh listening" + when: + - amazon2cis_ipv6_sshd_disable + - not amazon2cis_ipv6_required tags: - - skip_ansible_lint - - rule_6.2.8 + - always + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^AddressFamily + line: AddressFamily inet + notify: Restart_sshd + +- name: "PRELIM | Optional | If IPv6 disable to stop chronyd listening" + when: + - amazon2cis_ipv6_chrony_disable + - not amazon2cis_ipv6_required + tags: + - always + notify: Restart_chronyd + block: + - name: "PRELIM | Optional | If IPv6 disable to stop chronyd listening | Check existence" + ansible.builtin.shell: grep -E "OPTIONS=.*-4" /etc/sysconfig/chronyd + changed_when: false + failed_when: chrony_ipv6_exists.rc not in [ 0, 1] + register: chrony_ipv6_exists + + - name: "PRELIM | Optional | If IPv6 disable to stop chronyd listening" + when: chrony_ipv6_exists.stdout | length == 0 + ansible.builtin.lineinfile: + backrefs: true + path: /etc/sysconfig/chronyd + regexp: ^OPTIONS="(.*)" + line: OPTIONS="\1 -4" + +# Optional extra keys to extend auditd not part of CIS but can influence a system +# e.g. admin_space_left: '10%' -- name: "PRELIM | 6.2.8 | Set fact for home directory paths for interactive users" - set_fact: - amazon2cis_stig_interactive_homedir_results: "{{ amazon2cis_6_2_8_getent.stdout_lines }}" +- name: PRELIM | Optional | Configure other keys for auditd.conf when: - - amazon2cis_6_2_8_getent.stdout_lines is defined + - amazon2cis_auditd_extra_conf.keys() | length > 0 + - amazon2cis_level_2 tags: - - rule_6.2.8 + - always + ansible.builtin.lineinfile: + path: /etc/audit/auditd.conf + regexp: "^{{ item }}( |=)" + line: "{{ item }} = {{ amazon2cis_auditd_extra_conf[item] }}" + notify: Restart_auditd + loop: "{{ amazon2cis_auditd_extra_conf.keys() }}" diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index cf45fd3..b2021a4 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -1,76 +1,265 @@ --- -- name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled" +- name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available" + when: + - amazon2cis_rule_1_1_1_1 + tags: + - level1 + - automated + - patch + - rule_1.1.1.1 + - cramfs + - modprobe + - NIST800-53R5_CM-7 block: - - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Edit modprobe config" - lineinfile: - dest: /etc/modprobe.d/CIS.conf + - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install cramfs(\\s|$)" line: "install cramfs /bin/true" create: true mode: '0600' - - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove cramfs module" - modprobe: + - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist cramfs(\\s|$)" + line: "blacklist cramfs" + create: true + mode: '0600' + + - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Remove cramfs module" + community.general.modprobe: name: cramfs state: absent + +- name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available" when: - - amazon2cis_rule_1_1_1_1 - - ansible_connection != 'docker' + - amazon2cis_rule_1_1_1_2 tags: - level1 - automated - patch - - rule_1.1.1.1 + - rule_1.1.1.2 - cramfs - modprobe + - NIST800-53R5_CM-7 + block: + - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install freevxfs(\\s|$)" + line: "install freevxfs /bin/true" + create: true + mode: '0600' -- name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled" + - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist freevxfs(\\s|$)" + line: "blacklist freevxfs" + create: true + mode: '0600' + + - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Remove cramfs module" + community.general.modprobe: + name: freevxfs + state: absent + +- name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available" + when: + - amazon2cis_rule_1_1_1_3 + tags: + - level1 + - automated + - patch + - rule_1.1.1.3 + - hfs + - modprobe + - NIST800-53R5_CM-7 block: - - name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Edit modprobe config" - lineinfile: - dest: /etc/modprobe.d/CIS.conf - regexp: "^(#)?install squashfs(\\s|$)" - line: "install squashfs /bin/true" + - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install hfs(\\s|$)" + line: "install hfs /bin/true" create: true mode: '0600' - - name: "1.1.1.2 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove squashfs module" - modprobe: - name: squashfs + - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist hfs(\\s|$)" + line: "blacklist hfs" + create: true + mode: '0600' + + - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Remove hfs module" + community.general.modprobe: + name: hfs state: absent + +- name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available" when: - - amazon2cis_rule_1_1_1_2 - - ansible_connection != 'docker' + - amazon2cis_rule_1_1_1_4 tags: - level1 - automated - patch - - rule_1.1.1.2 + - rule_1.1.1.4 + - hfsplus + - modprobe + - NIST800-53R5_CM-7 + block: + - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install hfsplus(\\s|$)" + line: "install hfsplus /bin/true" + create: true + mode: '0600' + + - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist hfsplus(\\s|$)" + line: "blacklist hfsplus" + create: true + mode: '0600' + + - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Remove hfsplus module" + community.general.modprobe: + name: hfsplus + state: absent + +- name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available" + when: + - amazon2cis_rule_1_1_1_5 + tags: + - level1 + - automated + - patch + - rule_1.1.1.5 + - jffs2 + - modprobe + - NIST800-53R5_CM-7 + block: + - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install jffs2(\\s|$)" + line: "install jffs2 /bin/true" + create: true + mode: '0600' + + - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist jffs2(\\s|$)" + line: "blacklist jffs2" + create: true + mode: '0600' + + - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Remove jffs2 module" + community.general.modprobe: + name: jffs2 + state: absent + +- name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available" + when: + - amazon2cis_rule_1_1_1_6 + tags: + - level2 + - automated + - patch + - rule_1.1.1.6 - squashfs - modprobe + - NIST800-53R5_CM-7 + block: + - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install squashfs(\\s|$)" + line: "install squashfs /bin/true" + create: true + mode: '0600' -- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled" + - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist squashfs(\\s|$)" + line: "blacklist squashfs" + create: true + mode: '0600' + + - name: "1.1.1.6 | PATCH | Ensure cramfs kernel module is not available | Remove squashfs module" + community.general.modprobe: + name: squashfs + state: absent + +- name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available" + when: + - amazon2cis_rule_1_1_1_7 + tags: + - level2 + - automated + - patch + - rule_1.1.1.7 + - udf + - modprobe + - NIST800-53R5_CM-7 block: - - name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled | Edit modprobe config" - lineinfile: - dest: /etc/modprobe.d/CIS.conf + - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install udf(\\s|$)" line: "install udf /bin/true" create: true mode: '0600' - - name: "1.1.1.3 | PATCH | Remove udf module" - modprobe: + - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist udf(\\s|$)" + line: "blacklist udf" + create: true + mode: '0600' + + - name: "1.1.1.7 | PATCH | Remove udf module" + community.general.modprobe: name: udf state: absent + +- name: "1.1.1.8 | PATCH | Ensure udf kernel module is not available" when: - - amazon2cis_rule_1_1_1_3 - - ansible_connection != 'docker' + - amazon2cis_rule_1_1_1_8 tags: - level1 - automated - patch - - rule_1.1.1.3 - - udf + - rule_1.1.1.8 + - usb - modprobe + - NIST800-53R5_SI-3 + block: + - name: "1.1.1.8 | PATCH | Ensure usb-storage kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install usb-storage(\\s|$)" + line: "install usb-storage /bin/true" + create: true + mode: '0600' + + - name: "1.1.1.8 | PATCH | Ensure usb-storage kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist usb-storage(\\s|$)" + line: "blacklist usb-storage" + create: true + mode: '0600' + + - name: "1.1.1.8 | PATCH | Remove usb-storage module" + community.general.modprobe: + name: usb-storage + state: absent diff --git a/tasks/section_1/cis_1.1.2.1.x.yml b/tasks/section_1/cis_1.1.2.1.x.yml new file mode 100644 index 0000000..7613365 --- /dev/null +++ b/tasks/section_1/cis_1.1.2.1.x.yml @@ -0,0 +1,56 @@ +--- + +- name: "1.1.2.1.1 | PATCH | Ensure /tmp is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_1_1 + tags: + - level1 + - automated + - patch + - rule_1.1.2.1.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.1.1' + required_mount: '/tmp' + block: + - name: "1.1.2.1.1 | AUDIT | Ensure /tmp is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.1.1 | AUDIT | Ensure /tmp is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition + 1.1.2.1.3 | PATCH | Ensure nosuid option set on /tmp partition + 1.1.2.1.4 | PATCH | Ensure noexec option set on /tmp partition" + when: + - item.mount == "/tmp" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_1_2 or + amazon2cis_rule_1_1_2_1_3 or + amazon2cis_rule_1_1_2_1_4 + tags: + - level1 + - automated + - patch + - rule_1.1.2.1.2 + - rule_1.1.2.1.3 + - rule_1.1.2.1.4 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /tmp + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_1_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_1_3 %}nosuid,{% endif %}{% if amazon2cis_rule_1_1_2_1_4 %}noexec{% endif %} + notify: systemd restart tmp.mount + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.2.x.yml b/tasks/section_1/cis_1.1.2.2.x.yml new file mode 100644 index 0000000..64c47af --- /dev/null +++ b/tasks/section_1/cis_1.1.2.2.x.yml @@ -0,0 +1,56 @@ +--- + +- name: "1.1.2.2.1 | PATCH | Ensure /dev/shm is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_2_1 + tags: + - level1 + - automated + - patch + - rule_1.1.2.2.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.2.1' + required_mount: '/dev/shm' + block: + - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.2.2 | PATCH | Ensure nodev option set on /dev/shm partition + 1.1.2.2.3 | PATCH | Ensure nosuid option set on /dev/shm partition + 1.1.2.2.4 | PATCH | Ensure noexec option set on /dev/shm partition" + when: + - item.mount == "/dev/shm" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_2_2 or + amazon2cis_rule_1_1_2_2_3 or + amazon2cis_rule_1_1_2_2_4 + tags: + - level1 + - automated + - patch + - rule_1.1.2.2.2 + - rule_1.1.2.2.3 + - rule_1.1.2.2.4 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /dev/shm + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_2_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_2_3 %}nosuid,{% endif %}{% if amazon2cis_rule_1_1_2_2_4 %}noexec{% endif %} + notify: Remount dev_shm + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml new file mode 100644 index 0000000..39f88be --- /dev/null +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -0,0 +1,53 @@ +--- + +- name: "1.1.2.3.1 | PATCH | Ensure /home is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_3_1 + tags: + - level2 + - automated + - patch + - rule_1.1.2.3.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.3.1' + required_mount: '/home' + block: + - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.3.2 | PATCH | Ensure nodev option set on /home partition + 1.1.2.3.3 | PATCH | Ensure nosuid option set on /home partition + when: + - item.mount == "/home" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_3_2 or + amazon2cis_rule_1_1_2_3_3 + tags: + - level1 + - automated + - patch + - rule_1.1.2.3.2 + - rule_1.1.2.3.3 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /home + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_3_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_3_3 %}nosuid{% endif %} + notify: Remount home + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.4.x.yml b/tasks/section_1/cis_1.1.2.4.x.yml new file mode 100644 index 0000000..03bda37 --- /dev/null +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -0,0 +1,53 @@ +--- + +- name: "1.1.2.4.1 | PATCH | Ensure /var is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_4_1 + tags: + - level2 + - automated + - patch + - rule_1.1.2.4.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.4.1' + required_mount: '/var' + block: + - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.4.2 | PATCH | Ensure nodev option set on /var partition + 1.1.2.4.3 | PATCH | Ensure nosuid option set on /var partition + when: + - item.mount == "/var" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_4_2 or + amazon2cis_rule_1_1_2_4_3 + tags: + - level2 + - automated + - patch + - rule_1.1.2.4.2 + - rule_1.1.2.4.3 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /var + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_4_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_4_3 %}nosuid{% endif %} + notify: Remount var + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.5.x.yml b/tasks/section_1/cis_1.1.2.5.x.yml new file mode 100644 index 0000000..c24fccd --- /dev/null +++ b/tasks/section_1/cis_1.1.2.5.x.yml @@ -0,0 +1,56 @@ +--- + +- name: "1.1.2.5.1 | PATCH | Ensure /var/tmp is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_5_1 + tags: + - level2 + - automated + - patch + - rule_1.1.2.5.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.5.1' + required_mount: '/var/tmp' + block: + - name: "1.1.2.5.1 | AUDIT | Ensure /var/tmp is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.5.1 | AUDIT | Ensure /var/tmp is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.5.2 | PATCH | Ensure nodev option set on /var/tmp partition + 1.1.2.5.3 | PATCH | Ensure nosuid option set on /var/tmp partition + 1.1.2.5.4 | PATCH | Ensure noexec option set on /var/tmp partition" + when: + - item.mount == "/var/tmp" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_5_2 or + amazon2cis_rule_1_1_2_5_3 or + amazon2cis_rule_1_1_2_5_4 + tags: + - level2 + - automated + - patch + - rule_1.1.2.5.2 + - rule_1.1.2.5.3 + - rule_1.1.2.5.4 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /var/tmp + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_5_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_5_3 %}nosuid,{% endif %}{% if amazon2cis_rule_1_1_2_5_4 %}noexec{% endif %} + notify: Remount var_tmp + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.6.x.yml b/tasks/section_1/cis_1.1.2.6.x.yml new file mode 100644 index 0000000..f419f77 --- /dev/null +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -0,0 +1,57 @@ +--- + +- name: "1.1.2.6.1 | PATCH | Ensure /var/log is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_6_1 + tags: + - level2 + - automated + - patch + - rule_1.1.2.6.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.6.1' + required_mount: '/var/log' + + block: + - name: "1.1.2.6.1 | AUDIT | Ensure /var/log is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.6.1 | AUDIT | Ensure /var/log is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.6.2 | PATCH | Ensure nodev option set on /var/log partition + 1.1.2.6.3 | PATCH | Ensure nosuid option set on /var/log partition + 1.1.2.6.4 | PATCH | Ensure noexec option set on /var/log partition" + when: + - item.mount == "/var/log" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_6_2 or + amazon2cis_rule_1_1_2_6_3 or + amazon2cis_rule_1_1_2_6_4 + tags: + - level2 + - automated + - patch + - rule_1.1.2.6.2 + - rule_1.1.2.6.3 + - rule_1.1.2.6.4 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /var/log + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_6_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_6_3 %}nosuid,{% endif %}{% if amazon2cis_rule_1_1_2_6_4 %}noexec{% endif %} + notify: Remount var_log + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.2.7.x.yml b/tasks/section_1/cis_1.1.2.7.x.yml new file mode 100644 index 0000000..c789524 --- /dev/null +++ b/tasks/section_1/cis_1.1.2.7.x.yml @@ -0,0 +1,56 @@ +--- + +- name: "1.1.2.7.1 | PATCH | Ensure /var/log/audit is a seperate partition" + when: + - required_mount not in mount_names + - amazon2cis_rule_1_1_2_7_1 + tags: + - level2 + - automated + - patch + - rule_1.1.2.7.1 + - mounts + - NIST800-53R5_CM-7 + vars: + warn_control_id: '1.1.2.7.1' + required_mount: '/var/log/audit' + block: + - name: "1.1.2.7.1 | AUDIT | Ensure /var/log/audit is a separate partition | Absent" + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + + - name: "1.1.2.7.1 | AUDIT | Ensure /var/log/audit is a separate partition | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: | + "1.1.2.7.2 | PATCH | Ensure nodev option set on /var/log/audit partition + 1.1.2.7.3 | PATCH | Ensure nosuid option set on /var/log/audit partition + 1.1.2.7.4 | PATCH | Ensure noexec option set on /var/log/audit partition" + when: + - item.mount == "/var/log/audit" + - amazon2cis_tmp_svc + - amazon2cis_rule_1_1_2_7_2 or + amazon2cis_rule_1_1_2_7_3 or + amazon2cis_rule_1_1_2_7_4 + tags: + - level2 + - automated + - patch + - rule_1.1.2.7.2 + - rule_1.1.2.7.3 + - rule_1.1.2.7.4 + - mounts + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.posix.mount: + name: /var/log/audit + src: "{{ item.device }}" + fstype: "{{ item.fstype }}" + state: present + opts: defaults,{% if amazon2cis_rule_1_1_2_7_2 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_2_7_3 %}nosuid,{% endif %}{% if amazon2cis_rule_1_1_2_7_4 %}noexec{% endif %} + notify: Remount var_log_audit + with_items: + - "{{ ansible_mounts }}" + loop_control: + label: "{{ item.device }}" diff --git a/tasks/section_1/cis_1.1.x.yml b/tasks/section_1/cis_1.1.x.yml deleted file mode 100644 index f269d46..0000000 --- a/tasks/section_1/cis_1.1.x.yml +++ /dev/null @@ -1,334 +0,0 @@ ---- - -- name: "1.1.2 | AUDIT | Ensure /tmp is configured" - block: - - name: "1.1.2 | AUDIT | Ensure /tmp is configured" - ansible.builtin.shell: findmnt -n /tmp - changed_when: false - failed_when: false - register: amazon2_tmp_exists - - - name: "1.1.2 | WARN | Ensure /tmp is configured | Absent" - ansible.builtin.debug: - msg: "Warning!! /tmp is configured to use fstab but does not exist" - changed_when: true - when: amazon2_tmp_exists.stdout | length == 0 - when: - - amazon2cis_rule_1_1_2 - - not amazon2cis_tmp_svc - tags: - - level1-server - - level1-workstation - - automated - - audit - - mounts - - rule_1.1.2 - -- name: | - "1.1.3 | PATCH | Ensure noexec option set on /tmp partition" - "1.1.4 | PATCH | Ensure nodev option set on /tmp partition" - "1.1.5 | PATCH | Ensure nosuid option set on /tmp partition" - ansible.posix.mount: - name: /tmp - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: defaults,{% if amazon2cis_rule_1_1_3 %}noexec,{% endif %}{% if amazon2cis_rule_1_1_4 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_5 %}nosuid{% endif %} - notify: remount tmp - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - when: - - item.mount == "/tmp" - - not amazon2cis_tmp_svc - - amazon2_tmp_exists.stdout | length > 0 - - amazon2cis_rule_1_1_3 or - amazon2cis_rule_1_1_4 or - amazon2cis_rule_1_1_5 - tags: - - level1-server - - level1-workstation - - automated - - patch - - mounts - -- name: | - "1.1.2 | PATCH | Ensure /tmp is configured" - "1.1.3 | PATCH | Ensure noexec option set on /tmp partition" - "1.1.4 | PATCH | Ensure nodev option set on /tmp partition" - "1.1.5 | PATCH | Ensure nosuid option set on /tmp partition" - notify: systemd restart tmp.mount - ansible.builtin.template: - src: etc/systemd/system/tmp.mount.j2 - dest: /etc/systemd/system/tmp.mount - owner: root - group: root - mode: '0644' - when: - - amazon2cis_tmp_svc - - amazon2cis_rule_1_1_2 or - amazon2cis_rule_1_1_3 or - amazon2cis_rule_1_1_4 or - amazon2cis_rule_1_1_5 - tags: - - level1-server - - level1-workstation - - patch - - mounts - - rule_1.1.2 - - rule_1.1.3 - - rule_1.1.4 - - rule_1.1.5 - -- name: | - "1.1.6 | PATCH | Ensure /dev/shm is configured - 1.1.7 | PATCH | Ensure noexec option set on /dev/shm partition - 1.1.8 | PATCH | Ensure nodev option set on /dev/shm partition - 1.1.9 | PATCH | Ensure nosuid option set on /dev/shm partition" - mount: - name: /dev/shm - src: tmpfs - fstype: tmpfs - state: present - opts: defaults,{% if amazon2cis_rule_1_1_7 %}noexec,{% endif %}{% if amazon2cis_rule_1_1_8 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_9 %}nosuid{% endif %},seclabel - notify: remount dev_shm - when: - - amazon2cis_rule_1_1_6 or - amazon2cis_rule_1_1_7 or - amazon2cis_rule_1_1_8 or - amazon2cis_rule_1_1_9 - tags: - - level1 - - automated - - patch - - rule_1.1.6 - - rule_1.1.7 - - rule_1.1.8 - - rule_1.1.9 - -- name: "1.1.10 | AUDIT | Ensure separate partition exists for /var" - block: - - name: "1.1.10 | AUDIT | Ensure separate partition exists for /var | Message if absent" - debug: - msg: "Warning! /var does not exist on a seperate partition. You need will need to create a sepearte partition for /var manually" - when: "'/var' not in mount_names" - - - name: "1.1.10 | AUDIT | Ensure separate partition exists for /var | Message if present" - debug: - msg: "Congratulations: /var is on a seperate partition" - when: "'/var' in mount_names" - when: - - amazon2cis_rule_1_1_10 - tags: - - level2 - - automated - - audit - - rule_1.1.10 - - mounts - -- name: "1.1.11 | AUDIT | Ensure separate partition exists for /var/tmp" - block: - - name: "1.1.11 | AUDIT | Ensure separate partition exists for /var/tmp | Message if absent" - debug: - msg: "Warning! /var/tmp does not exist on a seperate partition. You will need to create a seperate partition for /var/tmp manually" - when: "'/var/tmp' not in mount_names" - - - name: "1.1.11 | AUDIT | Ensure separate partition exists for /var/tmp | Message if present" - debug: - msg: "Congratulations: /var/tmp is on a seperate partition" - when: "'/var/tmp' in mount_names" - when: - - amazon2cis_rule_1_1_11 - tags: - - level2 - - automated - - audit - - rule_1.1.11 - - mounts - -- name: | - "1.1.12 | PATCH | Ensure noexec option set on /var/tmp partition - 1.1.13 | PATCH | Ensure nodev option set on /var/tmp partition - 1.1.14 | PATCH | Ensure nosuid option set on /var/tmp partition" - mount: - name: /var/tmp - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: defaults,{% if amazon2cis_rule_1_1_12 %}noexec,{% endif %}{% if amazon2cis_rule_1_1_13 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_14 %}nosuid{% endif %} - notify: remount var_tmp - with_items: - - "{{ ansible_mounts }}" - loop_control: - label: "{{ item.device }}" - when: - - item.mount == "/var/tmp" - - amazon2cis_rule_1_1_11 or - amazon2cis_rule_1_1_12 or - amazon2cis_rule_1_1_13 or - amazon2cis_rule_1_1_14 - tags: - - level1 - - automated - - patch - - rule_1.1.11 - - rule_1.1.12 - - rule_1.1.13 - - rule_1.1.14 - - mounts - -- name: "1.1.15 | PATCH | Ensure separate partition exists for /var/log" - block: - - name: "1.1.15 | PATCH | Ensure separate partition exists for /var/log | Message if absent" - debug: - msg: "Warning! /var/log is not on a sperate partition. You will need to create a seperate partition for /var/log manually" - when: "'/var/log' not in mount_names" - - - name: "1.1.15 | PATCH | Ensure separate partition exists for /var/log | Message if present" - debug: - msg: "Congratulations: /var/log is on a seperate partition" - when: "'/var/log' in mount_names" - when: - - amazon2cis_rule_1_1_15 - tags: - - level2 - - automated - - audit - - rule_1.1.15 - - mounts - -- name: "1.1.16 | AUDIT | Ensure separate partition exists for /var/log/audit" - block: - - name: "1.1.16 | AUDIT | Ensure separate partition exists for /var/log/audit | Message if absent" - debug: - msg: "Warning! /var/log/audit is not on a sperate partition. You will need to create a seperate partition for /var/log manually" - when: "'/var/log/audit' not in mount_names" - - - name: "1.1.16 | AUDIT | Ensure separate partition exists for /var/log/audit | Message if present" - debug: - msg: "Congratulations: /var/log/audit is on a seperate partition" - when: "'/var/log/audit' in mount_names" - when: - - amazon2cis_rule_1_1_16 - tags: - - level2 - - automated - - audit - - rule_1.1.16 - - mounts - -- name: "1.1.17 | AUDIT | Ensure separate partition exists for /home" - block: - - name: "1.1.17 | AUDIT | Ensure separate partition exists for /home | Message if absent" - debug: - msg: "Warning! /home is not on a sperate partition. You will need to create a seperate partition for /var/log manually" - when: "'/home' not in mount_names" - - - name: "1.1.17 | AUDIT | Ensure separate partition exists for /home | Message if present" - debug: - msg: "Congratulations: /home is on a seperate partition" - when: "'/home' in mount_names" - when: - - amazon2cis_rule_1_1_17 - tags: - - level2 - - automated - - audit - - rule_1.1.17 - - mounts - -- name: "1.1.18 | PATCH | Ensure nodev option set on /home partition" - mount: - name: /home - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: defaults,{% if amazon2cis_rule_1_1_18 %}nodev{% endif %} - notify: remount home - with_items: - - "{{ ansible_mounts }}" - loop_control: - label: "{{ item.device }}" - when: - - item.mount == "/home" - - amazon2cis_rule_1_1_18 - tags: - - level2 - - automated - - patch - - rule_1.1.17 - - rule_1.1.18 - -- name: | - "1.1.19 | AUDIT | Ensure noexec option set on removable media partitions - 1.1.20 | AUDIT | Ensure nodev option set on removable media partitions - 1.1.21 | AUDIT | Ensure nosuid option set on removable media partitions" - debug: - msg: "--> Not Applicable" - changed_when: false - when: - - amazon2cis_rule_1_1_19 or - amazon2cis_rule_1_1_20 or - amazon2cis_rule_1_1_21 - tags: - - level1 - - automated - - audit - - rule_1.1.19 - - rule_1.1.20 - - rule_1.1.21 - - removable_devices - -- name: "1.1.22 | PATCH | Ensure sticky bit is set on all world-writable directories" - shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t - changed_when: false - failed_when: false - when: - - amazon2cis_rule_1_1_22 - tags: - - level1 - - automated - - patch - - rule_1.1.22 - - skip_ansible_lint - - stickybits - - permissions - -- name: "1.1.23 | PATCH | Disable Automounting" - service: - name: autofs - enabled: false - when: - - not amazon2cis_allow_autofs - - "'autofs' in ansible_facts.packages" - - amazon2cis_rule_1_1_23 - tags: - - level1 - - automated - - patch - - rule_1.1.23 - - mounts - - automounting - -- name: "1.1.24 | PATCH | Disable USB Storage" - block: - - name: "1.1.24 | PATCH | Disable USB Storage | Edit modprobe config" - lineinfile: - dest: /etc/modprobe.d/usb-storage.conf - regexp: "^(#)?install usb-storage(\\s|$)" - line: "install usb-storage /bin/true" - mode: 0600 - create: true - - - name: "1.1.24 | PATCH | Remove USB Storage module | Remove usb-storage module" - modprobe: - name: usb-storage - state: absent - when: - - amazon2cis_rule_1_1_24 - tags: - - level1 - - automated - - patch - - rule_1.1.24 - - usb-storage diff --git a/tasks/section_1/cis_1.2.x.yml b/tasks/section_1/cis_1.2.x.yml index f555f4a..384eba2 100644 --- a/tasks/section_1/cis_1.2.x.yml +++ b/tasks/section_1/cis_1.2.x.yml @@ -1,9 +1,6 @@ --- - name: "1.2.1 | PATCH | Ensure GPG keys are configured" - command: gpg --quiet --with-fingerprint /etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-{{ ansible_distribution_major_version }} - changed_when: "'created' in amazon2cis_1_2_1_status.stderr" - register: amazon2cis_1_2_1_status when: - amazon2cis_rule_1_2_1 tags: @@ -12,19 +9,12 @@ - patch - rule_1.2.1 - gpg + - NIST800-53R5_SI-2 + ansible.builtin.command: gpg --quiet --with-fingerprint /etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-{{ ansible_distribution_major_version }} + changed_when: "'created' in amazon2cis_1_2_1_status.stderr" + register: amazon2cis_1_2_1_status -- name: "1.2.2 | AUDIT | Ensure package manager repositories are configured" - block: - - name: "1.2.2 | AUDIT | Ensure package manager repositories are configured | Get repo list" - command: yum repolist - changed_when: false - register: amazon2cis_1_2_2_repolist - - - name: "AUDIT| 1.2.2 | AUDIT | Ensure package manager repositories are configured | Show repo list" - debug: - msg: - - "Please check against site policy repos listed below match expected:" - - "{{ amazon2cis_1_2_2_repolist.stdout_lines }}" +- name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated" when: - amazon2cis_rule_1_2_2 tags: @@ -32,30 +22,78 @@ - automated - patch - rule_1.2.2 - - skip_ansible_lint - -- name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated" + - gpg + - NIST800-53R5_SI-2 block: - - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | find repo files" - find: + - name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated | find repo files" + ansible.builtin.find: paths: /etc/yum.repos.d patterns: "*.repo" - register: amazon2_1_2_3_yum_repos + register: amazon2_1_2_2_yum_repos - - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | set gpgcheck" - replace: + - name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated | set gpgcheck" + ansible.builtin.replace: path: "{{ item.path }}" - regexp: "^gpgcheck=0" + regexp: ^gpgcheck\s*=\s*0 replace: "gpgcheck=1" with_items: - - "{{ amazon2_1_2_3_yum_repos.files }}" + - "{{ amazon2_1_2_2_yum_repos.files }}" loop_control: label: "{{ item.path }}" + +- name: "1.2.3 | PATCH | Ensure repo_gpgcheck is globally activated" when: - amazon2cis_rule_1_2_3 tags: - - level1 + - level2 - automated - patch - rule_1.2.3 - gpg + - NIST800-53R5_SI-2 + ansible.builtin.replace: + path: /etc/yum.conf + regexp: ^repo_gpgcheck\s*=\s*0 + replace: "repo_gpgcheck=1" + +- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured" + when: + - amazon2cis_rule_1_2_4 + tags: + - level1 + - automated + - patch + - rule_1.2.4 + - NIST800-53R5_SI-2 + vars: + warn_control_id: '1.2.4' + block: + - name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Get repo list" + ansible.builtin.command: yum repolist + changed_when: false + register: amazon2cis_1_2_4_repolist + + - name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Show repo list" + ansible.builtin.debug: + msg: + - "Please check against site policy repos listed below match expected:" + - "{{ amazon2cis_1_2_4_repolist.stdout_lines }}" + + - name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "1.2.5 | PATCH | Ensure updates, patches, and additional security software are installed" + when: + - amazon2cis_rule_1_2_5 + tags: + - level1 + - automated + - patch + - rule_1.2.5 + - NIST800-53R5_SI-2 + vars: + ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: "*" + state: latest diff --git a/tasks/section_1/cis_1.3.x.yml b/tasks/section_1/cis_1.3.x.yml index bcb51fb..4d8f5fb 100644 --- a/tasks/section_1/cis_1.3.x.yml +++ b/tasks/section_1/cis_1.3.x.yml @@ -1,47 +1,23 @@ --- -- name: "1.3.1 | PATCH | Ensure AIDE is installed" - block: - - name: "1.3.1 | PATCH | Ensure AIDE is installed | Install" - package: - name: aide - state: installed - - - name: "1.3.1 | PATCH | Ensure AIDE is installed | started" - command: /usr/sbin/aide --init -B 'database_out=file:/var/lib/aide/aide.db.gz' - changed_when: false - failed_when: false - async: 45 - poll: 0 - args: - creates: /var/lib/aide/aide.db.gz - vars: - ansible_python_interpreter: /bin/python +- name: "1.3.1 | PATCH | Ensure authentication required for single user mode" when: - - amazon2cis_config_aide - amazon2cis_rule_1_3_1 + - ansible_facts['distribution_major_version'] is version('2', '>=') tags: - level1 - automated - patch - rule_1.3.1 - - aide + block: + - name: "1.3.1 | PATCH | Ensure authentication required for single user mode | Emergency service" + ansible.builtin.lineinfile: + path: /usr/lib/systemd/system/emergency.service + regexp: '/sbin/sulogin' + line: 'ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default' -- name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked" - cron: - name: Run AIDE integrity check - minute: "{{ amazon2cis_aide_cron['aide_minute'] | default('0') }}" - hour: "{{ amazon2cis_aide_cron['aide_hour'] | default('5') }}" - day: "{{ amazon2cis_aide_cron['aide_day'] | default('*') }}" - month: "{{ amazon2cis_aide_cron['aide_month'] | default('*') }}" - weekday: "{{ amazon2cis_aide_cron['aide_weekday'] | default('*') }}" - job: "{{ amazon2cis_aide_cron['aide_job'] }}" - when: - - amazon2cis_rule_1_3_2 - tags: - - level1 - - automated - - patch - - rule_1.3.2 - - aide - - file_integrity + - name: "1.3.1 | PATCH | Ensure authentication required for single user mode | Rescue service" + ansible.builtin.lineinfile: + path: /usr/lib/systemd/system/rescue.service + regexp: '/sbin/sulogin' + line: 'ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default' diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 65251f2..f72b247 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -1,39 +1,71 @@ --- -- name: "1.4.1 | PATCH | Ensure permissions on bootloader config are configured" - file: - path: "{{ amazon2cis_bootloader_file }}" - owner: root - group: root - mode: 0600 +- name: "1.4.1 | PATCH | Ensure address space layout randomization (ASLR) is enabled" when: - - amazon2cis_legacy_boot - amazon2cis_rule_1_4_1 tags: - level1 - automated - patch - rule_1.4.1 - - grub + - NIST800-53R5_CM-6 + ansible.posix.sysctl: + name: kernel.randomize_va_space + value: '2' + state: present + reload: true + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ kernel_sysctl_file }}" -- name: "1.4.2 | PATCH | Ensure authentication required for single user mode" - block: - - name: "1.4.2 | PATCH | Ensure authentication required for single user mode | Emergency service" - lineinfile: - dest: /usr/lib/systemd/system/emergency.service - regexp: '/sbin/sulogin' - line: 'ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default' - - - name: "1.4.2 | PATCH | Ensure authentication required for single user mode | Rescue service" - lineinfile: - dest: /usr/lib/systemd/system/rescue.service - regexp: '/sbin/sulogin' - line: 'ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"' +- name: "1.4.2 | PATCH | Ensure ptrace_scope is restricted" when: - amazon2cis_rule_1_4_2 - - ansible_facts['distribution_major_version'] is version('2', '>=') tags: - level1 - automated - patch - rule_1.4.2 + ansible.posix.sysctl: + name: kernel.yama.ptrace_scope + value: '1' + state: present + reload: true + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ kernel_sysctl_file }}" + +- name: "1.4.3 | PATCH | Ensure core dump backtraces are disabled" + when: + - amazon2cis_rule_1_4_3 + tags: + - level1 + - automated + - patch + - rule_1.4.3 + - coredump + - NIST800-53R5_CM-6b + notify: Systemd_daemon_reload + ansible.builtin.lineinfile: + path: /etc/systemd/coredump.conf + regexp: ^ProcessSizeMax + line: ProcessSizeMax=0 + create: true + mode: '0644' + +- name: "1.4.4 | PATCH | Ensure core dump storage is disabled" + when: + - amazon2cis_rule_1_4_4 + tags: + - level1 + - automated + - patch + - rule_1.4.4 + - coredump + notify: Systemd_daemon_reload + ansible.builtin.lineinfile: + path: /etc/systemd/coredump.conf + regexp: ^Storage + line: Storage=none + create: true + mode: '0644' diff --git a/tasks/section_1/cis_1.5.x.yml b/tasks/section_1/cis_1.5.x.yml index 34b05aa..4cdb265 100644 --- a/tasks/section_1/cis_1.5.x.yml +++ b/tasks/section_1/cis_1.5.x.yml @@ -1,92 +1,145 @@ --- -- name: "1.5.1 | PATCH | Ensure core dumps are restricted" - block: - - name: "1.5.1 | PATCH | Ensure core dumps are restricted | Update limits.conf file" - lineinfile: - state: present - dest: /etc/security/limits.conf - regexp: '^#?\\*.*core' - line: '* hard core 0' - insertbefore: '^# End of file' +- name: "1.5.1.1 | PATCH | Ensure SELinux is installed" + when: + - not amazon2cis_selinux_disable + - amazon2cis_rule_1_5_1_1 + tags: + - level1 + - automated + - patch + - rule_1.5.1.1 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: libselinux + state: present - - name: "1.5.1 | PATCH | Ensure core dumps are restricted | Set active kernel parameter" - sysctl: - name: fs.suid_dumpable - value: '0' - state: present - reload: true - sysctl_set: true - ignoreerrors: true +- name: "1.5.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration" + when: + - not amazon2cis_selinux_disable + - amazon2cis_rule_1_5_1_2 + tags: + - level1 + - automated + - patch + - rule_1.5.1.2 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + notify: Rebuild_grub + ansible.builtin.replace: + path: /etc/default/grub + regexp: '{{ item }}' + replace: '' + loop: + - selinux=0 + - enforcing=0 - - name: "1.5.1 | PATCH | Ensure core dumps are restricted | coredump.conf" - lineinfile: - dest: /etc/systemd/coredump.conf - regexp: "{{ item.regex }}" - line: "{{ item.line }}" - create: true - mode: 0644 - notify: systemd daemon reload - with_items: - - { regex: '^Storage', line: 'Storage=none' } - - { regex: '^ProcessSizeMax', line: 'ProcessSizeMax=0' } +- name: | + "1.5.1.3 | PATCH | Ensure SELinux policy is configured + 1.5.1.4 | PATCH | Ensure the SELinux state is enforcing or permissive" when: - - amazon2cis_rule_1_5_1 + - not amazon2cis_selinux_disable + - amazon2cis_rule_1_5_1_3 + - amazon2cis_rule_1_5_1_4 tags: - level1 - automated - patch - - rule_1.5.1 - - sysctl + - rule_1.5.1.3 + - rule_1.5.1.4 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + ansible_python_interpreter: "{{ python2_bin }}" + ansible.posix.selinux: + conf: /etc/selinux/config + policy: "{{ amazon2cis_selinux_pol }}" + state: "{{ amazon2cis_selinux_state }}" -- name: "1.5.2 | PATCH | Ensure XD/NX support is enabled" - block: - - name: "1.5.2 | PATCH | Ensure XD/NX support is enabled | Get NX/DX status" - shell: dmesg|grep -E "NX|XD" | grep " active" - changed_when: false - failed_when: false - register: amazon2cis_1_5_2_nx_dx_status +- name: "1.5.1.5 | PATCH | Ensure the SELinux state is enforcing" + when: + - not amazon2cis_selinux_disable + - not amazon2cis_selinux_state == "permissive" + - amazon2cis_rule_1_5_1_5 + tags: + - level2 + - automated + - patch + - rule_1.5.1.5 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_SI-6 + vars: + ansible_python_interpreter: "{{ python2_bin }}" + ansible.posix.selinux: + conf: /etc/selinux/config + policy: "{{ amazon2cis_selinux_pol }}" + state: enforcing - - name: "1.5.2 | PATCH | Ensure XD/NX support is enabled | Alert on non-active status" - debug: - msg: - - "Alert! You do not have XD/NX support enabled. Please activate if your system supports it" - when: "'active' not in amazon2cis_1_5_2_nx_dx_status.stdout" +- name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist" when: - - amazon2cis_rule_1_5_2 + - amazon2cis_rule_1_5_1_6 tags: - level1 - - patch - automated - - rule_1.5.2 - - skip_ansible_lint + - audit + - rule_1.5.1.6 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + warn_control_id: '1.5.1.6' + block: + - name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" + ansible.builtin.shell: ps -eZ | grep unconfined_service_t + changed_when: false + failed_when: false + register: amazon2cis_1_5_1_6_unconf_services -- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled" - sysctl: - name: kernel.randomize_va_space - value: '2' - state: present - reload: true - sysctl_set: true - ignoreerrors: true + - name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist | Message on unconfined services" + ansible.builtin.debug: + msg: "Warning! You have unconfined services: {{ amazon2cis_1_5_1_6_unconf_services.stdout_lines }}" + when: amazon2cis_1_5_1_6_unconf_services.stdout | length > 0 + + - name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "1.5.1.7 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" when: - - amazon2cis_rule_1_5_3 + - amazon2cis_rule_1_5_1_7 tags: - level1 - automated - patch - - rule_1.5.3 - -- name: "1.5.4 | PATCH | Ensure prelink is not installed" - package: - name: prelink - state: absent + - rule_1.5.1.7 + - mcstrans + - NIST800-53R5_SI-4 vars: ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: mcstrans + state: absent + +- name: "1.5.1.8 | PATCH | Ensure SETroubleshoot is not installed" when: - - amazon2cis_rule_1_5_4 + - amazon2cis_rule_1_5_1_8 tags: - level1 - automated - patch - - rule_1.5.4 + - rule_1.5.1.8 + - selinux + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: setroubleshoot + state: absent diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index d6dd56c..4296d8f 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -1,128 +1,115 @@ --- -- name: "1.6.1.1 | PATCH | Ensure SELinux is installed" - package: - name: libselinux - state: present - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.1 | PATCH | Ensure message of the day is configured properly" when: - - not amazon2cis_selinux_disable - - amazon2cis_rule_1_6_1_1 + - amazon2cis_rule_1_6_1 tags: - level1 - automated - patch - - rule_1.6.1.1 - - selinux + - rule_1.6.1 + - banner + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-3 + - NIST800-53R5_CM-6 + ansible.builtin.template: + src: etc/motd.j2 + dest: /etc/motd + owner: root + group: root + mode: '0644' -- name: "1.6.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration" - replace: - dest: /etc/default/grub - regexp: '(selinux|enforcing)\s*=\s*0\s*' - ignore_errors: true - notify: grub2cfg +- name: "1.6.2 | PATCH | Ensure local login warning banner is configured properly" when: - - not amazon2cis_selinux_disable - - amazon2cis_rule_1_6_1_2 + - amazon2cis_rule_1_6_2 tags: - level1 - automated - patch - - rule_1.6.1.2 - - selinux + - rule_1.6.2 + - banner + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-3 + - NIST800-53R5_CM-6 + ansible.builtin.template: + src: etc/issue.j2 + dest: /etc/issue + owner: root + group: root + mode: '0644' -- name: | - "1.6.1.3 | PATCH | Ensure SELinux policy is configured - 1.6.1.4 | PATCH | Ensure the SELinux state is enforcing or permissive" - selinux: - conf: /etc/selinux/config - policy: "{{ amazon2cis_selinux_pol }}" - state: "{{ amazon2cis_selinux_state }}" - vars: - ansible_python_interpreter: "{{ python2_bin }}" +- name: "1.6.3 | PATCH | Ensure remote login warning banner is configured properly" when: - - not amazon2cis_selinux_disable - - amazon2cis_rule_1_6_1_3 - - amazon2cis_rule_1_6_1_4 + - amazon2cis_rule_1_6_3 tags: - level1 - automated - patch - - rule_1.6.1.3 - - rule_1.6.1.4 - - selinux + - rule_1.6.3 + - banner + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-3 + - NIST800-53R5_CM-6 + ansible.builtin.template: + src: etc/issue.net.j2 + dest: /etc/issue.net + owner: root + group: root + mode: '0644' -- name: "1.6.1.5 | PATCH | Ensure the SELinux state is enforcing" - selinux: - conf: /etc/selinux/config - policy: "{{ amazon2cis_selinux_pol }}" - state: enforcing - vars: - ansible_python_interpreter: "{{ python2_bin }}" +- name: "1.6.4 | PATCH | Ensure permissions on /etc/motd are configured" when: - - not amazon2cis_selinux_disable - - not amazon2cis_selinux_state == "permissive" - - amazon2cis_rule_1_6_1_5 - tags: - - level2 - - automated - - patch - - rule_1.6.1.5 - - selinux - -- name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist" - block: - - name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" - shell: ps -eZ | grep unconfined_service_t - changed_when: false - failed_when: false - register: amazon2cis_1_6_1_6_unconf_services - - - name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | Message on no unconfined services" - debug: - msg: "Good News! There are no unconfined services found on your system" - when: amazon2cis_1_6_1_6_unconf_services.stdout | length == 0 - - - name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | Message on unconfined services" - debug: - msg: "Warning! You have unconfined services: {{ amazon2cis_1_6_1_6_unconf_services.stdout_lines }}" - when: amazon2cis_1_6_1_6_unconf_services.stdout | length > 0 - when: - - amazon2cis_rule_1_6_1_6 + - amazon2cis_rule_1_6_4 tags: - level1 - automated - - audit - - rule_1.6.1.6 - - selinux + - patch + - rule_1.6.4 + - banner + - permissions + - NIST800-53R5_MP-2 + - NIST800-53R5_AC-3 + ansible.builtin.file: + path: /etc/motd + state: file + owner: root + group: root + mode: '0644' -- name: "1.6.1.7 | PATCH | Ensure SETroubleshoot is not installed" - package: - name: setroubleshoot - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.5 | PATCH | Ensure permissions on /etc/issue are configured" when: - - amazon2cis_rule_1_6_1_7 + - amazon2cis_rule_1_6_5 tags: - level1 - automated - patch - - rule_1.6.1.7 - - selinux + - rule_1.6.5 + - banner + - permissions + - NIST800-53R5_MP-2 + - NIST800-53R5_AC-3 + ansible.builtin.file: + path: /etc/issue + state: file + owner: root + group: root + mode: '0644' -- name: "1.6.1.8 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" - package: - name: mcstrans - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.6 | PATCH | Ensure permissions on /etc/issue.net are configured" when: - - amazon2cis_rule_1_6_1_8 + - amazon2cis_rule_1_6_6 tags: - level1 - automated - patch - - rule_1.6.1.8 - - mcstrans + - rule_1.6.6 + - banner + - permissions + - NIST800-53R5_MP-2 + - NIST800-53R5_AC-3 + ansible.builtin.file: + path: /etc/issue.net + state: file + owner: root + group: root + mode: '0644' diff --git a/tasks/section_1/cis_1.7.x.yml b/tasks/section_1/cis_1.7.x.yml deleted file mode 100644 index 5f45722..0000000 --- a/tasks/section_1/cis_1.7.x.yml +++ /dev/null @@ -1,100 +0,0 @@ ---- - -- name: "1.7.1 | PATCH | Ensure message of the day is configured properly" - template: - src: etc/motd.j2 - dest: /etc/motd - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_1 - tags: - - level1 - - automated - - patch - - rule_1.7.1 - - banner - -- name: "1.7.2 | PATCH | Ensure local login warning banner is configured properly" - template: - src: etc/issue.j2 - dest: /etc/issue - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_2 - tags: - - level1 - - automated - - patch - - rule_1.7.2 - - banner - -- name: "1.7.3 | PATCH | Ensure remote login warning banner is configured properly" - template: - src: etc/issue.net.j2 - dest: /etc/issue.net - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_3 - tags: - - level1 - - automated - - patch - - rule_1.7.3 - - banner - -- name: "1.7.4 | PATCH | Ensure permissions on /etc/motd are configured" - file: - path: /etc/motd - state: file - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_4 - tags: - - level1 - - automated - - patch - - rule_1.7.4 - - banner - - permissions - -- name: "1.7.5 | PATCH | Ensure permissions on /etc/issue are configured" - file: - path: /etc/issue - state: file - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_5 - tags: - - level1 - - automated - - patch - - rule_1.7.5 - - banner - - permissions - -- name: "1.7.6 | PATCH | Ensure permissions on /etc/issue.net are configured" - file: - path: /etc/issue.net - state: file - owner: root - group: root - mode: 0644 - when: - - amazon2cis_rule_1_7_6 - tags: - - level1 - - automated - - patch - - rule_1.7.6 - - banner - - permissions diff --git a/tasks/section_1/cis_1.8.x.yml b/tasks/section_1/cis_1.8.x.yml deleted file mode 100644 index c3323e6..0000000 --- a/tasks/section_1/cis_1.8.x.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- - -- name: "1.8 | PATCH | Ensure updates, patches, and additional security software are installed" - package: - name: "*" - state: latest - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_1_8 - tags: - - level1 - - automated - - patch - - rule_1.8 - - skip_ansible_lint diff --git a/tasks/section_1/main.yml b/tasks/section_1/main.yml index 28e0c7d..c1df0a2 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -1,30 +1,55 @@ --- - name: "SECTION | 1.1.1.x | Disable unused filesystems" - include_tasks: cis_1.1.1.x.yml + ansible.builtin.import_tasks: + file: cis_1.1.1.x.yml -- name: "SECTION | 1.1 | FileSystem Configuration" - include_tasks: cis_1.1.x.yml +- name: "SECTION | 1.1.2.1.x | FileSystem Configuration /tmp" + ansible.builtin.import_tasks: + file: cis_1.1.2.1.x.yml + +- name: "SECTION | 1.1.2.2.x | FileSystem Configuration /dev/shm" + ansible.builtin.import_tasks: + file: cis_1.1.2.2.x.yml + +- name: "SECTION | 1.1.2.3.x | FileSystem Configuration /home" + ansible.builtin.import_tasks: + file: cis_1.1.2.3.x.yml + +- name: "SECTION | 1.1.2.4.x | FileSystem Configuration /var" + ansible.builtin.import_tasks: + file: cis_1.1.2.4.x.yml + +- name: "SECTION | 1.1.2.5.x | FileSystem Configuration /var/tmp" + ansible.builtin.import_tasks: + file: cis_1.1.2.5.x.yml + +- name: "SECTION | 1.1.2.6.x | FileSystem Configuration /var/log" + ansible.builtin.import_tasks: + file: cis_1.1.2.6.x.yml + +- name: "SECTION | 1.1.2.7.x | FileSystem Configuration /var/log/audit" + ansible.builtin.import_tasks: + file: cis_1.1.2.7.x.yml - name: "SECTION | 1.2 | Configure Software Updates" - include_tasks: cis_1.2.x.yml + ansible.builtin.import_tasks: + file: cis_1.2.x.yml - name: "SECTION | 1.3 | Filesystem Integrity Checking" - include_tasks: cis_1.3.x.yml + ansible.builtin.import_tasks: + file: cis_1.3.x.yml when: amazon2cis_config_aide - name: "SECTION | 1.4 | Secure Boot Settings" - include_tasks: cis_1.4.x.yml + ansible.builtin.import_tasks: + file: cis_1.4.x.yml - name: "SECTION | 1.5 | Additional Process Hardening" - include_tasks: cis_1.5.x.yml + ansible.builtin.import_tasks: + file: cis_1.5.x.yml - name: "SECTION | 1.6 | Mandatory Access Control" - include_tasks: cis_1.6.x.yml + ansible.builtin.import_tasks: + file: cis_1.6.x.yml when: not amazon2cis_selinux_disable - -- name: "SECTION | 1.7 | Command Line Warning Banners" - include_tasks: cis_1.7.x.yml - -- name: "SECTION | 1.8 | Ensure updates, patches, and additional security software are installed" - include_tasks: cis_1.8.x.yml diff --git a/tasks/section_2/cis_2.1.1.x.yml b/tasks/section_2/cis_2.1.1.x.yml deleted file mode 100644 index 9436b69..0000000 --- a/tasks/section_2/cis_2.1.1.x.yml +++ /dev/null @@ -1,106 +0,0 @@ ---- - -- name: "2.1.1.1 | PATCH | Ensure time synchronization is in use" - block: - - name: "2.1.1.1 | PATCH | Ensure time synchronization is in use | service install" - package: - name: "{{ amazon2cis_time_synchronization }}" - state: present - vars: - ansible_python_interpreter: /bin/python - - - name: "2.1.1.1 | PATCH | Ensure time synchronization is in use | service start" - service: - name: "{{ amazon2cis_time_synchronization }}d" - state: started - enabled: true - - - name: "2.1.1.1 | PATCH | Ensure time synchronization is in use | service stop ntp" - service: - name: ntpd - state: stopped - enabled: false - when: - - "'ntp' in ansible_facts.packages" - - amazon2cis_time_synchronization == "chrony" - - - name: "2.1.1.1 | PATCH | Ensure time synchronization is in use | service stop chrony" - service: - name: chronyds - when: - - "'chrony' in ansible_facts.packages" - - amazon2cis_time_synchronization == "ntp" - when: - - amazon2cis_rule_2_1_1_1 - - not amazon2cis_system_is_container - tags: - - level1 - - automated - - patch - - rule_2.1.1.1 - - ntps - -- name: "2.1.1.2 | PATCH | Ensure chrony is configured" - block: - - name: "2.1.1.2 | PATCH | Ensure chrony is configured | modify /etc/chrony.conf" - template: - src: chrony.conf.j2 - dest: /etc/chrony.conf - owner: root - group: root - mode: 0644 - - - name: "2.1.1.2 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" - lineinfile: - dest: /etc/sysconfig/chronyd - regexp: "^(#)?OPTIONS" - line: "OPTIONS=\"-u chrony\"" - state: present - owner: root - group: root - mode: 0640 - create: true - when: - - amazon2cis_rule_2_1_1_2 - - amazon2cis_time_synchronization == "chrony" - - not amazon2cis_system_is_container - tags: - - level1 - - automated - - patch - - rule_2.1.1.2 - - ntp - -- name: "2.1.1.3 | PATCH | Ensure ntp is configured" - block: - - name: "2.1.1.3 | PATCH | Ensure ntp is configured | modify /etc/ntp.conf" - template: - src: ntp.conf.j2 - dest: /etc/ntp.conf - owner: root - group: root - mode: 0644 - - - name: "2.1.1.3 | PATCH | Ensure ntp is configured | modify /etc/sysconfig/ntpd" - lineinfile: - dest: /etc/sysconfig/ntpd - regexp: "^(#)?OPTIONS" - line: "OPTIONS=\"-u ntp:ntp\"" - notify: systemd daemon reloads - - - name: "2.1.1.3 | PATCH | Ensure ntp is configured | modify /usr/lib/systemd/system/ntpd.service" - lineinfile: - dest: /usr/lib/systemd/system/ntpd.service - regexp: "^(#)?ExecStart" - line: "ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS" - notify: systemd daemon reload - when: - - amazon2cis_rule_2_1_1_3 - - amazon2cis_time_synchronization == "ntp" - - not amazon2cis_system_is_container - tags: - - level1 - - automated - - patch - - rule_2.1.1.3 - - ntp diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index 9b9884f..f029ff5 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -1,356 +1,91 @@ --- -- name: "2.1.2 | PATCH | Ensure X11 Server components are not installed" - package: - state: absent - name: - - "@X Window System" - - "xorg-x11*" - vars: - ansible_python_interpreter: /bin/python +- name: "2.1.1 | PATCH | Ensure time synchronization is in use" when: - - not amazon2cis_xwindows_required - - amazon2cis_rule_2_1_2 + - amazon2cis_rule_2_1_1 tags: - level1 - automated - patch - - rule_2.1.2 - - xwindowss - -- name: "2.1.3 | PATCH | Ensure Avahi Server is not installed" + - rule_2.1.1 + - ntp + - chrony + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 block: - - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - service: - name: avahi-daemon - state: stopped - enabled: false - - - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - package: - name: - - avahi - - avahi-autoipd - state: absent - when: - - not amazon2cis_avahi_server - - "'avahi' in ansible_facts.packages" - - amazon2cis_rule_2_1_3 - tags: - - level1 - - automated - - patch - - rule_2.1.3 - - avahi - - services - -- name: "2.1.4 | PATCH | Ensure CUPS is not installed" - package: - name: cups - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_cups_server - - "'cups' in ansible_facts.packages" - - amazon2cis_rule_2_1_4 - tags: - - level1 - - automated - - patch - - rule_2.1.4 - - cups - - services - -- name: "2.1.5 | PATCH | Ensure DHCP Server is not installed" - package: - name: dhcpd - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_dhcp_server - - "'dhcp' in ansible_facts.packages" - - amazon2cis_rule_2_1_5 - tags: - - level1 - - automated - - patch - - rule_2.1.5 - - dhcp - - services - -- name: "2.1.6 | PATCH | Ensure LDAP server is not installed" - package: - name: openldap-servers - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_ldap_server - - "'openldap-servers' in ansible_facts.packages" - - amazon2cis_rule_2_1_6 - tags: - - level1 - - automated - - patch - - rule_2.1.6 - - ldap - - services - -- name: "2.1.7 | PATCH | Ensure dns server is not installed" - package: - name: bind - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_named_server - - "'bind' in ansible_facts.packages" - - amazon2cis_rule_2_1_7 - tags: - - level1 - - automated - - patch - - rule_2.1.7 - - dns - - services - -- name: "2.1.8 | PATCH | Ensure FTP server is not installed" - package: - name: vsftpd - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_vsftpd_server - - "'vsftpd' in ansible_facts.packages" - - amazon2cis_rule_2_1_8 - tags: - - level1 - - automated - - patch - - rule_2.1.8 - - ftp - - services - -- name: "2.1.9 | PATCH | Ensure HTTP server is not installed" - package: - name: httpd - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_httpd_server - - "'httpd' in ansible_facts.packages" - - amazon2cis_rule_2_1_9 - tags: - - level1 - - automated - - patch - - rule_2.1.9 - - ldap - - services - -- name: "2.1.10 | PATCH | Ensure IMAP and POP3 server is not installed" - package: - name: dovecot - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_dovecot_server - - "'dovecot' in ansible_facts.packages" - - amazon2cis_rule_2_1_10 - tags: - - level1 - - automated - - patch - - rule_2.1.10 - - dovecot - - services - -- name: "2.1.11 | PATCH | Ensure Samba server is not installed" - package: - name: samba - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_smb_server - - "'samba' in ansible_facts.packages" - - amazon2cis_rule_2_1_11 - tags: - - level1 - - automated - - patch - - rule_2.1.11 - - samba - - servicess - -- name: "2.1.12 | PATCH | Ensure HTTP Proxy server is not installed" - package: - name: squid - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_squid_server - - "'squid' in ansible_facts.packages" - - amazon2cis_rule_2_1_12 - tags: - - level1 - - scored - - patch - - rule_2.1.12 - - squid - - services - -- name: "2.1.13 | PATCH | Ensure net-snmp is not installed" - package: - name: net-snmp - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_snmp_server - - "'net-snmp' in ansible_facts.packages" - - amazon2cis_rule_2_1_13 - tags: - - level1 - - automated - - patch - - rule_2.1.13 - - squid - - services - -- name: "2.1.14 | PATCH | Ensure nis server is not installed" - package: - name: ypserv - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_nis_server - - "'ypserv' in ansible_facts.packages" - - amazon2cis_rule_2_1_14 - tags: - - level1 - - automated - - patch - - rule_2.1.14 - - nis - - services - -- name: "2.1.15 | PATCH | Ensure telnet server is not installed" - package: - name: telnet-server - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_telnet_server - - "'telnet-server' in ansible_facts.packages" - - amazon2cis_rule_2.1_15 - tags: - - level1 - - automated - - patch - - rule_2.1.15 - - telnet - - services - -- name: "2.1.16 | PATCH | Ensure mail transfer agent is configured for local-only mode" - lineinfile: - path: /etc/postfix/main.cf - regexp: "^(#)?inet_interfaces" - line: "inet_interfaces = loopback-only" - notify: restart postfix - when: - - not amazon2cis_is_mail_server - - "'postfix' in ansible_facts.packages" - - amazon2cis_rule_2_1_16 - tags: - - level1 - - automated - - patch - - rule_2.1.16 - - postfix - -- name: "2.1.17 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked" - block: - - name: "2.1.17 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | nfs-utils " - package: - name: nfs-utils - state: absent + - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service install" + ansible.builtin.package: + name: "{{ amazon2cis_time_synchronization }}" + state: present vars: ansible_python_interpreter: /bin/python - when: - - not amazon2cis_nfs_rpc_server - - not amazon2cis_nfs_server - - name: "2.1.17 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | nfs-server " - systemd: - name: nfs-server - masked: true - when: - - amazon2cis_nfs_rpc_server - - not amazon2cis_nfs_server - when: - - "'nfs-utils' in ansible_facts.packages" - - amazon2cis_rule_2_1_17 - tags: - - level1 - - automated - - patch - - rule_2.1.17 - - nfs - - services + - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service start" + ansible.builtin.service: + name: "{{ amazon2cis_time_synchronization }}d" + state: started + enabled: true -- name: "2.1.18 | PATCH | Ensure rpcbind is not installed or the irpcbind services are masked" - block: - - name: "2.1.18 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | rpcbind" - package: - name: rpcbind - state: absent - vars: - ansible_python_interpreter: /bin/python + - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service stop ntp" + ansible.builtin.service: + name: ntpd + state: stopped + enabled: false when: - - not amazon2cis_nfs_rpc_server - - not amazon2cis_rpc_server + - "'ntp' in ansible_facts.packages" + - amazon2cis_time_synchronization == "chrony" - - name: "2.1.18 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | rpcbind-server" - systemd: - name: rpcbind.socket - masked: true + - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service stop chrony" + ansible.builtin.service: + name: chronyds when: - - amazon2cis_nfs_rpc_server - - not amazon2cis_rpc_server + - "'chrony' in ansible_facts.packages" + - amazon2cis_time_synchronization == "ntp" + +- name: "2.1.2 | PATCH | Ensure chrony is configured | modify /etc/chrony.conf" when: - - "'rpcbind' in ansible_facts.packages" - - amazon2cis_rule_2_1_18 + - amazon2cis_rule_2_1_2 + - amazon2cis_time_synchronization == "chrony" tags: - level1 - automated - patch - - rule_2.1.18 - - rpc - - services - -- name: "2.1.19 | PATCH | Ensure rsync is not installed or the rsyncd services are masked" - package: - name: rsync - state: absent - vars: - ansible_python_interpreter: /bin/python + - rule_2.1.2 + - ntp + - chrony + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 + ansible.builtin.template: + src: chrony.conf.j2 + dest: /etc/chrony.conf + owner: root + group: root + mode: '0644' + +- name: "2.1.3 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" when: - - not amazon2cis_rsyncd_server - - "'rsync' in ansible_facts.packages" - - amazon2cis_rule_2_1_19 + - amazon2cis_rule_2_1_3 + - amazon2cis_time_synchronization == "chrony" tags: - level1 - automated - patch - - rule_2.1.19 - - rsync - - services + - rule_2.1.3 + - ntp + - chrony + block: + - name: "2.1.3 | AUDIT | Ensure chrony is configured | Check Setting" + ansible.builtin.shell: grep "u chrony" /etc/sysconfig/chronyd + changed_when: false + failed_when: amazon2_2_1_3_chrony_user.rc not in [ 0, 1 ] + register: amazon2_2_1_3_chrony_user + + - name: "2.1.3 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" + when: "'-u chrony' not in amazon2_2_1_3_chrony_user.stdout" + ansible.builtin.lineinfile: + path: /etc/sysconfig/chronyd + regexp: ^OPTIONS=\"(.*)" + line: OPTIONS="\1 -u chrony" + create: true + backrefs: true + mode: '0644' diff --git a/tasks/section_2/cis_2.2.x.yml b/tasks/section_2/cis_2.2.x.yml index cc870bb..2de60ba 100644 --- a/tasks/section_2/cis_2.2.x.yml +++ b/tasks/section_2/cis_2.2.x.yml @@ -1,86 +1,736 @@ --- -- name: "2.2.1 | PATCH | Ensure nis client is not installed" - package: - name: ypbind - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "2.2.1 | PATCH | Ensure autofs services are not in use" when: - - not amazon2cis_ypbind_required - - "'ypbind' in ansible_facts.packages" - amazon2cis_rule_2_2_1 tags: - - level1 + - level1-server + - level2-workstation - automated - patch + - NIST800-53R5_SI-3 + - NIST800-53R5_MP-7 - rule_2.2.1 - - nis + block: + - name: "2.2.1 | PATCH | Ensure autofs services are not in use | Remove Package" + when: + - "'autofs' in ansible_facts.packages" + - not amazon2cis_autofs_services + - not amazon2cis_autofs_mask + ansible.builtin.package: + name: autofs + state: absent -- name: "2.2.2 | PATCH | Ensure rsh client is not installed" - package: - name: rsh - state: absent - vars: - ansible_python_interpreter: /bin/python + - name: "2.2.1 | PATCH | Ensure autofs services are not in use | Mask service" + when: + - not amazon2cis_autofs_services + - amazon2cis_autofs_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: autofs + enabled: "{{ ('autofs' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('autofs' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.2 | PATCH | Ensure avahi daemon services are not in use" when: - - not amazon2cis_rsh_required - - "'rsh' in ansible_facts.packages" - amazon2cis_rule_2_2_2 tags: - - level1 + - level1-server + - level2-workstation - automated - patch + - avahi + - NIST800-53R5_SI-4 - rule_2.2.2 - - rsh + block: + - name: "2.2.2 | PATCH | Ensure avahi daemon services are not in use | Remove package" + when: + - not amazon2cis_avahi_server + - not amazon2cis_avahi_mask + - "'avahi' in ansible_facts.packages or 'avahi-autopd' in ansible_facts.packages" + ansible.builtin.package: + name: + - avahi-autoipd + - avahi + state: absent -- name: "2.2.3 | PATCH | Ensure talk client is not installed" - package: - name: talk - state: absent - vars: - ansible_python_interpreter: /bin/python + - name: "2.2.2 | PATCH | Ensure avahi daemon services are not in use | Mask service" + when: + - not amazon2cis_avahi_server + - amazon2cis_avahi_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ ('avahi' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('avahi' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - avahi-daemon.socket + - avahi-daemon.service + +- name: "2.2.3 | PATCH | Ensure dhcp server services are not in use" when: - - not amazon2cis_talk_required - - "'talk' in ansible_facts.packages" - amazon2cis_rule_2_2_3 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - dhcp + - NIST800-53R5_CM-7 - rule_2.2.3 - - talk + block: + - name: "2.2.3 | PATCH | Ensure dhcp server services are not in use | Remove package" + when: + - "'dhcp-server' in ansible_facts.packages" + - not amazon2cis_dhcp_server + - not amazon2cis_dhcp_mask + ansible.builtin.package: + name: dhcp-server + state: absent -- name: "2.2.4 | PATCH | Ensure telnet client is not installed" - package: - name: telnet - state: absent - vars: - ansible_python_interpreter: /bin/python + - name: "2.2.3 | PATCH | Ensure dhcp server services are not in use | Mask service" + when: + - not amazon2cis_dhcp_server + - amazon2cis_dhcp_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ ('dhcp-server' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('dhcp-server' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - dhcpd.service + - dhcpd6.service + +- name: "2.2.4 | PATCH | Ensure dns server services are not in use" when: - - "'telnet' in ansible_facts.packages" - - not amazon2cis_telnet_required - amazon2cis_rule_2_2_4 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - dns + - NIST800-53R5_CM-7 - rule_2.2.4 - - telnet + block: + - name: "2.2.4 | PATCH | Ensure dns server services are not in use | Remove package" + when: + - "'bind' in ansible_facts.packages" + - not amazon2cis_dns_server + - not amazon2cis_dns_mask + ansible.builtin.package: + name: bind + state: absent -- name: "2.2.5 | PATCH | Ensure LDAP client is not installed" - package: - name: openldap-client - state: absent - vars: - ansible_python_interpreter: /bin/python + - name: "2.2.4 | PATCH | Ensure dns server services are not in use | Mask service" + when: + - not amazon2cis_dns_server + - amazon2cis_dns_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: named.service + enabled: "{{ ('bind' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('bind' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.5 | PATCH | Ensure dnsmasq server services are not in use" when: - - not amazon2cis_openldap_clients_required - - "'openldap-client' in ansible_facts.packages" - amazon2cis_rule_2_2_5 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - dns + - NIST800-53R5_CM-7 - rule_2.2.5 - - ldap_client + block: + - name: "2.2.5 | PATCH | Ensure dnsmasq server services are not in use | Remove package" + when: + - "'dnsmasq' in ansible_facts.packages" + - not amazon2cis_dnsmasq_server + - not amazon2cis_dnsmasq_mask + ansible.builtin.package: + name: dnsmasq + state: absent + + - name: "2.2.5 | PATCH | Ensure dnsmasq server services are not in use | Mask service" + when: + - not amazon2cis_dnsmasq_server + - amazon2cis_dnsmasq_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: dnsmasq.service + enabled: "{{ ('dnsmasq' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('dnsmasq' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.6 | PATCH | Ensure samba file server services are not in use" + when: + - amazon2cis_rule_2_2_6 + tags: + - level1-server + - level1-workstation + - automated + - patch + - samba + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.6 + block: + - name: "2.2.6 | PATCH | Ensure samba file server services are not in use | Remove package" + when: + - "'samba' in ansible_facts.packages" + - not amazon2cis_samba_server + - not amazon2cis_samba_mask + ansible.builtin.package: + name: samba + state: absent + + - name: "2.2.6 | PATCH | Ensure samba file server services are not in use | Mask service" + when: + - not amazon2cis_samba_server + - amazon2cis_samba_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: smb.service + enabled: "{{ ('samba' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('samba' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.7 | PATCH | Ensure ftp server services are not in use" + when: + - amazon2cis_rule_2_2_7 + tags: + - level1-server + - level1-workstation + - automation + - patch + - ftp + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.7 + block: + - name: "2.2.7 | PATCH | Ensure ftp server services are not in use | Remove package" + when: + - "'vsftp' in ansible_facts.packages" + - not amazon2cis_ftp_server + - not amazon2cis_ftp_mask + ansible.builtin.package: + name: vsftpd + state: absent + + - name: "2.2.7 | PATCH | Ensure ftp server services are not in use | Mask service" + when: + - not amazon2cis_ftp_server + - amazon2cis_ftp_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: vsftpd.service + enabled: "{{ ('vsftpd' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('vsftpd' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.8 | PATCH | Ensure message access server services are not in use" + when: + - amazon2cis_rule_2_2_8 + tags: + - level1-server + - level1-workstation + - automated + - patch + - dovecot + - imap + - pop3 + - NIST800-53R5_CM-7 + - rule_2.2.8 + block: + - name: "2.2.8 | PATCH | Ensure message access server services are not in use | Remove package" + when: + - "'dovecot' in ansible_facts.packages or 'cyrus-imapd' in ansible_facts.packages" + - not amazon2cis_message_server + - not amazon2cis_message_mask + ansible.builtin.package: + name: + - dovecot + - cyrus-imapd + state: absent + + - name: "2.2.8 | PATCH | Ensure message access server services are not in use | Mask service" + when: + - not amazon2cis_message_server + - amazon2cis_message_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - "dovecot.socket" + - "dovecot.service" + - "cyrus-imapd.service" + +- name: "2.2.9 | PATCH | Ensure network file system services are not in use" + when: + - amazon2cis_rule_2_2_9 + tags: + - level1-server + - level1-workstation + - automated + - patch + - nfs + - services + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.9 + block: + - name: "2.2.9 | PATCH | Ensure network file system services are not in use | Remove package" + when: + - "'nfs-utils' in ansible_facts.packages" + - not amazon2cis_nfs_server + - not amazon2cis_nfs_mask + ansible.builtin.package: + name: nfs-utils + state: absent + + - name: "2.2.9 | PATCH | Ensure network file system services are not in use | Mask service" + when: + - not amazon2cis_nfs_server + - amazon2cis_nfs_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: nfs-server.service + enabled: "{{ ('nfs-utils' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('nfs-utils' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.10 | PATCH | Ensure nis server services are not in use" + when: + - amazon2cis_rule_2_2_10 + tags: + - level1-server + - level1-workstation + - automated + - patch + - nis + - NIST800-53R5_CM-7 + - rule_2.2.10 + notify: Systemd_daemon_reload + block: + - name: "2.2.10 | PATCH | Ensure nis server services are not in use | Remove package" + when: + - "'ypserv' in ansible_facts.packages" + - not amazon2cis_nis_server + - not amazon2cis_nis_mask + ansible.builtin.package: + name: ypserv + state: absent + + - name: "2.2.10 | PATCH | Ensure nis server services are not in use | Mask service" + when: + - not amazon2cis_nis_server + - amazon2cis_nis_mask + ansible.builtin.systemd: + name: ypserv.service + enabled: "{{ ('ypserv' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('ypserv' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.11 | PATCH | Ensure print server services are not in use" + when: + - amazon2cis_rule_2_2_11 + tags: + - level1-server + - automated + - patch + - cups + - NIST800-53R5_CM-7 + - rule_2.2.11 + block: + - name: "2.2.11 | PATCH | Ensure print server services are not in use | Remove package" + when: + - "'cups' in ansible_facts.packages" + - not amazon2cis_print_server + - not amazon2cis_print_mask + ansible.builtin.package: + name: cups + state: absent + + - name: "2.2.11 | PATCH | Ensure print server services are not in use | Mask service" + when: + - not amazon2cis_print_server + - amazon2cis_print_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - "cups.socket" + - "cups.service" + +- name: "2.2.12 | PATCH | Ensure rpcbind services are not in use" + when: + - amazon2cis_rule_2_2_12 + tags: + - level1-server + - level1-workstation + - automated + - patch + - rpc + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.12 + block: + - name: "2.2.12 | PATCH | Ensure rpcbind services are not in use | Remove package" + when: + - "'rpcbind' in ansible_facts.packages" + - not amazon2cis_rpc_server + - not amazon2cis_rpc_mask + ansible.builtin.package: + name: cups + state: absent + + - name: "2.2.12 | PATCH | Ensure rpcbind services are not in use | Mask service" + when: + - not amazon2cis_rpc_server + - amazon2cis_rpc_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - rpcbind.service + - rpcbind.socket + +- name: "2.2.13 | PATCH | Ensure rsync services are not in use" + when: + - amazon2cis_rule_2_2_13 + tags: + - level1-server + - level1-workstation + - automated + - patch + - rsync + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.13 + block: + - name: "2.2.13 | PATCH | Ensure rsync services are not in use | Remove package" + when: + - "'rsync-daemon' in ansible_facts.packages" + - not amazon2cis_rsync_server + - not amazon2cis_rsync_mask + ansible.builtin.package: + name: rsync-daemon + state: absent + + - name: "2.2.13 | PATCH | Ensure rsync services are not in use | Mask service" + when: + - not amazon2cis_rsync_server + - amazon2cis_rsync_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - 'rsyncd.socket' + - 'rsyncd.service' + +- name: "2.2.14 | PATCH | Ensure snmp services are not in use" + when: + - amazon2cis_rule_2_2_14 + tags: + - level1-server + - level1-workstation + - automation + - patch + - snmp + - NIST800-53R5_CM-7 + - rule_2.2.14 + block: + - name: "2.2.14 | PATCH | Ensure snmp services are not in use | Remove package" + when: + - "'net-snmp' in ansible_facts.packages" + - not amazon2cis_net_snmp_server + - not amazon2cis_net_snmp_mask + ansible.builtin.package: + name: rsync-daemon + state: absent + + - name: "2.2.14 | PATCH | Ensure snmp services are not in use | Mask service" + when: + - not amazon2cis_net_snmp_server + - amazon2cis_net_snmp_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: snmpd.service + enabled: "{{ ('net-snmp' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('net-snmp' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.15 | PATCH | Ensure telnet server services are not in use" + when: + - amazon2cis_rule_2_2_15 + tags: + - level1-server + - level1-workstation + - automated + - patch + - telnet + - NIST800-53R5_CM-7 + - NIST800-53R5_CM-11 + - rule_2.2.15 + block: + - name: "2.2.15 | PATCH | Ensure telnet server services are not in use | Remove package" + when: + - "'telnet-server' in ansible_facts.packages" + - not amazon2cis_telnet_server + - not amazon2cis_telnet_mask + ansible.builtin.package: + name: telnet-server + state: absent + + - name: "2.2.15 | PATCH | Ensure telnet server services are not in use | Mask service" + when: + - not amazon2cis_telnet_server + - amazon2cis_telnet_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: telnet.socket + enabled: "{{ ('telnet-server' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('telnet-server' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.16 | PATCH | Ensure tftp server services are not in use" + when: + - amazon2cis_rule_2_2_16 + tags: + - level1-server + - level1-workstation + - automated + - patch + - tftp + - NIST800-53R5_CM-7 + - rule_2.2.16 + block: + - name: "2.2.16 | PATCH | Ensure tftp server services are not in use | Remove package" + when: + - "'tftp-server' in ansible_facts.packages" + - not amazon2cis_tftp_server + - not amazon2cis_tftp_mask + ansible.builtin.package: + name: tftp-server + state: absent + + - name: "2.2.16 | PATCH | Ensure tftp server services are not in use | Mask service" + when: + - not amazon2cis_tftp_server + - amazon2cis_tftp_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: "{{ item }}" + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + loop: + - 'tftp.socket' + - 'tftp.service' + +- name: "2.2.17 | PATCH | Ensure web proxy server services are not in use" + when: + - amazon2cis_rule_2_2_17 + tags: + - level1-server + - level1-workstation + - automation + - patch + - squid + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - rule_2.2.17 + block: + - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use | Remove package" + when: + - "'squid' in ansible_facts.packages" + - not amazon2cis_squid_server + - not amazon2cis_squid_mask + ansible.builtin.package: + name: squid + state: absent + + - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use | Mask service" + when: + - not amazon2cis_squid_server + - amazon2cis_squid_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: squid.service + enabled: "{{ ('squid' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('squid' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.18 | PATCH | Ensure web server services are not in use" + when: + - amazon2cis_rule_2_2_18 + tags: + - level1-server + - level1-workstation + - automated + - patch + - httpd + - nginx + - webserver + - NIST800-53R5_CM-7 + - rule_2.2.18 + block: + - name: "2.2.18 | PATCH | Ensure web server services are not in use | Remove httpd server" + when: + - "'httpd' in ansible_facts.packages" + - not amazon2cis_httpd_server + - not amazon2cis_httpd_mask + ansible.builtin.package: + name: httpd + state: absent + + - name: "2.2.18 | PATCH | Ensure web server services are not in use | Remove nginx server" + when: + - "'nginx' in ansible_facts.packages" + - not amazon2cis_nginx_server + - not amazon2cis_nginx_mask + ansible.builtin.package: + name: nginx + state: absent + + - name: "2.2.18 | PATCH | Ensure web server services are not in use | Mask httpd service" + when: + - not amazon2cis_httpd_server + - amazon2cis_httpd_mask + - "'httpd' in ansible_facts.packages" + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: httpd.service + enabled: "{{ ('httpd' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('httpd' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + + - name: "2.2.18 | PATCH | Ensure web server services are not in use | Mask nginx service" + when: + - not amazon2cis_nginx_server + - amazon2cis_nginx_mask + - "'nginx' in ansible_facts.packages" + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: ngnix.service + enabled: "{{ ('nginx' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('nginx' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.19 | PATCH | Ensure xinetd services are not in use" + when: + - amazon2cis_rule_2_2_19 + tags: + - level1-server + - level1-workstation + - automated + - patch + - xinetd + - NIST800-53R5_CM-7 + - rule_2.2.19 + block: + - name: "2.2.19 | PATCH | Ensure xinetd services are not in use | Remove package" + when: + - "'xinetd' in ansible_facts.packages" + - not amazon2cis_xinetd_server + - not amazon2cis_xinetd_mask + ansible.builtin.package: + name: tftp-server + state: absent + + - name: "2.2.19 | PATCH | Ensure xinetd services are not in use | Mask service" + when: + - not amazon2cis_xinetd_server + - amazon2cis_xinetd_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: xinetd.service + enabled: "{{ ('xinetd' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('xinetd' in ansible_facts.packages) | ternary('stopped', omit) }}" + masked: true + +- name: "2.2.20 | PATCH | Ensure X window server services are not in use" + when: + - not amazon2cis_xwindow_server + - "'xorg-x11-server-common' in ansible_facts.packages" + - amazon2cis_rule_2_2_20 + tags: + - level1-server + - level1-workstation + - automated + - patch + - xwindow + - NIST800-53R5_CM-11 + - rule_2.2.20 + ansible.builtin.package: + name: xorg-x11-server-common + state: absent + +- name: "2.2.21 | PATCH | Ensure mail transfer agents are configured for local-only mode" + when: + - not amazon2cis_is_mail_server + - "'postfix' in ansible_facts.packages" + - amazon2cis_rule_2_2_21 + tags: + - level1-server + - level1-workstation + - automated + - patch + - postfix + - NIST800-53R5_CM-7 + - rule_2.2.21 + notify: Restart_postfix + ansible.builtin.lineinfile: + path: /etc/postfix/main.cf + regexp: "^(#)?inet_interfaces" + line: "inet_interfaces = loopback-only" + +- name: "2.2.22 | AUDIT | Ensure only approved services are listening on a network interface" + when: + - amazon2cis_rule_2_2_22 + tags: + - level1-server + - level1-workstation + - manual + - audit + - services + - NIST800-53R5_CM-7 + - rule_2.2.22 + vars: + warn_control_id: '2.2.22' + block: + - name: "2.2.22 | AUDIT | Ensure only approved services are listening on a network interface | Get list of services" + ansible.builtin.shell: systemctl list-units --type=service + changed_when: false + failed_when: amazon2cis_2_2_22_services.rc not in [ 0, 1 ] + check_mode: false + register: amazon2cis_2_2_22_services + + - name: "2.2.22 | AUDIT | Ensure only approved services are listening on a network interface | Display list of services" + ansible.builtin.debug: + msg: + - "Warning!! Below are the list of services, both active and inactive" + - "Please review to make sure all are essential" + - "{{ amazon2cis_2_2_22_services.stdout_lines }}" + + - name: "2.2.22 | AUDIT | Ensure only approved services are listening on a network interface | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml diff --git a/tasks/section_2/cis_2.3.x.yml b/tasks/section_2/cis_2.3.x.yml new file mode 100644 index 0000000..3f26c87 --- /dev/null +++ b/tasks/section_2/cis_2.3.x.yml @@ -0,0 +1,86 @@ +--- + +- name: "2.3.1 | PATCH | Ensure ftp client is not installed" + when: + - not amazon2cis_ftp_client + - "'ftp' in ansible_facts.packages" + - amazon2cis_rule_2_3_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - ftp + - NIST800-53R5_CM-7 + - rule_2.3.1 + ansible.builtin.package: + name: ftp + state: absent + +- name: "2.3.2 | PATCH | Ensure ldap client is not installed" + when: + - not amazon2cis_openldap_clients_required + - "'openldap-clients' in ansible_facts.packages" + - amazon2cis_rule_2_3_2 + tags: + - level2-server + - level2-workstation + - automated + - patch + - ldap + - NIST800-53R5_CM-7 + - rule_2.3.2 + ansible.builtin.package: + name: openldap-clients + state: absent + +- name: "2.3.3 | PATCH | Ensure nis client is not installed" + when: + - not amazon2cis_ypbind_required + - "'ypbind' in ansible_facts.packages" + - amazon2cis_rule_2_3_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - nis + - NIST800-53R5_CM-7 + - rule_2.3.3 + ansible.builtin.package: + name: ypbind + state: absent + +- name: "2.3.4 | PATCH | Ensure telnet client is not installed" + when: + - not amazon2cis_telnet_required + - "'telnet' in ansible_facts.packages" + - amazon2cis_rule_2_3_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - telnet + - NIST800-53R5_CM-7 + - rule_2.3.4 + ansible.builtin.package: + name: telnet + state: absent + +- name: "2.3.5 | PATCH | Ensure TFTP client is not installed" + when: + - not amazon2cis_tftp_client + - "'tftp' in ansible_facts.packages" + - amazon2cis_rule_2_3_5 + tags: + - level1-server + - level1-workstation + - automated + - patch + - tftp + - NIST800-53R5_CM-7 + - rule_2.3.5 + ansible.builtin.package: + name: tftp + state: absent diff --git a/tasks/section_2/cis_2.3.yml b/tasks/section_2/cis_2.3.yml deleted file mode 100644 index 0161d35..0000000 --- a/tasks/section_2/cis_2.3.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- - -- name: "2.3 | audit | Ensure nonessential services are removed or masked" - debug: - msg: "<----- not required" - when: - - amazon2cis_rule_2_3 - tags: - - level1 - - manual - - audit - - rule_2.3 diff --git a/tasks/section_2/main.yml b/tasks/section_2/main.yml index 66b5251..70d0b5e 100644 --- a/tasks/section_2/main.yml +++ b/tasks/section_2/main.yml @@ -1,13 +1,13 @@ --- -- name: "SECTION | 2.1.1 | Time Synchronization" - include_tasks: cis_2.1.1.x.yml +- name: "SECTION | 2.1.x | Time Synchronization" + ansible.builtin.import_tasks: + file: cis_2.1.x.yml - name: "SECTION | 2.1 | Special Purpose Services" - include_tasks: cis_2.1.x.yml + ansible.builtin.import_tasks: + file: cis_2.2.x.yml -- name: "SECTION | 2.2 | Service Clients" - include_tasks: cis_2.2.x.yml - -- name: "SECTION | 2.3 | Nonessential Services" - include_tasks: cis_2.3.yml +- name: "SECTION | 2.3 | Service Clients" + ansible.builtin.import_tasks: + file: cis_2.3.x.yml diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 7bafafe..88168a2 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -1,36 +1,65 @@ --- - name: "3.1.1 | PATCH | Disable IPv6" - sysctl: - name: "{{ item }}" - value: '1' - reload: true - state: present - loop: - - net.ipv6.conf.all.disable_ipv6 - - net.ipv6.conf.default.disable_ipv6 when: - not amazon2cis_ipv6_required - amazon2cis_rule_3_1_1 - notify: sysctl flush ipv6 route table + notify: Sysctl_flush_ipv6_routes tags: - level2 - manual - patch - rule_3.1.1 - ipv6 + - NIST800-53R5_CM-7 + block: + - name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system | disable all except localhost" + ansible.posix.sysctl: + name: "{{ item }}" + value: '1' + sysctl_set: true + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + loop: + - net.ipv6.conf.all.disable_ipv6 + - net.ipv6.conf.default.disable_ipv6 + + - name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system | disable localhost sysctl" + when: + - amazon2cis_ipv6_disable_localhost + ansible.posix.sysctl: + name: net.ipv6.conf.lo.disable_ipv6 + value: '1' + sysctl_set: true + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + + - name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system | disable localhost /etc/hosts" + when: + - amazon2cis_ipv6_disable_localhost + ansible.builtin.lineinfile: + path: /etc/hosts + regexp: '^(::1.*)' + line: '#\1' + backrefs: true - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled" + when: + - amazon2cis_rule_3_1_2 + tags: + - level1 + - automated + - patch + - rule_3.1.2 + - wireless block: - name: "3.1.2 | AUDIT | Ensure wireless interfaces are disabled | Check if nmcli command is available" - command: rpm -q NetworkManager + ansible.builtin.command: rpm -q NetworkManager changed_when: false failed_when: false check_mode: false register: amazon2_3_1_2_nmcli_available - name: "3.1.2 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled" - command: nmcli radio wifi + ansible.builtin.command: nmcli radio wifi changed_when: false failed_when: false check_mode: false @@ -38,15 +67,38 @@ when: amazon2_3_1_2_nmcli_available.rc == 0 - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Disable wifi if enabled" - command: nmcli radio wifi off + ansible.builtin.command: nmcli radio wifi off when: - amazon2_3_2_1_wifi_enabled.stdout is defined - "'enabled' in amazon2_3_2_1_wifi_enabled.stdout" + +- name: "3.1.3 | PATCH | Ensure bluetooth services are not in use" when: - - amazon2cis_rule_3_1_2 + - amazon2cis_rule_3_1_3 tags: - - level1 + - level1-server + - level2-workstation - automated - patch - - rule_3.1.2 - - wireless + - sctp + - NIST800-53R5_CM-7 + - rule_3.1.3 + block: + - name: "3.1.3 | PATCH | Ensure bluetooth services are not in use | pkg" + when: + - not amazon2cis_bluetooth_service + - not amazon2cis_bluetooth_mask + ansible.builtin.package: + name: bluez + state: absent + + - name: "3.1.3 | PATCH | Ensure bluetooth services are not in use | mask" + when: + - not amazon2cis_bluetooth_service + - amazon2cis_bluetooth_mask + notify: Systemd_daemon_reload + ansible.builtin.systemd: + name: bluetooth.service + enabled: false + state: stopped + masked: true diff --git a/tasks/section_3/cis_3.2.x.yml b/tasks/section_3/cis_3.2.x.yml index 7951eab..9699e5f 100644 --- a/tasks/section_3/cis_3.2.x.yml +++ b/tasks/section_3/cis_3.2.x.yml @@ -1,52 +1,118 @@ --- -- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled" - block: - - name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv4" - sysctl: - name: net.ipv4.ip_forward - value: '0' - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv4 route table - - - name: "AUTOMATED | 3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv6" - sysctl: - name: net.ipv6.conf.all.forwarding - value: '0' - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv6 route table - when: amazon2cis_ipv6_required + +- name: "3.2.1 | PATCH | Ensure dccp kernel module is not available" when: - - not amazon2cis_is_router - amazon2cis_rule_3_2_1 - - amazon2cis_ipv6_required tags: - - level1 - - sysctl + - level2-server + - level2-workstation + - automated + - dccp - patch + - NIST800-53R5_CM-7 + - NIST800-53R5_SI-4 - rule_3.2.1 + block: + - name: "3.2.1 | PATCH | Ensure dccp kernel module is not available | CIS" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install dccp(\\s|$)" + line: "install dccp /bin/true" + create: true + mode: '0600' + + - name: "3.2.1 | PATCH | Ensure dccp kernel module is not available | blacklist" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist dccp(\\s|$)" + line: "blacklist dccp" + create: true + mode: '0600' -- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv4 route table - with_items: - - { name: net.ipv4.conf.all.send_redirects, value: 0 } - - { name: net.ipv4.conf.default.send_redirects, value: 0 } +- name: "3.2.2 | PATCH | Ensure tipc kernel module is not available" when: - - not amazon2cis_is_router - amazon2cis_rule_3_2_2 tags: - - level1 + - level2-server + - level2-workstation - automated - patch + - tipc + - NIST800-53R5_CM-7 + - NIST800-53R5_SI-4 - rule_3.2.2 - - sysctl + + block: + - name: "3.2.2 | PATCH | Ensure tipc kernel module is not available | CIS" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install tipc(\\s|$)" + line: "install tipc /bin/true" + create: true + mode: '0600' + + - name: "3.2.2 | PATCH | Ensure tipc kernel module is not available | blacklist" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist tipc(\\s|$)" + line: "blacklist tipc" + create: true + mode: '0600' + +- name: "3.2.3 | PATCH | Ensure rds kernel module is not available" + when: + - amazon2cis_rule_3_2_3 + tags: + - level2-server + - level2-workstation + - automated + - patch + - rds + - NIST800-53R5_CM-7 + - NIST800-53R5_SI-4 + - rule_3.2.3 + block: + - name: "3.2.3 | PATCH | Ensure rds kernel module is not available | CIS" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install rpc(\\s|$)" + line: "install rds /bin/true" + create: true + mode: '0600' + + - name: "3.2.3 | PATCH | Ensure rds kernel module is not available | blacklist" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist rpc(\\s|$)" + line: "blacklist rds" + create: true + mode: '0600' + +- name: "3.2.4 | PATCH | Ensure sctp kernel module is not available" + when: + - amazon2cis_rule_3_2_4 + tags: + - level2-server + - level2-workstation + - automated + - patch + - sctp + - NIST800-53R5_CM-7 + - NIST800-53R5_SI-4 + - rule_3.2.4 + block: + - name: "3.2.4 | PATCH | Ensure sctp kernel module is not available | CIS" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install sctp(\\s|$)" + line: "install sctp /bin/true" + create: true + mode: '0600' + + - name: "3.2.4 | PATCH | Ensure sctp kernel module is not available | blacklist" + ansible.builtin.lineinfile: + path: /etc/modprobe.d/blacklist.conf + regexp: "^(#)?blacklist sctp(\\s|$)" + line: "blacklist sctp" + create: true + mode: '0600' diff --git a/tasks/section_3/cis_3.3.x.yml b/tasks/section_3/cis_3.3.x.yml index dedc137..829802a 100644 --- a/tasks/section_3/cis_3.3.x.yml +++ b/tasks/section_3/cis_3.3.x.yml @@ -1,210 +1,316 @@ --- -- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted" - block: - - name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv4" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv4 route table - with_items: - - { name: net.ipv4.conf.all.accept_source_route, value: 0 } - - { name: net.ipv4.conf.default.accept_source_route, value: 0 } - - name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv6 route table - with_items: - - { name: net.ipv6.conf.all.accept_source_route, value: 0 } - - { name: net.ipv6.conf.default.accept_source_route, value: 0 } +- name: "3.3.1 | PATCH | Ensure IP forwarding is disabled" when: + - not amazon2cis_is_router - amazon2cis_rule_3_3_1 - - amazon2cis_ipv6_required tags: - - level1 + - level1-server + - level1-workstation - automated + - sysctl - patch + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_3.3.1 - - sysctl - -- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted " block: - - name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv4" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true + - name: "3.3.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding" + ansible.posix.sysctl: + name: net.ipv4.ip_forward + value: '0' ignoreerrors: true - notify: sysctl flush ipv4 route table - with_items: - - { name: net.ipv4.conf.all.accept_redirects, value: 0 } - - { name: net.ipv4.conf.default.accept_redirects, value: 0 } + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes - - name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true + - name: "3.3.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding" + when: + - amazon2cis_ipv6_required or + amazon2cis_ipv6_sysctl_force + ansible.posix.sysctl: + name: net.ipv6.conf.all.forwarding + value: '0' ignoreerrors: true - notify: sysctl flush ipv6 route table - with_items: - - { name: net.ipv6.conf.all.accept_redirects, value: 0 } - - { name: net.ipv6.conf.default.accept_redirects, value: 0 } - when: amazon2cis_ipv6_required + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + notify: Sysctl_flush_ipv6_routes + +- name: "3.3.2 | PATCH | Ensure packet redirect sending is disabled" when: + - not amazon2cis_is_router - amazon2cis_rule_3_3_2 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - sysctl + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_3.3.2 - - sysctls - -- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" sysctl_set: true - state: present - reload: true ignoreerrors: true - notify: sysctl flush ipv4 route table - with_items: - - { name: net.ipv4.conf.all.secure_redirects, value: 0 } - - { name: net.ipv4.conf.default.secure_redirects, value: 0 } + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + loop: + - { name: net.ipv4.conf.all.send_redirects, value: 0 } + - { name: net.ipv4.conf.default.send_redirects, value: 0 } + +- name: "3.3.3 | PATCH | Ensure bogus ICMP responses are ignored" when: - amazon2cis_rule_3_3_3 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.3 - sysctl - -- name: "3.3.4 | PATCH | Ensure suspicious packets are logged" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.3 + ansible.posix.sysctl: + name: net.ipv4.icmp_ignore_bogus_error_responses + value: '1' state: present - reload: true ignoreerrors: true - notify: sysctl flush ipv4 route table - with_items: - - { name: net.ipv4.conf.all.log_martians, value: 1 } - - { name: net.ipv4.conf.default.log_martians, value: 1 } + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + +- name: "3.3.4 | PATCH | Ensure broadcast ICMP requests are ignored" when: - amazon2cis_rule_3_3_4 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.4 - sysctl - -- name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored" - sysctl: + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.3 + - rule_3.3.4 + ansible.posix.sysctl: name: net.ipv4.icmp_echo_ignore_broadcasts value: '1' - state: present - reload: true ignoreerrors: true - notify: sysctl flush ipv4 route table + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + +- name: "3.3.5 | PATCH | Ensure ICMP redirects are not accepted" when: - amazon2cis_rule_3_3_5 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.5 - sysctl + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.5 + block: + - name: "3.3.5 | PATCH | Ensure ICMP redirects are not accepted | Set ICMP redirects IPv4" + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + loop: + - { name: net.ipv4.conf.all.accept_redirects, value: 0 } + - { name: net.ipv4.conf.default.accept_redirects, value: 0 } -- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored" - sysctl: - name: net.ipv4.icmp_ignore_bogus_error_responses - value: '1' - state: present - reload: true - ignoreerrors: true - notify: sysctl flush ipv4 route table + - name: "3.3.5 | PATCH | Ensure ICMP redirects are not accepted | Set ICMP redirects IPv6" + when: amazon2cis_ipv6_required or amazon2cis_ipv6_sysctl_force + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + notify: Sysctl_flush_ipv6_routes + loop: + - { name: net.ipv6.conf.all.accept_redirects, value: 0 } + - { name: net.ipv6.conf.default.accept_redirects, value: 0 } + +- name: "3.3.6 | PATCH | Ensure secure ICMP redirects are not accepted" when: - amazon2cis_rule_3_3_6 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.6 - sysctl - -- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.6 + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" sysctl_set: true - state: present - reload: true ignoreerrors: true - with_items: - - { name: net.ipv4.conf.all.rp_filter, value: 1 } - - { name: net.ipv4.conf.default.rp_filter, value: 1 } - notify: sysctl flush ipv4 route table + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + loop: + - { name: net.ipv4.conf.all.secure_redirects, value: 0 } + - { name: net.ipv4.conf.default.secure_redirects, value: 0 } + +- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled" when: - amazon2cis_rule_3_3_7 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.7 - sysctl - -- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled" - sysctl: - name: net.ipv4.tcp_syncookies + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.7 + ansible.posix.sysctl: + name: "{{ item }}" value: '1' - state: present - reload: true + sysctl_set: true ignoreerrors: true - notify: sysctl flush ipv4 route table + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + loop: + - net.ipv4.conf.all.rp_filter + - net.ipv4.conf.default.rp_filter + notify: Sysctl_flush_ipv4_routes + +- name: "3.3.8 | PATCH | Ensure source routed packets are not accepted" when: - amazon2cis_rule_3_3_8 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - sysctl + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_3.3.8 + block: + - name: "3.3.8 | PATCH | Ensure source routed packets are not accepted | Set routed packets IPv4" + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + loop: + - { name: net.ipv4.conf.all.accept_source_route, value: 0 } + - { name: net.ipv4.conf.default.accept_source_route, value: 0 } + + - name: "3.3.8 | PATCH | Ensure source routed packets are not accepted | Set routed packets IPv6" + when: amazon2cis_ipv6_required or amazon2cis_ipv6_sysctl_force + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + notify: Sysctl_flush_ipv6_routes + loop: + - { name: net.ipv6.conf.all.accept_source_route, value: 0} + - { name: net.ipv6.conf.default.accept_source_route, value: 0 } + +- name: "3.3.9 | PATCH | Ensure suspicious packets are logged" + when: + - amazon2cis_rule_3_3_9 + tags: + - level1-server + - level1-workstation + - automated + - patch - sysctl + - NIST800-53R5_AU-3 + - rule_3.3.9 + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + loop: + - { name: net.ipv4.conf.all.log_martians, value: 1 } + - { name: net.ipv4.conf.default.log_martians, value: 1 } -- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted" - sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' +- name: "3.3.10 | PATCH | Ensure TCP SYN Cookies is enabled" + when: + - amazon2cis_rule_3_3_10 + tags: + - level1-server + - level1-workstation + - automated + - patch + - sysctl + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.10 + ansible.posix.sysctl: + name: net.ipv4.tcp_syncookies + value: '1' sysctl_set: true - state: present - reload: true ignoreerrors: true - with_items: - - { name: net.ipv6.conf.all.accept_ra, value: 0 } - - { name: net.ipv6.conf.default.accept_ra, value: 0 } - notify: sysctl flush ipv6 route table + sysctl_file: "{{ amazon2cis_ipv4_sysctl_file }}" + notify: Sysctl_flush_ipv4_routes + +- name: "3.3.11 | PATCH | Ensure IPv6 router advertisements are not accepted" when: - - amazon2cis_ipv6_required - - amazon2cis_rule_3_3_9 + - amazon2cis_ipv6_required or amazon2cis_ipv6_sysctl_force + - amazon2cis_rule_3_3_11 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_3.3.9 - sysctl + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_3.3.11 + ansible.posix.sysctl: + name: "{{ item.name }}" + value: "{{ item.value }}" + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ amazon2cis_ipv6_sysctl_file }}" + notify: Sysctl_flush_ipv6_routes + loop: + - { name: net.ipv6.conf.all.accept_ra, value: 0 } + - { name: net.ipv6.conf.default.accept_ra, value: 0 } diff --git a/tasks/section_3/cis_3.4.1.x.yml b/tasks/section_3/cis_3.4.1.x.yml new file mode 100644 index 0000000..80ed970 --- /dev/null +++ b/tasks/section_3/cis_3.4.1.x.yml @@ -0,0 +1,132 @@ +--- + +- name: "3.4.1.1 | PATCH | Ensure iptables is installed" + when: + - amazon2cis_rule_3_4_1_1 + - "'iptables' not in ansible_facts.packages" + tags: + - level1-server + - level1-workstation + - patch + - iptables + - NIST800-53R5_CA-9 + - rule_3.4.1.1 + ansible.builtin.package: + name: + - iptables + state: present + +- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use" + when: + - amazon2cis_rule_3_4_1_2 + tags: + - level1-server + - level1-workstation + - patch + - firewalld + - iptables + - rule_3.4.1.2 + block: + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | firewalld" + when: + - amazon2cis_system_firewall == "firewalld" + - amazon2cis_iptables == "mask" + ansible.builtin.systemd: + name: "{{ item }}" + masked: true + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + loop: + - iptables-services + - ip6tables-services + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | firewalld" + when: + - amazon2cis_system_firewall == "firewalld" + - amazon2cis_nftables == "mask" + ansible.builtin.systemd: + name: nftables + masked: true + enabled: "{{ ('nftables' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('nftables' in ansible_facts.packages) | ternary('stopped', omit) }}" + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | iptables" + when: + - amazon2cis_system_firewall == "iptables" + - amazon2cis_nftables == "mask" + ansible.builtin.systemd: + name: nftables + masked: true + enabled: "{{ ('nftables' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('nftables' in ansible_facts.packages) | ternary('stopped', omit) }}" + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | iptables" + when: + - amazon2cis_system_firewall == "iptables" + - amazon2cis_firewalld == "mask" + ansible.builtin.systemd: + name: firewalld + masked: true + enabled: "{{ ('firewalld' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('firewalld' in ansible_facts.packages) | ternary('stopped', omit) }}" + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables" + when: + - amazon2cis_system_firewall == "nftables" + - amazon2cis_iptables == "mask" + ansible.builtin.systemd: + name: "{{ item }}" + masked: true + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" + loop: + - iptables-services + - ip6tables-services + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables" + when: + - amazon2cis_system_firewall == "nftables" + - amazon2cis_firewalld == "mask" + ansible.builtin.systemd: + name: firewalld + masked: true + enabled: "{{ ('firewalld' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('firewalld' in ansible_facts.packages) | ternary('stopped', omit) }}" + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_system_firewall }} package installed" + when: "amazon2cis_system_firewall not in ansible_facts.packages" + ansible.builtin.package: + name: "{{ amazon2cis_system_firewall }}" + state: present + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_system_firewall }} started and enabled" + ansible.builtin.systemd: + name: "{{ amazon2cis_system_firewall }}" + enabled: true + state: started + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | remove nftables" + when: + - amazon2cis_system_firewall != "nftables" + - amazon2cis_nftables == "remove" + ansible.builtin.package: + name: nftables + state: absent + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | remove iptables" + when: + - amazon2cis_system_firewall != "iptables" + - amazon2cis_iptables == "remove" + ansible.builtin.package: + name: + - iptables-services + - ip6tables-services + state: absent + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | remove firewalld" + when: + - amazon2cis_system_firewall != "firewalld" + - amazon2cis_firewalld == "remove" + ansible.builtin.package: + name: firewalld + state: absent diff --git a/tasks/section_3/cis_3.4.2.x.yml b/tasks/section_3/cis_3.4.2.x.yml new file mode 100644 index 0000000..21c1c5d --- /dev/null +++ b/tasks/section_3/cis_3.4.2.x.yml @@ -0,0 +1,94 @@ +--- + +- name: "3.4.2.1 | PATCH | Ensure FirewallD is installed" + when: + - amazon2cis_rule_3_4_2_1 + tags: + - level1 + - automated + - patch + - rule_3.4.2.1 + - firewall + - firewalld + - NIST800-53R5_CA-9 + ansible.builtin.package: + name: firewalld + state: present + vars: + ansible_python_interpreter: /bin/python + +- name: "3.4.2.2 | PATCH | Ensure firewalld service is enabled and running" + when: + - amazon2cis_rule_3_4_2_2 + tags: + - level1 + - automated + - patch + - rule_3.4.2.2 + - firewall + - firewalld + - NIST800-53R5_CA-9 + ansible.builtin.systemd: + name: firewalld + state: started + enabled: true + +- name: "3.4.2.3 | AUDIT | Ensure firewalld drops unnecessary services and ports" + when: + - amazon2cis_rule_3_4_2_3 + tags: + - level1 + - manual + - audit + - rule_3.4.2.3 + - firewall + - NIST800-53R5_CA-9 + block: + - name: "3.4.2.3 | AUDIT | Ensure unnecessary services and ports are not accepted | Get list of services and ports" + ansible.builtin.shell: "firewall-cmd --get-active-zones | awk '!/:/ {print $1}' | while read ZN; do firewall-cmd --list-all --zone=$ZN; done" + changed_when: false + failed_when: false + register: amazon2cis_3_4_2_3_services_ports + + - name: "3.4.2.3 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports" + ansible.builtin.debug: + msg: + - "The items below are the services and ports that are accepted, please correct as needed" + - "{{ amazon2cis_3_4_2_3_services_ports.stdout_lines }}" + + - name: "3.4.2.3 | AUDIT | Ensure firewalld drops unnecessary services and ports | Warn Count" + when: amazon2cis_3_4_2_3_services_ports.stdout | length > 0 + vars: + warn_control_id: '3.4.2.3' + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "3.4.2.4 | AUDIT | Ensure network interfaces are assigned to appropriate zone" + when: + - amazon2cis_rule_3_4_2_4 + tags: + - level1 + - manual + - audit + - rule_3.4.2.4 + - firewall + - NIST800-53R5_CA-9 + block: + - name: "3.4.2.4 | AUDIT | Ensure network interfaces are assigned to appropriate zone | capture output" + ansible.builtin.shell: find /sys/class/net/* -maxdepth 1 | awk -F"/" '{print $NF}' | while read -r netint; do [ "$netint" != "lo" ] && firewall-cmd --get-active-zones | grep -B1 $netint; done + changed_when: false + failed_when: false + register: amazon2cis_3_4_2_4_nics_and_zones + + - name: "3.4.2.4 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Show nics and zones" + ansible.builtin.debug: + msg: + - "The items below are the system network interfaces and associated firewalld zones, please correct as needed" + - "{{ amazon2cis_3_4_2_4_nics_and_zones.stdout_lines }}" + + - name: "3.4.2.4 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Warn Count" + when: amazon2cis_3_4_2_4_nics_and_zones.stdout | length > 0 + vars: + warn_control_id: '3.4.2.4' + ansible.builtin.import_tasks: + file: warning_facts.yml diff --git a/tasks/section_3/cis_3.4.3.x.yml b/tasks/section_3/cis_3.4.3.x.yml new file mode 100644 index 0000000..14ee998 --- /dev/null +++ b/tasks/section_3/cis_3.4.3.x.yml @@ -0,0 +1,334 @@ +--- + +- name: "3.4.3.1 | PATCH | Ensure nftables is installed" + when: + - amazon2cis_rule_3_4_3_1 + tags: + - level1 + - automated + - patch + - rule_3.4.3.1 + - firewall + - nftables + - NIST800-53R5_CA-9 + vars: + ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: nftables + state: present + +- name: "3.4.3.2 | PATCH | Ensure iptables are flushed" + when: + - "'iptables' in ansible_facts.packages" + - amazon2cis_firewall != "iptables" + - amazon2cis_rule_3_4_3_2 + tags: + - level1 + - manual + - patch + - rule_3.4.3.2 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.2 | PATCH | Ensure iptables are flushed | Flush IPv4 tables" + ansible.builtin.command: iptables -F + + - name: "3.4.3.2 | PATCH | Ensure iptables are flushed | Flush IPv6 tables" + ansible.builtin.command: ip6tables -F + when: + - amazon2cis_ipv6_required + +- name: "3.4.3.3 | PATCH | Ensure an nftables table exists" + when: + - amazon2cis_rule_3_4_3_3 + tags: + - level1 + - automated + - patch + - rule_3.4.3.3 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.3 | AUDIT | Ensure an nftables table exists | Check for tables" + ansible.builtin.command: nft list tables + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_3_nft_tables + + - name: "3.4.3.3 | AUDIT | Ensure an nftables table exists | Show existing tables" + when: + - amazon2cis_3_4_3_3_nft_tables.stdout | length > 0 + ansible.builtin.debug: + msg: + - "Below are the current nft tables, please review" + - "{{ amazon2cis_3_4_3_3_nft_tables.stdout_lines }}" + + - name: "3.4.3.3 | AUDIT | Ensure an nftables table exists | Alert on no tables" + when: + - amazon2cis_3_4_3_3_nft_tables.stdout | length == 0 + - not amazon2cis_nft_tables_autoNewTable + ansible.builtin.debug: + msg: + - "Warning! You currently have no nft tables, please review your setup" + - 'Use the command "nft create table inet " to create a new table' + + - name: "3.4.3.3 | WARN | Ensure an nftables table exists | Warn Count" + when: not amazon2cis_nft_tables_autoNewTable + vars: + warn_control_id: '3.4.3.3' + ansible.builtin.import_tasks: + file: warning_facts.yml + + - name: "3.4.3.3 | PATCH | Ensure an nftables table exists | Create table if needed" + ansible.builtin.command: nft create table inet "{{ amazon2cis_nft_tables_tablename }}" + failed_when: false + when: + - amazon2cis_nft_tables_autoNewTable + +- name: "3.4.3.4 | PATCH | Ensure nftables base chains exist" + when: + - amazon2cis_rule_3_4_3_4 + tags: + - level1 + - automated + - patch + - rule_3.4.3.4 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.4 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT" + ansible.builtin.shell: nft list ruleset | grep 'hook input' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_4_input_chains + + - name: "3.4.3.4 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD" + ansible.builtin.shell: nft list ruleset | grep 'hook forward' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_4_forward_chains + + - name: "3.4.3.4 | AUDIT | Ensure nftables base chains exist | Get current chains for OUTPUT" + ansible.builtin.shell: nft list ruleset | grep 'hook output' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_4_output_chains + + - name: "3.4.3.4 | AUDIT | Ensure nftables base chains exist | Display chains for review" + when: + - not amazon2cis_nft_tables_autochaincreate + ansible.builtin.debug: + msg: + - "Below are the current INPUT chains" + - "{{ amazon2cis_3_4_3_4_input_chains.stdout_lines }}" + - "Below are the current FORWARD chains" + - "{{ amazon2cis_3_4_3_4_forward_chains.stdout_lines }}" + - "Below are teh current OUTPUT chains" + - "{{ amazon2cis_3_4_3_4_output_chains.stdout_lines }}" + + - name: "3.4.3.3 | WARN | Ensure nftables base chains exist | Warn Count" + when: not amazon2cis_nft_tables_autochaincreate + vars: + warn_control_id: '3.4.3.4' + ansible.builtin.import_tasks: + file: warning_facts.yml + + - name: "3.4.3.4 | PATCH | Ensure nftables base chains exist | Create chains if needed" + when: + - amazon2cis_nft_tables_autochaincreate + ansible.builtin.command: "{{ item }}" + failed_when: false + with_items: + - nft create chain inet "{{ amazon2cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; } + - nft create chain inet "{{ amazon2cis_nft_tables_tablename }}" forward { type filter hook forward priority 0 \; } + - nft create chain inet "{{ amazon2cis_nft_tables_tablename }}" output { type filter hook output priority 0 \; } + +- name: "3.4.3.5 | PATCH | Ensure nftables loopback traffic is configured" + when: + - amazon2cis_rule_3.4.3.5 + tags: + - level1 + - automated + - patch + - rule_3.4.3.5 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.5 | AUDIT | Ensure nftables loopback traffic is configured | Gather iif lo accept existence" + ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_5_iiflo + + - name: "3.4.3.5 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip saddr existence" + ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_5_ipsaddr + + - name: "3.4.3.5 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip6 saddr existence" + ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_2_ip6saddr + + - name: "3.4.3.5 | PATCH | Ensure nftables loopback traffic is configured | Set iif lo accept rule" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input iif lo accept + when: + - '"iif \"lo\" accept" not in amazon2cis_3_4_3_5_iiflo.stdout' + + - name: "3.4.3.5 | PATCH | Ensure nftables loopback traffic is configured | Set ip sddr rule" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input ip saddr 127.0.0.0/8 counter drop + when: + - '"ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop" not in amazon2cis_3_4_3_5_ipsaddr.stdout' + + - name: "3.4.3.5 | PATCH | Ensure nftables loopback traffic is configured | Set ip6 saddr rule" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input ip6 saddr ::1 counter drop + when: + - '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in amazon2cis_3_4_3_5_ip6saddr.stdout' + +- name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured" + when: + - amazon2cis_rule_3_4_3_6 + tags: + - level1 + - manual + - patch + - rule_3.4.3.6 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.6 | AUDIT | Ensure nftables outbound and established connections are configured | Gather incoming connection rules" + ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_6_inconnectionrule + + - name: "3.4.3.6 | AUDIT | Ensure nftables outbound and established connections are configured | Gather outbound connection rules" + ansible.builtin.shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + changed_when: false + failed_when: false + register: amazon2cis_3_4_3_6_outconnectionrule + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add input tcp established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input ip protocol tcp ct state established accept + when: + - '"ip protocol tcp ct state established accept" not in amazon2cis_3_4_3_6_inconnectionrule.stdout' + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add input udp established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input ip protocol udp ct state established accept + when: + - '"ip protocol udp ct state established accept" not in amazon2cis_3_4_3_6_inconnectionrule.stdout' + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add input icmp established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input ip protocol icmp ct state established accept + when: + - '"ip protocol icmp ct state established accept" not in amazon2cis_3_4_3_6_inconnectionrule.stdout' + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add output tcp new, related, established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" output ip protocol tcp ct state new,related,established accept + when: + - '"ip protocol tcp ct state established,related,new accept" not in amazon2cis_3_4_3_6_outconnectionrule.stdout' + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add output udp new, related, established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" output ip protocol udp ct state new,related,established accept + when: + - '"ip protocol udp ct state established,related,new accept" not in amazon2cis_3_4_3_6_outconnectionrule.stdout' + + - name: "3.4.3.6 | PATCH | Ensure nftables outbound and established connections are configured | Add output icmp new, related, established accpet policy" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" output ip protocol icmp ct state new,related,established accept + when: + - '"ip protocol icmp ct state established,related,new accept" not in amazon2cis_3_4_3_6_outconnectionrule.stdout' + +- name: "3.4.3.7 | PATCH | Ensure nftables default deny firewall policy" + when: + - amazon2cis_rule_3_4_3_7 + tags: + - level1 + - manual + - patch + - rule_3.4.3.7 + - firewall + - nftables + - NIST800-53R5_CA-9 + block: + - name: "3.4.3.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook input deny policy" + ansible.builtin.shell: nft list table inet "{{ amazon2cis_nft_tables_tablename }}" | grep 'hook input' + failed_when: false + changed_when: false + register: amazon2cis_3_4_3_7_inputpolicy + + - name: "3.4.3.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook forward deny policy" + ansible.builtin.shell: nft list table inet "{{ amazon2cis_nft_tables_tablename }}" | grep 'hook forward' + failed_when: false + changed_when: false + register: amazon2cis_3_4_3_7_forwardpolicy + + - name: "3.4.3.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook output deny policy" + ansible.builtin.shell: nft list table inet "{{ amazon2cis_nft_tables_tablename }}" | grep 'hook output' + failed_when: false + changed_when: false + register: amazon2cis_3_4_3_7_outputpolicy + + - name: "3.4.3.7 | AUDIT | Ensure nftables default deny firewall policy | Check for SSH allow" + ansible.builtin.shell: nft list table inet "{{ amazon2cis_nft_tables_tablename }}" | grep 'ssh' + failed_when: false + changed_when: false + register: amazon2cis_3_4_3_7_sshallowcheck + + - name: "3.4.3.7 | PATCH | Ensure nftables default deny firewall policy | Enable SSH traffic" + ansible.builtin.command: nft add rule inet "{{ amazon2cis_nft_tables_tablename }}" input tcp dport ssh accept + when: + - '"tcp dport ssh accept" not in amazon2cis_3_4_3_7_sshallowcheck.stdout' + + - name: "3.4.3.7 | PATCH | Ensure nftables default deny firewall policy | Set hook input deny policy" + ansible.builtin.command: nft chain inet "{{ amazon2cis_nft_tables_tablename }}" input { policy drop \; } + when: + - '"type filter hook input priority 0; policy drop;" not in amazon2cis_3_4_3_7_inputpolicy.stdout' + + - name: "3.4.3.7 | PATCH | Ensure nftables default deny firewall policy | Create hook forward deny policy" + ansible.builtin.command: nft chain inet "{{ amazon2cis_nft_tables_tablename }}" forward { policy drop \; } + when: + - '"type filter hook forward priority 0; policy drop;" not in amazon2cis_3_4_3_7_forwardpolicy.stdout' + + - name: "3.4.3.7 | PATCH | Ensure nftables default deny firewall policy | Create hook output deny policy" + ansible.builtin.command: nft chain inet "{{ amazon2cis_nft_tables_tablename }}" output { policy drop \; } + when: + - '"type filter hook output priority 0; policy drop;" not in amazon2cis_3_4_3_7_outputpolicy.stdout' + +- name: "3.4.3.8 | PATCH | Ensure nftables service is enabled and active" + when: + - amazon2cis_rule_3_4_3_8 + tags: + - level1 + - automated + - patch + - rule_3.4.3.8 + - firewall + - nftables + - NIST800-53R5_CA-9 + ansible.builtin.systemd: + name: nftables + enabled: true + state: started + +- name: "3.4.3.9 | PATCH | Ensure nftables rules are permanent" + ansible.builtin.lineinfile: + path: /etc/sysconfig/nftables.conf + state: present + insertafter: EOF + line: include "/etc/nftables/inet-{{ amazon2cis_nft_tables_tablename }}.rules" + when: + - amazon2cis_rule_3_4_3_9 + tags: + - level1 + - automated + - patch + - rule_3.4.3.9 + - firewall + - nftables diff --git a/tasks/section_3/cis_3.4.4.1.x.yml b/tasks/section_3/cis_3.4.4.1.x.yml new file mode 100644 index 0000000..dd84408 --- /dev/null +++ b/tasks/section_3/cis_3.4.4.1.x.yml @@ -0,0 +1,21 @@ +--- + +- name: "3.4.4.1.1 | PATCH | Ensure iptables packages are installed" + when: + - amazon2cis_rule_3_4_4_1_1 + tags: + - level1 + - automated + - patch + - rule_3.4.4.1.1 + - firewall + - iptables + - NIST800-53R5_CA-9 + vars: + ansible_python_interpreter: /bin/python + ansible.builtin.package: + name: "{{ item }}" + state: present + with_items: + - iptables + - iptables-services diff --git a/tasks/section_3/cis_3.4.4.2.x.yml b/tasks/section_3/cis_3.4.4.2.x.yml new file mode 100644 index 0000000..2fdb856 --- /dev/null +++ b/tasks/section_3/cis_3.4.4.2.x.yml @@ -0,0 +1,179 @@ +--- + +- name: "3.4.4.2.1 | PATCH | Ensure iptables loopback traffic is configured" + when: + - amazon2cis_rule_3_4_4_2_1 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.2.1 + - iptables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.2.1 | PATCH | Ensure iptables loopback traffic is configured | INPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: INPUT + in_interface: lo + jump: ACCEPT + + - name: "3.4.4.2.1 | PATCH | Ensure iptables loopback traffic is configured | OUTPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: OUTPUT + out_interface: lo + jump: ACCEPT + + - name: "3.4.4.2.1 | PATCH | Ensure iptables loopback traffic is configured | OUTPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: INPUT + source: 127.0.0.0/8 + jump: DROP + +- name: "3.4.4.2.2 | PATCH | Ensure iptables outbound and established connections are configured" + when: + - amazon2cis_rule_3_4_4_2_2 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.2.2 + - iptables + - NIST800-53R5_CA-9 + ansible.builtin.iptables: + action: append + chain: '{{ item.chain }}' + protocol: '{{ item.protocol }}' + match: state + ctstate: '{{ item.ctstate }}' + jump: ACCEPT + with_items: + - { chain: OUTPUT, protocol: tcp, ctstate: 'NEW,ESTABLISHED' } + - { chain: OUTPUT, protocol: udp, ctstate: 'NEW,ESTABLISHED' } + - { chain: OUTPUT, protocol: icmp, ctstate: 'NEW,ESTABLISHED' } + - { chain: INPUT, protocol: tcp, ctstate: 'ESTABLISHED' } + - { chain: INPUT, protocol: udp, ctstate: 'ESTABLISHED' } + - { chain: INPUT, protocol: icmp, ctstate: 'ESTABLISHED' } + +- name: "3.4.4.2.3 | AUDIT | Ensure iptables firewall rules exist for all open ports" + when: + - amazon2cis_rule_3_4_4_2_3 + tags: + - level1-server + - level1-workstation + - audit + - rule_3.4.4.2.3 + - iptables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.2.3 | AUDIT | Ensure iptables firewall rules exist for all open ports | Get list of open ports" + ansible.builtin.command: ss -4tuln + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_3_4_4_2_3_open_ports + + - name: "3.4.4.2.3 | AUDIT | Ensure iptables firewall rules exist for all open ports | Get list of rules" + ansible.builtin.command: iptables -L INPUT -v -n + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_3_4_4_2_3_current_rules + + - name: "3.4.4.2.3 | AUDIT | Ensure iptables firewall rules exist for all open ports | Alert about settings" + ansible.builtin.debug: + msg: + - "ALERT!!!!Below is the list the open ports and current rules" + - "Please create a rule for any open port that does not have a current rule" + - "Open Ports:" + - "{{ amazon2cis_3_4_4_2_3_open_ports.stdout_lines }}" + - "Current Rules:" + - "{{ amazon2cis_3_4_4_2_3_current_rules.stdout_lines }}" + + - name: "3.4.4.2.3 | WARN | Ensure iptables firewall rules exist for all open ports | Warn Count" + vars: + warn_control_id: '3.4.4.2.3' + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "3.4.4.2.4 | PATCH | Ensure iptables default deny firewall policy" + when: + - amazon2cis_rule_3_4_4_2_4 + - not system_is_ec2 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.2.4 + - iptables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.2.4 | PATCH | Ensure iptables default deny firewall policy | Configure SSH to be allowed in" + ansible.builtin.iptables: + chain: INPUT + protocol: tcp + destination_port: 22 + jump: ACCEPT + ctstate: 'NEW,ESTABLISHED' + + - name: "3.4.4.2.4 | PATCH | Ensure iptables default deny firewall policy | Configure SSH to be allowed out" + ansible.builtin.iptables: + chain: OUTPUT + protocol: tcp + source_port: 22 + jump: ACCEPT + ctstate: 'NEW,ESTABLISHED' + + - name: "3.4.4.2.4 | PATCH | Ensure iptables default deny firewall policy | Enable apt traffic" + ansible.builtin.iptables: + chain: INPUT + ctstate: 'ESTABLISHED' + jump: ACCEPT + + - name: "3.4.4.2.4 | PATCH | Ensure iptables default deny firewall policy | Set drop items" + ansible.builtin.iptables: + policy: DROP + chain: "{{ item }}" + with_items: + - INPUT + - FORWARD + - OUTPUT + +- name: "3.4.4.2.5 | Ensure iptables rules are saved" + when: + - amazon2cis_save_iptables_cis_rules + - amazon2cis_rule_3_4_4_2_1 or + amazon2cis_rule_3_4_4_2_2 or + amazon2cis_rule_3_4_4_2_3 or + amazon2cis_rule_3_4_4_2_4 or + amazon2cis_rule_3_4_4_2_5 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.2.5 + - iptables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.2.5 | Ensure iptables rules are saved " + ansible.builtin.shell: service iptables save + changed_when: amazon2cis_iptables_save.rc == 0 + failed_when: amazon2cis_iptables_save.rc != 0 + register: amazon2cis_iptables_save + +- name: "3.4.4.2.6 | Ensure iptables service is enabled and running" + when: + - amazon2cis_rule_3_4_4_2_6 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.2.6 + - iptables + - NIST800-53R5_CA-9 + ansible.builtin.service: + name: iptables + state: started + enabled: true diff --git a/tasks/section_3/cis_3.4.4.3.x.yml b/tasks/section_3/cis_3.4.4.3.x.yml new file mode 100644 index 0000000..d73081b --- /dev/null +++ b/tasks/section_3/cis_3.4.4.3.x.yml @@ -0,0 +1,193 @@ +--- + +- name: "3.4.4.3.1 | PATCH | Ensure ip6tables loopback traffic is configured" + when: + - amazon2cis_rule_3_4_4_3_1 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.3.1 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | INPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: INPUT + in_interface: lo + jump: ACCEPT + ip_version: ipv6 + + - name: "3.4.4.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | OUTPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: OUTPUT + out_interface: lo + jump: ACCEPT + ip_version: ipv6 + + - name: "3.4.4.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | OUTPUT loopback ACCEPT" + ansible.builtin.iptables: + action: append + chain: INPUT + source: ::1 + jump: DROP + ip_version: ipv6 + +- name: "3.4.4.3.2 | PATCH | Ensure ip6tables outbound and established connections are configured" + when: + - amazon2cis_rule_3_4_4_3_2 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.3.2 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + ansible.builtin.iptables: + action: append + chain: '{{ item.chain }}' + protocol: '{{ item.protocol }}' + match: state + ctstate: '{{ item.ctstate }}' + jump: ACCEPT + ip_version: ipv6 + with_items: + - { chain: OUTPUT, protocol: tcp, ctstate: 'NEW,ESTABLISHED' } + - { chain: OUTPUT, protocol: udp, ctstate: 'NEW,ESTABLISHED' } + - { chain: OUTPUT, protocol: icmp, ctstate: 'NEW,ESTABLISHED' } + - { chain: INPUT, protocol: tcp, ctstate: 'ESTABLISHED' } + - { chain: INPUT, protocol: udp, ctstate: 'ESTABLISHED' } + - { chain: INPUT, protocol: icmp, ctstate: 'ESTABLISHED' } + +- name: "3.4.4.3.3 | AUDIT | Ensure ip6tables firewall rules exist for all open ports" + when: + - amazon2cis_rule_3_4_4_3_3 + tags: + - level1-server + - level1-workstation + - audit + - rule_3.4.4.3.3 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.3.3 | AUDIT | Ensure ip6tables firewall rules exist for all open ports | Get list of open ports" + ansible.builtin.command: ss -6tuln + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_3_4_4_3_3_open_ports + + - name: "3.4.4.3.3 | AUDIT | Ensure ip6tables firewall rules exist for all open ports | Get list of rules" + ansible.builtin.command: ip6tables -L INPUT -v -n + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_3_4_4_3_3_current_rules + + - name: "3.4.4.3.3 | AUDIT | Ensure ip6tables firewall rules exist for all open ports | Alert about settings" + ansible.builtin.debug: + msg: + - "Warning!! Below is the list the open ports and current rules" + - "Please create a rule for any open port that does not have a current rule" + - "Open Ports:" + - "{{ amazon2cis_3_4_4_3_3_open_ports.stdout_lines }}" + - "Current Rules:" + - "{{ amazon2cis_3_4_4_3_3_current_rules.stdout_lines }}" + + - name: "3.4.4.3.3 | WARN | Ensure ip6tables firewall rules exist for all open ports | Warn Count" + vars: + warn_control_id: '3.4.4.3.3' + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "3.4.4.3.4 | PATCH | Ensure ip6tables default deny firewall policy" + when: + - amazon2cis_rule_3_4_4_3_4 + - not system_is_ec2 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.3.4 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Configure SSH to be allowed in" + ansible.builtin.iptables: + chain: INPUT + protocol: tcp + destination_port: 22 + jump: ACCEPT + ctstate: 'NEW,ESTABLISHED' + ip_version: ipv6 + + - name: "3.4.4.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Configure SSH to be allowed out" + ansible.builtin.iptables: + chain: OUTPUT + protocol: tcp + source_port: 22 + jump: ACCEPT + ctstate: 'NEW,ESTABLISHED' + ip_version: ipv6 + + - name: "3.4.4.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Enable apt traffic" + ansible.builtin.iptables: + chain: INPUT + ctstate: 'ESTABLISHED' + jump: ACCEPT + ip_version: ipv6 + + - name: "3.4.4.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Set drop items" + ansible.builtin.iptables: + policy: DROP + chain: "{{ item }}" + ip_version: ipv6 + with_items: + - INPUT + - FORWARD + - OUTPUT + +- name: "3.4.4.3.5 | Ensure ip6tables rules are saved" + when: + - amazon2cis_save_ip6tables_cis_rules + - amazon2cis_rule_3_4_4_3_1 or + amazon2cis_rule_3_4_4_3_2 or + amazon2cis_rule_3_4_4_3_3 or + amazon2cis_rule_3_4_4_3_4 or + amazon2cis_rule_3_4_4_3_5 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.3.5 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + block: + - name: "3.4.4.3.5 | Ensure ip6tables rules are saved " + ansible.builtin.shell: service ip6tables save + changed_when: amazon2cis_ip6tables_save.rc == 0 + failed_when: amazon2cis_ip6tables_save.rc != 0 + register: amazon2cis_ip6tables_save + +- name: "3.4.4.3.6 | Ensure ip6tables is enabled and running" + when: + - amazon2cis_rule_3_4_4_3_6 + tags: + - level1-server + - level1-workstation + - patch + - rule_3.4.4.3.6 + - iptables + - ip6tables + - NIST800-53R5_CA-9 + ansible.builtin.service: + name: ip6tables + state: started + enabled: true diff --git a/tasks/section_3/cis_3.4.x.yml b/tasks/section_3/cis_3.4.x.yml deleted file mode 100644 index b691e56..0000000 --- a/tasks/section_3/cis_3.4.x.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- - -- name: "3.4.1 | PATCH | Ensure DCCP is disabled" - lineinfile: - dest: /etc/modprobe.d/CIS.conf - regexp: "^(#)?install dccp(\\s|$)" - line: "install dccp /bin/true" - create: true - owner: root - group: root - mode: 0600 - when: - - amazon2cis_rule_3_4_1 - tags: - - level2 - - automated - - patch - - rule_3.4.1 - - dccp - -- name: "3.4.2 | PATCH | Ensure SCTP is disabled" - lineinfile: - dest: /etc/modprobe.d/CIS.conf - regexp: "^(#)?install sctp(\\s|$)" - line: "install sctp /bin/true" - create: true - owner: root - group: root - mode: 0600 - when: - - amazon2cis_rule_3_4_2 - tags: - - level2 - - automated - - patch - - rule_3.4.2 - - sctp diff --git a/tasks/section_3/cis_3.5.1.x.yml b/tasks/section_3/cis_3.5.1.x.yml deleted file mode 100644 index 8662ad7..0000000 --- a/tasks/section_3/cis_3.5.1.x.yml +++ /dev/null @@ -1,128 +0,0 @@ ---- - -- name: "3.5.1.1 | PATCH | Ensure FirewallD is installed" - package: - name: firewalld - state: present - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_1_1 - tags: - - level1 - - automated - - patch - - rule_3.5.1.1 - - firewall - - firewalld - -- name: "3.5.1.2 | PATCH | Ensure iptables-services not installed with firewalld" - package: - name: iptables-services - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_1_2 - tags: - - level1 - - automated - - patch - - rule_3.5.1.2 - - firewall - - firewalld - -- name: "3.5.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld " - package: - name: nftables - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_1_3 - tags: - - level1 - - automated - - patch - - rule_3.5.1.3 - - firewall - - firewalld - -- name: "3.5.1.4 | PATCH | Ensure firewalld service is enabled and running" - systemd: - name: firewalld - state: started - enabled: true - when: - - amazon2cis_rule_3_5_1_4 - tags: - - level1 - - automated - - patch - - rule_3.5.1.4 - - firewall - - firewalld - -- name: "3.5.1.5 | PATCH | Ensure default zone is set" - block: - - name: "3.5.1.5 | AUDIT | Ensure default zone is set" - command: firewall-cmd --get-default-zone - changed_when: false - register: amazon2cis_3_5_1_5_current_default_zone - - - name: "3.5.1.5 | PATCH | Ensure default zone is set" - command: firewall-cmd --set-default-zone="{{ amazon2cis_default_zone }}" - when: - - amazon2cis_3_5_1_5_current_default_zone.stdout != amazon2cis_default_zone - when: - - amazon2cis_rule_3_5_1_5 - tags: - - level1 - - automated - - patch - - rule_3.5.1.5 - - firewall - -- name: "3.5.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone" - block: - - name: "3.5.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and policies" - shell: "nmcli -t connection show | awk -F: '{ if($4){print $4} }' | while read INT; do firewall-cmd --get-active-zones | grep -B1 $INT; done" - changed_when: false - failed_when: false - register: amazon2cis_3_5_1_6_interfacepolicy - - - name: "3.5.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and policies | Show the interface to policy" - debug: - msg: - - "The items below are the policies tied to the interfaces, please correct as needed" - - "{{ amazon2cis_3_5_1_6_interfacepolicy.stdout_lines }}" - when: - - amazon2cis_rule_3_5_1_6 - tags: - - level1 - - manual - - audit - - rule_3.5.1.6 - - firewall - -- name: "3.5.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports" - block: - - name: "3.5.1.7 | AUDIT | Ensure unnecessary services and ports are not accepted | Get list of services and ports" - shell: "firewall-cmd --get-active-zones | awk '!/:/ {print $1}' | while read ZN; do firewall-cmd --list-all --zone=$ZN; done" - changed_when: false - failed_when: false - register: amazon2cis_3_5_1_7_servicesport - - - name: "3.5.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports" - debug: - msg: - - "The items below are the services and ports that are accepted, please correct as needed" - - "{{ amazon2cis_3_5_1_7_servicesport.stdout_lines }}" - when: - - amazon2cis_rule_3_5_1_7 - tags: - - level1 - - manual - - audit - - rule_3.5.1.7 - - firewall diff --git a/tasks/section_3/cis_3.5.2.x.yml b/tasks/section_3/cis_3.5.2.x.yml deleted file mode 100644 index 03d6e56..0000000 --- a/tasks/section_3/cis_3.5.2.x.yml +++ /dev/null @@ -1,343 +0,0 @@ ---- - -- name: "3.5.2.1 | PATCH | Ensure nftables is installed" - package: - name: nftables - state: present - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_2_1 - tags: - - level1 - - automated - - patch - - rule_3.5.2.1 - - firewall - - nftables - -- name: "3.5.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables" - package: - name: firewalld - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_2_2 - tags: - - level1 - - automated - - patch - - rule_3.5.2.2 - - firewall - - nftables - -- name: "3.5.2.3 | PATCH | Ensure iptables-services package is not installed" - package: - name: iptables-services - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_2_3 - tags: - - level1 - - automated - - patch - - rule_3.5.2.3 - - firewall - - nftables - -- name: "3.5.2.4 | PATCH | Ensure iptables are flushed" - block: - - name: "3.5.2.4 | PATCH | Ensure iptables are flushed | Flush IPv4 tables" - command: iptables -F - - - name: "3.5.2.4 | PATCH | Ensure iptables are flushed | Flush IPv6 tables" - command: ip6tables -F - when: - - amazon2cis_ipv6_required - when: - - amazon2cis_firewall != "iptables" - - amazon2cis_rule_3_5_2_4 - tags: - - level1 - - manual - - patch - - rule_3.5.2.4 - - firewall - - nftables - -- name: "3.5.2.5 | PATCH | Ensure a table exists" - block: - - name: "3.5.2.5 | AUDIT | Ensure a table exists | Check for tables" - command: nft list tables - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_4_nft_tables - - - name: "3.5.2.5 | AUDIT | Ensure a table exists | Show existing tables" - debug: - msg: - - "Below are the current nft tables, please review" - - "{{ amazon2cis_3_5_2_5_nft_tables.stdout_lines }}" - when: - - amazon2cis_3_5_2_5_nft_tables.stdout | length > 0 - - - name: "3.5.2.5 | AUDIT | Ensure a table exists | Alert on no tables" - debug: - msg: - - "Warning! You currently have no nft tables, please review your setup" - - 'Use the command "nft create table inet
" to create a new table' - when: - - amazon2cis_3_5_2_5_nft_tables.stdout | length == 0 - - not amazon2cis_nft_tables_autoNewTable - - - name: "3.5.2.5 | PATCH | Ensure a table exists | Create table if needed" - command: nft create table inet "{{ amazon2cis_nft_tables_tableName }}" - failed_when: false - when: - - amazon2cis_nft_tables_autoNewTable - when: - - amazon2cis_rule_3_5_2_5 - tags: - - level1 - - automated - - patch - - rule_3.5.2.5 - - firewall - - nftables - -- name: "3.5.2.6 | PATCH | Ensure base chains exist" - block: - - name: "3.5.2.6 | AUDIT | Ensure base chains exist | Get current chains for INPUT" - shell: nft list ruleset | grep 'hook input' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_6_input_chains - - - name: "3.5.2.6 | AUDIT | Ensure base chains exist | Get current chains for FORWARD" - shell: nft list ruleset | grep 'hook forward' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_6_forward_chains - - - name: "3.5.2.6 | AUDIT | Ensure base chains exist | Get current chains for OUTPUT" - shell: nft list ruleset | grep 'hook output' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_6_output_chains - - - name: "3.5.2.6 | AUDIT | Ensure base chains exist | Display chains for review" - debug: - msg: - - "Below are the current INPUT chains" - - "{{ amazon2cis_3_5_2_6_input_chains.stdout_lines }}" - - "Below are the current FORWARD chains" - - "{{ amazon2cis_3_5_2_6_forward_chains.stdout_lines }}" - - "Below are teh current OUTPUT chains" - - "{{ amazon2cis_3_4_2_6_output_chains.stdout_lines }}" - when: - - not amazon2cis_nft_tables_autoChainCreate - - - name: "3.5.2.6 | PATCH | Ensure base chains exist | Create chains if needed" - command: "{{ item }}" - failed_when: false - with_items: - - nft create chain inet "{{ amazon2cis_nft_tables_tableName }}" input { type filter hook input priority 0 \; } - - nft create chain inet "{{ amazon2cis_nft_tables_tableName }}" forward { type filter hook forward priority 0 \; } - - nft create chain inet "{{ amazon2cis_nft_tables_tableName }}" output { type filter hook output priority 0 \; } - when: - - amazon2cis_nft_tables_autoChainCreate - when: - - amazon2cis_rule_3_5_2_6 - tags: - - level1 - - automated - - patch - - rule_3.5.2.6 - - skip_ansible_lint - - firewall - - nftables - -- name: "3.5.2.7 | PATCH | Ensure loopback traffic is configured" - block: - - name: "3.5.2.7 | AUDIT | Ensure loopback traffic is configured | Gather iif lo accept existence" - shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_7_iiflo - - - name: "3.5.2.7 | AUDIT | Ensure loopback traffic is configured | Gather ip saddr existence" - shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_7_ipsaddr - - - name: "3.5.2.7 | AUDIT | Ensure loopback traffic is configured | Gather ip6 saddr existence" - shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_7_ip6saddr - - - name: "3.5.2.7 | PATCH | Ensure loopback traffic is configured | Set iif lo accept rule" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input iif lo accept - when: - - '"iif \"lo\" accept" not in amazon2cis_3_5_2_7_iiflo.stdout' - - - name: "3.5.2.7 | PATCH | Ensure loopback traffic is configured | Set ip sddr rule" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input ip saddr 127.0.0.0/8 counter drop - when: - - '"ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop" not in amazon2cis_3_5_2_7_ipsaddr.stdout' - - - name: "3.5.2.7 | PATCH | Ensure loopback traffic is configured | Set ip6 saddr rule" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input ip6 saddr ::1 counter drop - when: - - '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in amazon2cis_3_5_2_7_ip6saddr.stdout' - when: - - amazon2cis_rule_3.5.2.7 - tags: - - level1 - - automated - - patch - - rule_3.5.2.7 - - firewall - - nftables - -- name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured" - block: - - name: "3.5.2.8 | AUDIT | Ensure outbound and established connections are configured | Gather incoming connection rules" - shell: nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_8_inconnectionrule - - - name: "3.5.2.8 | AUDIT | Ensure outbound and established connections are configured | Gather outbound connection rules" - shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' - changed_when: false - failed_when: false - register: amazon2cis_3_5_2_8_outconnectionrule - - - name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add input tcp established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input ip protocol tcp ct state established accept - when: - - '"ip protocol tcp ct state established accept" not in amazon2cis_3_5_2_8_inconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add input udp established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input ip protocol udp ct state established accept - when: - - '"ip protocol udp ct state established accept" not in amazon2cis_3_5_2_8_inconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add input icmp established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input ip protocol icmp ct state established accept - when: - - '"ip protocol icmp ct state established accept" not in amazon2cis_3_5_2_8_inconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add output tcp new, related, established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" output ip protocol tcp ct state new,related,established accept - when: - - '"ip protocol tcp ct state established,related,new accept" not in amazon2cis_3_5_2_8_outconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add output udp new, related, established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" output ip protocol udp ct state new,related,established accept - when: - - '"ip protocol udp ct state established,related,new accept" not in amazon2cis_3_5_2_8_outconnectionrule.stdout' - - - name: "MANUAL| 3.5.2.8 | PATCH | Ensure outbound and established connections are configured | Add output icmp new, related, established accpet policy" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" output ip protocol icmp ct state new,related,established accept - when: - - '"ip protocol icmp ct state established,related,new accept" not in amazon2cis_3_5_2_8_outconnectionrule.stdout' - when: - - amazon2cis_rule_3_5_2_8 - tags: - - level1 - - manual - - patch - - rule_3.5.2.8 - - firewall - - nftables - -- name: "3.5.2.9 | PATCH | Ensure default deny firewall policy" - block: - - name: "AUTOMATED | 3.5.2.9 | AUDIT | Ensure default deny firewall policy | Check for hook input deny policy" - shell: nft list table inet "{{ amazon2cis_nft_tables_tableName }}" | grep 'hook input' - failed_when: false - changed_when: false - register: amazon2cis_3_5_2_9_inputpolicy - - - name: "3.5.2.9 | AUDIT | Ensure default deny firewall policy | Check for hook forward deny policy" - shell: nft list table inet "{{ amazon2cis_nft_tables_tableName }}" | grep 'hook forward' - failed_when: false - changed_when: false - register: amazon2cis_3_5_2_9_forwardpolicy - - - name: "3.5.2.9 | AUDIT | Ensure default deny firewall policy | Check for hook output deny policy" - shell: nft list table inet "{{ amazon2cis_nft_tables_tableName }}" | grep 'hook output' - failed_when: false - changed_when: false - register: amazon2cis_3_5_2_9_outputpolicy - - - name: "3.5.2.9 | AUDIT | Ensure default deny firewall policy | Check for SSH allow" - shell: nft list table inet "{{ amazon2cis_nft_tables_tableName }}" | grep 'ssh' - failed_when: false - changed_when: false - register: amazon2cis_3_5_2_9_sshallowcheck - - - name: "3.5.2.9 | PATCH | Ensure default deny firewall policy | Enable SSH traffic" - command: nft add rule inet "{{ amazon2cis_nft_tables_tableName }}" input tcp dport ssh accept - when: - - '"tcp dport ssh accept" not in amazon2cis_3_5_2_9_sshallowcheck.stdout' - - - name: "3.5.2.9 | PATCH | Ensure default deny firewall policy | Set hook input deny policy" - command: nft chain inet "{{ amazon2cis_nft_tables_tableName }}" input { policy drop \; } - when: - - '"type filter hook input priority 0; policy drop;" not in amazon2cis_3_5_2_9_inputpolicy.stdout' - - - name: "3.5.2.9 | PATCH | Ensure default deny firewall policy | Create hook forward deny policy" - command: nft chain inet "{{ amazon2cis_nft_tables_tableName }}" forward { policy drop \; } - when: - - '"type filter hook forward priority 0; policy drop;" not in amazon2cis_3_5_2_9_forwardpolicy.stdout' - - - name: "3.5.2.9 | PATCH | Ensure default deny firewall policy | Create hook output deny policy" - command: nft chain inet "{{ amazon2cis_nft_tables_tableName }}" output { policy drop \; } - when: - - '"type filter hook output priority 0; policy drop;" not in amazon2cis_3_5_2_9_outputpolicy.stdout' - when: - - amazon2cis_rule_3_5_2_9 - tags: - - level1 - - manual - - patch - - rule_3.5.2.9 - - firewall - - nftables - -- name: "3.5.2.10 | PATCH | Ensure nftables service is enabled" - systemd: - name: nftables - enabled: true - when: - - amazon2cis_rule_3_5_2_10 - tags: - - level1 - - automated - - patch - - rule_3.5.2.10 - - firewall - - nftables - -- name: "3.5.2.11 | PATCH | Ensure nftables rules are permanent" - lineinfile: - path: /etc/sysconfig/nftables.conf - state: present - insertafter: EOF - line: include "/etc/nftables/inet-{{ amazon2cis_nft_tables_tableName }}" - when: - - amazon2cis_rule_3_5_2_11 - tags: - - level1 - - automated - - patch - - rule_3.5.2.11 - - firewall - - nftables diff --git a/tasks/section_3/cis_3.5.3.1.x.yml b/tasks/section_3/cis_3.5.3.1.x.yml deleted file mode 100644 index b0d0e75..0000000 --- a/tasks/section_3/cis_3.5.3.1.x.yml +++ /dev/null @@ -1,52 +0,0 @@ ---- - -- name: "3.5.3.1.1 | PATCH | Ensure iptables packages are installed" - package: - name: "{{ item }}" - state: present - with_items: - - iptables - - iptables-services - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_3_1_1 - tags: - - level1 - - automated - - patch - - rule_3.5.3.1 - - firewall - - iptables - -- name: "3.5.3.1.2 | PATCH | Ensure nftables is not installed with iptables" - package: - name: nftables - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_3_1_2 - tags: - - level1 - - automated - - patch - - rule_3.5.3.2 - - firewall - - iptables - -- name: "AUTOMATED | 3.5.3.1.3 | PATCH | Ensure firewalld is either not installed or masked with iptables" - package: - name: firewalld - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_3_5_3_1_3 - tags: - - level1 - - automated - - patch - - rule_3.5.3.3 - - firewall - - iptables diff --git a/tasks/section_3/main.yml b/tasks/section_3/main.yml index cecdfdf..2c02c83 100644 --- a/tasks/section_3/main.yml +++ b/tasks/section_3/main.yml @@ -1,28 +1,48 @@ --- -- name: "SECTION | 3.1 | Disable unused network protocols and devices" - include_tasks: cis_3.1.x.yml +- name: "SECTION | 3.1.x | Disable unused network protocols and devices" + ansible.builtin.import_tasks: + file: cis_3.1.x.yml -- name: "SECTION | 3.2 | Network Parameters (Host Only)" - include_tasks: cis_3.2.x.yml +- name: "SECTION | 3.2 | Network Kernel modules (Host Only)" + ansible.builtin.import_tasks: + file: cis_3.2.x.yml -- name: "SECTION | 3.3 | Network Parameters (Host and Router)" - include_tasks: cis_3.3.x.yml +- name: "SECTION | 3.3 | Network Kernel Parameters (Host and Router)" + ansible.builtin.import_tasks: + file: cis_3.3.x.yml -- name: "SECTION | 3.4 | Uncommon Network Protocols" - include_tasks: cis_3.4.x.yml +- name: "SECTION | 3.4.1 | Configure host based firewall" + ansible.builtin.import_tasks: + file: cis_3.4.1.x.yml -- name: "SECTION | 3.5.1 | Configure firewalld" - include_tasks: cis_3.5.1.x.yml +- name: "SECTION | 3.4.2 | Configure firewalld" when: - - amazon2cis_firewall == "firewalld" + - amazon2cis_system_firewall == "firewalld" + ansible.builtin.import_tasks: + file: cis_3.4.2.x.yml -- name: "SECTION | 3.5.2 | Configure nftables" - include_tasks: cis_3.5.2.x.yml +- name: "SECTION | 3.4.3 | Configure nftables" when: - - amazon2cis_firewall == "nftables" + - amazon2cis_system_firewall == "nftables" + ansible.builtin.import_tasks: + file: cis_3.4.3.x.yml -- name: "SECTION | 3.5.3.1.x | Configure iptables" - include_tasks: cis_3.5.3.1.x.yml +- name: "SECTION | 3.4.4.1.x | Configure iptables software" when: - - amazon2cis_firewall == "iptables" + - amazon2cis_system_firewall == "iptables" + ansible.builtin.import_tasks: + file: cis_3.4.4.1.x.yml + +- name: "SECTION | 3.4.4.2.x | Configure iptables" + when: + - amazon2cis_system_firewall == "iptables" + ansible.builtin.import_tasks: + file: cis_3.4.4.2.x.yml + +- name: "SECTION | 3.4.4.3.x | Configure ip6tables" + when: + - amazon2cis_system_firewall == "iptables" + - amazon2cis_ipv6_required + ansible.builtin.import_tasks: + file: cis_3.4.4.3.x.yml diff --git a/tasks/section_4/cis_4.1.1.x.yml b/tasks/section_4/cis_4.1.1.x.yml deleted file mode 100644 index a9a0ac0..0000000 --- a/tasks/section_4/cis_4.1.1.x.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- -- name: "4.1.1.1 | PATCH | Ensure auditd is installed" - package: - name: ['audit', 'audit-libs'] - state: present - notify: restart auditd - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_4_1_1_1 - tags: - - level2 - - automated - - patch - - rule_4.1.1.1 - - auditd - -- name: "4.1.1.2 | PATCH | Ensure auditd service is enabled and running" - service: - name: auditd - state: started - enabled: true - when: - - not amazon2cis_skip_for_travis - - amazon2cis_rule_4_1_1_2 - - ansible_connection != 'docker' - tags: - - level2 - - automated - - patch - - rule_4.1.1.2 - - auditd - -- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled" - block: - - name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Get Grub CMDLINE Settings" - shell: grep -c -E '^GRUB_CMDLINE_LINUX(_DEFAULT)?=' /etc/default/grub - changed_when: false - failed_when: false - register: amazon2cis_4_1_1_3_grub_cmdline_linux - - - name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Set if Grub CMDLINE exists" - lineinfile: - path: /etc/default/grub - regexp: '^(GRUB_CMDLINE_LINUX(?:_DEFAULT)?)="(.*)( audit=\d)?(.*)"' - line: '\1="\2 audit=1\3"' - backrefs: true - notify: grub2cfg - when: "'1' in amazon2cis_4_1_1_3_grub_cmdline_linux.stdout" - - - name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Set if Grub CMDLINE does not exist" - lineinfile: - path: /etc/default/grub - line: 'GRUB_CMDLINE_LINUX="audit=1"' - notify: grub2cfg - when: "'0' in amazon2cis_4_1_1_3_grub_cmdline_linux.stdout" - when: - - amazon2cis_rule_4_1_1_3 - tags: - - level2 - - automated - - patch - - rule_4.1.1.3 - - auditd diff --git a/tasks/section_4/cis_4.1.2.x.yml b/tasks/section_4/cis_4.1.2.x.yml deleted file mode 100644 index 15afb76..0000000 --- a/tasks/section_4/cis_4.1.2.x.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- - -- name: "4.1.2.1 | PATCH | Ensure audit log storage size is configured" - lineinfile: - dest: /etc/audit/auditd.conf - regexp: "^max_log_file( |=)" - line: "max_log_file = {{ amazon2cis_maxauditlog_size }}" - state: present - notify: restart auditd - when: - - amazon2cis_rule_4_1_2_1 - tags: - - level2 - - automated - - patch - - rule_4.1.2.1 - - auditd - -- name: "4.1.2.2 | PATCH | Ensure audit logs are not automatically deleted" - lineinfile: - dest: /etc/audit/auditd.conf - regexp: "^max_log_file_action" - line: "max_log_file_action = {{ amazon2cis_auditd['max_log_file_action'] }}" - state: present - notify: restart auditd - when: - - amazon2cis_rule_4_1_2_2 - tags: - - level2 - - automated - - patch - - rule_4.1.2.2 - - auditd - -- name: "4.1.2.3 | PATCH | Ensure system is disabled when audit logs are full" - lineinfile: - dest: /etc/audit/auditd.conf - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - state: present - with_items: - - { regexp: '^space_left_action', line: "space_left_action = {{ amazon2cis_auditd['space_left_action'] }}" } - - { regexp: '^action_mail_acct', line: "action_mail_acct = {{ amazon2cis_auditd['action_mail_acct'] }}" } - - { regexp: '^admin_space_left_action', line: "admin_space_left_action = {{ amazon2cis_auditd['admin_space_left_action'] }}" } - notify: restart auditd - when: - - amazon2cis_rule_4_1_2_3 - tags: - - level2 - - automated - - patch - - rule_4.1.2.3 - - auditd - -- name: "4.1.2.4 | PATCH | Ensure audit_backlog_limit is sufficient" - block: - - name: "4.1.2.4 | AUDIT | Ensure audit_backlog_limit is sufficient | Grep GRUB_CMDLINE_LINUX parameter" - shell: grep -c -E 'GRUB_CMDLINE_LINUX(_DEFAULT)?=' /etc/default/grub - changed_when: false - failed_when: false - register: amazon2cis_4_1_2_4_grub_cmdline_linux_settings - - - name: "4.1.2.4 | PATCH | Ensure audit_backlog_limit is sufficient | Set audit_backlog_limit if GRUB_CMDLINE_LINUX exists" - lineinfile: - path: /etc/default/grub - regexp: '^(GRUB_CMDLINE_LINUX(?:_DEFAULT)?)="(.*)( audit_backlog_limit={{ amazon2cis_audit_backlog_limit }})?(.*)"' - line: '\1="\2 audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}\3"' - backrefs: true - notify: grub2cfg - when: "'1' in amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout" - - - name: "4.1.2.4 | PATCH | Ensure audit_backlog_limit is sufficient | Set audit_backlog_limit if GRUB_CMDLINE_LINUX does not exists" - lineinfile: - path: /etc/default/grub - replace: 'GRUB_CMDLINE_LINUX="audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}"' - notify: grub2cfg - when: "'0' in amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout" - when: - - amazon2cis_rule_4_1_2_4 - tags: - - level2 - - automated - - patch - - rule_4.1.2.4 - - grub diff --git a/tasks/section_4/cis_4.1.x.x.yml b/tasks/section_4/cis_4.1.x.x.yml new file mode 100644 index 0000000..72c76e6 --- /dev/null +++ b/tasks/section_4/cis_4.1.x.x.yml @@ -0,0 +1,193 @@ +--- + +- name: "4.1.1.1 | PATCH | Ensure cron daemon is enabled and active" + when: + - amazon2cis_rule_4_1_1_1 + tags: + - level1 + - automated + - patch + - rule_4.1.1.1 + - cron + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + ansible.builtin.service: + name: crond + state: started + enabled: true + +- name: "4.1.1.2 | PATCH | Ensure permissions on /etc/crontab are configured" + when: + - amazon2cis_rule_4_1_1_2 + tags: + - level1 + - automated + - patch + - rule_4.1.1.2 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/crontab + owner: root + group: root + mode: '0600' + +- name: "4.1.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured" + when: + - amazon2cis_rule_4_1_1_3 + tags: + - level1 + - automated + - patch + - rule_4.1.1.3 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/cron.hourly + state: directory + owner: root + group: root + mode: '0700' + +- name: "4.1.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured" + when: + - amazon2cis_rule_4_1_1_4 + tags: + - level1 + - automated + - patch + - rule_4.1.1.4 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/cron.daily + state: directory + owner: root + group: root + mode: '0700' + +- name: "4.1.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured" + when: + - amazon2cis_rule_4_1_1_5 + tags: + - level1 + - patch + - rule_4.1.1.5 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/cron.weekly + state: directory + owner: root + group: root + mode: '0700' + +- name: "4.1.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured" + when: + - amazon2cis_rule_4_1_1_6 + tags: + - level1 + - automated + - patch + - rule_4.1.1.6 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/cron.monthly + state: directory + owner: root + group: root + mode: '0700' + +- name: "4.1.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured" + when: + - amazon2cis_rule_4_1_1_7 + tags: + - level1 + - automated + - patch + - rule_4.1.1.7 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + ansible.builtin.file: + dest: /etc/cron.d + state: directory + owner: root + group: root + mode: '0700' + +- name: "4.1.1.8 | PATCH | Ensure cron is restricted to authorized users" + when: + - amazon2cis_rule_4_1_1_8 + tags: + - level1 + - automated + - patch + - rule_4.1.1.8 + - permissions + - cron + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + block: + - name: "4.1.1.8 | PATCH | Ensure cron is restricted to authorized users | Remove cron.deny" + ansible.builtin.file: + dest: /etc/cron.deny + state: absent + + - name: "4.1.1.8 | PATCH | Ensure cron is restricted to authorized users | Check if cron.allow exists" + ansible.builtin.stat: + path: "/etc/cron.allow" + register: amazon2cis_4_1_1_8_p + + - name: "4.1.1.8 | PATCH | Ensure cron is restricted to authorized users | Ensure cron.allow is restricted to authorized users" + ansible.builtin.file: + dest: /etc/cron.allow + state: '{{ "file" if amazon2cis_4_1_1_8_p.stat.exists else "touch" }}' + owner: root + group: root + mode: '0600' + +- name: "4.1.2.1 | PATCH | Ensure at is restricted to authorized users" + when: + - amazon2cis_rule_4_1_2_1 + tags: + - level1 + - automated + - patch + - rule_4.1.2.1 + - at + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + block: + - name: "4.1.2.1 | PATCH | Ensure at is restricted to authorized users | Remove at.deny" + ansible.builtin.file: + dest: /etc/at.deny + state: absent + + - name: "4.1.2.1 | AUDIT | Ensure at is restricted to authorized users | Check if at.allow exists" + ansible.builtin.stat: + path: "/etc/at.allow" + register: amazon2cis_4_1_1_9_p + + - name: "4.1.2.1 | PATCH | Ensure at is restricted to authorized users | Ensure at.allow is restricted to authorized users" + ansible.builtin.file: + dest: /etc/at.allow + state: '{{ "file" if amazon2cis_4_1_1_9_p.stat.exists else "touch" }}' + owner: root + group: root + mode: '0600' diff --git a/tasks/section_4/cis_4.1.x.yml b/tasks/section_4/cis_4.1.x.yml deleted file mode 100644 index 85a0a70..0000000 --- a/tasks/section_4/cis_4.1.x.yml +++ /dev/null @@ -1,229 +0,0 @@ ---- - -- name: "4.1.3 | PATCH | Ensure events that modify date and time information are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_3 - tags: - - level2 - - auditd - - patch - - automated - - rule_4.1.3 - -- name: "4.1.4 | PATCH | Ensure events that modify user/group information are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_4 - tags: - - level2 - - automated - - patch - - rule_4.1.4 - - auditd - -- name: "4.1.5 | PATCH | Ensure events that modify the system's network environment are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_5 - tags: - - level2 - - automated - - patch - - rule_4.1.5 - - auditd - -- name: "4.1.6 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_6 - tags: - - level2 - - automated - - patch - - rule_4.1.6 - - auditd - -- name: "4.1.7 | PATCH | Ensure login and logout events are collected" - block: - - name: "4.1.7 | AUDIT | Ensure login and logout events are collected | Check for pam_fallock or pam_tally2" - shell: grep pam_tally2.so /etc/pam.d/system-auth /etc/pam.d/password-auth - changed_when: false - failed_when: false - register: amazon2cis_4_1_7_tally2_check - tags: - - skip_ansible_lint - - - name: "4.1.7 | PATCH | Ensure login and logout events are collected | Set login and logout events" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_7 - tags: - - level2 - - automated - - patch - - rule_4.1.7 - - auditd - -- name: "4.1.8 | PATCH | Ensure session initiation information is collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_8 - tags: - - level2 - - automated - - patch - - rule_4.1.8 - - auditd - -- name: "4.1.9 | PATCH | Ensure discretionary access control permission modification events are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_9 - tags: - - level2 - - automated - - patch - - rule_4.1.9 - - auditd - -- name: "4.1.10 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_10 - tags: - - level2 - - automated - - patch - - rule_4.1.10 - - auditd - -- name: "4.1.11 | PATCH | Ensure use of privileged commands is collected" - block: - - name: "4.1.11 | AUDIT | Ensure use of privileged commands is collected" - shell: for i in $(df | grep '^/dev' | awk '{ print $NF }'); do find $i -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null; done - changed_when: false - check_mode: false - register: amazon2cis_4_1_11_priv_procs - - - name: "4.1.11 | PATCH | Ensure use of privileged commands is collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_11 - tags: - - level2 - - automated - - patch - - rule_4.1.11 - - auditd - -- name: "4.1.12 | PATCH | Ensure successful file system mounts are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_12 - tags: - - level2 - - auditd - - patch - - automated - - rule_4.1.12 - -- name: "4.1.13 | PATCH | Ensure file deletion events by users are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_13 - tags: - - level2 - - automated - - patch - - rule_4.1.13 - - auditd - -- name: "4.1.14 | PATCH | Ensure changes to system administration scope (sudoers) is collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_14 - tags: - - level2 - - automated - - patch - - rule_4.1.14 - - auditd - -- name: "4.1.15 | PATCH | Ensure system administrator command executions (sudo) are collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_15 - tags: - - level2 - - automated - - patch - - rule_4.1.15 - - auditd - -- name: "4.1.16 | PATCH | Ensure kernel module loading and unloading is collected" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_16 - tags: - - level2 - - automated - - patch - - rule_4.1.16 - - auditd - -- name: "4.1.17 | PATCH | Ensure the audit configuration is immutable" - debug: - msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" - changed_when: true - notify: update auditd - when: - - amazon2cis_rule_4_1_17 - tags: - - level2 - - automated - - patch - - rule_4.1.17 - - auditd diff --git a/tasks/section_4/cis_4.2.1.x.yml b/tasks/section_4/cis_4.2.1.x.yml deleted file mode 100644 index 61eab66..0000000 --- a/tasks/section_4/cis_4.2.1.x.yml +++ /dev/null @@ -1,197 +0,0 @@ ---- - -- name: "4.2.1.1 | PATCH | Ensure rsyslog is installed" - package: - name: rsyslog - state: present - vars: - ansible_python_interpreter: /bin/python - when: - - amazon2cis_rule_4_2_1_1 - tags: - - level1 - - automated - - patch - - rule_4.2.1.1 - - rsyslog - -- name: "4.2.1.2 | PATCH | Ensure rsyslog Service is enabled and running" - service: - name: rsyslog - state: started - enabled: true - when: - - amazon2cis_rule_4_2_1_2 - tags: - - level1 - - automated - - patch - - rule_4.2.1.2 - - rsyslog - -- name: "4.2.1.3 | PATCH | Ensure rsyslog default file permissions configured" - lineinfile: - dest: /etc/rsyslog.conf - regexp: '^\$FileCreateMode' - line: '$FileCreateMode 0640' - notify: restart rsyslog - when: - - amazon2cis_rule_4_2_1_3 - tags: - - level1 - - automated - - patch - - rule_4.2.1.3 - - rsyslog - -- name: "4.2.1.4 | PATCH | Ensure logging is configured" - block: - - name: "4.2.1.4 | AUDIT | Ensure logging is configured | rsyslog current config message out" - command: cat /etc/rsyslog.conf - changed_when: false - failed_when: false - register: amazon2_4_2_1_4_audit - - - name: "4.2.1.4 | PATCH | Ensure logging is configured | Debug out rsyslog settings" - debug: - msg: - - "These are the current logging configurations for rsyslog, please review:" - - "{{ amazon2_4_2_1_4_audit.stdout_lines }}" - when: not amazon2cis_rsyslog_ansibleManaged - - - name: "4.2.1.4 | PATCH | Ensure logging is configured | Set logging settings lineinfile" - lineinfile: - path: /etc/rsyslog.conf - state: present - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - insertafter: '^[# ]*{{ item.insertafter }}\s*=\s*' - with_items: - - { regexp: '^\*\.emerge(.*)$', line: '*.emerg :omusrmsg:*', insertafter: '# Everybody gets emergency messages' } - - { regexp: '^auth,authpriv\.\*', line: 'auth,authpriv.* /var/log/secure', insertafter: '# The authpriv file has restricted access.' } - - { regexp: '^mail\.\*(.*)$', line: 'mail.* -/var/log/mail', insertafter: '# Log all the mail messages in one place.' } - - { regexp: '^mail.info(.*)$', line: 'mail.info -/var/log/mail.info', insertafter: '# Log all the mail messages in one place.' } - - { regexp: '^mail.warning(.*)$', line: 'mail.warning -/var/log/mail.warning', insertafter: '# Log all the mail messages in one place.' } - - { regexp: '^mail.err(.*)$', line: 'mail.err /var/log/mail.err', insertafter: '# Log all the mail messages in one place.' } - - { regexp: '^news.crit(.*)$', line: 'news.crit -/var/log/news/news.crit', insertafter: '# Save news errors of level crit and higher in a special file.' } - - { regexp: '^news.err(.*)$', line: 'news.err -/var/log/news/news.crit', insertafter: '# Save news errors of level crit and higher in a special file.' } - - { regexp: '^news.notice(.*)$', line: 'news.notice -/var/log/news/news.crit', insertafter: '# Save news errors of level crit and higher in a special file.' } - loop_control: - label: "{{ item.line }}" - notify: restart rsyslog - when: amazon2cis_rsyslog_ansibleManaged - - - name: "4.2.1.4 | PATCH | Ensure logging is configured | Misc. log setting" - blockinfile: - path: /etc/rsyslog.conf - state: present - marker: "# {mark} MISC. LOG SETTINGS (ANSIBLE MANAGED)" - block: | - # misc. logging additions to meet CIS standards - *.=warning;*.=err -/var/log/warn - *.crit /var/log/warn - *.*;mail.none;news.none /var/log/messages - insertafter: '#### RULES ####' - notify: restart rsyslog - when: amazon2cis_rsyslog_ansibleManaged - - - name: "4.2.1.4 | PATCH | Ensure logging is configured | Local log settings" - blockinfile: - path: /etc/rsyslog.conf - state: present - marker: "#{mark} LOCAL LOG SETTINGS (ANSIBLE MANAGED)" - block: | - # local log settings - local0,local1.* -/var/log/localmessages - local2,local3.* -/var/log/localmessages - local4,local5.* -/var/log/localmessages - local6,local7.* -/var/log/localmessages - insertafter: '#### RULES ####' - notify: restart rsyslog - when: - - amazon2cis_rule_4_2_1_4 - tags: - - level1 - - manual - - patch - - rule_4.2.1.4 - - rsyslog - -- name: "4.2.1.5 | PATCH | Ensure rsyslog is configured to send logs to a remote log host" - blockinfile: - path: /etc/rsyslog.conf - state: present - block: | - # remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional - *.* @@{{ amazon2cis_remote_log_server }} - insertafter: EOF - failed_when: - - amazon2cis_4_2_1_5_result is failed - - amazon2cis_4_2_1_5_result.rc != 257 - register: amazon2cis_4_2_1_5_result - notify: restart rsyslog - when: - - amazon2cis_rule_4_2_1_5 - - amazon2cis_remote_log_server is defined - tags: - - level1 - - automated - - patch - - rule_4.2.1.5 - - rsyslog - -- name: "4.2.1.6 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts." - block: - - name: "4.2.1.6 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts. | When not log host" - replace: - path: /etc/rsyslog.conf - regexp: '({{ item }})' - replace: '#\1' - with_items: - - '^(\$ModLoad imtcp)' - - '^(\$InputTCPServerRun)' - notify: restart rsyslog - when: - - not amazon2cis_system_is_log_server - - - name: "4.2.1.6 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts. | When log host" - replace: - path: /etc/rsyslog.conf - regexp: '^#(.*{{ item }}.*)' - replace: '\1' - with_items: - - 'ModLoad imtcp' - - 'InputTCPServerRun' - notify: restart rsyslog - when: - - amazon2cis_system_is_log_server - when: - - amazon2cis_rule_4_2_1_6 - tags: - - level1 - - patch - - manual - - rule_4.2.1.6 - - rsyslog - -# - name: "MANUAL | 4.2.3 | AUDIT | Ensure logrotate is configured" -# find: -# paths: /etc/logrotate.d/ -# register: log_rotates -# tags: -# - level1 -# - audit -# - manual -# - rule_4.2.3 - -# - name: "AUTOMATED | 4.2.4 | PATCH | Ensure permissions on all logfiles are configured" -# command: find /var/log -type f -exec chmod g-wx,o-rwx "{}" + -o -type d -exec chmod g-wx,o-rwx "{}" + -# changed_when: no -# failed_when: no -# when: -# - amazon2cis_rule_4_2_3 -# tags: -# - level1 -# - patch -# - automated -# - rule_4.2.4 diff --git a/tasks/section_4/cis_4.2.2.x.yml b/tasks/section_4/cis_4.2.2.x.yml deleted file mode 100644 index cd3526b..0000000 --- a/tasks/section_4/cis_4.2.2.x.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- - -- name: "4.2.2.1 | PATCH | Ensure journald is configured to send logs to rsyslog" - lineinfile: - path: /etc/systemd/journald.conf - regexp: '^[F|f]orward[T|t]o[S|s]yslog=' - line: "ForwardToSyslog=yes" - when: - - amazon2cis_rule_4_2_2_1 - tags: - - level1 - - manual - - patch - - rule_4.2.2.1 - - journald - -- name: "4.2.2.2 | PATCH | Ensure journald is configured to compress large log files" - lineinfile: - path: /etc/systemd/journald.conf - regexp: '^[C|c]ompress=' - line: "Compress=yes" - when: - - amazon2cis_rule_4_2_2_2 - tags: - - level1 - - automated - - patch - - rule_4.2.2.2 - - journald - -- name: "4.2.2.3 | PATCH | Ensure journald is configured to write logfiles to persistent disk" - lineinfile: - path: /etc/systemd/journald.conf - regexp: '^[S|s]torage=' - line: "Storage=persistent" - when: - - amazon2cis_rule_4_2_2_3 - tags: - - level1 - - automated - - patch - - rule_4.2.2.3 - - journald diff --git a/tasks/section_4/cis_4.2.x.yml b/tasks/section_4/cis_4.2.x.yml index 84ccadd..1e3873a 100644 --- a/tasks/section_4/cis_4.2.x.yml +++ b/tasks/section_4/cis_4.2.x.yml @@ -1,40 +1,498 @@ --- -- name: "4.2.3 | PATCH | Ensure logrotate is configured" +- name: "4.2.1 | PATCH | Ensure permissions on /etc/ssh/sshd_config are configured" + ansible.builtin.file: + path: /etc/ssh/sshd_config + state: file + owner: root + group: root + mode: '0600' + when: + - amazon2cis_rule_4_2_1 + tags: + - level1 + - automated + - patch + - rule_4.2.1 + - ssh + - permissions + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + +- name: "4.2.2 | PATCH | Ensure permissions on SSH private host key files are configured" + when: + - amazon2cis_rule_4_2_2 + tags: + - level1 + - automated + - patch + - rule_4.2.2 + - ssh + - permissions + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 block: - - name: "4.2.3 | AUDIT | Ensure logrotate is configured" - find: - paths: /etc/logrotate.d/ - register: amazon2cis_4_2_3_log_rotates + - name: "4.2.2 | AUDIT | Ensure permissions on SSH private host key files are configured" + ansible.builtin.find: + paths: /etc/ssh + patterns: 'ssh_host_*_key' + recurse: true + file_type: any + register: amazon2_4_2_2_priv_ssh_key_results - - name: "4.2.3 | PATCH | Ensure logrotate is configured" - replace: + - name: "4.2.2 | AUDIT | Ensure permissions on SSH private host key files are configured" + ansible.builtin.file: path: "{{ item.path }}" - regexp: '^(\s*)(daily|weekly|monthly|yearly)$' - replace: "\\1{{ amazon2cis_logrotate }}" + owner: root + group: root + mode: 0600 with_items: - - "{{ amazon2cis_4_2_3_log_rotates.files }}" - - { path: "/etc/logrotate.conf" } + - "{{ amazon2_4_2_2_priv_ssh_key_results.files }}" loop_control: label: "{{ item.path }}" + +- name: "4.2.3 | PATCH | Ensure permissions on SSH public host key files are configured" when: - amazon2cis_rule_4_2_3 tags: - level1 - - manual + - automated - patch - rule_4.2.3 - - logrotate + - ssh + - permissions + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + block: + - name: "4.2.3 | AUDIT | Ensure permissions on SSH public host key files are configured" + ansible.builtin.find: + paths: /etc/ssh + patterns: 'ssh_host_*_key' + recurse: true + file_type: any + register: amazon2_4_2_3_pub_ssh_key_results + + - name: "4.2.3 | AUDIT | Ensure permissions on SSH public host key files are configured" + ansible.builtin.file: + path: "{{ item.path }}" + owner: root + group: root + mode: 0600 + with_items: + - "{{ amazon2_4_2_3_pub_ssh_key_results.files }}" + loop_control: + label: "{{ item.path }}" -- name: "4.2.4 | PATCH | Ensure permissions on all logfiles are configured" - command: find /var/log -type f -exec chmod g-wx,o-rwx "{}" + -o -type d -exec chmod g-wx,o-rwx "{}" + - changed_when: false - failed_when: false +- name: "4.2.4 | PATCH | Ensure sshd access is configured" when: - amazon2cis_rule_4_2_4 tags: - level1 - - manual + - automated - patch - rule_4.2.4 - - logs + - ssh + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + block: + - name: "4.2.4 | PATCH | Ensure sshd access is configured | Add line to sshd_config for allowusers" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "^AllowUsers" + line: AllowUsers {{ amazon2cis_sshd['allowusers'] }} + validate: 'sshd -t -f %s' + notify: restart sshd + when: "amazon2cis_sshd['allowusers']|default('') | length > 0" + + - name: "4.2.4 | PATCH | Ensure sshd access is configured | Add line to sshd_config for allowgroups" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "^AllowGroups" + line: AllowGroups {{ amazon2cis_sshd['allowgroups'] }} + validate: 'sshd -t -f %s' + notify: restart sshd + when: "amazon2cis_sshd['allowgroups']|default('') | length > 0" + + - name: "4.2.4 | PATCH | Ensure sshd access is configured | Add line to sshd_config for denyusers" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "^DenyUsers" + line: DenyUsers {{ amazon2cis_sshd['denyusers'] }} + validate: 'sshd -t -f %s' + notify: restart sshd + when: "amazon2cis_sshd['denyusers']|default('') | length > 0" + + - name: "4.2.4 | PATCH | Ensure sshd access is configured | Add line to sshd_config for denygroups" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "^DenyGroups" + line: DenyGroups {{ amazon2cis_sshd['denygroups'] }} + validate: 'sshd -t -f %s' + notify: restart sshd + when: "amazon2cis_sshd['denygroups']|default('') | length > 0" + +- name: "4.2.5 | PATCH | Ensure SSH banner is configured" + when: + - amazon2cis_rule_4_2_5 + tags: + - level1 + - automated + - patch + - rule_4.2.5 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^Banner' + line: 'Banner /etc/issue.net' + validate: 'sshd -t -f %s' + +- name: "4.2.6 | PATCH | Ensure only strong Ciphers are used" + when: + - amazon2cis_rule_4_2_6 + tags: + - level1 + - automated + - patch + - rule_4.2.6 + - ssh + - NIST800-53R5_SC-8 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^Cipherss' + line: "Ciphers {{ amazon2cis_sshd['ciphers'] }}" + validate: 'sshd -t -f %s' + +- name: "4.2.7 | PATCH | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured" + when: + - amazon2cis_rule_4_2_7 + tags: + - level1 + - automated + - patch + - rule_4.2.7 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + block: + - name: "4.2.7 | PATCH | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured | Add line in sshd_config for ClientAliveInterval" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^ClientAliveInterval' + line: "ClientAliveInterval {{ amazon2cis_sshd['clientaliveinterval'] }}" + validate: 'sshd -t -f %s' + notify: restart sshd + + - name: "4.2.7 | PATCH | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured | Ensure SSH ClientAliveCountMax set" + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^ClientAliveCountMax' + line: "ClientAliveCountMax {{ amazon2cis_sshd['clientalivecountmax'] }}" + validate: 'sshd -t -f %s' + notify: restart sshd + +- name: "4.2.8 | PATCH | Ensure sshd DisableForwarding is enabled" + when: + - amazon2cis_rule_4_2_8 + tags: + - level1 + - automated + - patch + - rule_4.2.8 + - ssh + - NIST800-53R5_CM-7 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*disableforwarding + line: 'DisableForwarding yes' + validate: 'sshd -t -f %s' + +- name: "4.2.9 | PATCH | Ensure sshd GSSAPIAuthentication is disabled" + when: + - amazon2cis_rule_4_2_9 + tags: + - level1 + - automated + - patch + - rule_4.2.9 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*gssapiauthentication + line: 'GSSAPIAuthentication no' + validate: 'sshd -t -f %s' + +- name: "4.2.10 | PATCH | Ensure sshd HostbasedAuthentication is disabled" + when: + - amazon2cis_rule_4_2_10 + tags: + - level1 + - automated + - patch + - rule_4.2.10 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*HostbasedAuthentication + line: 'HostbasedAuthentication no' + validate: 'sshd -t -f %s' + +- name: "4.2.11 | PATCH | Ensure sshd IgnoreRhosts is enabled" + when: + - amazon2cis_rule_4_2_11 + tags: + - level1 + - automated + - patch + - rule_4.2.11 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*IgnoreRhosts + line: 'IgnoreRhosts yes' + validate: 'sshd -t -f %s' + +- name: "4.2.12 | PATCH | Ensure only strong Key Exchange algorithms are used" + when: + - amazon2cis_rule_4_2_12 + tags: + - level1 + - automated + - patch + - rule_4.2.12 + - ssh + - NIST800-53R5_SC-8 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^KexAlgorithms' + line: "KexAlgorithms {{ amazon2cis_sshd['kex'] }}" + validate: 'sshd -t -f %s' + +- name: "4.2.13 | PATCH | Ensure sshd LoginGraceTime is configured" + when: + - amazon2cis_rule_4_2_13 + tags: + - level1 + - automated + - patch + - rule_4.2.13 + - ssh + - NIST800-53R5_CM-6 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*LoginGraceTime + line: "LoginGraceTime {{ amazon2cis_sshd['logingracetime'] }}" + validate: 'sshd -t -f %s' + +- name: "4.2.14 | PATCH | Ensure SSH LogLevel is configured" + when: + - amazon2cis_rule_4_2_14 + tags: + - level1 + - automated + - patch + - rule_4.2.14 + - ssh + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*LogLevel + line: 'LogLevel {{ amazon2cis_ssh_loglevel }}' + validate: 'sshd -t -f %s' + +- name: "4.2.15 | PATCH | Ensure sshd MACs are configured" + when: + - amazon2cis_rule_4_2_15 + tags: + - level1 + - automated + - patch + - rule_4.2.15 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^MACs' + line: "MACs {{ amazon2cis_sshd['macs'] }}" + validate: 'sshd -t -f %s' + +- name: "4.2.16 | PATCH | Ensure sshd MaxAuthTries is configured" + when: + - amazon2cis_rule_4_2_16 + tags: + - level1 + - automated + - patch + - rule_4.2.16 + - ssh + - NIST800-53R5_AU-3 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*maxauthtries + line: 'MaxAuthTries {{ amazon2cis_ssh_maxauthtries }}' + validate: 'sshd -t -f %s' + +- name: "4.2.17 | PATCH | Ensure sshd MaxSessions is configured" + when: + - amazon2cis_rule_4_2_17 + tags: + - level1 + - automated + - patch + - rule_4.2.17 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*MaxSessions + line: 'MaxSessions {{ amazon2cis_ssh_maxsessions }}' + validate: 'sshd -t -f %s' + +- name: "4.2.18 | PATCH | Ensure SSH MaxStartups is configured" + when: + - amazon2cis_rule_4_2_18 + tags: + - level1 + - automated + - patch + - rule_4.2.18 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*MaxStartups + line: 'MaxStartups 10:30:60' + validate: 'sshd -t -f %s' + +- name: "4.2.19 | PATCH | Ensure sshd PermitEmptyPasswords is disabled" + when: + - amazon2cis_rule_4_2_19 + tags: + - level1 + - automated + - patch + - rule_4.2.19 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*PermitEmptyPasswords + line: 'PermitEmptyPasswords no' + validate: 'sshd -t -f %s' + +- name: "4.2.20 | PATCH | Ensure sshd PermitRootLogin is disabled" + when: + - amazon2cis_rule_4_2_20 + tags: + - level1 + - automated + - patch + - rule_4.2.20 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*PermitRootLogin + line: 'PermitRootLogin no' + validate: 'sshd -t -f %s' + +- name: "4.2.21 | PATCH | Ensure sshd PermitUserEnvironment is disabled" + when: + - amazon2cis_rule_4_2_21 + tags: + - level1 + - automated + - patch + - rule_4.2.21 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*PermitUserEnvironment + line: 'PermitUserEnvironment no' + validate: 'sshd -t -f %s' + +- name: "4.2.22 | PATCH | Ensure sshd UsePAM is enabled" + when: + - amazon2cis_rule_4_2_22 + tags: + - level1 + - automated + - patch + - rule_4.2.22 + - ssh + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + notify: restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: ^(?i)(#|)\s*UsePAM + line: 'UsePAM yes' + validate: 'sshd -t -f %s' diff --git a/tasks/section_4/cis_4.3.x.yml b/tasks/section_4/cis_4.3.x.yml new file mode 100644 index 0000000..848ccbc --- /dev/null +++ b/tasks/section_4/cis_4.3.x.yml @@ -0,0 +1,150 @@ +--- + +- name: "4.3.1 | PATCH | Ensure sudo is installed" + when: + - amazon2cis_rule_4_3_1 + tags: + - level1 + - automated + - patch + - rule_4.3.1 + - sudo + - NIST800-53R5_AC-6 + ansible.builtin.package: + name: sudo + state: present + +- name: "4.3.2 | PATCH | Ensure sudo commands use pty" + when: + - amazon2cis_rule_4_3_2 + tags: + - level1 + - automated + - patch + - rule_4.3.2 + - sudo + - NIST800-53R5_AC-6 + ansible.builtin.lineinfile: + path: /etc/sudoers + regexp: ^Defaults\s+use_pty + line: "Defaults use_pty" + validate: '/usr/sbin/visudo -cf %s' + +- name: "4.3.3 | PATCH | Ensure sudo log file exists" + when: + - amazon2cis_rule_4_3_3 + tags: + - level1 + - automated + - patch + - rule_4.3.3 + - sudo + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 + ansible.builtin.lineinfile: + path: /etc/sudoers + regexp: '^Defaults\s+logfile=' + line: 'Defaults logfile="{{ amazon2cis_sudolog_location }}"' + validate: '/usr/sbin/visudo -cf %s' + +- name: "4.3.4 | PATCH | Ensure users must provide password for escalation" + when: + - amazon2cis_rule_4_3_4 + tags: + - level2-server + - level2-workstation + - automated + - patch + - sudo + - rule_4.3.4 + - NIST800-53R5_AC-6 + ansible.builtin.replace: + path: "{{ item }}" + regexp: '^([^#|{% if system_is_ec2 %}ec2-user{% endif %}].*)NOPASSWD(.*)' + replace: '\1PASSWD\2' + validate: '/usr/sbin/visudo -cf %s' + loop: "{{ amazon2cis_sudoers_files.stdout_lines }}" + +- name: "4.3.5 | PATCH | Ensure re-authentication for privilege escalation is not disabled globally" + when: + - amazon2cis_rule_4_3_5 + tags: + - level1-server + - level1-workstation + - automated + - patch + - sudo + - rule_4.3.5 + - NIST800-53R5_AC-6 + ansible.builtin.replace: + path: "{{ item }}" + regexp: '^([^#].*)!authenticate(.*)' + replace: '\1authenticate\2' + validate: '/usr/sbin/visudo -cf %s' + loop: "{{ amazon2cis_sudoers_files.stdout_lines }}" + +- name: "4.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly" + when: + - amazon2cis_rule_4_3_6 + tags: + - level1-server + - level1-workstation + - automated + - patch + - sudo + - rule_4.3.6 + block: + - name: "4.3.6 | AUDIT | Ensure sudo authentication timeout is configured correctly | Get files with timeout set" + ansible.builtin.shell: grep -is 'timestamp_timeout' /etc/sudoers /etc/sudoers.d/* | cut -d":" -f1 | uniq | sort + changed_when: false + failed_when: false + register: amazon2cis_4_3_6_timeout_files + + - name: "4.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly | Set value if no results" + when: amazon2cis_4_3_6_timeout_files.stdout | length == 0 + ansible.builtin.lineinfile: + path: /etc/sudoers + regexp: 'Defaults\s+timestamp_timeout=' + line: "Defaults timestamp_timeout={{ amazon2cis_sudo_timestamp_timeout }}" + validate: '/usr/sbin/visudo -cf %s' + + - name: "4.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly | Set value if has results" + when: amazon2cis_4_3_6_timeout_files.stdout | length > 0 + ansible.builtin.replace: + path: "{{ item }}" + regexp: 'timestamp_timeout=(\d+)' + replace: "timestamp_timeout={{ amazon2cis_sudo_timestamp_timeout }}" + validate: '/usr/sbin/visudo -cf %s' + loop: "{{ amazon2cis_4_3_6_timeout_files.stdout_lines }}" + +- name: "4.3.7 | PATCH | Ensure access to the su command is restricted" + when: + - amazon2cis_rule_4_3_7 + tags: + - level1-server + - level1-workstation + - automated + - patch + - sudo + - rule_4.3.7 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + block: + - name: "4.3.7 | PATCH | Ensure access to the su command is restricted | Ensure sugroup exists" + ansible.builtin.group: + name: "{{ amazon2cis_sugroup }}" + state: present + register: amazon2cis_4_3_7_sugroup + + - name: "4.3.7 | PATCH | Ensure access to the su command is restricted | remove users from group" + ansible.builtin.lineinfile: + path: /etc/group + regexp: '^{{ amazon2cis_sugroup }}(:.:.*:).*$' + line: '{{ amazon2cis_sugroup }}\g<1>' + backrefs: true + + - name: "4.3.7 | PATCH | Ensure access to the su command is restricted | Setting pam_wheel to use_uid" + ansible.builtin.lineinfile: + path: /etc/pam.d/su + regexp: '^(#)?auth\s+required\s+pam_wheel\.so' + line: 'auth required pam_wheel.so use_uid group={{ amazon2cis_sugroup }}' diff --git a/tasks/section_4/cis_4.4.1.x.yml b/tasks/section_4/cis_4.4.1.x.yml new file mode 100644 index 0000000..70bbb72 --- /dev/null +++ b/tasks/section_4/cis_4.4.1.x.yml @@ -0,0 +1,30 @@ +--- + +- name: "4.4.1.1 | PATCH | Ensure latest version of pam is installed" + when: + - amazon2cis_rule_4_4_1_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - rule_4.4.1.1 + ansible.builtin.package: + name: pam + state: latest + +- name: "4.4.1.2 | PATCH | Ensure libpwquality is installed" + when: + - amazon2cis_rule_4_4_1_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - rule_4.4.1.2 + - NIST800-53R5_IA-5 + ansible.builtin.package: + name: libpwquality + state: present diff --git a/tasks/section_4/cis_4.4.2.1.x.yml b/tasks/section_4/cis_4.4.2.1.x.yml new file mode 100644 index 0000000..2bc7746 --- /dev/null +++ b/tasks/section_4/cis_4.4.2.1.x.yml @@ -0,0 +1,199 @@ +--- + +- name: | + "4.4.2.1.1 | PATCH | Ensure pam_faillock module is enabled + 4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured + 4.4.2.1.3 | PATCH | Ensure password unlock time is configured + 4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account" + when: + - amazon2cis_rule_4_4_2_1_1 or + amazon2cis_rule_4_4_2_1_2 or + amazon2cis_rule_4_4_2_1_3 or + amazon2cis_rule_4_4_2_1_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_faillock + - rule_4.4.2.1.1 + - rule_4.4.2.1.2 + - rule_4.4.2.1.3 + - rule_4.4.2.1.4 + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + block: + - name: | + "4.4.2.1.1 | PATCH | Ensure pam_faillock module is enabled + 4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured + 4.4.2.1.3 | PATCH | Ensure password unlock time is configured + 4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_required" + community.general.pamd: + name: "{{ item }}" + type: auth + control: required + module_path: pam_env.so + state: after + new_type: auth + new_control: required + new_module_path: pam_faillock.so + module_arguments: 'preauth + silent + audit + {% if amazon2cis_rule_4_4_2_1_2 %}deny="{{ amazon2cis_pam_faillock.deny }}"{% endif %} + {% if amazon2cis_rule_4_4_2_1_3 %}unlock_time="{{ amazon2cis_pam_faillock.unlock_time }}"{% endif %} + {% if amazon2cis_rule_4_4_2_1_4 %}even_deny_root{% endif %}' + loop: + - system-auth + - password-auth + + - name: | + "4.4.2.1.1 | PATCH | Ensure pam_faillock module is enabled + 4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured + 4.4.2.1.3 | PATCH | Ensure password unlock time is configured + 4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_default" + community.general.pamd: + name: "{{ item }}" + type: auth + control: sufficient + module_path: pam_unix.so + state: after + new_type: auth + new_control: '[default=die]' + new_module_path: pam_faillock.so + module_arguments: 'authfail + audit + {% if amazon2cis_rule_4_4_2_1_2 %}deny={{ amazon2cis_pam_faillock.deny }}{% endif %} + {% if amazon2cis_rule_4_4_2_1_3 %}unlock_time={{ amazon2cis_pam_faillock.unlock_time }}{% endif %} + {% if amazon2cis_rule_4_4_2_1_4 %}even_deny_root{% endif %}' + loop: + - system-auth + - password-auth + + - name: | + "4.4.2.1.1 | PATCH | Ensure pam_faillock module is enabled + 4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured + 4.4.2.1.3 | PATCH | Ensure password unlock time is configured + 4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | add to account section" + community.general.pamd: + name: "{{ item }}" + type: account + control: required + module_path: pam_unix.so + state: before + new_type: account + new_control: required + new_module_path: pam_faillock.so + module_arguments: '' + loop: + - system-auth + - password-auth + +- name: "4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured" + when: amazon2cis_rule_4_4_2_1_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_faillock + - rule_4.4.2.1.2 + block: + - name: "4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured | auth_required" + community.general.pamd: + name: "{{ item }}" + type: auth + control: required + module_path: pam_faillock.so + state: args_present + module_arguments: 'deny={{ amazon2cis_pam_faillock.deny }}' + loop: + - system-auth + - password-auth + + - name: "4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured | auth_default" + community.general.pamd: + name: "{{ item }}" + type: auth + control: '[default=die]' + module_path: pam_faillock.so + state: args_present + module_arguments: 'deny={{ amazon2cis_pam_faillock.deny }}' + loop: + - system-auth + - password-auth + +- name: "4.4.2.1.3 | PATCH | Ensure password unlock time is configured" + when: amazon2cis_rule_4_4_2_1_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_faillock + - rule_4.4.2.1.3 + block: + - name: "4.4.2.1.3 | PATCH | Ensure password unlock time is configured | auth_required" + community.general.pamd: + name: "{{ item }}" + type: auth + control: required + module_path: pam_faillock.so + state: args_present + module_arguments: 'unlock_time={{ amazon2cis_pam_faillock.unlock_time }}' + loop: + - system-auth + - password-auth + + - name: "4.4.2.1.3 | PATCH | Ensure password unlock time is configured | auth_default" + community.general.pamd: + name: "{{ item }}" + type: auth + control: '[default=die]' + module_path: pam_faillock.so + state: args_present + module_arguments: 'unlock_time={{ amazon2cis_pam_faillock.unlock_time }}' + loop: + - system-auth + - password-auth + +- name: "4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account" + when: amazon2cis_rule_4_4_2_1_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_faillock + - rule_4.4.2.1.4 + block: + - name: "4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_required" + community.general.pamd: + name: "{{ item }}" + type: auth + control: required + module_path: pam_faillock.so + state: args_present + module_arguments: 'even_deny_root' + loop: + - system-auth + - password-auth + + - name: "4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_default" + community.general.pamd: + name: "{{ item }}" + type: auth + control: '[default=die]' + module_path: pam_faillock.so + state: args_present + module_arguments: 'even_deny_root' + loop: + - system-auth + - password-auth diff --git a/tasks/section_4/cis_4.4.2.2.x.yml b/tasks/section_4/cis_4.4.2.2.x.yml new file mode 100644 index 0000000..27cb4aa --- /dev/null +++ b/tasks/section_4/cis_4.4.2.2.x.yml @@ -0,0 +1,150 @@ +--- + +- name: "4.4.2.2.1 | PATCH | Ensure pam_pwquality module is enabled" + when: + - amazon2cis_rule_4_4_2_2_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.1 + - NIST800-53R5_IA-5 + block: + - name: "4.4.2.2.1 | PATCH | Ensure pam_pwquality module is enabled | present" + community.general.pamd: + name: "{{ item }}" + type: password + control: required + module_path: pam_pwhistory.so + state: before + new_type: password + new_control: requisite + new_module_path: pam_pwquality.so + module_arguments: 'try_first_pass + local_users_only' + loop: + - system-auth + - password-auth + + - name: "4.4.2.2.1 | PATCH | Ensure pam_pwquality module is enabled | args_updated" + community.general.pamd: + name: "{{ item }}" + type: password + control: requisite + module_path: pam_pwquality.so + state: args_present + module_arguments: 'try_first_pass + local_users_only' + loop: + - system-auth + - password-auth + +- name: "4.4.2.2.2 | PATCH | Ensure password number of changed characters is configured" + when: amazon2cis_rule_4_4_2_2_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.2 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^(?i)(#|)\s*difok + line: "difok = {{ amazon2cis_pwquality_difok }}" + +- name: "4.4.2.2.3 | PATCH | Ensure password length is configured" + when: amazon2cis_rule_4_4_2_2_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.3 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^(?i)(#|)\s*minlen + line: "minlen = {{ amazon2cis_pwquality_minlen }}" + +- name: "4.4.2.2.4 | PATCH | Ensure password complexity is configured" + when: amazon2cis_rule_4_4_2_2_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.4 + - NIST800-53R5_IA-5 + block: + - name: "4.4.2.2.4 | PATCH | Ensure password complexity is configured | minclass" + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^minclass + line: "minclass = {{ amazon2cis_pwquality_minclass_value }}" + when: amazon2cis_pwquality_minclass + + - name: "4.4.2.2.4 | PATCH | Ensure password complexity is configured | seperated values" + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^{{ item.key }} + line: "{{ item.key }} = {{ item.value }}" + loop: "{{ amazon2cis_pwquality }}" + when: not amazon2cis_pwquality_minclass + +- name: "4.4.2.2.5 | PATCH | Ensure password same consecutive characters is configured" + when: amazon2cis_rule_4_4_2_2_5 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.5 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^(?i)(#|)\s*maxrepeat + line: "maxrepeat = {{ amazon2cis_pwquality_maxrepeat }}" + +- name: "4.4.2.2.6 | PATCH | Ensure password maximum sequential characters is configured" + when: amazon2cis_rule_4_4_2_2_6 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.6 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^(?i)(#|)\s*maxsequence + line: "maxsequence = {{ amazon2cis_pwquality_maxsequence }}" + +- name: "4.4.2.2.7 | PATCH | Ensure password dictionary check is enabled" + when: amazon2cis_rule_4_4_2_2_7 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwquality + - rule_4.4.2.2.7 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + path: /etc/security/pwquality.conf + regexp: ^(?i)(#|)\s*dictcheck + line: "dictcheck = 1" diff --git a/tasks/section_4/cis_4.4.2.3.x.yml b/tasks/section_4/cis_4.4.2.3.x.yml new file mode 100644 index 0000000..4a1f246 --- /dev/null +++ b/tasks/section_4/cis_4.4.2.3.x.yml @@ -0,0 +1,118 @@ +--- + +- name: "4.4.2.3.1 | PATCH | Ensure pam_pwhistory module is enabled" + when: + - amazon2cis_rule_4_4_2_3_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwhistory + - rule_4.4.2.3.1 + - NIST800-53R5_IA-5 + block: + - name: "4.4.2.3.1 | AUDIT | Ensure pam_pwhistory module is enabled | check if exists" + ansible.builtin.shell: grep -P "^auth\s+(sufficient|required|requisite)\s+pam_pwhistory.so" /etc/pam.d/{system,password}-auth | wc -l + changed_when: false + failed_when: amazon2cis_4_4_2_3_1_pwhistory_exists.rc not in [ 0, 1 ] + register: amazon2cis_4_4_2_3_1_pwhistory_exists + + - name: "4.4.2.3.1 | PATCH | Ensure pam_pwhistory module is enabled | present" + when: amazon2cis_4_4_2_3_1_pwhistory_exists.stdout|int < 2 + community.general.pamd: + name: "{{ item }}" + type: password + control: sufficient + module_path: pam_unix.so + state: before + new_type: password + new_control: required + new_module_path: pam_pwhistory.so + module_arguments: 'use_authtok' + loop: + - system-auth + - password-auth + + - name: "4.4.2.3.1 | PATCH | Ensure pam_pwhistory module is enabled | updated" + when: amazon2cis_4_4_2_3_1_pwhistory_exists.stdout | int < 2 + community.general.pamd: + name: "{{ item }}" + type: password + control: required + module_path: pam_pwhistory.so + state: args_present + module_arguments: 'use_authtok' + loop: + - system-auth + - password-auth + +- name: "4.4.2.3.2 | PATCH | Ensure password history remember is configured" + when: + - amazon2cis_rule_4_4_2_3_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwhistory + - rule_4.4.2.3.2 + - NIST800-53R5_IA-5 + community.general.pamd: + name: "{{ item }}" + type: password + control: required + module_path: pam_pwhistory.so + state: args_present + module_arguments: 'remember={{ amazon2cis_pwhistory_remember }}' + loop: + - system-auth + - password-auth + +- name: "4.4.2.3.3 | PATCH | Ensure password history is enforced for the root user" + when: + - amazon2cis_rule_4_4_2_3_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwhistory + - rule_4.4.2.3.3 + - NIST800-53R5_IA-5 + community.general.pamd: + name: "{{ item }}" + type: password + control: required + module_path: pam_pwhistory.so + state: args_present + module_arguments: 'enforce_for_root' + loop: + - system-auth + - password-auth + +- name: "4.4.2.3.4 | PATCH | Ensure pam_pwhistory includes use_authtok" + when: + - amazon2cis_rule_4_4_2_3_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_pwhistory + - rule_4.4.2.3.4 + - NIST800-53R5_IA-5 + community.general.pamd: + name: "{{ item }}" + type: password + control: required + module_path: pam_pwhistory.so + state: args_present + module_arguments: 'use_authtok' + loop: + - system-auth + - password-auth diff --git a/tasks/section_4/cis_4.4.2.4.x.yml b/tasks/section_4/cis_4.4.2.4.x.yml new file mode 100644 index 0000000..ca341f5 --- /dev/null +++ b/tasks/section_4/cis_4.4.2.4.x.yml @@ -0,0 +1,83 @@ +--- + +- name: "4.4.2.4.1 | PATCH | Ensure pam_unix does not include nullok" + when: + - amazon2cis_rule_4_4_2_4_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.4.2.4.1 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + backrefs: true + path: "/etc/pam.d/{{ item }}" + regexp: (.*pam_unix.so.*)(nullok)(.*) + line: \1\3 + loop: + - system-auth + - password-auth + +- name: "4.4.2.4.2 | PATCH | Ensure pam_unix does not include remember" + when: + - amazon2cis_rule_4_4_2_4_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.4.2.4.2 + ansible.builtin.lineinfile: + backrefs: true + path: "/etc/pam.d/{{ item }}" + regexp: (.*pam_unix.so.*)remember(.*) + line: \1\2 + loop: + - system-auth + - password-auth + +- name: "4.4.2.4.3 | PATCH | Ensure pam_unix includes a strong password hashing algorithm" + when: + - amazon2cis_rule_4_4_2_4_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.4.2.4.3 + ansible.builtin.lineinfile: + backrefs: true + path: "/etc/pam.d/{{ item }}" + regexp: (.*pam_unix.so.*)(md5|bigcrypt|sha256|blowfish)(.*) + line: \1\2 sha512 + loop: + - system-auth + - password-auth + +- name: "4.4.2.4.4 | PATCH | Ensure pam_unix includes use_authtok" + when: + - amazon2cis_rule_4_4_2_4_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.4.2.4.4 + - NIST800-53R5_IA-5 + ansible.builtin.lineinfile: + backrefs: true + path: "/etc/pam.d/{{ item }}" + regexp: (.*pam_unix.so.*)(use_authtok)(.*) + line: \1use_authtok\3 + loop: + - system-auth + - password-auth diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml new file mode 100644 index 0000000..9c28584 --- /dev/null +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -0,0 +1,186 @@ +--- + +- name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured" + when: + - amazon2cis_rule_4_5_1_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.5.1.1 + - NIST800-53R5_IA-5 + block: + - name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured | libuser.conf" + ansible.builtin.lineinfile: + path: /etc/libuser.conf + regexp: ^(?i)(#|)\s*crypt_style + line: "crypt_style = {{ amazon2cis_encryption }}" + + - name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured | login.defs" + ansible.builtin.lineinfile: + path: /etc/login.defs + regexp: ^(?i)(#|)\s*ENCRYPT_METHOD + line: "ENCRYPT_METHOD {{ amazon2cis_encryption | upper }}" + + - name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured | Captures users who need to change passwd" + when: amazon2cis_force_user_passwd_change + ansible.builtin.shell: "awk -F: '( $3>='{{ amazon2cis_uid_min }}' && $1 != 'nfsnobody' ) { print $1 }' /etc/passwd" + failed_when: false + changed_when: false + register: amazon2cis_4_5_1_1_user_crypt_password + + - name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured | force user password change" + when: + - amazon2cis_force_user_passwd_change + - amazon2cis_4_5_1_1_user_crypt_password.stdout | length > 0 + ansible.builtin.shell: "chage -d 0 {{ item }}" + loop: "{{ amazon2cis_4_5_1_1_user_crypt_password.stdout_lines }}" + +- name: "4.5.1.2 | PATCH | Ensure password expiration is 365 days or less" + when: + - amazon2cis_rule_4_5_1_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - pam + - pam_unix + - rule_4.5.1.2 + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + block: + - name: "4.5.1.2 | PATCH | Ensure password expiration is 365 days or less | Set /etc/login.defs PASS_MAX_DAYS" + ansible.builtin.lineinfile: + path: /etc/login.defs + regexp: '^PASS_MAX_DAYS|^#PASS_MAX_DAYS' + line: 'PASS_MAX_DAYS {{ amazon2cis_pass.max_days }}' + insertafter: '# Password aging controls' + + - name: "4.5.1.2 | PATCH | Ensure password expiration is 365 days or less | Get existing users PASS_MAX_DAYS" + ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5>{{ amazon2cis_pass.max_days }} || $5<{{ amazon2cis_pass.min_days }} || $5 == -1)){print $1}' /etc/shadow" + changed_when: false + failed_when: false + register: amazon2cis_4_5_1_2_max_days + + - name: "4.5.1.2 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS" + ansible.builtin.shell: chage --maxdays {{ amazon2cis_pass.max_days }} {{ item }} + failed_when: false + changed_when: amazon2cis_4_5_1_2_max_days.stdout | length > 0 + loop: "{{ amazon2cis_4_5_1_2_max_days.stdout_lines }}" + when: + - amazon2cis_disruption_high + - item not in amazon2cis_user_skip_list + +- name: "4.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more" + when: + - amazon2cis_rule_4_5_1_3 + tags: + - level1 + - automated + - patch + - rule_4.5.1.3 + - accounts + - password + block: + - name: "4.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more" + ansible.builtin.lineinfile: + path: /etc/login.defs + regexp: '^PASS_WARN_AGE' + line: "PASS_WARN_AGE {{ amazon2cis_pass['warn_age'] }}" + + - name: "4.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more | Get existing users WARN_DAYS" + ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5>{{ amazon2cis_pass['max_days'] }} || $5<{{ amazon2cis_pass['min_days'] }} || $5 == -1)){print $1}' /etc/shadow" + changed_when: false + failed_when: amazon2cis_users_warn_days.rc not in [ 0, 1 ] + register: amazon2cis_users_warn_days + + - name: "4.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more | change users not matching req" + when: + - amazon2cis_users_warn_days is defined + - amazon2cis_users_warn_days.stdout | length > 0 + ansible.builtin.shell: chage --warndays {{ amazon2cis_pass['warn_age'] }} {{ item }} + loop: "{{ amazon2cis_users_warn_days.stdout_lines }}" + +- name: "4.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less" + when: + - amazon2cis_rule_4_5_1_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - shadow_suite + - rule_4.5.1.4 + block: + - name: "4.5.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | capture default state" + ansible.builtin.shell: useradd -D | grep INACTIVE | cut -d= -f2 + changed_when: false + failed_when: amazon2cis_users_inactive_def.rc not in [ 0, 1 ] + register: amazon2cis_users_inactive_def + + - name: "4.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | change default" + when: + - amazon2cis_users_inactive_def is defined + - (amazon2cis_pass.inactive | string) not in amazon2cis_users_inactive_def.stdout + ansible.builtin.shell: "useradd -D -f {{ amazon2cis_pass.inactive }}" + + - name: "4.5.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | capture users not matching" + ansible.builtin.shell: | + awk -F: '/^[^#:]+:[^!*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\s*$/ {print $1}' /etc/shadow + changed_when: false + failed_when: amazon2cis_users_inactive.rc not in [ 0, 1 ] + register: amazon2cis_users_inactive + + - name: "4.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | change users not matching req" + when: + - amazon2cis_users_inactive is defined + - amazon2cis_users_inactive.stdout | length > 0 + ansible.builtin.shell: "chage --inactive {{ amazon2cis_pass.inactive }} {{ item }}" + loop: "{{ amazon2cis_users_inactive.stdout_lines }}" + +- name: "4.5.1.5 | PATCH | Ensure all users last password change date is in the past" + when: + - amazon2cis_rule_4_5_1_5 + tags: + - level1-server + - level1-workstation + - automated + - patch + - shadow_suite + - rule_4.5.1.5 + vars: + warn_control_id: '4.5.1.5' + block: + - name: "4.5.1.5 | FACT | Ensure inactive password lock is 30 days or less | set fact days since_epoch" + ansible.builtin.set_fact: + days_since_epoch: "{{ (ansible_facts['date_time']['epoch']|int)/86400 }}" + + - name: "4.5.1.5 | AUDIT | Ensure inactive password lock is 30 days or less | capture users date in future" + ansible.builtin.shell: | + awk -F: '{ if ($3 > "{{ days_since_epoch }}") { print $1 } }' /etc/shadow + changed_when: false + failed_when: amazon2cis_users_user_future.rc not in [ 0, 1 ] + register: amazon2cis_users_user_future + + - name: "4.5.1.5 | WARN | Ensure inactive password lock is 30 days or less | Warn Users in future" + when: + - amazon2cis_users_user_future + - amazon2cis_users_user_future.stdout | length > 0 + ansible.builtin.debug: + msg: + - "Warning!! - The following users have passwords set in the future please investigate" + - "{{ amazon2cis_users_user_future.stdout_lines }}" + + - name: "4.5.1.5 | WARN | Ensure inactive password lock is 30 days or less | Warn Users in future" + when: + - amazon2cis_users_user_future + - amazon2cis_users_user_future.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml diff --git a/tasks/section_4/cis_4.5.2.x.yml b/tasks/section_4/cis_4.5.2.x.yml new file mode 100644 index 0000000..c1c47e6 --- /dev/null +++ b/tasks/section_4/cis_4.5.2.x.yml @@ -0,0 +1,99 @@ +--- + +- name: "4.5.2.1 | PATCH | Ensure default group for the root account is GID 0" + when: + - amazon2cis_rule_4_5_2_1 + tags: + - level1-server + - level1-workstation + - automated + - patch + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - root + - rule_4.5.2.1 + ansible.builtin.user: + name: root + group: 0 + +- name: "4.5.2.2 | PATCH | Ensure root user umask is configured" + when: + - amazon2cis_rule_4_5_2_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + - shadow_suite + - rule_4.5.2.2 + ansible.builtin.lineinfile: + path: /root/.bash_profile + regexp: \s*umask + line: "umask {{ amazon2cis_root_umask }}" + +- name: "4.5.2.3 | PATCH | Ensure system accounts are secured" + when: + - amazon2cis_rule_4_5_2_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - NIST800-53R5_AC-2 + - NIST800-53R5_AC-3 + - NIST800-53R5_AC-11 + - NIST800-53R5_MP-2 + - shadow_suite + - rule_4.5.2.3 + block: + - name: "4.5.2.3 | PATCH | | Ensure system accounts are secured | Set nologin" + when: + - item.id != "root" + - item.id != "sync" + - item.id != "shutdown" + - item.id != "halt" + - item.id != "nfsnobody" + - item.uid < amazon2cis_min_uid | int + - item.shell != " /bin/false" + - item.shell != " /usr/sbin/nologin" + ansible.builtin.user: + name: "{{ item.id }}" + shell: /usr/sbin/nologin + loop: "{{ amazon2cis_passwd }}" + loop_control: + label: "{{ item.id }}" + + - name: "4.5.2.3 | PATCH | Ensure system accounts are secured | Lock accounts" + when: + - item.id != "root" + - item.id != "sync" + - item.id != "shutdown" + - item.id != "halt" + - item.id != "nfsnobody" + - item.uid < amazon2cis_min_uid | int + - item.shell != " /bin/false" + - item.shell != " /usr/sbin/nologin" + ansible.builtin.user: + name: "{{ item.id }}" + password_lock: true + loop: "{{ amazon2cis_passwd }}" + loop_control: + label: "{{ item.id }}" + +- name: "4.5.2.4 | PATCH | Ensure root password is set" + when: + - amazon2cis_rule_4_5_2_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - shadow_suite + - rule_4.5.2.4 + ansible.builtin.debug: + msg: "This is set as an assert in tasks/main" diff --git a/tasks/section_4/cis_4.5.3.x.yml b/tasks/section_4/cis_4.5.3.x.yml new file mode 100644 index 0000000..af527c3 --- /dev/null +++ b/tasks/section_4/cis_4.5.3.x.yml @@ -0,0 +1,68 @@ +--- + +- name: "4.5.3.1 | PATCH | Ensure nologin is not listed in /etc/shells" + when: + - amazon2cis_rule_4_5_3_1 + tags: + - level2-server + - level2-workstation + - automated + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - patch + - shells + - rule_4.5.3.1 + ansible.builtin.replace: + path: /etc/shells + regexp: nologin + replace: "" + +- name: "4.5.3.2 | PATCH | Ensure default user shell timeout is configured" + when: + - amazon2cis_rule_4_5_3_2 + tags: + - level1-server + - level1-workstation + - automated + - patch + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + - shell + - rule_4.5.3.2 + ansible.builtin.blockinfile: + path: "{{ item.path }}" + state: "{{ item.state }}" + marker: "# {mark} - CIS benchmark - Ansible-lockdown" + create: true + mode: '0644' + block: | + TMOUT={{ amazon2cis_shell_session_timeout.timeout }} + readonly TMOUT + export TMOUT + loop: + - { path: "{{ amazon2cis_shell_session_timeout.file }}", state: present } + - { path: /etc/profile, state: "{{ (amazon2cis_shell_session_timeout.file == '/etc/profile') | ternary('present', 'absent') }}" } + +- name: "4.5.3.3 | PATCH | Ensure default user umask is configured" + when: + - amazon2cis_rule_4_5_3_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - umask + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + - rule_4.5.3.3 + ansible.builtin.replace: + path: "{{ item.path }}" + regexp: (?i)(umask\s+\d\d\d) + replace: '{{ item.line }} 027' + loop: + - { path: '/etc/bashrc', line: 'umask' } + - { path: '/etc/profile', line: 'umask' } + - { path: '/etc/login.defs', line: 'UMASK' } diff --git a/tasks/section_4/main.yml b/tasks/section_4/main.yml index c540a05..00bf9e9 100644 --- a/tasks/section_4/main.yml +++ b/tasks/section_4/main.yml @@ -1,19 +1,45 @@ --- -- name: "SECTION | 4.1.1 | Ensure auditing is enabled" - include_tasks: cis_4.1.1.x.yml +- name: "SECTION | 4.1.x.x | Configure Job Schedulers" + ansible.builtin.import_tasks: + file: cis_4.1.x.x.yml -- name: "SECTION | 4.1.2.x | Configure Data Retention" - include_tasks: cis_4.1.2.x.yml +- name: "SECTION | 4.2.x | Configure SSH Server" + ansible.builtin.import_tasks: + file: cis_4.2.x.yml -- name: "SECTION | 4.1.x | Misc" - include_tasks: cis_4.1.x.yml +- name: "SECTION | 4.3.x | Configure Privilege Escalation" + ansible.builtin.import_tasks: + file: cis_4.3.x.yml -- name: "SECTION | 4.2.x | Configure Logging" - include_tasks: cis_4.2.1.x.yml +- name: "SECTION | 4.4.1.x | Configure PAM software" + ansible.builtin.import_tasks: + file: cis_4.4.1.x.yml -- name: "SECTION | 4.2.2.x | Configure journald" - include_tasks: cis_4.2.2.x.yml +- name: "SECTION | 4.4.2.1.x | Configure pam_faillock" + ansible.builtin.import_tasks: + file: cis_4.4.2.1.x.yml -- name: "SECTION | 4.2.x | Misc. Logging settings" - include_tasks: cis_4.2.x.yml +- name: "SECTION | 4.4.2.2.x | Configure pam_pwquality" + ansible.builtin.import_tasks: + file: cis_4.4.2.2.x.yml + +- name: "SECTION | 4.4.2.3.x | Configure pam_pwhistory" + ansible.builtin.import_tasks: + file: cis_4.4.2.3.x.yml + +- name: "SECTION | 4.4.2.4.x | Configure pam_unix" + ansible.builtin.import_tasks: + file: cis_4.4.2.4.x.yml + +- name: "SECTION | 4.5.1.x | Configure shadow password settings" + ansible.builtin.import_tasks: + file: cis_4.5.1.x.yml + +- name: "SECTION | 4.5.2.x | Configure root and system accounts" + ansible.builtin.import_tasks: + file: cis_4.5.2.x.yml + +- name: "SECTION | 4.5.3.x | Configure user default env" + ansible.builtin.import_tasks: + file: cis_4.5.3.x.yml diff --git a/tasks/section_5/cis_5.1.1.x.yml b/tasks/section_5/cis_5.1.1.x.yml new file mode 100644 index 0000000..a97b606 --- /dev/null +++ b/tasks/section_5/cis_5.1.1.x.yml @@ -0,0 +1,210 @@ +--- + +- name: "5.1.1.1 | PATCH | Ensure rsyslog installed" + when: + - "'rsyslog' not in ansible_facts.packages" + - amazon2cis_rule_5_1_1_1 + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - rule_5.1.1.1 + ansible.builtin.package: + name: rsyslog + state: present + +- name: "5.1.1.2 | PATCH | Ensure rsyslog service is enabled" + when: + - amazon2cis_rule_5_1_1_2 + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 + - rule_5.1.1.2 + ansible.builtin.systemd: + name: rsyslog + enabled: true + +- name: "5.1.1.3 | PATCH | Ensure journald is configured to send logs to rsyslog" + ansible.builtin.lineinfile: + path: /etc/systemd/journald.conf + regexp: "^#ForwardToSyslog=|^ForwardToSyslog=" + line: ForwardToSyslog=yes + notify: Restart_journald + when: + - amazon2cis_rule_5_1_1_3 + - amazon2cis_syslog == "rsyslog" + tags: + - level1-server + - level1-workstation + - patch + - NIST800-53R5_AC-3 + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-4 + - NIST800-53R5_AU-12 + - NIST800-53R5_MP-2 + - NIST800-53R5_SI-5 + - rsyslog + - rule_5.1.1.3 + +- name: "5.1.1.4 | PATCH | Ensure rsyslog default file permissions configured" + when: + - amazon2cis_rule_5_1_1_4 + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - rule_5.1.1.4 + notify: Restart_rsyslog + ansible.builtin.lineinfile: + path: /etc/rsyslog.conf + regexp: '^\$FileCreateMode' + line: '$FileCreateMode 0640' + +- name: "5.1.1.5 | PATCH | Ensure logging is configured" + when: + - amazon2cis_rule_5_1_1_5 + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - rule_5.1.1.5 + notify: Restart_rsyslog + block: + - name: "5.1.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out" + ansible.builtin.shell: cat /etc/rsyslog.conf + changed_when: false + failed_when: false + check_mode: false + register: amazon2_5_1_1_5_audit + + - name: "5.1.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out" + ansible.builtin.debug: + msg: + - "These are the current logging configurations for rsyslog, please review:" + - "{{ amazon2_5_1_1_5_audit.stdout_lines }}" + + - name: "5.1.1.5 | PATCH | Ensure logging is configured | mail.* log setting" + when: amazon2cis_rsyslog_ansiblemanaged + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + marker: "# {mark} MAIL LOG SETTINGS - CIS benchmark - Ansible-lockdown" + block: | + # mail logging additions to meet CIS standards + mail.* -/var/log/mail + mail.info -/var/log/mail.info + mail.warning -/var/log/mail.warning + mail.err /var/log/mail.err + insertafter: '# Log all the mail messages in one place.' + + - name: "5.1.1.5 | PATCH | Ensure logging is configured | Misc. log setting" + when: amazon2cis_rsyslog_ansiblemanaged + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + state: present + marker: "# {mark} MISC. LOG SETTINGS - CIS benchmark - Ansible-lockdown" + block: | + # misc. logging additions to meet CIS standards + *.=warning;*.=err -/var/log/warn + *.crit /var/log/warn + *.*;mail.none;news.none /var/log/messages + insertafter: '#### RULES ####' + + - name: "5.1.1.5 | PATCH | Ensure logging is configured | Local log settings" + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + state: present + marker: "#{mark} LOCAL LOG SETTINGS - CIS benchmark - Ansible-lockdown" + block: | + # local log settings to meet CIS standards + local0,local1.* -/var/log/localmessages + local2,local3.* -/var/log/localmessages + local4,local5.* -/var/log/localmessages + local6,local7.* -/var/log/localmessages + *.emerg :omusrmsg:* + insertafter: '#### RULES ####' + + - name: "5.1.1.5 | PATCH | Ensure logging is configured | Auth Settings" + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + state: present + marker: "#{mark} Auth SETTINGS - CIS benchmark - Ansible-lockdown" + block: | + # Private settings to meet CIS standards + auth,authpriv.* /var/log/secure + insertafter: '#### RULES ####' + + - name: "5.1.1.5 | PATCH | Ensure logging is configured | Cron Settings" + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + state: present + marker: "#{mark} Cron SETTINGS - CIS benchmark - Ansible-lockdown" + block: | + # Cron settings to meet CIS standards + cron.* /var/log/cron + insertafter: '#### RULES ####' + +- name: "5.1.1.6 | PATCH | Ensure rsyslog is configured to send logs to a remote log host" + when: + - amazon2cis_rule_5_1_1_6 + - amazon2cis_remote_log_server + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - rule_5.1.1.6 + notify: Restart_rsyslog + ansible.builtin.blockinfile: + path: /etc/rsyslog.conf + state: present + block: | + # target can be IP or FQDN + *.* action(type="omfwd" target="{{ amazon2cis_remote_log_host }}" port="{{ amazon2cis_remote_log_port }}" protocol="{{ amazon2cis_remote_log_protocol }}" action.resumeRetryCount="{{ amazon2cis_remote_log_retrycount }}" queue.type="LinkedList" queue.size="{{ amazon2cis_remote_log_queuesize }}") + insertafter: EOF + register: result + failed_when: + - result is failed + - result.rc != 257 + +- name: "5.1.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client" + when: + - amazon2cis_rule_5_1_1_7 + tags: + - level1-server + - level1-workstation + - patch + - rsyslog + - rule_5.1.1.7 + notify: Restart_rsyslog + block: + - name: "5.1.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client. | When not log host" + when: not amazon2cis_system_is_log_server + ansible.builtin.replace: + path: /etc/rsyslog.conf + regexp: '{{ item }}' + replace: '#\1' + loop: + - '^(\$ModLoad imtcp)' + - '^(\$InputTCPServerRun)' + - '^(module\(load="imtcp"\))' + - '^(input\(type="imtcp")' + + - name: "5.1.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote clients. | When log host" + when: amazon2cis_system_is_log_server + ansible.builtin.replace: + path: /etc/rsyslog.conf + regexp: '^#(.*{{ item }}.*)' + replace: '\1' + loop: + - 'ModLoad imtcp' + - 'InputTCPServerRun' diff --git a/tasks/section_5/cis_5.1.2.x.yml b/tasks/section_5/cis_5.1.2.x.yml new file mode 100644 index 0000000..6fdee38 --- /dev/null +++ b/tasks/section_5/cis_5.1.2.x.yml @@ -0,0 +1,197 @@ +--- + +- name: "5.1.2.1.1 | PATCH | Ensure systemd-journal-remote is installed" + when: + - amazon2cis_rule_5_1_2_1_1 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - manual + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - journald + - rule_5.1.2.1.1 + ansible.builtin.package: + name: systemd-journal-remote + state: present + +- name: "5.1.2.1.2 | PATCH | Ensure systemd-journal-remote is configured" + when: + - amazon2cis_rule_5_1_2_1_2 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - manual + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - journald + - rule_5.1.2.1.2 + notify: Restart_systemd_journal_upload + ansible.builtin.lineinfile: + path: /etc/systemd/journal-upload.conf + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + loop: + - { regexp: 'URL=', line: 'URL={{ amazon2cis_journal_upload_url }}'} + - { regexp: 'ServerKeyFile=', line: 'ServerKeyFile={{ amazon2cis_journal_upload_serverkeyfile }}'} + - { regexp: 'ServerCertificateFile=', line: 'ServerCertificateFile={{ amazon2cis_journal_servercertificatefile }}'} + - { regexp: 'TrustedCertificateFile=', line: 'TrustedCertificateFile={{ amazon2cis_journal_trustedcertificatefile }}'} + +- name: "5.1.2.1.3 | PATCH | Ensure systemd-journal-remote is enabled" + when: + - amazon2cis_system_is_log_server + - amazon2cis_rule_5_1_2_1_3 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - automated + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - journald + - rule_5.1.2.1.3 + ansible.builtin.systemd: + name: systemd-journal-upload + state: started + enabled: true + +- name: "5.1.2.1.4 | PATCH | Ensure journald is not configured to recieve logs from a remote client" + when: + - not amazon2cis_system_is_log_server + - amazon2cis_rule_5_1_2_1_4 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - automated + - patch + - journald + - rule_5.1.2.1.4 + ansible.builtin.systemd: + name: systemd-journal-remote.socket + state: stopped + enabled: false + masked: true + +- name: "5.1.2.2 | PATCH | Ensure journald service is enabled" + when: + - amazon2cis_rule_5_1_2_2 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - automated + - audit + - journald + - rule_5.1.2.2 + block: + - name: "5.1.2.2 | PATCH | Ensure journald service is enabled | Enable service" + ansible.builtin.systemd: + name: systemd-journald + state: started + enabled: true + + - name: "5.1.2.2 | AUDIT | Ensure journald service is enabled | Capture status" + ansible.builtin.shell: systemctl is-enabled systemd-journald.service + changed_when: false + failed_when: false + register: amazon2cis_5_1_2_2_status + + - name: "5.1.2.2 | AUDIT | Ensure journald service is enabled | Alert on bad status" + ansible.builtin.debug: + msg: + - "Warning!! The status of systemd-journald should be static and it is not. Please investigate" + when: "'static' not in amazon2cis_5_1_2_2_status.stdout" + + - name: "5.1.2.2 | AUDIT | Ensure journald service is enabled | Warn Count" + ansible.builtin.import_tasks: + file: warning_facts.yml + vars: + warn_control_id: '5.1.2.2' + when: "'static' not in amazon2cis_5_1_2_2_status.stdout" + +- name: "5.1.2.3 | PATCH | Ensure journald is configured to compress large log files" + when: + - amazon2cis_rule_5_1_2_3 + tags: + - level1-server + - level1-workstation + - automated + - patch + - journald + - rule_5.1.2.3 + notify: Restart_journald + ansible.builtin.lineinfile: + path: /etc/systemd/journald.conf + regexp: 'Compress=' + line: Compress=yes + insertafter: ^#Compress + validate: /usr/bin/bash -n %s + +- name: "5.1.2.4 | PATCH | Ensure journald is configured to write logfiles to persistent disk" + when: + - amazon2cis_rule_5_1_2_4 + tags: + - level1-server + - level1-workstation + - automated + - patch + - journald + - rule_5.1.2.4 + notify: Restart_journald + ansible.builtin.lineinfile: + path: /etc/systemd/journald.conf + regexp: 'Storage=' + line: Storage=persistent + state: present + insertafter: ^#Storage + validate: /usr/bin/bash -n %s + +# This is counter to control 5.1.1.3?? +- name: "5.1.2.5 | PATCH | Ensure journald is not configured to send logs to rsyslog" + when: + - amazon2cis_rule_5_1_2_5 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level2-workstation + - manual + - patch + - journald + - rule_5.1.2.5 + notify: Restart_journald + ansible.builtin.lineinfile: + path: /etc/systemd/journald.conf + regexp: "^ForwardToSyslog=" + line: "#ForwardToSyslog=yes" + +- name: "5.1.2.6 | PATCH | Ensure journald log rotation is configured per site policy" + when: + - amazon2cis_rule_5_1_2_6 + - amazon2cis_syslog == 'journald' + tags: + - level1-server + - level1-workstation + - manual + - patch + - journald + - rule_5.1.2.6 + ansible.builtin.lineinfile: + path: /etc/systemd/journald.conf + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + notify: Restart_journald + loop: + - { regexp: '^#SystemMaxUse=|^SystemMaxUse=', line: 'SystemMaxUse={{ amazon2cis_journald_systemmaxuse }}'} + - { regexp: '^#SystemKeepFree=|^SystemKeepFree=', line: 'SystemKeepFree={{ amazon2cis_journald_systemkeepfree }}' } + - { regexp: '^#RuntimeMaxUse=|^RuntimeMaxUse=', line: 'RuntimeMaxUse={{ amazon2cis_journald_runtimemaxuse }}'} + - { regexp: '^#RuntimeKeepFree=|^RuntimeKeepFree=', line: 'RuntimeKeepFree={{ amazon2cis_journald_runtimekeepfree }}'} + - { regexp: '^#MaxFileSec=|^MaxFileSec=', line: 'MaxFileSec={{ amazon2cis_journald_maxfilesec }}'} diff --git a/tasks/section_5/cis_5.1.3.yml b/tasks/section_5/cis_5.1.3.yml new file mode 100644 index 0000000..3547a3a --- /dev/null +++ b/tasks/section_5/cis_5.1.3.yml @@ -0,0 +1,30 @@ +--- + +- name: "5.1.3 | PATCH | Ensure logrotate is configured" + when: + - amazon2cis_rule_5_1_3 + tags: + - level1-server + - level1-workstation + - manual + - patch + - logrotate + - rule_5.1.3 + block: + - name: "5.1.3 | AUDIT | Ensure logrotate is configured | Get logrotate settings" + ansible.builtin.find: + paths: /etc/logrotate.d/ + register: amazon2cis_log_rotate_conf + + - name: "5.1.3 | PATCH | Ensure logrotate is configured | conf files" + ansible.builtin.replace: + path: "{{ item.path }}" + regexp: '^(\s*)(daily|weekly|monthly|yearly)$' + replace: "\\1{{ amazon2cis_logrotate }}" + loop: "{{ amazon2cis_log_rotate_conf.files }}" + + - name: "5.1.3 | PATCH | Ensure logrotate is configured | logrotate.conf" + ansible.builtin.replace: + path: /etc/logrotate.conf + regexp: '^(\s*)(daily|weekly|monthly|yearly)$' + replace: "\\1{{ amazon2cis_logrotate }}" diff --git a/tasks/section_5/cis_5.1.4.yml b/tasks/section_5/cis_5.1.4.yml new file mode 100644 index 0000000..3d34db2 --- /dev/null +++ b/tasks/section_5/cis_5.1.4.yml @@ -0,0 +1,37 @@ +--- + +- name: "5.1.4 | PATCH | Ensure all logfiles have appropriate access configured" + when: + - amazon2cis_rule_5_1_4 + tags: + - level1-server + - level1-workstation + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - logfiles + - rule_5.1.4 + block: + - name: "5.1.4 | AUDIT | Ensure all logfiles have appropriate access configured | find files" + ansible.builtin.shell: find /var/log/ -type f -perm /g+wx,o+rwx -exec ls {} \; + changed_when: false + failed_when: false + register: amazon2cis_5_1_4_logfiles + + - name: "5.1.4 | AUDIT | Ensure all logfiles have appropriate access configured | set_fact" + ansible.builtin.set_fact: + amazon2cis_4_2_3_logfiles_flattened: "{{ amazon2cis_5_1_4_logfiles | json_query('stdout_lines[*]') | flatten }}" # noqa: jinja[invalid] + when: + - amazon2cis_5_1_4_logfiles.stdout_lines | length > 0 + - amazon2cis_5_1_4_logfiles is defined + + - name: "5.1.4 | PATCH | Ensure all logfiles have appropriate access configured | change permissions" + ansible.builtin.file: + path: "{{ item }}" + mode: '0640' + loop: "{{ amazon2cis_5_1_4_logfiles_flattened }}" + when: + - amazon2cis_5_1_4_logfiles_flattened is defined + - item != "/var/log/btmp" + - item != "/var/log/utmp" + - item != "/var/log/wtmp" diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml deleted file mode 100644 index 22b85a4..0000000 --- a/tasks/section_5/cis_5.1.x.yml +++ /dev/null @@ -1,170 +0,0 @@ ---- - -- name: "5.1.1 | PATCH | Ensure cron daemon is enabled and running" - service: - name: crond - state: started - enabled: true - when: - - amazon2cis_rule_5_1_1 - tags: - - level1 - - automated - - patch - - rule_5.1.1 - - cron - -- name: "5.1.2 | PATCH | Ensure permissions on /etc/crontab are configured" - file: - dest: /etc/crontab - owner: root - group: root - mode: 0600 - when: - - amazon2cis_rule_5_1_2 - tags: - - level1 - - automated - - patch - - rule_5.1.2 - - permissions - - cron - -- name: "5.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured" - file: - dest: /etc/cron.hourly - state: directory - owner: root - group: root - mode: 0700 - when: - - amazon2cis_rule_5_1_3 - tags: - - level1 - - automated - - patch - - rule_5.1.3 - - permissions - - cron - -- name: "5.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured" - file: - dest: /etc/cron.daily - state: directory - owner: root - group: root - mode: 0700 - when: - - amazon2cis_rule_5_1_4 - tags: - - level1 - - automated - - patch - - rule_5.1.4 - - permissions - - cron - -- name: "5.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured" - file: - dest: /etc/cron.weekly - state: directory - owner: root - group: root - mode: 0700 - when: - - amazon2cis_rule_5_1_5 - tags: - - level1 - - patch - - rule_5.1.5 - -- name: "5.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured" - file: - dest: /etc/cron.monthly - state: directory - owner: root - group: root - mode: 0700 - when: - - amazon2cis_rule_5_1_6 - tags: - - level1 - - automated - - patch - - rule_5.1.6 - - permissions - - cron - -- name: "5.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured" - file: - dest: /etc/cron.d - state: directory - owner: root - group: root - mode: 0700 - when: - - amazon2cis_rule_5_1_7 - tags: - - level1 - - automated - - patch - - rule_5.1.7 - - permissions - - cron - -- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users" - block: - - name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Remove cron.deny" - file: - dest: /etc/cron.deny - state: absent - - - name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Check if cron.allow exists" - stat: - path: "/etc/cron.allow" - register: amazon2cis_5_1_8_p - - - name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Ensure cron.allow is restricted to authorized users" - file: - dest: /etc/cron.allow - state: '{{ "file" if amazon2cis_5_1_8_p.stat.exists else "touch" }}' - owner: root - group: root - mode: 0600 - when: - - amazon2cis_rule_5_1_8 - tags: - - level1 - - automated - - patch - - rule_5.1.8 - - permissions - - cron - -- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users" - block: - - name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Remove at.deny" - file: - dest: /etc/at.deny - state: absent - - - name: "5.1.9 | AUDIT | Ensure at is restricted to authorized users | Check if at.allow exists" - stat: - path: "/etc/at.allow" - register: amazon2cis_5_1_9_p - - - name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Ensure at.allow is restricted to authorized users" - file: - dest: /etc/at.allow - state: '{{ "file" if amazon2cis_5_1_9_p.stat.exists else "touch" }}' - owner: root - group: root - mode: 0600 - when: - - amazon2cis_rule_5_1_9 - tags: - - level1 - - automated - - patch - - rule_5.1.9 - - at diff --git a/tasks/section_5/cis_5.2.1.x.yml b/tasks/section_5/cis_5.2.1.x.yml new file mode 100644 index 0000000..4b07f19 --- /dev/null +++ b/tasks/section_5/cis_5.2.1.x.yml @@ -0,0 +1,121 @@ +--- + +- name: "5.2.1.1 | PATCH | Ensure audit is installed" + when: + - amazon2cis_rule_5_2_1_1 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - auditd + - rule_5.2.1.1 + block: + - name: "5.2.1.1 | PATCH | Ensure auditd is installed | Install auditd packages" + ansible.builtin.package: + name: audit + state: present + when: '"auditd" not in ansible_facts.packages' + + - name: "5.2.1.1 | PATCH | Ensure auditd is installed | Install auditd-lib packages" + ansible.builtin.package: + name: audit-libs + state: present + when: '"auditd-lib" not in ansible_facts.packages' + +- name: "5.2.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled" + when: + - amazon2cis_rule_5_2_1_2 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - grub + - rule_5.2.1.2 + notify: Rebuild_grub + block: + - name: "5.2.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get GRUB_CMDLINE_LINUX" + ansible.builtin.shell: grep "GRUB_CMDLINE_LINUX_DEFAULT=" /etc/default/grub | cut -f2 -d'"' + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_5_2_1_2_grub_cmdline_linux + + - name: "5.2.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Replace existing setting" + when: "'audit=' in amazon2cis_5_2_1_2_grub_cmdline_linux.stdout" + ansible.builtin.replace: + dest: /etc/default/grub + regexp: 'audit=([0-9]+)' + replace: 'audit=1' + after: '^GRUB_CMDLINE_LINUX_DEFAULT="' + before: '"' + + - name: "5.2.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Add audit setting if missing" + when: "'audit=' not in amazon2cis_5_2_1_2_grub_cmdline_linux.stdout" + ansible.builtin.lineinfile: + path: /etc/default/grub + regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=' + line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ amazon2cis_5_2_1_2_grub_cmdline_linux.stdout }} audit=1"' + +- name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient" + when: + - amazon2cis_rule_5_2_1_3 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - grub + - rule_5.2.1.3 + notify: Rebuild_grub + block: + - name: "5.2.1.3 | AUDIT | Ensure audit_backlog_limit is sufficient | Get GRUB_CMDLINE_LINUX" + ansible.builtin.shell: grep 'GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | cut -f2 -d'"' + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_5_2_1_3_grub_cmdline_linux + + - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Replace existing setting" + when: "'audit_backlog_limit=' in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" + ansible.builtin.replace: + dest: /etc/default/grub + regexp: 'audit_backlog_limit=([0-9]+)' + replace: 'audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}' + after: '^GRUB_CMDLINE_LINUX_DEFAULT="' + before: '"' + + - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Add audit_backlog_limit setting if missing" + when: "'audit_backlog_limit=' not in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" + ansible.builtin.lineinfile: + path: /etc/default/grub + regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=' + line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ amazon2cis_5_2_1_3_grub_cmdline_linux.stdout }} audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}"' + +- name: "5.2.1.4 | PATCH | Ensure auditd service is enabled" + when: + - amazon2cis_rule_5_2_1_4 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - auditd + - rule_5.2.1.4 + ansible.builtin.service: + name: auditd + state: started + enabled: true diff --git a/tasks/section_5/cis_5.2.2.x.yml b/tasks/section_5/cis_5.2.2.x.yml new file mode 100644 index 0000000..98e8c13 --- /dev/null +++ b/tasks/section_5/cis_5.2.2.x.yml @@ -0,0 +1,81 @@ +--- + +- name: "5.2.2.1 | PATCH | Ensure audit log storage size is configured" + when: + - amazon2cis_rule_5_2_2_1 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-8 + - auditd + - rule_5.2.2.1 + notify: Restart_auditd + ansible.builtin.lineinfile: + path: /etc/audit/auditd.conf + regexp: ^max_log_file(\s|=) + line: "max_log_file = {{ amazon2cis_max_log_file_size }}" + +- name: "5.2.2.2 | PATCH | Ensure audit logs are not automatically deleted" + when: + - amazon2cis_rule_5_2_2_2 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-8 + - auditd + - rule_5.2.2.2 + notify: Restart_auditd + ansible.builtin.lineinfile: + path: /etc/audit/auditd.conf + regexp: "^max_log_file_action" + line: "max_log_file_action = {{ amazon2cis_auditd['max_log_file_action'] }}" + +- name: "5.2.2.3 | PATCH | Ensure system is disabled when audit logs are full" + when: + - amazon2cis_rule_5_2_2_3 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-8 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - auditd + - rule_5.2.2.3 + ansible.builtin.lineinfile: + path: /etc/audit/auditd.conf + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + notify: Restart_auditd + loop: + - { regexp: '^disk_full_action', line: 'disk_full_action = {{ amazon2cis_auditd.disk_full_action }}' } + - { regexp: '^disk_error_action', line: 'disk_error_action = {{ amazon2cis_auditd.disk_error_action }}' } + +- name: "5.2.2.4 | PATCH | Ensure system warns when audit logs are low on space" + when: + - amazon2cis_rule_5_2_2_4 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-2 + - NIST800-53R5_AU-8 + - NIST800-53R5_AU-12 + - NIST800-53R5_SI-5 + - auditd + - rule_5.2.2.4 + ansible.builtin.lineinfile: + path: /etc/audit/auditd.conf + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + notify: Restart_auditd + loop: + - { regexp: '^admin_space_left_action', line: 'admin_space_left_action = {{ amazon2cis_auditd.admin_space_left_action }}' } + - { regexp: '^space_left_action', line: 'space_left_action = {{ amazon2cis_auditd.space_left_action }}' } diff --git a/tasks/section_5/cis_5.2.3.x.yml b/tasks/section_5/cis_5.2.3.x.yml new file mode 100644 index 0000000..3039afb --- /dev/null +++ b/tasks/section_5/cis_5.2.3.x.yml @@ -0,0 +1,299 @@ +--- + +- name: "5.2.3.1 | PATCH | Ensure changes to system administration scope (sudoers) is collected" + when: + - amazon2cis_rule_5_2_3_1 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.1 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.2 | PATCH | Ensure actions as another user are always logged" + when: + - amazon2cis_rule_5_2_3_2 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.2 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.3 | PATCH | Ensure events that modify the sudo log file are collected" + when: + - amazon2cis_rule_5_2_3_3 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.3 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.4 | PATCH | Ensure events that modify date and time information are collected" + when: + - amazon2cis_rule_5_2_3_4 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.4 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.5 | PATCH | Ensure events that modify the system's network environment are collected" + when: + - amazon2cis_rule_5_2_3_5 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.5 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.6 | AUDIT | Ensure use of privileged commands is collected" + when: + - amazon2cis_rule_5_2_3_6 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-3 + - auditd + - rule_5.2.3.6 + block: + - name: "5.2.3.6 | AUDIT | Ensure use of privileged commands is collected" + ansible.builtin.shell: for i in $(df | grep '^/dev' | awk '{ print $NF }'); do find $i -xdev -type f -perm /6000 2>/dev/null; done + changed_when: false + failed_when: false + check_mode: false + register: priv_procs + + - name: "5.2.3.6 | AUDIT | Ensure use of privileged commands is collected | set_fact for auditd rules" + ansible.builtin.set_fact: + update_audit_template: true + notify: Update_auditd_rules + +- name: "5.2.3.7 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected" + ansible.builtin.set_fact: + update_audit_template: true + when: + - amazon2cis_rule_5_2_3_7 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3_7 + +- name: "5.2.3.8 | PATCH | Ensure events that modify user/group information are collected" + when: + - amazon2cis_rule_5_2_3_8 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.8 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.9 | PATCH | Ensure discretionary access control permission modification events are collected" + when: + - amazon2cis_rule_5_2_3_9 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.9 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.10 | PATCH | Ensure successful file system mounts are collected" + when: + - amazon2cis_rule_5_2_3_10 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_CM-6 + - auditd + - rule_5.2.3.10 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.11 | PATCH | Ensure session initiation information is collected" + when: + - amazon2cis_rule_5_2_3_11 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-3 + - auditd + - rule_5.2.3.11 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.12 | PATCH | Ensure login and logout events are collected" + when: + - amazon2cis_rule_5_2_3_12 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-3 + - auditd + - rule_5.2.3.12 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.13 | PATCH | Ensure file deletion events by users are collected" + when: + - amazon2cis_rule_5_2_3_13 + tags: + - level2-server + - level2-workstation + - auditd + - patch + - rule_5.2.3.13 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.14 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected" + when: + - amazon2cis_rule_5_2_3_14 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AU-3 + - auditd + - rule_5.2.3.14 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.15 | PATCH | Ensure successful and unsuccessful attempts to use the chcon command are recorded" + when: + - amazon2cis_rule_5_2_3_15 + tags: + - level2-server + - level2- workstation + - automated + - patch + - auditd + - rule_5.2.3.15 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.16 | PATCH | Ensure successful and unsuccessful attempts to use the setfacl command are recorded" + when: + - amazon2cis_rule_5_2_3_16 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.16 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.17 | PATCH | Ensure successful and unsuccessful attempts to use the chacl command are recorded" + when: + - amazon2cis_rule_5_2_3_17 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.17 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.18 | PATCH | Ensure successful and unsuccessful attempts to use the usermod command are recorded" + when: + - amazon2cis_rule_5_2_3_18 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.18 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.19 | PATCH | Ensure kernel module loading and unloading is collected" + when: + - amazon2cis_rule_5_2_3_19 + tags: + - level2-server + - level2-workstation + - automated + - patch + - auditd + - rule_5.2.3.19 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.20 | PATCH | Ensure the audit configuration is immutable" + when: + - amazon2cis_rule_5_2_3_20 + tags: + - level2-server + - level2-workstation + - automated + - patch + - NIST800-53R5_AC-3 + - NIST800-53R5_AU-3 + - NIST800-53R5_MP-2 + - auditd + - rule_4.1.20 + ansible.builtin.set_fact: + update_audit_template: true + +- name: "5.2.3.21 | AUDIT | Ensure the running and on disk configuration is the same" + when: + - amazon2cis_rule_5_2_3_21 + tags: + - level2-server + - level2-workstation + - manual + - patch + - auditd + - rule_5.2.3.21 + ansible.builtin.debug: + msg: + - "Please run augenrules --load if you suspect there is a configuration that is not active" + +- name: Auditd | 5.2.3 | Auditd controls updated + when: + - update_audit_template + ansible.builtin.debug: + msg: "Auditd Controls handled in POST using template - updating /etc/auditd/rules.d/99_auditd.rules" + changed_when: false diff --git a/tasks/section_5/cis_5.2.4.x.yml b/tasks/section_5/cis_5.2.4.x.yml new file mode 100644 index 0000000..7fbeab6 --- /dev/null +++ b/tasks/section_5/cis_5.2.4.x.yml @@ -0,0 +1,174 @@ +--- + +- name: "5.2.4.1 | PATCH | Ensure the audit log directory is 0750 or more restrictive" + when: + - amazon2cis_rule_5_2_4_1 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.1 + block: + - name: "5.2.4.1 | AUDIT | Ensure the audit log directory is 0750 or more restrictive | get current permissions" + ansible.builtin.stat: + path: "{{ audit_discovered_logfile.stdout | dirname }}" + register: auditlog_dir + + - name: "5.2.4.1 | PATCH | Ensure the audit log directory is 0750 or more restrictive | set" + ansible.builtin.file: + path: "{{ audit_discovered_logfile.stdout | dirname }}" + state: directory + mode: g-w,o-rwx + +- name: | + "5.2.4.2 | PATCH | Ensure audit log files are mode 0640 or less permissive" + "5.2.4.3 | PATCH | Ensure only authorized users own audit log files" + "5.2.4.4 | PATCH | Ensure only authorized groups are assigned ownership of audit log files" + when: + - amazon2cis_rule_5_2_4_2 or + amazon2cis_rule_5_2_4_3 or + amazon2cis_rule_5_2_4_4 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.2 + - rule_5.2.4.3 + - rule_5.2.4.4 + block: + - name: "5.2.4.2 | AUDIT | Ensure audit log files are mode 0640 or less permissive | stat file" + ansible.builtin.stat: + path: "{{ audit_discovered_logfile.stdout }}" + changed_when: false + register: auditd_logfile + + - name: | + "5.2.4.2 | PATCH | Ensure audit log files are mode 0640 or less permissive" + "5.2.4.3 | PATCH | Ensure only authorized users own audit log files" + "5.2.4.4 | PATCH | Ensure only authorized groups are assigned ownership of audit log files" + ansible.builtin.file: + path: "{{ audit_discovered_logfile.stdout }}" + mode: "{% if auditd_logfile.stat.mode != '0600' %}0640{% endif %}" + owner: root + group: root + +- name: "5.2.4.5 | PATCH | Ensure audit configuration files are 640 or more restrictive" + when: + - amazon2cis_rule_5_2_4_5 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.5 + ansible.builtin.file: + path: "{{ item.path }}" + mode: g-wx,o-rwx + loop: "{{ auditd_conf_files.files }}" + loop_control: + label: "{{ item.path }}" + +- name: "5.2.4.6 | PATCH | Ensure audit configuration files are owned by root" + when: + - amazon2cis_rule_5_2_4_6 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.6 + ansible.builtin.file: + path: "{{ item.path }}" + owner: root + loop: "{{ auditd_conf_files.files }}" + loop_control: + label: "{{ item.path }}" + +- name: "5.2.4.7 | PATCH | Ensure audit configuration files belong to group root" + when: + - amazon2cis_rule_5_2_4_7 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.7 + ansible.builtin.file: + path: "{{ item.path }}" + group: root + loop: "{{ auditd_conf_files.files }}" + loop_control: + label: "{{ item.path }}" + +- name: "5.2.4.8 | PATCH | Ensure audit tools are 755 or more restrictive" + when: + - amazon2cis_rule_5_2_4_8 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.8 + block: + - name: "5.2.4.8 | AUDIT | Get audit binary file stat | get current mode" + ansible.builtin.stat: + path: "{{ item }}" + register: "audit_bins" + loop: + - /sbin/auditctl + - /sbin/aureport + - /sbin/ausearch + - /sbin/autrace + - /sbin/auditd + - /sbin/augenrules + + - name: "5.2.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required" + ansible.builtin.file: + path: "{{ item.item }}" + mode: g-w,o-w + loop: "{{ audit_bins.results }}" + loop_control: + label: "{{ item.item }}" + +- name: "5.2.4.9 | PATCH | Ensure audit tools are owned by root" + when: + - amazon2cis_rule_5_2_4_9 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.9 + ansible.builtin.file: + path: "{{ item }}" + owner: root + group: root + loop: + - /sbin/auditctl + - /sbin/aureport + - /sbin/ausearch + - /sbin/autrace + - /sbin/auditd + - /sbin/augenrules + +- name: "5.2.4.10 | PATCH | Ensure audit tools belong to group root" + when: + - amazon2cis_rule_5_2_4_10 + tags: + - level2-server + - level2-workstation + - patch + - auditd + - rule_5.2.4.10 + ansible.builtin.file: + path: "{{ item }}" + group: root + loop: + - /sbin/auditctl + - /sbin/aureport + - /sbin/ausearch + - /sbin/autrace + - /sbin/auditd + - /sbin/augenrules diff --git a/tasks/section_5/cis_5.2.x.yml b/tasks/section_5/cis_5.2.x.yml deleted file mode 100644 index 9c7e42f..0000000 --- a/tasks/section_5/cis_5.2.x.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- - -- name: "5.2.1 | PATCH | Ensure sudo is installed" - package: - name: sudo - state: present - when: - - amazon2cis_rule_5_2_1 - tags: - - level1 - - automated - - patch - - rule_5.2.1 - - sudo - -- name: "5.2.2 | PATCH | Ensure sudo commands use pty" - lineinfile: - path: /etc/sudoers - line: 'Defaults use_pty' - when: - - amazon2cis_rule_5_2_2 - tags: - - level1 - - automated - - patch - - rule_5.2.2 - - sudo - -- name: "5.2.3 | PATCH | Ensure sudo log file exists" - lineinfile: - path: /etc/sudoers - line: 'Defaults logfile="/var/log/sudo.log"' - when: - - amazon2cis_rule_5_2_3 - tags: - - level1 - - automated - - patch - - rule_5.2.3 - - sudo diff --git a/tasks/section_5/cis_5.3.x.yml b/tasks/section_5/cis_5.3.x.yml index 70e901c..a8d1f50 100644 --- a/tasks/section_5/cis_5.3.x.yml +++ b/tasks/section_5/cis_5.3.x.yml @@ -1,399 +1,73 @@ --- -- name: "5.3.1 | PATCH | Ensure permissions on /etc/ssh/sshd_config are configured" - file: - path: /etc/ssh/sshd_config - state: file - owner: root - group: root - mode: 0600 +- name: "5.3.1 | PATCH | Ensure AIDE is installed" when: + - amazon2cis_config_aide - amazon2cis_rule_5_3_1 tags: - - level1 + - level1-server + - level1-workstation - automated + - aide + - NIST800-53R5_AU-2 - patch - rule_5.3.1 - - ssh - - permissions - -- name: "5.3.2 | PATCH | Ensure permissions on SSH private host key files are configured" block: - - name: "5.3.2 | AUDIT | Ensure permissions on SSH private host key files are configured" - find: - paths: /etc/ssh - patterns: 'ssh_host_*_key' - recurse: true - file_type: any - register: amazon2_5_3_2_priv_results - - - name: "5.3.2 | AUDIT | Ensure permissions on SSH private host key files are configured" - file: - path: "{{ item.path }}" - owner: root - group: root - mode: 0600 - with_items: - - "{{ amazon2_5_3_2_priv_results.files }}" - loop_control: - label: "{{ item.path }}" + - name: "5.3.1 | PATCH | Ensure AIDE is installed | Install AIDE" + ansible.builtin.package: + name: aide + state: present + + - name: "5.3.1 | PATCH | Ensure AIDE is installed | Configure AIDE" + ansible.builtin.shell: /usr/sbin/aide --init + changed_when: false + failed_when: false + async: 45 + poll: 0 + args: + creates: /var/lib/aide/aide.db.new.gz + when: not ansible_check_mode + + - name: "5.3.1 | PATCH | Ensure AIDE is installed | copy AIDE DB" + ansible.builtin.copy: + src: /var/lib/aide/aide.db.new.gz + dest: /var/lib/aide/aide.db.gz + remote_src: true + +- name: "5.3.2 | PATCH | Ensure filesystem integrity is regularly checked" when: - amazon2cis_rule_5_3_2 + - amazon2cis_config_aide + - not system_is_ec2 tags: - - level1 + - level1-server + - level1-workstation - automated + - aide + - NIST800-53R5_AU-2 + - file_integrity - patch - rule_5.3.2 - - ssh - - permissions - -- name: "5.3.3 | PATCH | Ensure permissions on SSH public host key files are configured" - block: - - name: "5.3.3 | AUDIT | Ensure permissions on SSH public host key files are configured" - find: - paths: /etc/ssh - patterns: 'ssh_host_*_key' - recurse: true - file_type: any - register: amazon2_5_3_3_pub_results - - - name: "5.3.3 | AUDIT | Ensure permissions on SSH public host key files are configured" - file: - path: "{{ item.path }}" - owner: root - group: root - mode: 0600 - with_items: - - "{{ amazon2_5_3_3_pub_results.files }}" - loop_control: - label: "{{ item.path }}" - when: - - amazon2cis_rule_5_3_3 - tags: - - level1 - - automated - - patch - - rule_5.3.3 - - ssh - - permissions - -- name: "5.3.4 | PATCH | Ensure SSH access is limited" block: - - name: "5.3.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^AllowUsers" - line: AllowUsers {{ amazon2cis_sshd['allowusers'] }} - notify: restart sshd - when: "amazon2cis_sshd['allowusers']|default('') | length > 0" - - - name: "5.3.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^AllowGroups" - line: AllowGroups {{ amazon2cis_sshd['allowgroups'] }} - notify: restart sshd - when: "amazon2cis_sshd['allowgroups']|default('') | length > 0" - - - name: "5.3.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^DenyUsers" - line: DenyUsers {{ amazon2cis_sshd['denyusers'] }} - notify: restart sshd - when: "amazon2cis_sshd['denyusers']|default('') | length > 0" - - - name: "5.3.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^DenyGroups" - line: DenyGroups {{ amazon2cis_sshd['denygroups'] }} - notify: restart sshd - when: "amazon2cis_sshd['denygroups']|default('') | length > 0" - when: - - amazon2cis_rule_5_3_4 - tags: - - level1 - - automated - - patch - - rule_5.3.4 - - ssh - -- name: "5.3.5 | PATCH | Ensure SSH LogLevel is appropriate" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#LogLevel|^LogLevel" - line: 'LogLevel {{ amazon2cis_ssh_loglevel }}' - notify: restart sshd - when: - - amazon2cis_rule_5_3_5 - tags: - - level1 - - automated - - patch - - rule_5.3.5 - - ssh - -- name: "5.3.6 | PATCH | Ensure SSH X11 forwarding is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#X11Forwarding|^X11Forwarding" - line: 'X11Forwarding no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_6 - tags: - - level1 - - automated - - patch - - rule_5.3.6 - - ssh - -- name: "5.3.7 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^(#)?MaxAuthTries \d' - line: "MaxAuthTries {{ amazon2_max_auth_tries }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_7 - tags: - - level1 - - automated - - patch - - rule_5.3.7 - - ssh - -- name: "5.3.8 | PATCH | Ensure SSH IgnoreRhosts is enabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#IgnoreRhosts|^IgnoreRhosts" - line: 'IgnoreRhosts yes' - notify: restart sshd - when: - - amazon2cis_rule_5_3_8 - tags: - - level1 - - automated - - patch - - rule_5.3.8 - - ssh - -- name: "5.3.9 | PATCH | Ensure SSH HostbasedAuthentication is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: ^#HostbasedAuthentication|^HostbasedAuthentication" - line: 'HostbasedAuthentication no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_9 - tags: - - level1 - - automated - - patch - - rule_5.3.9 - - ssh - -- name: "5.3.10 | PATCH | Ensure SSH root login is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#PermitRootLogin|^PermitRootLogin" - line: 'PermitRootLogin no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_10 - tags: - - level1 - - automated - - patch - - rule_5.3.10 - - ssh - -- name: "5.3.11 | PATCH | Ensure SSH PermitEmptyPasswords is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords" - line: 'PermitEmptyPasswords no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_11 - tags: - - level1 - - automated - - patch - - rule_5.3.11 - - ssh - -- name: "5.3.12 | PATCH | Ensure SSH PermitUserEnvironment is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#PermitUserEnvironment|^PermitUserEnvironment" - line: 'PermitUserEnvironment no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_12 - tags: - - level1 - - automated - - patch - - rule_5.3.12 - - ssh - -- name: "5.3.13 | PATCH | Ensure only strong Ciphers are used" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^Cipherss' - line: "Ciphers {{ amazon2cis_sshd['ciphers'] }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_13 - tags: - - level1 - - automated - - patch - - rule_5.3.13 - - ssh - -- name: "5.3.14 | PATCH | Ensure only strong MAC algorithms are used" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^MACs' - line: "MACs {{ amazon2cis_sshd['macs'] }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_14 - tags: - - level1 - - automated - - patch - - rule_5.3.14 - - ssh - -- name: "5.3.15 | PATCH | Ensure only strong Key Exchange algorithms are used" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^KexAlgorithms' - line: "KexAlgorithms {{ amazon2cis_sshd['kex'] }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_15 - tags: - - level1 - - automated - - patch - - rule_5.3.15 - - ssh - -- name: "5.3.16 | PATCH | Ensure SSH Idle Timeout Interval is configured" - block: - - name: "5.3.16 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^ClientAliveInterval' - line: "ClientAliveInterval {{ amazon2cis_sshd['clientaliveinterval'] }}" - notify: restart sshd - - - name: "5.3.16 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^ClientAliveCountMax' - line: "ClientAliveCountMax {{ amazon2cis_sshd['clientalivecountmax'] }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_16 - tags: - - level1 - - automated - - patch - - rule_5.3.16 - - ssh - -- name: "5.3.17 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#LoginGraceTime|^LoginGraceTime" - line: "LoginGraceTime {{ amazon2cis_sshd['logingracetime'] }}" - notify: restart sshd - when: - - amazon2cis_rule_5_3_17 - tags: - - level1 - - automated - - patch - - rule_5.3.17 - - ssh - -- name: "5.3.18 | PATCH | Ensure SSH warning banner is configured" - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^Banner' - line: 'Banner /etc/issue.net' - notify: restart sshd - when: - - amazon2cis_rule_5_3_18 - tags: - - level1 - - automated - - patch - - rule_5.3.18 - - ssh - -- name: "5.3.19 | PATCH | Ensure SSH PAM is enabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#UsePAM|^UsePAM" - line: 'UsePAM yes' - notify: restart sshd - when: - - amazon2cis_rule_5_3_19 - tags: - - level1 - - automated - - patch - - rule_5.3.19 - - ssh - -- name: "5.3.20 | PATCH | Ensure SSH AllowTcpForwarding is disabled" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#AllowTcpForwarding|^AllowTcpForwarding" - line: 'AllowTcpForwarding no' - notify: restart sshd - when: - - amazon2cis_rule_5_3_20 - tags: - - level2 - - automated - - patch - - rule_5.3.20 - - ssh - -- name: "5.3.21 | PATCH | Ensure SSH MaxStartups is configured" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#MaxStartups|^MaxStartups" - line: 'MaxStartups 10:30:60' - notify: restart sshd - when: - - amazon2cis_rule_5_3_21 - tags: - - level1 - - automated - - patch - - rule_5.3.21 - - ssh - -- name: "5.3.22 | PATCH | Ensure SSH MaxSessions is limited" - lineinfile: - path: /etc/ssh/sshd_config - regexp: "^#MaxSessions|^MaxSessions" - line: 'MaxSessions {{ amazon2cis_ssh_maxsessions }}' - notify: restart sshd - when: - - amazon2cis_rule_5_3_22 - tags: - - level1 - - automated - - patch - - rule_5.3.22 - - ssh + - name: "5.3.2 | PATCH | Ensure filesystem integrity is regularly checked | cron" + when: amazon2cis_aide_scan == "cron" + ansible.builtin.cron: + name: Run AIDE integrity check + cron_file: "{{ amazon2cis_aide_cron['cron_file'] }}" + user: "{{ amazon2cis_aide_cron['cron_user'] }}" + minute: "{{ amazon2cis_aide_cron['aide_minute'] | default('0') }}" + hour: "{{ amazon2cis_aide_cron['aide_hour'] | default('5') }}" + day: "{{ amazon2cis_aide_cron['aide_day'] | default('*') }}" + month: "{{ amazon2cis_aide_cron['aide_month'] | default('*') }}" + weekday: "{{ amazon2cis_aide_cron['aide_weekday'] | default('*') }}" + job: "{{ amazon2cis_aide_cron['aide_job'] }}" + + - name: "5.3.2 | PATCH | Ensure filesystem integrity is regularly checked | timer" + when: amazon2cis_aide_scan == "timer" + ansible.builtin.systemd: + name: "{{ item.name }}" + enabled: true + state: "{{ item.state | default(omit)}}" + loop: + - { name: 'aidecheck.service' } + - { name: 'aidecheck.timer', state: started } diff --git a/tasks/section_5/cis_5.4.x.yml b/tasks/section_5/cis_5.4.x.yml deleted file mode 100644 index 729d68d..0000000 --- a/tasks/section_5/cis_5.4.x.yml +++ /dev/null @@ -1,131 +0,0 @@ ---- - -- name: "5.4.1 | PATCH | Ensure password creation requirements are configured" - lineinfile: - path: /etc/security/pwquality.conf - regexp: '^{{ item.key }}' - line: '{{ item.key }} = {{ item.value }}' - with_items: - - { key: 'minlen', value: '14' } - - { key: 'minclass', value: '4' } - when: - - amazon2cis_rule_5_4_1 - tags: - - level1 - - automated - - patch - - rule_5.4.1 - - pamd - -- name: | - "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured - 5.4.3 | PATCH | Ensure password hashing algorithm is SHA-512 - 5.4.4 | PATCH | Ensure password reuse is limited" - block: - - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Add deny count and unlock time for preauth" - lineinfile: - path: /etc/pam.d/{{ item }} - state: present - line: "auth required pam_faillock.so preauth audit silent deny={{ amazon2cis_pam_faillock.attempts }}{{ (amazon2cis_pam_faillock.fail_for_root) | ternary(' even_deny_root ',' ') }}unlock_time={{ amazon2cis_pam_faillock.unlock_time }}" - insertafter: '^#?auth ?' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Add success and default settings to pam_unix.so" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "auth [success=1 default=bad] pam_unix.so" - insertafter: '^#?auth ?' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Add default, deny count, and unlock times for authfail" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "auth [default=die] pam_faillock.so authfail audit deny={{ amazon2cis_pam_faillock.attempts }}{{ (amazon2cis_pam_faillock.fail_for_root) | ternary(' even_deny_root ',' ') }}unlock_time={{ amazon2cis_pam_faillock.unlock_time }}" - insertafter: '^#?auth ?' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Add deny count and unlock times to authsucc" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "auth sufficient pam_faillock.so authsucc audit deny={{ amazon2cis_pam_faillock.attempts }}{{ (amazon2cis_pam_faillock.fail_for_root) | ternary(' even_deny_root ',' ') }}unlock_time={{ amazon2cis_pam_faillock.unlock_time }}" - insertafter: '^#?auth ?' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Activate deny count and unlock times to failed password" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "account required pam_faillock.so" - insertbefore: '^#?account ?' - firstmatch: true - regexp: '^\s*account\s+required\s+pam_faillock.so\s*' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.3 | PATCH | Ensure password hashing algorithm is SHA-512 | add sha512 settings" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "password sufficient pam_unix.so {{ amazon2cis_pam_faillock.pwhash }} shadow nullok try_first_pass use_authtok" - insertafter: '^#?password ?' - with_items: - - "system-auth" - - "password-auth" - - - name: "5.4.4 | PATCH | Ensure password reuse is limited | add remember settings" - lineinfile: - path: /etc/pam.d/{{ item }} - line: "password required pam_pwhistory.so remember={{ amazon2cis_pam_faillock.remember }}" - insertafter: '^#?password ?' - with_items: - - "system-auth" - - "password-auth" - - # The two steps below were added to keep authconfig from overwritting the above configs. This follows steps from here: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-hardening_your_system_with_tools_and_services - # With the steps below you will score five (5) points lower due to false positive results - - - name: | - "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Copy system/passowrd-auth to system/password-auth-local - 5.4.3 | PATCH | Ensure password hashing algorithm is SHA-512" - 5.4.4 | PATCH | Ensure password reuse is limited | Copy system/password-auth to system/password-auth-local" - copy: - src: /etc/pam.d/{{ item }} - dest: /etc/pam.d/{{ item }}-local - remote_src: true - owner: root - group: root - mode: '0644' - with_items: - - "system-auth" - - "password-auth" - - - name: | - "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Setup symbolic link - 5.4.4 | PATCH | Ensure password reuse is limited | Setup symbolic link" - file: - src: /etc/pam.d/{{ item }}-local - dest: /etc/pam.d/{{ item }} - state: link - force: true - with_items: - - "system-auth" - - "password-auth" - when: - - amazon2cis_rule_5_4_2 - - amazon2cis_rule_5_4_3 - - amazon2cis_rule_5_4_4 - tags: - - level1 - - automated - - patch - - rule_5.4.2 - - rule_5.4.3 - - rule_5.4.4 - - pamd diff --git a/tasks/section_5/cis_5.5.1.x.yml b/tasks/section_5/cis_5.5.1.x.yml deleted file mode 100644 index f6715fd..0000000 --- a/tasks/section_5/cis_5.5.1.x.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -- name: "5.5.1.1 | PATCH | Ensure password expiration is 365 days or less" - lineinfile: - path: /etc/login.defs - regexp: '^PASS_MAX_DAYS' - line: "PASS_MAX_DAYS {{ amazon2cis_pass['max_days'] }}" - when: - - amazon2cis_rule_5_5_1_1 - tags: - - level1 - - automated - - patch - - rule_5.5.1.1 - - accounts - - password - -- name: "5.5.1.2 | PATCH | Ensure minimum days between password changes is configured" - lineinfile: - path: /etc/login.defs - regexp: '^PASS_MIN_DAYS' - line: "PASS_MIN_DAYS {{ amazon2cis_pass['min_days'] }}" - when: - - amazon2cis_rule_5_5_1_2 - tags: - - level1 - - automated - - patch - - rule_5.5.1.2 - - accounts - - password - -- name: "5.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more" - lineinfile: - path: /etc/login.defs - regexp: '^PASS_WARN_AGE' - line: "PASS_WARN_AGE {{ amazon2cis_pass['warn_age'] }}" - when: - - amazon2cis_rule_5_5_1_3 - tags: - - level1 - - automated - - patch - - rule_5.5.1.3 - - accounts - - password - -- name: "5.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less" - block: - - name: "5.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Set default inactive setting" - lineinfile: - path: /etc/default/useradd - regexp: '^INACTIVE=' - line: "INACTIVE={{ amazon2cis_inactivelock['lock_days'] }}" - - - name: "5.5.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list" - shell: "egrep ^[^:]+:[^\\!*] /etc/shadow | awk -F: '{print $1 \",\" $7}' | egrep -v ',\\d|,[1-2][0-9]|,30|{{ amazon2cis_inactive_whitelist | join('|') }}' | cut -d , -f1" - changed_when: false - failed_when: false - register: amazon2_5_5_1_4_audit - - - name: "5.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts" - command: "chage --inactive {{ amazon2cis_inactivelock.lock_days }} {{ item }}" - with_items: - - "{{ amazon2_5_5_1_4_audit.stdout_lines }}" - when: - - amazon2_5_5_1_4_audit.stdout | length > 0 - when: - - amazon2cis_rule_5_5_1_4 - tags: - - level1 - - automated - - patch - - rule_5.5.1.4 - - accounts - - password - -- name: "5.5.1.5 | PATCH | Ensure all users last password change date is in the past" - block: - - name: "5.5.1.5 | AUDIT | Ensure all users last password change date is in the past | Get current date in Unix Time" - shell: echo $(($(date --utc --date "$1" +%s)/86400)) - failed_when: false - changed_when: false - register: amazon2cis_5_5_1_5_current_unix_time - - - name: "5.5.1.5 | AUDIT | Ensure all users last password change date is in the past | Get list of users with last changed pw date in the future" - shell: "cat /etc/shadow | awk -F: '{if($3>{{ amazon2cis_5_5_1_5_current_unix_time.stdout }})print$1}'" - changed_when: false - register: amazon2cis_5_5_1_5_user_list - - - name: "5.5.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert no pw change in the future exist" - debug: - msg: "Good News! All accounts have PW change dates that are in the past" - when: amazon2cis_5_5_1_5_user_list.stdout | length == 0 - - - name: "5.5.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future" - debug: - msg: "Warning! The following accounts have the last PW change date in the future: {{ amazon2cis_5_5_1_5_user_list.stdout_lines }}" - when: - - amazon2cis_5_5_1_5_user_list.stdout | length > 0 - - not amazon2cis_futurepwchgdate_autofix - - - name: "5.5.1.5 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future" - command: passwd --expire {{ item }} - when: - - amazon2cis_5_5_1_5_user_list | length > 0 - - amazon2cis_futurepwchgdate_autofix - with_items: - - "{{ amazon2cis_5_5_1_5_user_list.stdout_lines }}" - when: - - amazon2cis_rule_5_5_1_5 - tags: - - level1 - - automated - - patch - - rule_5.5.1.5 - - accounts - - password diff --git a/tasks/section_5/cis_5.5.x.yml b/tasks/section_5/cis_5.5.x.yml deleted file mode 100644 index ae5f973..0000000 --- a/tasks/section_5/cis_5.5.x.yml +++ /dev/null @@ -1,105 +0,0 @@ ---- - -- name: "5.5.2 | PATCH | Ensure system accounts are secured" - block: - - name: "5.5.2 | PATCH | Ensure system accounts are secured | Set nologin" - user: - name: "{{ item.id }}" - shell: /usr/sbin/nologin - with_items: - - "{{ amazon2cis_passwd }}" - when: - - item.id != "root" - - item.id != "sync" - - item.id != "shutdown" - - item.id != "halt" - - item.gid < amazon2cis_int_gid - - item.shell != " /bin/false" - - item.shell != " /usr/sbin/nologin" - loop_control: - label: "{{ item.id }}" - - - name: "5.5.2 | PATCH | Ensure system accounts are secured | Lock accounts" - user: - name: "{{ item.id }}" - password_lock: true - with_items: - - "{{ amazon2cis_passwd }}" - when: - - item.id != "halt" - - item.id != "shutdown" - - item.id != "sync" - - item.id != "root" - - item.gid < amazon2cis_int_gid - - item.shell != " /bin/false" - - item.shell != " /usr/sbin/nologin" - loop_control: - label: "{{ item.id }}" - when: - - amazon2cis_rule_5_5_2 - tags: - - level1 - - automated - - patch - - rule_5.5.2 - - accounts - -- name: "5.5.3 | PATCH | Ensure default group for the root account is GID 0" - user: - name: root - group: "0" - when: - - amazon2cis_rule_5_5_3 - tags: - - level1 - - automated - - patch - - rule_5.5.3 - - accounts - - root - -- name: "5.5.4 | PATCH | Ensure default user shell timeout is configured" - blockinfile: - path: "{{ item.dest }}" - state: "{{ item.state }}" - create: true - mode: 0644 - marker: "# {mark} ANSIBLE MANAGED" - block: | - # Set session timeout - CIS ID AMZN LNX 2-5.5.4 - TMOUT={{ amazon2cis_shell_session_timeout.timeout }} - readonly TMOUT - export TMOUT - with_items: - - { dest: "{{ amazon2cis_shell_session_timeout.file }}", state: present } - - { dest: /etc/profile, state: "{{ (amazon2cis_shell_session_timeout.file == '/etc/profile') | ternary('present', 'absent') }}" } - when: - - amazon2cis_rule_5_5_4 - tags: - - level2 - - automated - - patch - - rule_5.5.4 - - account - -- name: "5.5.5 | PATCH | Ensure default user umask is configured" - block: - - name: "5.5.5 | PATCH | Ensure default user umask is configured | Set umask for /etc/bashrc" - replace: - path: /etc/bashrc - regexp: '(^\s+umask) 002' - replace: '\1 027' - - - name: "5.5.5 | PATCH | Ensure default user umask is configured | Set umask for /etc/profile" - replace: - path: /etc/profile - regexp: '(^\s+umask) 002' - replace: '\1 027' - when: - - amazon2cis_rule_5_5_5 - tags: - - level1 - - automated - - patch - - rule_5.5.5 - - account diff --git a/tasks/section_5/cis_5.6.x.yml b/tasks/section_5/cis_5.6.x.yml deleted file mode 100644 index af2529c..0000000 --- a/tasks/section_5/cis_5.6.x.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- - -- name: "5.6 | AUDIT | Ensure root login is restricted to system console " - block: - - name: "5.6 | AUDIT | Ensure root login is restricted to system console" - command: cat /etc/securetty - changed_when: false - failed_when: false - register: amazon2_5_6_audit - - - name: "5.6 | AUDIT | Ensure root login is restricted to system console" - debug: - msg: - - "These are the consoles with root login access, please review:" - - "{{ amazon2_5_6_audit.stdout_lines }}" - when: - - amazon2cis_rule_5_6 - tags: - - level1 - - manual - - audit - - rule_5.6 - - accounts - - root diff --git a/tasks/section_5/cis_5.7.x.yml b/tasks/section_5/cis_5.7.x.yml deleted file mode 100644 index e558c32..0000000 --- a/tasks/section_5/cis_5.7.x.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- - -- name: "5.7 | PATCH | Ensure access to the su command is restricted" - block: - - name: "5.7 | PATCH | Ensure access to the su command is restricted | Setting pam_wheel to use_uid" - lineinfile: - path: /etc/pam.d/su - regexp: '^(#)?auth\s+required\s+pam_wheel\.so' - line: 'auth required pam_wheel.so use_uid {% if amazon2cis_sugroup is defined %}group={{ amazon2cis_sugroup }}{% endif %}' - - - name: "5.7 | PATCH | Ensure access to the su command is restricted | wheel group contains root" - user: - name: root - groups: "{{ amazon2cis_sugroup | default('wheel') }}" - when: - - amazon2cis_rule_5_7 - tags: - - level1 - - automated - - patch - - rule_5.7 - - sudo diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index e17862a..e1b7e99 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -1,25 +1,41 @@ --- -- name: "SECTION | 5.1 | Configure time-based job schedulers" - include_tasks: cis_5.1.x.yml - -- name: "SECTION | 5.2 | Configure sudo" - include_tasks: cis_5.2.x.yml - -- name: "SECTION | 5.3 | Configure SSH Server" - include_tasks: cis_5.3.x.yml - -- name: "SECTION | 5.4 | Configure PAM" - include_tasks: cis_5.4.x.yml - -- name: "SECTION | 5.5.1.x | Set Shadow Password Suite Parameters" - include_tasks: cis_5.5.1.x.yml - -- name: "SECTION | 5.5.x" - include_tasks: cis_5.5.x.yml - -- name: "SECTION | 5.6.x" - include_tasks: cis_5.6.x.yml - -- name: "SECTION | 5.7.x" - include_tasks: cis_5.7.x.yml +# 5.1 Configure Logging +- name: "SECTION | 5.1.1.x | Configure rsyslog" + when: amazon2cis_syslog == 'rsyslog' + ansible.builtin.import_tasks: + file: cis_5.1.1.x.yml + +- name: "SECTION | 5.1.2.x | Configure journald" + when: amazon2cis_syslog == 'journald' + ansible.builtin.import_tasks: + file: cis_5.1.2.x.yml + +- name: "SECTION | 5.1.3 | Configure logile perms" + ansible.builtin.import_tasks: + file: cis_5.1.3.yml + +- name: "SECTION | 5.1.4 | Configure logrotate" + ansible.builtin.import_tasks: + file: cis_5.1.4.yml + +# 5.2 Configure System Accounting (auditd) +- name: "SECTION | 5.2.1 | Ensure auditing is enabled" + ansible.builtin.import_tasks: + file: cis_5.2.1.x.yml + +- name: "SECTION | 5.2.2 | Configure Data Retention" + ansible.builtin.import_tasks: + file: cis_5.2.2.x.yml + +- name: "SECTION | 5.2.3.x | Configure auditd rules" + ansible.builtin.import_tasks: + file: cis_5.2.3.x.yml + +- name: "SECTION | 5.2.4.x | Audit file permissions" + ansible.builtin.import_tasks: + file: cis_5.2.4.x.yml + +- name: "SECTION | 5.3.x | Aide" + ansible.builtin.import_tasks: + file: cis_5.3.x.yml diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 4b906de..fc052eb 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -1,312 +1,429 @@ --- -- name: "6.1.1 | PATCH | Audit system file permissions" - block: - - name: "6.1.1 | AUDIT | Audit system file permissions | Audit the packages" - shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto - changed_when: false - failed_when: false - register: amazon2cis_6_1_1_packages_rpm - tags: - - skip_ansible_lint - - - name: "6.1.1 | AUDIT | Audit system file permissions | Add file discrepancy list to system" # noqa template-instead-of-copy - copy: - dest: "{{ amazon2cis_rpm_audit_file }}" - content: "{{ amazon2cis_6_1_1_packages_rpm.stdout }}" - changed_when: amazon2cis_6_1_1_packages_rpm.stdout|length > 0 - - - name: "6.1.1 | AUDIT | Audit system file permissions | Message out alert for package descrepancies" - debug: - msg: - - Warning! You have some package descrepancies issues. - - "The file list can be found in {{ amazon2cis_rpm_audit_file }}" - when: amazon2cis_6_1_1_packages_rpm.stdout|length > 0 - - - name: "6.1.1 | AUDIT | Audit system file permissions | Message out no package descrepancies" - debug: - msg: "Good News! There are no package descrepancies" - when: amazon2cis_6_1_1_packages_rpm.stdout|length == 0 +- name: "6.1.1 | PATCH | Ensure permissions on /etc/passwd are configured" when: - amazon2cis_rule_6_1_1 tags: - - level2 - - manual + - level1-server + - level1-workstation + - automated - patch - - rule_6.1.1 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.2 | PATCH | Ensure permissions on /etc/passwd are configured" - file: + - rule_6.1.1 + ansible.builtin.file: path: /etc/passwd owner: root group: root - mode: 0644 + mode: u-x,go-wx + +- name: "6.1.2 | PATCH | Ensure permissions on /etc/passwd- are configured" when: - amazon2cis_rule_6_1_2 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.3 | PATCH | Ensure permissions on /etc/passwd- are configured" - file: + - rule_6.1.2 + ansible.builtin.file: path: /etc/passwd- owner: root group: root - mode: 0644 + mode: u-x,go-wx + +- name: "6.1.3 | PATCH | Ensure permissions on /etc/security/opasswd are configured" when: - amazon2cis_rule_6_1_3 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.4 | PATCH | Ensure permissions on /etc/shadow are configured" - file: - path: /etc/shadow + - rule_6.1.3 + ansible.builtin.file: + path: /etc/security/opasswd owner: root group: root - mode: 0000 + mode: '0600' + +- name: "6.1.4 | PATCH | Ensure permissions on /etc/group are configured" when: - amazon2cis_rule_6_1_4 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.4 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.5 | PATCH | Ensure permissions on /etc/shadow- are configured" - file: - path: /etc/shadow- + - rule_6.1.4 + ansible.builtin.file: + path: /etc/group owner: root group: root - mode: 0000 + mode: u-x,go-wx + +- name: "6.1.5 | PATCH | Ensure permissions on /etc/group- are configured" when: - amazon2cis_rule_6_1_5 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.5 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.6 | PATCH | Ensure permissions on /etc/gshadow- are configured" - file: - path: /etc/gshadow- + - rule_6.1.5 + ansible.builtin.file: + path: /etc/group- owner: root group: root - mode: 0000 + mode: u-x,go-wx + +- name: "6.1.6 | PATCH | Ensure permissions on /etc/shadow are configured" when: - amazon2cis_rule_6_1_6 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.6 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.7 | PATCH | Ensure permissions on /etc/gshadow are configured" - file: - path: /etc/gshadow + - rule_6.1.6 + ansible.builtin.file: + path: /etc/shadow owner: root group: root - mode: 0000 + mode: '0000' + +- name: "6.1.7 | PATCH | Ensure permissions on /etc/shadow- are configured" when: - amazon2cis_rule_6_1_7 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.7 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.8 | PATCH | Ensure permissions on /etc/group are configured" - file: - path: /etc/group + - rule_6.1.7 + ansible.builtin.file: + path: /etc/shadow- owner: root group: root - mode: 0644 + mode: '0000' + +- name: "6.1.8 | PATCH | Ensure permissions on /etc/gshadow are configured" when: - amazon2cis_rule_6_1_8 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.8 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.9 | PATCH | Ensure permissions on /etc/group- are configured" - file: - path: /etc/group- + - rule_6.1.8 + ansible.builtin.file: + path: /etc/gshadow owner: root group: root - mode: 0644 + mode: '0000' + +- name: "6.1.9 | PATCH | Ensure permissions on /etc/gshadow- are configured" when: - amazon2cis_rule_6_1_9 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.9 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions + - rule_6.1.9 + ansible.builtin.file: + path: /etc/gshadow- + owner: root + group: root + mode: '0000' -- name: "6.1.10 | PATCH | Ensure no world writable files exist" - block: - - name: "6.1.10 | AUDIT | Ensure no world writable files exist | Get list of world-writable files" - shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002 - changed_when: false - failed_when: false - register: amazon2_6_1_10_perms_results - - - name: "6.1.10 | AUDIT | Ensure no world writable files exist | Alert no world-writable files exist" - debug: - msg: "Good news! We have not found any world-writable files on your system" - when: amazon2_6_1_10_perms_results.stdout is not defined - - - name: "6.1.10 | PATCH | Ensure no world writable files exist | Adjust world-writable files if they exist (Configurable)" - file: - path: '{{ item }}' - mode: o-w - state: touch - with_items: - - "{{ amazon2_6_1_10_perms_results.stdout_lines }}" - when: - - amazon2_6_1_10_perms_results.stdout_lines is defined - - amazon2cis_no_world_write_adjust +- name: "6.1.10 | PATCH | Ensure permissions on /etc/shells are configured" when: - amazon2cis_rule_6_1_10 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.10 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions + - rule_6.1.10 + ansible.builtin.file: + path: /etc/shells + owner: root + group: root + mode: u-x,go-wx -- name: "6.1.11 | PATCH | Ensure no unowned files or directories exist" - block: - - name: "6.1.11 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories" - command: find "{{ item.mount }}" -xdev -nouser - changed_when: false - failed_when: false - check_mode: false - register: amazon2_6_1_11_audit - with_items: - - "{{ ansible_mounts }}" - loop_control: - label: "{{ item.mount }}" - when: item['device'].startswith('/dev') and not 'bind' in item['options'] - - - name: "6.1.11 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories" - debug: - msg: "Warning - Manual intervention is required -- missing owner on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}" - when: - - item.stdout_lines is defined - - item.stdout_lines | length > 0 - with_items: - - "{{ amazon2_6_1_11_audit.results }}" +- name: "6.1.11 | PATCH | Ensure world writable files and directories are secured" when: - amazon2cis_rule_6_1_11 + - amazon2cis_disruption_high tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.1.11 + - files + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - permissions - -- name: "6.1.12 | PATCH | Ensure no ungrouped files or directories exist" + - rule_6.1.11 + vars: + warn_control_id: '6.1.11' block: - - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Finding all ungrouped files or directories" - command: find "{{ item.mount }}" -xdev -nogroup + - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Get list of world-writable files" + ansible.builtin.shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002 + failed_when: false + changed_when: false + register: amazon2cis_6_1_11_perms_results + + - name: "6.1.11 | PATCH | Adjust world-writable files if they exist (Configurable)" + when: + - amazon2cis_6_1_11_perms_results.stdout_lines is defined + - amazon2cis_no_world_write_adjust + ansible.builtin.file: + path: '{{ item }}' + mode: o-w + state: touch + with_items: "{{ amazon2cis_6_1_11_perms_results.stdout_lines }}" + + - name: "6.1.11 | PATCH | Ensure world writable files and directories are secured | sticky bit set on world-writable directories" + ansible.builtin.shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t changed_when: false failed_when: false - check_mode: false - register: amazon2_6_1_12_audit - with_items: - - "{{ ansible_mounts }}" - loop_control: - label: "{{ item.mount }}" - when: item['device'].startswith('/dev') and not 'bind' in item['options'] - - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories" - debug: - msg: "Warning - Manual intervention is required -- missing group on items in {{ item }}!" - with_items: - - "{{ amazon2_6_1_12_audit.results | map(attribute='stdout_lines') }}" - when: item | length > 0 + - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Warning" + when: + - amazon2cis_6_1_11_perms_results.stdout_lines is defined + - not amazon2cis_no_world_write_adjust + ansible.builtin.debug: + msg: "Warning!! - WorldWritable files have been found" + + - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Warn Count" + when: + - amazon2cis_6_1_11_perms_results.stdout_lines is defined + - not amazon2cis_no_world_write_adjust + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.1.12 | PATCH | Ensure no ungrouped files or directories exist" when: - amazon2cis_rule_6_1_12 + - amazon2cis_disruption_high tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 - rule_6.1.12 - permissions - -- name: "6.1.13 | PATCH | Audit SUID executables" + vars: + warn_control_id: '6.1.12' block: - - name: "6.1.13 | AUDIT | Audit SUID executables | Find all SUID executables" - shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Get ungrouped files or directories" + ansible.builtin.shell: find {{ item.mount }} -xdev -nogroup -not -fstype nfs changed_when: false failed_when: false - register: amazon2_6_1_13_perms_results + check_mode: false + register: amazon2cis_6_1_12_ungrouped_items with_items: - - "{{ ansible_mounts }}" + - "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.mount }}" - - name: "6.1.13 | AUDIT | Audit SUID executables | Alert no SUID executables exist" - debug: - msg: "Good news! We have not found any SUID executable files on your system" - when: amazon2_6_1_13_perms_results.stdout is not defined + - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Flatten ungrouped_items results for easier use" + ansible.builtin.set_fact: + amazon2cis_6_1_12_ungrouped_items_flatten: "{{ amazon2cis_6_1_12_ungrouped_items.results | map(attribute='stdout_lines') | flatten }}" - - name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist" - debug: - msg: "Warning - Manual intervention is required -- SUID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}" - with_items: "{{ amazon2_6_1_13_perms_results.stdout_lines }}" - when: amazon2_6_1_13_perms_results.stdout is defined + - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Alert on ungrouped files and directories" + when: + - not amazon2cis_ungrouped_adjust + - amazon2cis_6_1_12_ungrouped_items_flatten | length > 0 + ansible.builtin.debug: + msg: + - "Warning!! You have ungrouped files/directories and are configured to not auto-remediate for this task" + - "Please review the files/directories below and assign a group" + - "{{ amazon2cis_6_1_12_ungrouped_items_flatten }}" + + - name: "6.1.12 | PATCH | Ensure no ungrouped files or directories exist | Set ungrouped files/directories to configured group" + when: + - amazon2cis_ungrouped_adjust + - amazon2cis_6_1_12_ungrouped_items_flatten | length > 0 + ansible.builtin.file: + path: "{{ item }}" + group: "{{ amazon2cis_ungrouped_group }}" + loop: + - "{{ amazon2cis_6_1_12_ungrouped_items_flatten }}" + + - name: "6.1.12 | AUDIT | Ensure no ungrouped files or directories exist | Warn Count" + when: + - amazon2cis_ungrouped_adjust + - amazon2cis_6_1_12_ungrouped_items_flatten | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.1.13 | AUDIT | Ensure SUID and SGID files are reviewed" when: - amazon2cis_rule_6_1_13 + - amazon2cis_disruption_high tags: - - level1 + - level1-server + - level1-workstation - manual - audit - rule_6.1.13 - permissions - -- name: "6.1.14 | PATCH | Audit SGID executables" + vars: + warn_control_id: '6.1.13' block: - - name: "6.1.14 | AUDIT | Audit SGID executables | Find all SGID executables" - shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000 + - name: "6.1.13 | AUDIT | Ensure SUID and SGID files are reviewed | Find SUID executables" + ansible.builtin.shell: find {{ item.mount }} -xdev -type f -perm -4000 -not -fstype nfs changed_when: false failed_when: false - register: amazon2_6_1_14_perms_results - with_items: - - "{{ ansible_mounts }}" + check_mode: false + register: amazon2cis_6_1_13_suid_executables + loop: "{{ ansible_facts.mounts }}" + loop_control: + label: "{{ item.mount }}" + + - name: "6.1.13 | AUDIT | Ensure SUID and SGID files are reviewed | Find all SGID executables" + ansible.builtin.shell: find {{ item.mount }} -xdev -type f -perm -2000 -not -fstype nfs + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_6_1_13_sgid_executables + loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.mount }}" - - name: "6.1.14 | AUDIT | Audit SGID executables | Alert no SGID executables exist" - debug: - msg: "Good news! We have not found any SGID executable files on your system" - when: amazon2_6_1_14_perms_results.stdout is not defined + - name: "6.1.13 | AUDIT | Ensure SUID and SGID files are reviewed | Flatten suid_executables results for easier use" + ansible.builtin.set_fact: + amazon2cis_6_1_13_suid_executables_flatten: "{{ amazon2cis_6_1_13_suid_executables.results | map(attribute='stdout_lines') | flatten }}" - - name: "6.1.14 | AUDIT | Audit SGID executables | Alert SGID executables exist" - debug: - msg: "Warning - Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}" + - name: "6.1.13 | AUDIT | Ensure SUID and SGID files are reviewed | Set fact SGID executables" + ansible.builtin.set_fact: + amazon2cis_6_1_13_sgid_executables_flatten: "{{ amazon2cis_6_1_13_sgid_executables.results | map(attribute='stdout_lines') | flatten }}" + + - name: "6.1.13 | PATCH | Ensure SUID and SGID files are reviewed | Remove SUID bit" + when: + - amazon2cis_suid_adjust + - amazon2cis_6_1_13_suid_executables_flatten | length > 0 + ansible.builtin.file: + path: "{{ item }}" + mode: 'u-s' + loop: + - "{{ amazon2cis_6_1_13_suid_executables_flatten }}" + + - name: "6.1.13 | PATCH | Audit SGID executables | Remove SGID bit" + ansible.builtin.file: + path: "{{ item }}" + mode: 'g-s' with_items: - - "{{ amazon2_6_1_14_perms_results.stdout_lines }}" - when: amazon2_6_1_14_perms_results.stdout is defined + - "{{ amazon2cis_6_1_13_sgid_executables_flatten }}" + when: + - amazon2cis_sgid_adjust + - amazon2cis_6_1_13_sgid_executables_flatten | length > 0 + + - name: "6.1.13 | WARN | Ensure SUID and SGID files are reviewed | Alert SUID executables exist" + when: + - amazon2cis_6_1_13_suid_executables_flatten | length > 0 + - not amazon2cis_suid_adjust + ansible.builtin.debug: + msg: + - "Warning!! You have SUID executables" + - "The files are listed below, please confirm the integrity of these binaries" + - "{{ amazon2cis_6_1_13_suid_executables_flatten }}" + + - name: "6.1.13 | WARN | Ensure SUID and SGID files are reviewed | Alert SGID executables exist" + when: + - amazon2cis_6_1_13_sgid_executables_flatten | length > 0 + - not amazon2cis_sgid_adjust + ansible.builtin.debug: + msg: + - "Warning!! You have SGID executables" + - "The files are listed below, please review the integrity of these binaries" + - "{{ amazon2cis_6_1_13_sgid_executables_flatten }}" + + - name: "6.1.13 | WARN | Ensure SUID and SGID files are reviewed | Warn Count" + when: + - (amazon2cis_6_1_13_suid_executables_flatten | length > 0 and not amazon2cis_suid_adjust) or + (amazon2cis_6_1_13_sgid_executables_flatten | length > 0 and not amazon2cis_sgid_adjust) + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.1.14 | AUDIT | Audit system file permissions" when: - amazon2cis_rule_6_1_14 + - amazon2cis_disruption_high tags: - - level1 + - level2-server + - level2-workstation - manual - - patch - - rule_6.1.14 + - audit + - NIST800-53R5_AC-3 + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - NIST800-53R5_MP-2 - permissions + - rule_6.1.14 + vars: + warn_control_id: '6.1.14' + block: + - name: "6.1.14 | AUDIT | Audit system file permissions | Audit the packages" + ansible.builtin.shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto + changed_when: false + failed_when: false + register: amazon2cis_6_1_14_packages_rpm + + - name: "6.1.14 | AUDIT | Audit system file permissions | Create list and warning" + block: + - name: "6.1.14 | AUDIT | Audit system file permissions | Add file discrepancy list to system" + ansible.builtin.copy: + dest: "{{ amazon2cis_rpm_audit_file }}" # noqa template-instead-of-copy + content: "{{ amazon2cis_6_1_14_packages_rpm.stdout }}" + owner: root + group: root + mode: '0644' + + - name: "6.1.14 | AUDIT | Audit system file permissions | Message out alert for package descrepancies" + when: amazon2cis_6_1_14_packages_rpm.stdout | length > 0 + ansible.builtin.debug: + msg: | + "Warning!! You have some package descrepancies issues. + The file list can be found in {{ amazon2cis_rpm_audit_file }}" + + - name: "6.1.14 | AUDIT | Audit system file permissions | Warn Count" + when: amazon2cis_6_1_14_packages_rpm.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml diff --git a/tasks/section_6/cis_6.2.x.yml b/tasks/section_6/cis_6.2.x.yml index 0bbb680..0fd6486 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -1,488 +1,446 @@ --- -- name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords" - block: - - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadow passwords" - shell: sed -e 's/^\([a-zA-Z0-9_]*\):[^:]*:/\1:x:/' -i /etc/passwd - changed_when: false - failed_when: false - register: amazon2_6_2_1_shadow - - - name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords | Good News" - debug: - msg: "Good News!! No Unshadowed passwords have been found" - when: amazon2_6_2_1_shadow.stdout | length == 0 - - - name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords | Alert on no shadow passwords" - debug: - msg: - - "ALERT! There are users that are not using shadow passwords. Please address to conform to CIS standards" - - "The users below are the out of compliance users" - - "{{ amazon2_6_2_1_shadow.stdout_lines }}" - when: amazon2_6_2_1_shadow.stdout | length > 0 +- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords" when: - amazon2cis_rule_6_2_1 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit + - NIST800-53R5_IA-5 - rule_6.2.1 - - accounts + - user_accounts + vars: + warn_control_id: '6.2.1' + block: + - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | Get users not using shadowed passwords" + ansible.builtin.shell: awk -F':' '($2 != "x" ) { print $1}' /etc/passwd + changed_when: false + failed_when: false + register: amazon2cis_6_2_1_nonshadowed_users -- name: "6.2.2 | PATCH | Ensure /etc/shadow password fields are not empty" - command: passwd -l {{ item }} - changed_when: false - failed_when: false - with_items: - - "{{ empty_password_accounts.stdout_lines }}" + - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | Warn on findings" + when: amazon2cis_6_2_1_nonshadowed_users.stdout | length > 0 + ansible.builtin.debug: + msg: + - "Warning!! You have users that are not using a shadowed password. Please convert the below accounts to use a shadowed password" + - "{{ amazon2cis_6_2_1_nonshadowed_users.stdout_lines }}" + + - name: "6.2.1 | WARN | Ensure accounts in /etc/passwd use shadowed passwords | warn_count" + when: amazon2cis_6_2_1_nonshadowed_users.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.2.2 | PATCH | Ensure /etc/shadow password fields are not empty" when: - - empty_password_accounts.rc - amazon2cis_rule_6_2_2 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - rule_6.2.2 - - accounts - -- name: "6.2.3 | PATCH | Ensure all groups in /etc/passwd exist in /etc/group" + - NIST800-53R5_IA-5 + - user + - permissions block: - - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries" - shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}' + - name: "6.2.2 | AUDIT | Ensure /etc/shadow password fields are not empty | Find users with no password" + ansible.builtin.shell: awk -F":" '($2 == "" ) { print $1 }' /etc/shadow changed_when: false - failed_when: false check_mode: false - register: amazon2_6_2_3_passwd_gid_check + register: amazon2cis_6_2_2_empty_password_acct - - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print message that all groups match between passwd and group files" - debug: - msg: "Good News! There are no users that have non-existent GUIDs (Groups)" - when: amazon2_6_2_3_passwd_gid_check.stdout | length == 0 + - name: "6.2.2 | PATCH | Ensure /etc/shadow password fields are not empty | Lock users with empty password" + when: amazon2cis_6_2_2_empty_password_acct.stdout | length > 0 + ansible.builtin.user: + name: "{{ item }}" + password_lock: true + loop: + - "{{ amazon2cis_6_2_2_empty_password_acct.stdout_lines }}" - - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group" - debug: - msg: "WARNING: The following users have non-existent GIDs (Groups): {{ amazon2_6_2_3_passwd_gid_check.stdout_lines | join (', ') }}" - changed_when: false - when: amazon2_6_2_3_passwd_gid_check.stdout | length > 0 +- name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group" when: - amazon2cis_rule_6_2_3 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit - rule_6.2.3 + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - groups - -- name: "6.2.4 | AUDIT | Ensure shadow group is empty" + vars: + warn_control_id: '6.2.3' block: - - name: "6.2.4 | AUDIT | Ensure shadow group is empty" - shell: "grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group" + - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries" + ansible.builtin.shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}' changed_when: false failed_when: false - register: amazon2_6_2_4_users_in_shadow_group + check_mode: false + register: amazon2cis_6_2_3_passwd_gid_check + + - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group" + when: amazon2cis_6_2_3_passwd_gid_check.stdout | length > 0 + ansible.builtin.debug: + msg: "Warning!! The following users have non-existent GIDs (Groups): {{ amazon2cis_6_2_3_passwd_gid_check.stdout_lines | join (', ') }}" - - name: "6.2.4 | AUDIT | Ensure shadow group is empty | Print no user in shadow group" - debug: - msg: "Good News! There are no users in the shadow group" - when: amazon2_6_2_4_users_in_shadow_group.stdout | length == 0 + - name: "6.2.3 | WARN | Ensure all groups in /etc/passwd exist in /etc/group | warn_count" + when: amazon2cis_6_2_3_passwd_gid_check.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml - - name: "6.2.4 | AUDIT | Ensure shadow group is empty | Print no user in shadow group" - debug: - msg: "Warning: The following users are in the shadow group: {{ amazon2_6_2_4_users_in_shadow_group.stdout_lines }}" - when: amazon2_6_2_4_users_in_shadow_group.stdout | length > 0 +- name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist" when: - amazon2cis_rule_6_2_4 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_6.2.4 - - groups - -- name: "6.2.5 | PATCH | Ensure no duplicate user names exist" + - user + vars: + warn_control_id: '6.2.4' block: - - name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names" - shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd" + - name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs" + ansible.builtin.shell: "pwck -r | awk -F: '{if ($3 in uid) print $1 ; else uid[$3]}' /etc/passwd" changed_when: false failed_when: false - register: amazon2_6_2_5_user_username_check + check_mode: false + register: amazon2cis_6_2_4_user_uid_check - - name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print message that no duplicate user names exist" - debug: - msg: "Good News! There are no duplicate user names in the system" - when: amazon2_6_2_5_user_username_check.stdout | length == 0 + - name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs" + when: amazon2cis_6_2_4_user_uid_check.stdout | length > 0 + ansible.builtin.debug: + msg: "Warning!! The following users have UIDs that are duplicates: {{ amazon2cis_6_2_4_user_uid_check.stdout_lines }}" - - name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names" - debug: - msg: "Warning: The following user names are duplicates: {{ amazon2_6_2_5_user_username_check.stdout_lines }}" - when: amazon2_6_2_5_user_username_check.stdout | length > 0 + - name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Set warning count" + when: amazon2cis_6_2_4_user_uid_check.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist" when: - amazon2cis_rule_6_2_5 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_6.2.5 - - accounts - -- name: "6.2.6 | PATCH | Ensure no duplicate group names exist" + - groups + vars: + warn_control_id: '6.2.5' block: - - name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names" - shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d' + - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs" + ansible.builtin.shell: "pwck -r | awk -F: '{if ($3 in users) print $1 ; else users[$3]}' /etc/group" changed_when: false failed_when: false - register: amazon2_6_2_6_group_group_check + check_mode: false + register: amazon2cis_6_2_5_user_user_check + + - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs" + when: amazon2cis_6_2_5_user_user_check.stdout | length > 0 + ansible.builtin.debug: + msg: "Warning!! The following groups have duplicate GIDs: {{ amazon2cis_6_2_5_user_user_check.stdout_lines }}" - - name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist" - debug: - msg: "Good News! There are no duplicate group names in the system" - when: amazon2_6_2_6_group_group_check.stdout | length == 0 + - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Set warning count" + when: amazon2cis_6_2_5_user_user_check.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml - - name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" - debug: - msg: "Warning: The following group names are duplicates: {{ amazon2_6_2_6_group_group_check.stdout_lines }}" - when: amazon2_6_2_6_group_group_check.stdout | length > 0 +- name: "6.2.6 | AUDIT | Ensure no duplicate user names exist" + vars: + warn_control_id: '6.2.6' when: - amazon2cis_rule_6_2_6 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit - rule_6.2.6 - - groups - -- name: "6.2.7 | PATCH | Ensure no duplicate UIDs exist" + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - user block: - - name: "6.2.7 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs" - shell: "pwck -r | awk -F: '{if ($3 in uid) print $1 ; else uid[$3]}' /etc/passwd" + - name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names" + ansible.builtin.shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd" changed_when: false failed_when: false - register: amazon2_6_2_7_user_uid_check + check_mode: false + register: amazon2cis_6_2_6_username_check + + - name: "6.2.6 | WARN | Ensure no duplicate user names exist | Print warning about users with duplicate User Names" + when: amazon2cis_6_2_6_username_check.stdout | length > 0 + ansible.builtin.debug: + msg: "Warning!! The following user names are duplicates: {{ amazon2cis_6_2_6_user_username_check.stdout_lines }}" - - name: "6.2.7 | AUDIT | Ensure no duplicate UIDs exist | Print message that no duplicate UIDs exist" - debug: - msg: "Good News! There are no duplicate UID's in the system" - when: amazon2_6_2_7_user_uid_check.stdout | length == 0 + - name: "6.2.6 | WARN | Ensure no duplicate user names exist | Set warning count" + when: amazon2cis_6_2_6_username_check.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml - - name: "6.2.7 | AUDIT | Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs" - debug: - msg: "Warning: The following users have UIDs that are duplicates: {{ amazon2_6_2_7_user_uid_check.stdout_lines }}" - when: amazon2_6_2_7_user_uid_check.stdout | length > 0 +- name: "6.2.7 | AUDIT | Ensure no duplicate group names exist" when: - amazon2cis_rule_6_2_7 tags: - - level1 + - level1-server + - level1-workstation - automated - - patch + - audit + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_6.2.7 - - accounts - -- name: "6.2.8 | PATCH | Ensure no duplicate GIDs exist" + - groups + vars: + warn_control_id: '6.2.7' block: - - name: "6.2.8 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs" - shell: "pwck -r | awk -F: '{if ($3 in users) print $1 ; else users[$3]}' /etc/group" + - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names" + ansible.builtin.shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d' changed_when: false failed_when: false - register: amazon2_6_2_8_user_user_check + check_mode: false + register: amazon2cis_6_2_7_group_check - - name: "6.2.8 | AUDIT | Ensure no duplicate GIDs exist | Print message that no duplicate GID's exist" - debug: - msg: "Good News! There are no duplicate GIDs in the system" - when: amazon2_6_2_8_user_user_check.stdout | length == 0 + - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" + when: amazon2cis_6_2_7_group_check.stdout | length > 0 + ansible.builtin.debug: + msg: "Warning!! The following group names are duplicates: {{ amazon2cis_6_2_7_group_group_check.stdout_lines }}" - - name: "6.2.8 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs" - debug: - msg: "Warning: The following groups have duplicate GIDs: {{ amazon2_6_2_8_user_user_check.stdout_lines }}" - when: amazon2_6_2_8_user_user_check.stdout | length > 0 + - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Set warning count" + when: amazon2cis_6_2_7_group_check.stdout | length > 0 + ansible.builtin.import_tasks: + file: warning_facts.yml + +- name: "6.2.8 | PATCH | Ensure root PATH Integrity" when: - amazon2cis_rule_6_2_8 tags: - - level1 - - automated + - level1-server + - level1-workstation - patch + - paths + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_6.2.8 - - groups - -- name: "6.2.9 | PATCH | Ensure root is the only UID 0 account" - command: passwd -l {{ item }} - changed_when: false - failed_when: false - with_items: - - "{{ uid_zero_accounts_except_root.stdout_lines }}" - when: - - uid_zero_accounts_except_root.rc - - amazon2cis_rule_6_2_9 - tags: - - level1 - - automated - - patch - - rule_6.2.9 - - accounts - - root - -- name: "6.2.10 | PATCH | Ensure root PATH Integrity" block: - - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Determine empty value" - shell: 'echo $PATH | grep ::' + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths" + ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2 changed_when: false - failed_when: amazon2_6_2_10_path_colon.rc == 0 - register: amazon2_6_2_10_path_colon + register: amazon2cis_6_2_8_root_paths - - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Determin colon end" - shell: 'echo $PATH | grep :$' + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths" + ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2 | tr ":" "\n" changed_when: false - failed_when: amazon2_6_2_10_path_colon_end.rc == 0 - register: amazon2_6_2_10_path_colon_end + register: amazon2cis_6_2_8_root_paths_split - - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Determine dot in path" - shell: "/bin/bash --login -c 'env | grep ^PATH=' | grep ^PATH | sed -e 's/PATH=//' -e 's/::/:/' -e 's/:$//' -e 's/:/\\n/g'" + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set fact" + ansible.builtin.set_fact: + root_paths: "{{ amazon2cis_6_2_8_root_paths.stdout }}" + + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for empty dirs" + ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"' changed_when: false - failed_when: '"." in amazon2_6_2_10_dot_in_path.stdout_lines' - register: amazon2_6_2_10_dot_in_path + failed_when: root_path_empty_dir.rc not in [ 0, 1 ] + register: root_path_empty_dir - - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Alert on empty value, colon end, and dot in path" - debug: - msg: - - "The following paths have an empty value: {{ amazon2_6_2_10_path_colon.stdout_lines }}" - - "The following paths have colon end: {{ amazon2_6_2_10_path_colon_end.stdout_lines }}" - - "The following paths have a dot in the path: {{ amazon2_6_2_10_dot_in_path.stdout_lines }}" + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for trailing ':'" + ansible.builtin.shell: '{{ root_paths }} | cut -d= -f2 | grep -q ":$" && echo "roots path contains a trailing (:)"' + changed_when: false + failed_when: root_path_trailing_colon.rc not in [ 0, 1 ] + register: root_path_trailing_colon + + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions" + block: + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions" + ansible.builtin.stat: + path: "{{ item }}" + register: root_path_perms + loop: "{{ amazon2cis_6_2_8_root_paths_split.stdout_lines }}" + + - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set permissions" + when: + - item.stat.exists + - item.stat.isdir + - item.stat.pw_name != 'root' or item.stat.gr_name != 'root' or item.stat.woth or item.stat.wgrp + - (item != 'root') and (not amazon2cis_uses_root) + ansible.builtin.file: + path: "{{ item.stat.path }}" + state: directory + owner: root + group: root + mode: '0755' + follow: false + loop: "{{ root_path_perms.results }}" + loop_control: + label: "{{ item }}" - - name: "6.2.10 | PATCH | Ensure root PATH Integrity (AUTOMATED) | Determine rights and owner" - file: - path: '{{ item }}' - state: directory - owner: root - mode: 'o-w,g-w' - follow: true - with_items: - - "{{ amazon2_6_2_10_dot_in_path.stdout_lines }}" +- name: "6.2.9 | PATCH | Ensure root is the only UID 0 account" + when: + - amazon2cis_uid_zero_accounts_except_root.rc + - amazon2cis_rule_6_2_9 + tags: + - level1-server + - level1-workstation + - patch + - accounts + - users + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_6.2.9 + ansible.builtin.shell: passwd -l {{ item }} + changed_when: false + failed_when: false + loop: "{{ amazon2cis_uid_zero_accounts_except_root.stdout_lines }}" + +- name: "6.2.10 | PATCH | Ensure local interactive user home directories exist" when: - amazon2cis_rule_6_2_10 tags: - - level1 - - automated + - level1-server + - level1-workstation - patch + - users + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 - rule_6.2.10 - - root - -- name: "6.2.11 | PATCH | Ensure all users' home directories exist" block: - - name: "6.2.11 | PATCH | Ensure all users' home directories exist | Check for paths" - stat: + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Create dir if absent" + ansible.builtin.file: + path: "{{ item.dir }}" + state: directory + owner: "{{ item.id }}" + group: "{{ item.gid }}" + register: amazon2cis_6_2_10_home_dir + loop: "{{ amazon2cis_passwd | selectattr('uid', '>=', amazon2cis_min_uid | int ) | selectattr('uid', '<=', amazon2cis_max_uid | int ) | list }}" + loop_control: + label: "{{ item.id }}" + + - name: "6.2.10 | AUDIT | Ensure local interactive user home directories exist | get perms stat" + ansible.builtin.stat: path: "{{ item }}" - register: amazon2_6_2_11_audit - with_items: - - "{{ amazon2cis_passwd | selectattr('uid', '>=', amazon2cis_int_gid) | selectattr('uid', '!=', 65534) | map(attribute='dir') | list }}" + register: amazon2cis_6_2_10_home_dir_perms + loop: "{{ interactive_users_home.stdout_lines }}" - - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - shell: find -H {{ item.0 | quote }} -not -type l -perm /027 - changed_when: amazon2_6_2_11_patch_audit | length > 0 - check_mode: false - register: amazon2_6_2_11_patch_audit - with_together: - - "{{ amazon2_6_2_11_audit.results | map(attribute='item') | list }}" - - "{{ amazon2_6_2_11_audit.results | map(attribute='stat') | list }}" + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | set perms if needed" + ansible.builtin.file: + path: "{{ item.stat.path }}" + state: directory + mode: g-w,o-rwx + loop: "{{ amazon2cis_6_2_10_home_dir_perms.results }}" loop_control: - label: "{{ item.0 }}" + label: "{{ item }}" + + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | own their home directories" when: - - ansible_check_mode - - item.1.exists - - - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - file: - path: "{{ item.0 }}" - mode: a-st,g-w,o-rwx - recurse: true - register: amazon2_6_2_11_patch - with_together: - - "{{ amazon2_6_2_11_audit.results | map(attribute='item') | list }}" - - "{{ amazon2_6_2_11_audit.results | map(attribute='stat') | list }}" + - item.uid >= amazon2cis_min_uid | int + - item.id != 'nobody' + - (item.id != 'tss' and item.dir != '/dev/null') + - item.shell != '/sbin/nologin' + ansible.builtin.file: + path: "{{ item.dir }}" + owner: "{{ item.id }}" + state: directory + loop: "{{ amazon2cis_passwd | selectattr('uid', '>=', amazon2cis_min_uid | int ) | selectattr('uid', '<=', amazon2cis_max_uid | int ) | list }}" loop_control: - label: "{{ item.0 }}" - when: - - not ansible_check_mode - - item.1.exists + label: "{{ item.id }}" # set default ACLs so the homedir has an effective umask of 0027 - - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - acl: - path: "{{ item.0 }}" + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set group ACL" + ansible.posix.acl: + path: "{{ item }}" default: true + etype: group + permissions: rx state: present - recursive: true - etype: "{{ item.1.etype }}" - permissions: "{{ item.1.mode }}" - with_nested: - - "{{ (ansible_check_mode | ternary(amazon2_6_2_11_patch_audit, amazon2_6_2_11_patch)).results | - rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}" - - - - { etype: group, mode: rx } - - { etype: other, mode: '0' } - when: - - amazon2cis_rule_6_2_11 - tags: - - level1 - - automated - - patch - - rule_6.2.11 - - accounts - -- name: "6.2.12 | PATCH | Ensure users own their home directories" - file: - path: "{{ item.dir }}" - owner: "{{ item.id }}" - state: directory - with_items: - - "{{ amazon2cis_passwd | selectattr('uid', '>=', 1000) | selectattr('uid', '!=', 65534) | list }}" - loop_control: - label: "{{ amazon2cis_passwd_label }}" - when: - - amazon2cis_rule_6_2_12 - tags: - - level1 - - automated - - patch - - rule_6.2.12 - - accounts - - skip_ansible_lint + loop: "{{ interactive_users_home.stdout_lines }}" -- name: "6.2.13 | PATCH | Ensure users' home directories permissions are 750 or more restrictive" - block: - - name: "6.2.13 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive" - stat: + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set other ACL" + ansible.posix.acl: path: "{{ item }}" - with_items: "{{ amazon2cis_passwd | selectattr('uid', '>=', 1000) | selectattr('uid', '!=', 65534) | map(attribute='dir') | list }}" - register: amazon2_6_2_13_audit - - - name: "6.2.13 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive" - command: find -H {{ item.0 | quote }} -not -type l -perm /027 - changed_when: amazon2_6_2_13_patch_audit.stdout != "" - failed_when: false - check_mode: false - register: amazon2_6_2_13_patch_audit - with_together: - - "{{ amazon2_6_2_13_audit.results | map(attribute='item') | list }}" - - "{{ amazon2_6_2_13_audit.results | map(attribute='stat') | list }}" - loop_control: - label: "{{ item.0 }}" - when: - - ansible_check_mode - - item.1.exists - - - name: "6.2.13 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive" - file: - path: "{{ item.0 }}" - recurse: true - mode: a-st,g-w,o-rwx - register: amazon2_6_2_13_patch - with_together: - - "{{ amazon2_6_2_13_audit.results | map(attribute='item') | list }}" - - "{{ amazon2_6_2_13_audit.results | map(attribute='stat') | list }}" - loop_control: - label: "{{ item.0 }}" - when: - - not ansible_check_mode - - item.1.exists - - # set default ACLs so the homedir has an effective umask of 0027 - - name: "6.2.13 | PATCH | Ensure users' home directories permissions are 750 or more restrictive" - acl: - path: "{{ item.0 }}" default: true + etype: other + permissions: 0 state: present - recursive: true - etype: "{{ item.1.etype }}" - permissions: "{{ item.1.mode }}" - with_nested: - - "{{ (ansible_check_mode | ternary(amazon2_6_2_13_patch_audit, amazon2_6_2_13_patch)).results | - rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}" - - - - { etype: group, mode: rx } - - { etype: other, mode: '0' } - when: not amazon2cis_system_is_container + loop: "{{ interactive_users_home.stdout_lines }}" + +- name: "6.2.11 | PATCH | Ensure local interactive user dot files access is configured" when: - - amazon2cis_rule_6_2_13 + - amazon2cis_rule_6_2_11 + - amazon2cis_disruption_high tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_6.2.13 - - permissions - -- name: "6.2.14 | PATCH | Ensure users' dot files are not group or world-writable" + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 + - rule_6.2.11 + - user + vars: + warn_control_id: '6.2.11' block: - - name: "6.2.14 | AUDIT | Ensure users' dot files are not group or world-writable | Check for files" - shell: find /home/ -name "\.*" -perm /g+w,o+w + - name: "6.2.11 | AUDIT | Ensure local interactive user dot files access is configured | Check for files" + ansible.builtin.shell: find /home/ -name "\.*" -perm /g+w,o+w changed_when: false - failed_when: false - register: amazon2cis_6_2_14_audit + failed_when: amazon2cis_6_2_11_audit.rc not in [ 0, 1 ] + check_mode: false + register: amazon2cis_6_2_11_audit - - name: "6.2.14 | AUDIT | Ensure users' dot files are not group or world-writable | Alert on files found" - debug: - msg: "Good news! We have not found any group or world-writable dot files on your sytem" - failed_when: false - changed_when: false - when: amazon2cis_6_2_14_audit.stdout | length == 0 + - name: "6.2.11 | AUDIT | Ensure local interactive user dot files access is configured | Warning on files found" + when: + - amazon2cis_6_2_11_audit.stdout | length > 0 + - amazon2cis_dotperm_ansiblemanaged + ansible.builtin.debug: + msg: + - "Warning!! You have group or world-writable dot files on your system and have configured for manual intervention" - - name: "6.2.14 | PATCH | Ensure users' dot files are not group or world-writable | Changes files if configured" - file: - path: '{{ item }}' - mode: go-w - with_items: - - "{{ amazon2cis_6_2_14_audit.stdout_lines }}" + - name: "6.2.11 | PATCH | Ensure local interactive user dot files access is configured | Set warning count" when: - - amazon2cis_6_2_14_audit.stdout | length > 0 - - amazon2cis_dotperm_ansibleManaged - when: - - amazon2cis_rule_6_2_14 - tags: - - level1 - - automated - - patch - - rule_6.2.14 - - permissions + - amazon2cis_6_2_11_audit.stdout | length > 0 + - amazon2cis_dotperm_ansiblemanaged + ansible.builtin.import_tasks: + file: warning_facts.yml -- name: "6.2.15 | PATCH | Ensure no users have .forward files" - file: - path: "~{{ item }}/.forward" - state: absent - with_items: - - "{{ users.stdout_lines }}" - when: - - amazon2cis_rule_6_2_15 - tags: - - level1 - - automated - - patch - - rule_6.2.15 - - files - -- name: "6.2.16 | PATCH | Ensure no users have .netrc files" - file: - path: "~{{ item }}/.netrc" - state: absent - with_items: - - "{{ users.stdout_lines }}" - when: - - amazon2cis_rule_6_2_16 - tags: - - level1 - - automated - - patch - - rule_6.2.16 - - files - -- name: "6.2.17 | PATCH | Ensure no users have .rhosts files" - file: - path: "~{{ item }}/.rhosts" - state: absent - with_items: - - "{{ users.stdout_lines }}" - when: - - amazon2cis_rule_6_2_17 - tags: - - level1 - - automated - - patch - - rule_6.2.17 - - files + - name: "6.2.11 | PATCH | Ensure local interactive user dot files access is configured | Changes files if configured" + when: + - amazon2cis_6_2_11_audit.stdout | length > 0 + - amazon2cis_dotperm_ansiblemanaged + ansible.builtin.file: + path: '{{ item }}' + mode: go-w + with_items: "{{ amazon2cis_6_2_11_audit.stdout_lines }}" diff --git a/tasks/section_6/main.yml b/tasks/section_6/main.yml index 479b9c8..b194fdc 100644 --- a/tasks/section_6/main.yml +++ b/tasks/section_6/main.yml @@ -1,7 +1,9 @@ --- - name: "SECTION | 6.1 | System File Permissions" - include_tasks: cis_6.1.x.yml + ansible.builtin.import_tasks: + file: cis_6.1.x.yml - name: "SECTION | 6.2 | User and Group Settings" - include_tasks: cis_6.2.x.yml + ansible.builtin.import_tasks: + file: cis_6.2.x.yml diff --git a/tasks/warning_facts.yml b/tasks/warning_facts.yml new file mode 100644 index 0000000..3032b7c --- /dev/null +++ b/tasks/warning_facts.yml @@ -0,0 +1,20 @@ +--- + +# This task is used to create variables used in giving a warning summary for manual tasks +# that need attention +# +# The warn_control_list and warn_count vars start life in vars/main.yml but get updated +# as the tasks that have a warning complete +# +# Those two variables are used in the tasks/main.yml to display a list of warnings +# +# warn_control_id is set within the task itself and has the control ID as the value +# +# warn_control_list is the main variable to be used and is a list made up of the warn_control_id’s +# +# warn_count the main variable for the number of warnings and each time a warn_control_id is added +# the count increases by a value of 1 +- name: "{{ warn_control_id }} | WARNING | Set fact for manual task warning." + ansible.builtin.set_fact: + warn_control_list: "{{ warn_control_list }} [{{ warn_control_id }}]" + warn_count: "{{ warn_count | int + 1 }}" diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index e7f8e41..fcb0bb6 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -1,13 +1,14 @@ -## metadata for Audit benchmark -benchmark_version: '2.0.0' +--- -# Set if genuine RHEL (subscription manager check) not for derivatives e.g. CentOS -host_os_distribution: {{ ansible_distribution }} +## metadata for Audit benchmark +benchmark_version: '3.0.0' # timeout for each command to run where set - default = 10seconds/10000ms timeout_ms: {{ audit_cmd_timeout }} -# Taken from LE rhel8-cis +# +host_os_distribution: AmazonLinux2 + amazon2cis_section1: {{ amazon2cis_section1 }} amazon2cis_section2: {{ amazon2cis_section2 }} amazon2cis_section3: {{ amazon2cis_section3 }} @@ -15,129 +16,167 @@ amazon2cis_section4: {{ amazon2cis_section4 }} amazon2cis_section5: {{ amazon2cis_section5 }} amazon2cis_section6: {{ amazon2cis_section6 }} -amazon2cis_level1: true -amazon2cis_level2: true - amazon2cis_selinux_disable: {{ amazon2cis_selinux_disable }} amazon2cis_selinux_state: {{ amazon2cis_selinux_state }} +amazon2cis_level_1: {{ amazon2cis_level_1 }} +amazon2cis_level_2: {{ amazon2cis_level_2 }} # to enable rules that may have IO impact on a system e.g. full filesystem scans or CPU heavy -amazon2cis_run_heavy_tests: true -{% if amazon2cis_legacy_boot is defined %} -amazon2cis_legacy_boot: {{ amazon2cis_legacy_boot }} -{% endif %} -# if Bios boot +amazon2cis_run_heavy_tests: {{ audit_run_heavy_tests }} + amazon2cis_bootloader_file: /boot/grub2/grub.cfg +amazon2cis_bootloader_user: /boot/grub2/user.cfg -amazon2cis_set_boot_pass: false # These variables correspond with the CIS rule IDs or paragraph numbers defined in # the CIS benchmark documents. # PLEASE NOTE: These work in coordination with the section # group variables and tags. # You must enable an entire section in order for the variables below to take effect. -# Section 1 rules +# +## Section 1 rules +## +# Section 1 is Initial Setup (Filesystem Configuration, Configure Software Updates, Configure Sudo, Filesystem Integrity Checking, Secure Boot Settings, Additional Process Hardening, Mandatory Access Control, and Warning Banners) +# Configure Filesystem Kernel Modules +## Configure Filesystem Kernel Modules amazon2cis_rule_1_1_1_1: {{ amazon2cis_rule_1_1_1_1 }} amazon2cis_rule_1_1_1_2: {{ amazon2cis_rule_1_1_1_2 }} amazon2cis_rule_1_1_1_3: {{ amazon2cis_rule_1_1_1_3 }} -amazon2cis_rule_1_1_2: {{ amazon2cis_rule_1_1_2 }} -amazon2cis_rule_1_1_3: {{ amazon2cis_rule_1_1_3 }} -amazon2cis_rule_1_1_4: {{ amazon2cis_rule_1_1_4 }} -amazon2cis_rule_1_1_5: {{ amazon2cis_rule_1_1_5 }} -amazon2cis_rule_1_1_6: {{ amazon2cis_rule_1_1_6 }} -amazon2cis_rule_1_1_7: {{ amazon2cis_rule_1_1_7 }} -amazon2cis_rule_1_1_8: {{ amazon2cis_rule_1_1_8 }} -amazon2cis_rule_1_1_9: {{ amazon2cis_rule_1_1_9 }} -amazon2cis_rule_1_1_10: {{ amazon2cis_rule_1_1_10 }} -amazon2cis_rule_1_1_11: {{ amazon2cis_rule_1_1_11 }} -amazon2cis_rule_1_1_12: {{ amazon2cis_rule_1_1_12 }} -amazon2cis_rule_1_1_13: {{ amazon2cis_rule_1_1_13 }} -amazon2cis_rule_1_1_14: {{ amazon2cis_rule_1_1_14 }} -amazon2cis_rule_1_1_15: {{ amazon2cis_rule_1_1_15 }} -amazon2cis_rule_1_1_16: {{ amazon2cis_rule_1_1_16 }} -amazon2cis_rule_1_1_17: {{ amazon2cis_rule_1_1_17 }} -amazon2cis_rule_1_1_18: {{ amazon2cis_rule_1_1_18 }} -amazon2cis_rule_1_1_19: {{ amazon2cis_rule_1_1_19 }} -amazon2cis_rule_1_1_20: {{ amazon2cis_rule_1_1_20 }} -amazon2cis_rule_1_1_21: {{ amazon2cis_rule_1_1_21 }} -amazon2cis_rule_1_1_22: {{ amazon2cis_rule_1_1_22 }} -amazon2cis_rule_1_1_23: {{ amazon2cis_rule_1_1_23 }} -amazon2cis_rule_1_1_24: {{ amazon2cis_rule_1_1_24 }} - - +amazon2cis_rule_1_1_1_4: {{ amazon2cis_rule_1_1_1_4 }} +amazon2cis_rule_1_1_1_5: {{ amazon2cis_rule_1_1_1_5 }} +amazon2cis_rule_1_1_1_6: {{ amazon2cis_rule_1_1_1_6 }} +amazon2cis_rule_1_1_1_7: {{ amazon2cis_rule_1_1_1_7 }} +amazon2cis_rule_1_1_1_8: {{ amazon2cis_rule_1_1_1_8 }} + +# /tmp +amazon2cis_rule_1_1_2_1_1: {{ amazon2cis_rule_1_1_2_1_1 }} +amazon2cis_rule_1_1_2_1_2: {{ amazon2cis_rule_1_1_2_1_2 }} +amazon2cis_rule_1_1_2_1_3: {{ amazon2cis_rule_1_1_2_1_3 }} +amazon2cis_rule_1_1_2_1_4: {{ amazon2cis_rule_1_1_2_1_4 }} + +# /dev/shm +amazon2cis_rule_1_1_2_2_1: {{ amazon2cis_rule_1_1_2_2_1 }} +amazon2cis_rule_1_1_2_2_2: {{ amazon2cis_rule_1_1_2_2_2 }} +amazon2cis_rule_1_1_2_2_3: {{ amazon2cis_rule_1_1_2_2_3 }} +amazon2cis_rule_1_1_2_2_4: {{ amazon2cis_rule_1_1_2_2_4 }} + +# /home +amazon2cis_rule_1_1_2_3_1: {{ amazon2cis_rule_1_1_2_3_1 }} +amazon2cis_rule_1_1_2_3_2: {{ amazon2cis_rule_1_1_2_3_2 }} +amazon2cis_rule_1_1_2_3_3: {{ amazon2cis_rule_1_1_2_3_3 }} + +# /var +amazon2cis_rule_1_1_2_4_1: {{ amazon2cis_rule_1_1_2_4_1 }} +amazon2cis_rule_1_1_2_4_2: {{ amazon2cis_rule_1_1_2_4_1 }} +amazon2cis_rule_1_1_2_4_3: {{ amazon2cis_rule_1_1_2_4_1 }} + +# /var/tmp +amazon2cis_rule_1_1_2_5_1: {{ amazon2cis_rule_1_1_2_5_1 }} +amazon2cis_rule_1_1_2_5_2: {{ amazon2cis_rule_1_1_2_5_2 }} +amazon2cis_rule_1_1_2_5_3: {{ amazon2cis_rule_1_1_2_5_3 }} +amazon2cis_rule_1_1_2_5_4: {{ amazon2cis_rule_1_1_2_5_4 }} + +# /var/log +amazon2cis_rule_1_1_2_6_1: {{ amazon2cis_rule_1_1_2_6_1 }} +amazon2cis_rule_1_1_2_6_2: {{ amazon2cis_rule_1_1_2_6_2 }} +amazon2cis_rule_1_1_2_6_3: {{ amazon2cis_rule_1_1_2_6_3 }} +amazon2cis_rule_1_1_2_6_4: {{ amazon2cis_rule_1_1_2_6_4 }} + +# /var/log/audit +amazon2cis_rule_1_1_2_7_1: {{ amazon2cis_rule_1_1_2_7_1 }} +amazon2cis_rule_1_1_2_7_2: {{ amazon2cis_rule_1_1_2_7_2 }} +amazon2cis_rule_1_1_2_7_3: {{ amazon2cis_rule_1_1_2_7_3 }} +amazon2cis_rule_1_1_2_7_4: {{ amazon2cis_rule_1_1_2_7_4 }} + +# Software and Patch management amazon2cis_rule_1_2_1: {{ amazon2cis_rule_1_2_1 }} amazon2cis_rule_1_2_2: {{ amazon2cis_rule_1_2_2 }} amazon2cis_rule_1_2_3: {{ amazon2cis_rule_1_2_3 }} +amazon2cis_rule_1_2_4: {{ amazon2cis_rule_1_2_4 }} +amazon2cis_rule_1_2_5: {{ amazon2cis_rule_1_2_5 }} - +# Secure boot settings amazon2cis_rule_1_3_1: {{ amazon2cis_rule_1_3_1 }} -amazon2cis_rule_1_3_2: {{ amazon2cis_rule_1_3_2 }} +# Additional Process Hardening amazon2cis_rule_1_4_1: {{ amazon2cis_rule_1_4_1 }} amazon2cis_rule_1_4_2: {{ amazon2cis_rule_1_4_2 }} - -amazon2cis_rule_1_5_1: {{ amazon2cis_rule_1_5_1 }} -amazon2cis_rule_1_5_2: {{ amazon2cis_rule_1_5_2 }} -amazon2cis_rule_1_5_3: {{ amazon2cis_rule_1_5_3 }} -amazon2cis_rule_1_5_4: {{ amazon2cis_rule_1_5_4 }} - -amazon2cis_rule_1_6_1_1: {{ amazon2cis_rule_1_6_1_1 }} -amazon2cis_rule_1_6_1_2: {{ amazon2cis_rule_1_6_1_2 }} -amazon2cis_rule_1_6_1_3: {{ amazon2cis_rule_1_6_1_3 }} -amazon2cis_rule_1_6_1_4: {{ amazon2cis_rule_1_6_1_4 }} -amazon2cis_rule_1_6_1_5: {{ amazon2cis_rule_1_6_1_5 }} -amazon2cis_rule_1_6_1_6: {{ amazon2cis_rule_1_6_1_6 }} -amazon2cis_rule_1_6_1_7: {{ amazon2cis_rule_1_6_1_7 }} -amazon2cis_rule_1_6_1_8: {{ amazon2cis_rule_1_6_1_8 }} - -amazon2cis_rule_1_7_1: {{ amazon2cis_rule_1_7_1 }} -amazon2cis_rule_1_7_2: {{ amazon2cis_rule_1_7_2 }} -amazon2cis_rule_1_7_3: {{ amazon2cis_rule_1_7_3 }} -amazon2cis_rule_1_7_4: {{ amazon2cis_rule_1_7_4 }} -amazon2cis_rule_1_7_5: {{ amazon2cis_rule_1_7_5 }} -amazon2cis_rule_1_7_6: {{ amazon2cis_rule_1_7_6 }} - -amazon2cis_rule_1_8: {{ amazon2cis_rule_1_8 }} - - -# section 2 rules -amazon2cis_rule_2_1_1_1: {{ amazon2cis_rule_2_1_1_1 }} -amazon2cis_rule_2_1_1_2: {{ amazon2cis_rule_2_1_1_2 }} -amazon2cis_rule_2_1_1_3: {{ amazon2cis_rule_2_1_1_3 }} - - +amazon2cis_rule_1_4_3: {{ amazon2cis_rule_1_4_3 }} +amazon2cis_rule_1_4_4: {{ amazon2cis_rule_1_4_4 }} + +# SElinux +amazon2cis_rule_1_5_1_1: {{ amazon2cis_rule_1_5_1_1 }} +amazon2cis_rule_1_5_1_2: {{ amazon2cis_rule_1_5_1_2 }} +amazon2cis_rule_1_5_1_3: {{ amazon2cis_rule_1_5_1_3 }} +amazon2cis_rule_1_5_1_4: {{ amazon2cis_rule_1_5_1_4 }} +amazon2cis_rule_1_5_1_5: {{ amazon2cis_rule_1_5_1_5 }} +amazon2cis_rule_1_5_1_6: {{ amazon2cis_rule_1_5_1_6 }} +amazon2cis_rule_1_5_1_7: {{ amazon2cis_rule_1_5_1_7 }} +amazon2cis_rule_1_5_1_8: {{ amazon2cis_rule_1_5_1_8 }} + +# Command line banner warnings +amazon2cis_rule_1_6_1: {{ amazon2cis_rule_1_6_1 }} +amazon2cis_rule_1_6_2: {{ amazon2cis_rule_1_6_2 }} +amazon2cis_rule_1_6_3: {{ amazon2cis_rule_1_6_3 }} +amazon2cis_rule_1_6_4: {{ amazon2cis_rule_1_6_4 }} +amazon2cis_rule_1_6_5: {{ amazon2cis_rule_1_6_5 }} +amazon2cis_rule_1_6_6: {{ amazon2cis_rule_1_6_6 }} + +## +## Section 2 rules +## +# Section 2 is Services (inetd Services, Special Purpose Services, and Service Clients) + +# Time Service (Chrony) +amazon2cis_rule_2_1_1: {{ amazon2cis_rule_2_1_1 }} amazon2cis_rule_2_1_2: {{ amazon2cis_rule_2_1_2 }} amazon2cis_rule_2_1_3: {{ amazon2cis_rule_2_1_3 }} -amazon2cis_rule_2_1_4: {{ amazon2cis_rule_2_1_4 }} -amazon2cis_rule_2_1_5: {{ amazon2cis_rule_2_1_5 }} -amazon2cis_rule_2_1_6: {{ amazon2cis_rule_2_1_6 }} -amazon2cis_rule_2_1_7: {{ amazon2cis_rule_2_1_7 }} -amazon2cis_rule_2_1_8: {{ amazon2cis_rule_2_1_8 }} -amazon2cis_rule_2_1_9: {{ amazon2cis_rule_2_1_9 }} -amazon2cis_rule_2_1_10: {{ amazon2cis_rule_2_1_10 }} -amazon2cis_rule_2_1_11: {{ amazon2cis_rule_2_1_11 }} -amazon2cis_rule_2_1_12: {{ amazon2cis_rule_2_1_12 }} -amazon2cis_rule_2_1_13: {{ amazon2cis_rule_2_1_13 }} -amazon2cis_rule_2_1_14: {{ amazon2cis_rule_2_1_14 }} -amazon2cis_rule_2_1_15: {{ amazon2cis_rule_2_1_15 }} -amazon2cis_rule_2_1_16: {{ amazon2cis_rule_2_1_16 }} -amazon2cis_rule_2_1_17: {{ amazon2cis_rule_2_1_17 }} -amazon2cis_rule_2_1_18: {{ amazon2cis_rule_2_1_18 }} -amazon2cis_rule_2_1_19: {{ amazon2cis_rule_2_1_19 }} +# Special purpose services amazon2cis_rule_2_2_1: {{ amazon2cis_rule_2_2_1 }} amazon2cis_rule_2_2_2: {{ amazon2cis_rule_2_2_2 }} amazon2cis_rule_2_2_3: {{ amazon2cis_rule_2_2_3 }} amazon2cis_rule_2_2_4: {{ amazon2cis_rule_2_2_4 }} amazon2cis_rule_2_2_5: {{ amazon2cis_rule_2_2_5 }} - -amazon2cis_rule_2_3: {{ amazon2cis_rule_2_3 }} - -# Section 3 rules +amazon2cis_rule_2_2_6: {{ amazon2cis_rule_2_2_6 }} +amazon2cis_rule_2_2_7: {{ amazon2cis_rule_2_2_7 }} +amazon2cis_rule_2_2_8: {{ amazon2cis_rule_2_2_8 }} +amazon2cis_rule_2_2_9: {{ amazon2cis_rule_2_2_9 }} +amazon2cis_rule_2_2_10: {{ amazon2cis_rule_2_2_10 }} +amazon2cis_rule_2_2_11: {{ amazon2cis_rule_2_2_11 }} +amazon2cis_rule_2_2_12: {{ amazon2cis_rule_2_2_12 }} +amazon2cis_rule_2_2_13: {{ amazon2cis_rule_2_2_13 }} +amazon2cis_rule_2_2_14: {{ amazon2cis_rule_2_2_14 }} +amazon2cis_rule_2_2_15: {{ amazon2cis_rule_2_2_15 }} +amazon2cis_rule_2_2_16: {{ amazon2cis_rule_2_2_16 }} +amazon2cis_rule_2_2_17: {{ amazon2cis_rule_2_2_17 }} +amazon2cis_rule_2_2_18: {{ amazon2cis_rule_2_2_18 }} +amazon2cis_rule_2_2_19: {{ amazon2cis_rule_2_2_19 }} +amazon2cis_rule_2_2_20: {{ amazon2cis_rule_2_2_20 }} +amazon2cis_rule_2_2_21: {{ amazon2cis_rule_2_2_21 }} +amazon2cis_rule_2_2_22: {{ amazon2cis_rule_2_2_22 }} + +# Client Services +amazon2cis_rule_2_3_1: {{ amazon2cis_rule_2_3_1 }} +amazon2cis_rule_2_3_2: {{ amazon2cis_rule_2_3_2 }} +amazon2cis_rule_2_3_3: {{ amazon2cis_rule_2_3_3 }} +amazon2cis_rule_2_3_4: {{ amazon2cis_rule_2_3_4 }} +amazon2cis_rule_2_3_5: {{ amazon2cis_rule_2_3_5 }} + +## +## Section 3 rules +## +# Section 3 is Network Configuration (Disable unused network protocols, Network parameters (host), Network parameters (Host and Router), Uncommon Network Protocols, Firewall Configuration, and Configure iptables) +# ipv6, bluettoth and wireless amazon2cis_rule_3_1_1: {{ amazon2cis_rule_3_1_1 }} amazon2cis_rule_3_1_2: {{ amazon2cis_rule_3_1_2 }} +amazon2cis_rule_3_1_3: {{ amazon2cis_rule_3_1_3 }} +# network kernel modules amazon2cis_rule_3_2_1: {{ amazon2cis_rule_3_2_1 }} amazon2cis_rule_3_2_2: {{ amazon2cis_rule_3_2_2 }} +amazon2cis_rule_3_2_3: {{ amazon2cis_rule_3_2_3 }} +amazon2cis_rule_3_2_4: {{ amazon2cis_rule_3_2_4 }} +# network kernel parameters amazon2cis_rule_3_3_1: {{ amazon2cis_rule_3_3_1 }} amazon2cis_rule_3_3_2: {{ amazon2cis_rule_3_3_2 }} amazon2cis_rule_3_3_3: {{ amazon2cis_rule_3_3_3 }} @@ -147,150 +186,223 @@ amazon2cis_rule_3_3_6: {{ amazon2cis_rule_3_3_6 }} amazon2cis_rule_3_3_7: {{ amazon2cis_rule_3_3_7 }} amazon2cis_rule_3_3_8: {{ amazon2cis_rule_3_3_8 }} amazon2cis_rule_3_3_9: {{ amazon2cis_rule_3_3_9 }} - -amazon2cis_rule_3_4_1: {{ amazon2cis_rule_3_4_1 }} -amazon2cis_rule_3_4_2: {{ amazon2cis_rule_3_4_2 }} - -amazon2cis_rule_3_5_1_1: {{ amazon2cis_rule_3_5_1_1 }} -amazon2cis_rule_3_5_1_2: {{ amazon2cis_rule_3_5_1_2 }} -amazon2cis_rule_3_5_1_3: {{ amazon2cis_rule_3_5_1_3 }} -amazon2cis_rule_3_5_1_4: {{ amazon2cis_rule_3_5_1_4 }} -amazon2cis_rule_3_5_1_5: {{ amazon2cis_rule_3_5_1_5 }} -amazon2cis_rule_3_5_1_6: {{ amazon2cis_rule_3_5_1_6 }} -amazon2cis_rule_3_5_1_7: {{ amazon2cis_rule_3_5_1_7 }} - -amazon2cis_rule_3_5_2_1: {{ amazon2cis_rule_3_5_2_1 }} -amazon2cis_rule_3_5_2_2: {{ amazon2cis_rule_3_5_2_2 }} -amazon2cis_rule_3_5_2_3: {{ amazon2cis_rule_3_5_2_3 }} -amazon2cis_rule_3_5_2_4: {{ amazon2cis_rule_3_5_2_4 }} -amazon2cis_rule_3_5_2_5: {{ amazon2cis_rule_3_5_2_5 }} -amazon2cis_rule_3_5_2_6: {{ amazon2cis_rule_3_5_2_6 }} -amazon2cis_rule_3_5_2_7: {{ amazon2cis_rule_3_5_2_7 }} -amazon2cis_rule_3_5_2_8: {{ amazon2cis_rule_3_5_2_8 }} -amazon2cis_rule_3_5_2_9: {{ amazon2cis_rule_3_5_2_9 }} -amazon2cis_rule_3_5_2_10: {{ amazon2cis_rule_3_5_2_10 }} -amazon2cis_rule_3_5_2_11: {{ amazon2cis_rule_3_5_2_11 }} - -amazon2cis_rule_3_5_3_1_1: {{ amazon2cis_rule_3_5_3_1_1 }} -amazon2cis_rule_3_5_3_1_2: {{ amazon2cis_rule_3_5_3_1_2 }} -amazon2cis_rule_3_5_3_1_3: {{ amazon2cis_rule_3_5_3_1_3 }} - -# To be Written -amazon2cis_rule_3_5_3_2_1: false -#amazon2cis_rule_3_5_3_2_2: false -#amazon2cis_rule_3_5_3_2_3: false -#amazon2cis_rule_3_5_3_2_4: false -#amazon2cis_rule_3_5_3_2_5: false -#amazon2cis_rule_3_5_3_2_6: false - -#amazon2cis_rule_3_4_3_3_1: false -#amazon2cis_rule_3_4_3_3_2: false -#amazon2cis_rule_3_4_3_3_3: false -#amazon2cis_rule_3_4_3_3_4: false -#amazon2cis_rule_3_4_3_3_5: false -#amazon2cis_rule_3_4_3_3_6: false - - +amazon2cis_rule_3_3_10: {{ amazon2cis_rule_3_3_10 }} +amazon2cis_rule_3_3_11: {{ amazon2cis_rule_3_3_11 }} + +# Configure firewall utility +amazon2cis_rule_3_4_1_1: {{ amazon2cis_rule_3_4_1_1 }} +amazon2cis_rule_3_4_1_2: {{ amazon2cis_rule_3_4_1_2 }} + +# firewalld +amazon2cis_rule_3_4_2_1: {{ amazon2cis_rule_3_4_2_1 }} +amazon2cis_rule_3_4_2_2: {{ amazon2cis_rule_3_4_2_2 }} +amazon2cis_rule_3_4_2_3: {{ amazon2cis_rule_3_4_2_3 }} +amazon2cis_rule_3_4_2_4: {{ amazon2cis_rule_3_4_2_4 }} + +# nftables +amazon2cis_rule_3_4_3_1: {{ amazon2cis_rule_3_4_3_1 }} +amazon2cis_rule_3_4_3_2: {{ amazon2cis_rule_3_4_3_2 }} +amazon2cis_rule_3_4_3_3: {{ amazon2cis_rule_3_4_3_3 }} +amazon2cis_rule_3_4_3_4: {{ amazon2cis_rule_3_4_3_4 }} +amazon2cis_rule_3_4_3_5: {{ amazon2cis_rule_3_4_3_5 }} +amazon2cis_rule_3_4_3_6: {{ amazon2cis_rule_3_4_3_6 }} +amazon2cis_rule_3_4_3_7: {{ amazon2cis_rule_3_4_3_7 }} +amazon2cis_rule_3_4_3_8: {{ amazon2cis_rule_3_4_3_8 }} +amazon2cis_rule_3_4_3_9: {{ amazon2cis_rule_3_4_3_9 }} + +# iptables +amazon2cis_rule_3_4_4_1_1: {{ amazon2cis_rule_3_4_4_1_1 }} + +# ip4tables +amazon2cis_rule_3_4_4_2_1: {{ amazon2cis_rule_3_4_4_2_1 }} +amazon2cis_rule_3_4_4_2_2: {{ amazon2cis_rule_3_4_4_2_2 }} +amazon2cis_rule_3_4_4_2_3: {{ amazon2cis_rule_3_4_4_2_3 }} +amazon2cis_rule_3_4_4_2_4: {{ amazon2cis_rule_3_4_4_2_4 }} +amazon2cis_rule_3_4_4_2_5: {{ amazon2cis_rule_3_4_4_2_5 }} +amazon2cis_rule_3_4_4_2_6: {{ amazon2cis_rule_3_4_4_2_6 }} + +# ip6tables +amazon2cis_rule_3_4_4_3_1: {{ amazon2cis_rule_3_4_4_3_1 }} +amazon2cis_rule_3_4_4_3_2: {{ amazon2cis_rule_3_4_4_3_2 }} +amazon2cis_rule_3_4_4_3_3: {{ amazon2cis_rule_3_4_4_3_3 }} +amazon2cis_rule_3_4_4_3_4: {{ amazon2cis_rule_3_4_4_3_4 }} +amazon2cis_rule_3_4_4_3_5: {{ amazon2cis_rule_3_4_4_3_5 }} +amazon2cis_rule_3_4_4_3_6: {{ amazon2cis_rule_3_4_4_3_6 }} + + +## # Section 4 rules +## + +# Crond and at amazon2cis_rule_4_1_1_1: {{ amazon2cis_rule_4_1_1_1 }} amazon2cis_rule_4_1_1_2: {{ amazon2cis_rule_4_1_1_2 }} amazon2cis_rule_4_1_1_3: {{ amazon2cis_rule_4_1_1_3 }} - +amazon2cis_rule_4_1_1_4: {{ amazon2cis_rule_4_1_1_4 }} +amazon2cis_rule_4_1_1_5: {{ amazon2cis_rule_4_1_1_5 }} +amazon2cis_rule_4_1_1_6: {{ amazon2cis_rule_4_1_1_6 }} +amazon2cis_rule_4_1_1_7: {{ amazon2cis_rule_4_1_1_7 }} +amazon2cis_rule_4_1_1_8: {{ amazon2cis_rule_4_1_1_8 }} amazon2cis_rule_4_1_2_1: {{ amazon2cis_rule_4_1_2_1 }} -amazon2cis_rule_4_1_2_2: {{ amazon2cis_rule_4_1_2_2 }} -amazon2cis_rule_4_1_2_3: {{ amazon2cis_rule_4_1_2_3 }} -amazon2cis_rule_4_1_2_4: {{ amazon2cis_rule_4_1_2_4 }} - -amazon2cis_rule_4_1_3: {{ amazon2cis_rule_4_1_3 }} -amazon2cis_rule_4_1_4: {{ amazon2cis_rule_4_1_4 }} -amazon2cis_rule_4_1_5: {{ amazon2cis_rule_4_1_5 }} -amazon2cis_rule_4_1_6: {{ amazon2cis_rule_4_1_6 }} -amazon2cis_rule_4_1_7: {{ amazon2cis_rule_4_1_7 }} -amazon2cis_rule_4_1_8: {{ amazon2cis_rule_4_1_8 }} -amazon2cis_rule_4_1_9: {{ amazon2cis_rule_4_1_9 }} -amazon2cis_rule_4_1_10: {{ amazon2cis_rule_4_1_10 }} -amazon2cis_rule_4_1_11: {{ amazon2cis_rule_4_1_11 }} -amazon2cis_rule_4_1_12: {{ amazon2cis_rule_4_1_12 }} -amazon2cis_rule_4_1_13: {{ amazon2cis_rule_4_1_13 }} -amazon2cis_rule_4_1_14: {{ amazon2cis_rule_4_1_14 }} -amazon2cis_rule_4_1_15: {{ amazon2cis_rule_4_1_15 }} -amazon2cis_rule_4_1_16: {{ amazon2cis_rule_4_1_16 }} -amazon2cis_rule_4_1_17: {{ amazon2cis_rule_4_1_17 }} - - -amazon2cis_rule_4_2_1_1: {{ amazon2cis_rule_4_2_1_1 }} -amazon2cis_rule_4_2_1_2: {{ amazon2cis_rule_4_2_1_2 }} -amazon2cis_rule_4_2_1_3: {{ amazon2cis_rule_4_2_1_3 }} -amazon2cis_rule_4_2_1_4: {{ amazon2cis_rule_4_2_1_4 }} -amazon2cis_rule_4_2_1_5: {{ amazon2cis_rule_4_2_1_5 }} -amazon2cis_rule_4_2_1_6: {{ amazon2cis_rule_4_2_1_6 }} - -amazon2cis_rule_4_2_2_1: {{ amazon2cis_rule_4_2_2_1 }} -amazon2cis_rule_4_2_2_2: {{ amazon2cis_rule_4_2_2_2 }} -amazon2cis_rule_4_2_2_3: {{ amazon2cis_rule_4_2_2_3 }} +# SSHD +amazon2cis_rule_4_2_1: {{ amazon2cis_rule_4_2_1 }} +amazon2cis_rule_4_2_2: {{ amazon2cis_rule_4_2_2 }} amazon2cis_rule_4_2_3: {{ amazon2cis_rule_4_2_3 }} - amazon2cis_rule_4_2_4: {{ amazon2cis_rule_4_2_4 }} - -# Section 5 -amazon2cis_rule_5_1_1: {{ amazon2cis_rule_5_1_1 }} -amazon2cis_rule_5_1_2: {{ amazon2cis_rule_5_1_2 }} +amazon2cis_rule_4_2_5: {{ amazon2cis_rule_4_2_5 }} +amazon2cis_rule_4_2_6: {{ amazon2cis_rule_4_2_6 }} +amazon2cis_rule_4_2_7: {{ amazon2cis_rule_4_2_7 }} +amazon2cis_rule_4_2_8: {{ amazon2cis_rule_4_2_8 }} +amazon2cis_rule_4_2_9: {{ amazon2cis_rule_4_2_9 }} +amazon2cis_rule_4_2_10: {{ amazon2cis_rule_4_2_10 }} +amazon2cis_rule_4_2_11: {{ amazon2cis_rule_4_2_11 }} +amazon2cis_rule_4_2_12: {{ amazon2cis_rule_4_2_12 }} +amazon2cis_rule_4_2_13: {{ amazon2cis_rule_4_2_13 }} +amazon2cis_rule_4_2_14: {{ amazon2cis_rule_4_2_14 }} +amazon2cis_rule_4_2_15: {{ amazon2cis_rule_4_2_15 }} +amazon2cis_rule_4_2_16: {{ amazon2cis_rule_4_2_16 }} +amazon2cis_rule_4_2_17: {{ amazon2cis_rule_4_2_17 }} +amazon2cis_rule_4_2_18: {{ amazon2cis_rule_4_2_18 }} +amazon2cis_rule_4_2_19: {{ amazon2cis_rule_4_2_19 }} +amazon2cis_rule_4_2_20: {{ amazon2cis_rule_4_2_20 }} +amazon2cis_rule_4_2_21: {{ amazon2cis_rule_4_2_21 }} +amazon2cis_rule_4_2_22: {{ amazon2cis_rule_4_2_22 }} + +# Privilege Escalation +amazon2cis_rule_4_3_1: {{ amazon2cis_rule_4_3_1 }} +amazon2cis_rule_4_3_2: {{ amazon2cis_rule_4_3_2 }} +amazon2cis_rule_4_3_3: {{ amazon2cis_rule_4_3_3 }} +amazon2cis_rule_4_3_4: {{ amazon2cis_rule_4_3_4 }} +amazon2cis_rule_4_3_5: {{ amazon2cis_rule_4_3_5 }} +amazon2cis_rule_4_3_6: {{ amazon2cis_rule_4_3_6 }} +amazon2cis_rule_4_3_7: {{ amazon2cis_rule_4_3_7 }} + +## Configure Pluggable Authentication +# software packages +amazon2cis_rule_4_4_1_1: {{ amazon2cis_rule_4_4_1_1 }} +amazon2cis_rule_4_4_1_2: {{ amazon2cis_rule_4_4_1_2 }} + +# pam_faillock +amazon2cis_rule_4_4_2_1_1: {{ amazon2cis_rule_4_4_2_1_1 }} +amazon2cis_rule_4_4_2_1_2: {{ amazon2cis_rule_4_4_2_1_2 }} +amazon2cis_rule_4_4_2_1_3: {{ amazon2cis_rule_4_4_2_1_3 }} +amazon2cis_rule_4_4_2_1_4: {{ amazon2cis_rule_4_4_2_1_4 }} + +# pam_pwquality +amazon2cis_rule_4_4_2_2_1: {{ amazon2cis_rule_4_4_2_2_1 }} +amazon2cis_rule_4_4_2_2_2: {{ amazon2cis_rule_4_4_2_2_2 }} +amazon2cis_rule_4_4_2_2_3: {{ amazon2cis_rule_4_4_2_2_3 }} +amazon2cis_rule_4_4_2_2_4: {{ amazon2cis_rule_4_4_2_2_4 }} +amazon2cis_rule_4_4_2_2_5: {{ amazon2cis_rule_4_4_2_2_5 }} +amazon2cis_rule_4_4_2_2_6: {{ amazon2cis_rule_4_4_2_2_6 }} +amazon2cis_rule_4_4_2_2_7: {{ amazon2cis_rule_4_4_2_2_7 }} + +# pam pwhistory +amazon2cis_rule_4_4_2_3_1: {{ amazon2cis_rule_4_4_2_3_1 }} +amazon2cis_rule_4_4_2_3_2: {{ amazon2cis_rule_4_4_2_3_2 }} +amazon2cis_rule_4_4_2_3_3: {{ amazon2cis_rule_4_4_2_3_3 }} +amazon2cis_rule_4_4_2_3_4: {{ amazon2cis_rule_4_4_2_3_4 }} + +# pam pam_unix +amazon2cis_rule_4_4_2_4_1: {{ amazon2cis_rule_4_4_2_4_1 }} +amazon2cis_rule_4_4_2_4_2: {{ amazon2cis_rule_4_4_2_4_2 }} +amazon2cis_rule_4_4_2_4_3: {{ amazon2cis_rule_4_4_2_4_3 }} +amazon2cis_rule_4_4_2_4_4: {{ amazon2cis_rule_4_4_2_4_4 }} + +# shadow password +amazon2cis_rule_4_5_1_1: {{ amazon2cis_rule_4_5_1_1 }} +amazon2cis_rule_4_5_1_2: {{ amazon2cis_rule_4_5_1_2 }} +amazon2cis_rule_4_5_1_3: {{ amazon2cis_rule_4_5_1_3 }} +amazon2cis_rule_4_5_1_4: {{ amazon2cis_rule_4_5_1_4 }} +amazon2cis_rule_4_5_1_5: {{ amazon2cis_rule_4_5_1_5 }} + +# root and system accts +amazon2cis_rule_4_5_2_1: {{ amazon2cis_rule_4_5_2_1 }} +amazon2cis_rule_4_5_2_2: {{ amazon2cis_rule_4_5_2_2 }} +amazon2cis_rule_4_5_2_3: {{ amazon2cis_rule_4_5_2_3 }} +amazon2cis_rule_4_5_2_4: {{ amazon2cis_rule_4_5_2_4 }} + +# user default envs +amazon2cis_rule_4_5_3_1: {{ amazon2cis_rule_4_5_3_1 }} +amazon2cis_rule_4_5_3_2: {{ amazon2cis_rule_4_5_3_2 }} +amazon2cis_rule_4_5_3_3: {{ amazon2cis_rule_4_5_3_3 }} + + +# +## Section 5 rules +## + +# Rsyslog +amazon2cis_rule_5_1_1_1: {{ amazon2cis_rule_5_1_1_1 }} +amazon2cis_rule_5_1_1_2: {{ amazon2cis_rule_5_1_1_2 }} +amazon2cis_rule_5_1_1_3: {{ amazon2cis_rule_5_1_1_3 }} +amazon2cis_rule_5_1_1_4: {{ amazon2cis_rule_5_1_1_4 }} +amazon2cis_rule_5_1_1_5: {{ amazon2cis_rule_5_1_1_5 }} +amazon2cis_rule_5_1_1_6: {{ amazon2cis_rule_5_1_1_6 }} +amazon2cis_rule_5_1_1_7: {{ amazon2cis_rule_5_1_1_7 }} + +# Journald +amazon2cis_rule_5_1_2_1_1: {{ amazon2cis_rule_5_1_2_1_1 }} +amazon2cis_rule_5_1_2_1_2: {{ amazon2cis_rule_5_1_2_1_2 }} +amazon2cis_rule_5_1_2_1_3: {{ amazon2cis_rule_5_1_2_1_3 }} +amazon2cis_rule_5_1_2_1_4: {{ amazon2cis_rule_5_1_2_1_4 }} +amazon2cis_rule_5_1_2_2: {{ amazon2cis_rule_5_1_2_2 }} +amazon2cis_rule_5_1_2_3: {{ amazon2cis_rule_5_1_2_3 }} +amazon2cis_rule_5_1_2_4: {{ amazon2cis_rule_5_1_2_4 }} +amazon2cis_rule_5_1_2_5: {{ amazon2cis_rule_5_1_2_5 }} +amazon2cis_rule_5_1_2_6: {{ amazon2cis_rule_5_1_2_6 }} amazon2cis_rule_5_1_3: {{ amazon2cis_rule_5_1_3 }} amazon2cis_rule_5_1_4: {{ amazon2cis_rule_5_1_4 }} -amazon2cis_rule_5_1_5: {{ amazon2cis_rule_5_1_5 }} -amazon2cis_rule_5_1_6: {{ amazon2cis_rule_5_1_6 }} -amazon2cis_rule_5_1_7: {{ amazon2cis_rule_5_1_7 }} -amazon2cis_rule_5_1_8: {{ amazon2cis_rule_5_1_8 }} -amazon2cis_rule_5_1_9: {{ amazon2cis_rule_5_1_9 }} - -amazon2cis_rule_5_2_1: {{ amazon2cis_rule_5_2_1 }} -amazon2cis_rule_5_2_2: {{ amazon2cis_rule_5_2_2 }} -amazon2cis_rule_5_2_3: {{ amazon2cis_rule_5_2_3 }} - +# Auditd +amazon2cis_rule_5_2_1_1: {{ amazon2cis_rule_5_2_1_1 }} +amazon2cis_rule_5_2_1_2: {{ amazon2cis_rule_5_2_1_2 }} +amazon2cis_rule_5_2_1_3: {{ amazon2cis_rule_5_2_1_3 }} +amazon2cis_rule_5_2_1_4: {{ amazon2cis_rule_5_2_1_4 }} +amazon2cis_rule_5_2_2_1: {{ amazon2cis_rule_5_2_2_1 }} +amazon2cis_rule_5_2_2_2: {{ amazon2cis_rule_5_2_2_2 }} +amazon2cis_rule_5_2_2_3: {{ amazon2cis_rule_5_2_2_3 }} +amazon2cis_rule_5_2_2_4: {{ amazon2cis_rule_5_2_2_4 }} + +# auditd rules +amazon2cis_rule_5_2_3_1: {{ amazon2cis_rule_5_2_3_1 }} +amazon2cis_rule_5_2_3_2: {{ amazon2cis_rule_5_2_3_2 }} +amazon2cis_rule_5_2_3_3: {{ amazon2cis_rule_5_2_3_3 }} +amazon2cis_rule_5_2_3_4: {{ amazon2cis_rule_5_2_3_4 }} +amazon2cis_rule_5_2_3_5: {{ amazon2cis_rule_5_2_3_5 }} +amazon2cis_rule_5_2_3_6: {{ amazon2cis_rule_5_2_3_6 }} +amazon2cis_rule_5_2_3_7: {{ amazon2cis_rule_5_2_3_7 }} +amazon2cis_rule_5_2_3_8: {{ amazon2cis_rule_5_2_3_8 }} +amazon2cis_rule_5_2_3_9: {{ amazon2cis_rule_5_2_3_9 }} +amazon2cis_rule_5_2_3_10: {{ amazon2cis_rule_5_2_3_10 }} +amazon2cis_rule_5_2_3_11: {{ amazon2cis_rule_5_2_3_11 }} +amazon2cis_rule_5_2_3_12: {{ amazon2cis_rule_5_2_3_12 }} +amazon2cis_rule_5_2_3_13: {{ amazon2cis_rule_5_2_3_13 }} +amazon2cis_rule_5_2_3_14: {{ amazon2cis_rule_5_2_3_14 }} +amazon2cis_rule_5_2_3_15: {{ amazon2cis_rule_5_2_3_15 }} +amazon2cis_rule_5_2_3_16: {{ amazon2cis_rule_5_2_3_16 }} +amazon2cis_rule_5_2_3_17: {{ amazon2cis_rule_5_2_3_17 }} +amazon2cis_rule_5_2_3_18: {{ amazon2cis_rule_5_2_3_18 }} +amazon2cis_rule_5_2_3_19: {{ amazon2cis_rule_5_2_3_19 }} +amazon2cis_rule_5_2_3_20: {{ amazon2cis_rule_5_2_3_20 }} +amazon2cis_rule_5_2_3_21: {{ amazon2cis_rule_5_2_3_21 }} + +# auditd file access +amazon2cis_rule_5_2_4_1: {{ amazon2cis_rule_5_2_4_1 }} +amazon2cis_rule_5_2_4_2: {{ amazon2cis_rule_5_2_4_2 }} +amazon2cis_rule_5_2_4_3: {{ amazon2cis_rule_5_2_4_3 }} +amazon2cis_rule_5_2_4_4: {{ amazon2cis_rule_5_2_4_4 }} +amazon2cis_rule_5_2_4_5: {{ amazon2cis_rule_5_2_4_5 }} +amazon2cis_rule_5_2_4_6: {{ amazon2cis_rule_5_2_4_6 }} +amazon2cis_rule_5_2_4_7: {{ amazon2cis_rule_5_2_4_7 }} +amazon2cis_rule_5_2_4_8: {{ amazon2cis_rule_5_2_4_8 }} +amazon2cis_rule_5_2_4_9: {{ amazon2cis_rule_5_2_4_9 }} +amazon2cis_rule_5_2_4_10: {{ amazon2cis_rule_5_2_4_10 }} + +# Aide amazon2cis_rule_5_3_1: {{ amazon2cis_rule_5_3_1 }} amazon2cis_rule_5_3_2: {{ amazon2cis_rule_5_3_2 }} -amazon2cis_rule_5_3_3: {{ amazon2cis_rule_5_3_3 }} -amazon2cis_rule_5_3_4: {{ amazon2cis_rule_5_3_4 }} -amazon2cis_rule_5_3_5: {{ amazon2cis_rule_5_3_5 }} -amazon2cis_rule_5_3_6: {{ amazon2cis_rule_5_3_6 }} -amazon2cis_rule_5_3_7: {{ amazon2cis_rule_5_3_7 }} -amazon2cis_rule_5_3_8: {{ amazon2cis_rule_5_3_8 }} -amazon2cis_rule_5_3_9: {{ amazon2cis_rule_5_3_9 }} -amazon2cis_rule_5_3_10: {{ amazon2cis_rule_5_3_10 }} -amazon2cis_rule_5_3_11: {{ amazon2cis_rule_5_3_11 }} -amazon2cis_rule_5_3_12: {{ amazon2cis_rule_5_3_12 }} -amazon2cis_rule_5_3_13: {{ amazon2cis_rule_5_3_13 }} -amazon2cis_rule_5_3_14: {{ amazon2cis_rule_5_3_14 }} -amazon2cis_rule_5_3_15: {{ amazon2cis_rule_5_3_15 }} -amazon2cis_rule_5_3_16: {{ amazon2cis_rule_5_3_16 }} -amazon2cis_rule_5_3_17: {{ amazon2cis_rule_5_3_17 }} -amazon2cis_rule_5_3_18: {{ amazon2cis_rule_5_3_18 }} -amazon2cis_rule_5_3_19: {{ amazon2cis_rule_5_3_19 }} -amazon2cis_rule_5_3_20: {{ amazon2cis_rule_5_3_20 }} -amazon2cis_rule_5_3_21: {{ amazon2cis_rule_5_3_21 }} -amazon2cis_rule_5_3_22: {{ amazon2cis_rule_5_3_22 }} - - -amazon2cis_rule_5_4_1: {{ amazon2cis_rule_5_4_1 }} -amazon2cis_rule_5_4_2: {{ amazon2cis_rule_5_4_2 }} -amazon2cis_rule_5_4_3: {{ amazon2cis_rule_5_4_3 }} -amazon2cis_rule_5_4_4: {{ amazon2cis_rule_5_4_4 }} - -amazon2cis_rule_5_5_1_1: {{ amazon2cis_rule_5_5_1_1 }} -amazon2cis_rule_5_5_1_2: {{ amazon2cis_rule_5_5_1_2 }} -amazon2cis_rule_5_5_1_3: {{ amazon2cis_rule_5_5_1_3 }} -amazon2cis_rule_5_5_1_4: {{ amazon2cis_rule_5_5_1_4 }} -amazon2cis_rule_5_5_1_5: {{ amazon2cis_rule_5_5_1_5 }} - -amazon2cis_rule_5_5_2: {{ amazon2cis_rule_5_5_2 }} -amazon2cis_rule_5_5_3: {{ amazon2cis_rule_5_5_3 }} -amazon2cis_rule_5_5_4: {{ amazon2cis_rule_5_5_4 }} -amazon2cis_rule_5_5_5: {{ amazon2cis_rule_5_5_5 }} - -amazon2cis_rule_5_6: {{ amazon2cis_rule_5_6 }} -amazon2cis_rule_5_7: {{ amazon2cis_rule_5_7 }} # Section 6 @@ -328,106 +440,147 @@ amazon2cis_rule_6_2_16: {{ amazon2cis_rule_6_2_16 }} amazon2cis_rule_6_2_17: {{ amazon2cis_rule_6_2_17 }} +#### +## Section 1 +#### +# Warning Banner Content (issue, issue.net, motd) +amazon2cis_warning_banner: {{ amazon2cis_warning_banner }} +# End Banner + +#### +## Section 2 variables +#### + +amazon2cis_time_synchronization: {{ amazon2cis_time_synchronization }} +amazon2cis_time_synchronization_servers: +{% for server in amazon2cis_time_synchronization_servers %} + - {{ server }} +{% endfor %} + + +amazon2cis_chrony_server_options: "{{ amazon2cis_chrony_server_options }}" +amazon2cis_ntp_server_options: "{{ amazon2cis_ntp_server_options }}" + +# 2.2.x # Service configuration booleans set true to keep service +# Service configuration +# Options are +# true to leave installed if exists not changes take place +# false - this removes the package +# mask - if a dependancy for product so cannot be removed +# Server Services +amazon2cis_autofs_services: {{ amazon2cis_autofs_services }} +amazon2cis_autofs_mask: {{ amazon2cis_autofs_mask }} amazon2cis_avahi_server: {{ amazon2cis_avahi_server }} -amazon2cis_cups_server: {{ amazon2cis_cups_server }} +amazon2cis_avahi_mask: {{ amazon2cis_avahi_mask }} amazon2cis_dhcp_server: {{ amazon2cis_dhcp_server }} -amazon2cis_ldap_server: {{ amazon2cis_ldap_server }} -amazon2cis_telnet_server: {{ amazon2cis_telnet_server }} +amazon2cis_dhcp_mask: {{ amazon2cis_dhcp_mask }} +amazon2cis_dns_server: {{ amazon2cis_dns_server }} +amazon2cis_dns_mask: {{ amazon2cis_dns_mask }} +amazon2cis_dnsmasq_server: {{ amazon2cis_dnsmasq_server }} +amazon2cis_dnsmasq_mask: {{ amazon2cis_dnsmasq_mask }} +amazon2cis_samba_server: {{ amazon2cis_samba_server }} +amazon2cis_samba_mask: {{ amazon2cis_samba_mask }} +amazon2cis_ftp_server: {{ amazon2cis_ftp_server }} +amazon2cis_ftp_mask: {{ amazon2cis_ftp_mask }} +amazon2cis_message_server: {{ amazon2cis_message_server }} # This is for messaging dovecot and cyrus-imap +amazon2cis_message_mask: {{ amazon2cis_message_mask }} amazon2cis_nfs_server: {{ amazon2cis_nfs_server }} +amazon2cis_nfs_mask: {{ amazon2cis_nfs_mask }} +amazon2cis_nis_server: {{ amazon2cis_nis_server }} # set to mask if nis client required +amazon2cis_nis_mask: {{ amazon2cis_nis_mask }} +amazon2cis_print_server: {{ amazon2cis_print_server }} # replaces cups +amazon2cis_print_mask: {{ amazon2cis_print_mask }} amazon2cis_rpc_server: {{ amazon2cis_rpc_server }} -amazon2cis_rsyncd_server: {{ amazon2cis_rsyncd_server }} -amazon2cis_nis_server: {{ amazon2cis_nis_server }} -amazon2cis_snmp_server: {{ amazon2cis_snmp_server }} +amazon2cis_rpc_mask: {{ amazon2cis_rpc_mask }} +amazon2cis_rsync_server: {{ amazon2cis_rsync_server }} +amazon2cis_rsync_mask: {{ amazon2cis_rsync_mask }} +amazon2cis_net_snmp_server: {{ amazon2cis_net_snmp_server }} +amazon2cis_net_snmp_mask: {{ amazon2cis_net_snmp_mask }} +amazon2cis_telnet_server: {{ amazon2cis_telnet_server }} +amazon2cis_telnet_mask: {{ amazon2cis_telnet_mask }} +amazon2cis_tftp_server: {{ amazon2cis_tftp_server }} +amazon2cis_tftp_mask: {{ amazon2cis_tftp_mask }} amazon2cis_squid_server: {{ amazon2cis_squid_server }} -amazon2cis_smb_server: {{ amazon2cis_smb_server }} -amazon2cis_dovecot_server: {{ amazon2cis_dovecot_server }} +amazon2cis_squid_mask: {{ amazon2cis_squid_mask }} amazon2cis_httpd_server: {{ amazon2cis_httpd_server }} -amazon2cis_vsftpd_server: {{ amazon2cis_vsftpd_server }} -amazon2cis_nfs_rpc_server: {{ amazon2cis_nfs_rpc_server }} +amazon2cis_httpd_mask: {{ amazon2cis_httpd_mask }} +amazon2cis_nginx_server: {{ amazon2cis_nginx_server }} +amazon2cis_nginx_mask: {{ amazon2cis_nginx_mask }} +amazon2cis_xinetd_server: {{ amazon2cis_xinetd_server }} +amazon2cis_xinetd_mask: {{ amazon2cis_xinetd_mask }} +amazon2cis_xwindow_server: {{ amazon2cis_xwindow_server }} # will remove mask not an option amazon2cis_is_mail_server: {{ amazon2cis_is_mail_server }} -amazon2cis_bind: {{ amazon2cis_named_server}} - -# client services +# Service Clients +# Client Services +amazon2cis_ftp_client: {{ amazon2cis_ftp_client }} amazon2cis_openldap_clients_required: {{ amazon2cis_openldap_clients_required }} +amazon2cis_ypbind_required: {{ amazon2cis_ypbind_required }} # Same package as NIS server amazon2cis_telnet_required: {{ amazon2cis_telnet_required }} -amazon2cis_talk_required: {{ amazon2cis_talk_required }} -amazon2cis_rsh_required: {{ amazon2cis_rsh_required }} -amazon2cis_ypbind_required: {{ amazon2cis_ypbind_required }} - -# AIDE -amazon2cis_config_aide: {{ amazon2cis_config_aide }} - -# aide setup via - cron, timer -amazon2cis_aide_scan_type: cron - -# AIDE cron settings -amazon2cis_aide_cron: - cron_user: {{ amazon2cis_aide_cron.cron_user }} - cron_file: '{{ amazon2cis_aide_cron.cron_file }}' - aide_job: ' {{ amazon2cis_aide_cron.aide_job }}' - aide_minute: '{{ amazon2cis_aide_cron.aide_minute }}' - aide_hour: '{{ amazon2cis_aide_cron.aide_hour }}' - aide_day: '{{ amazon2cis_aide_cron.aide_day }}' - aide_month: '{{ amazon2cis_aide_cron.aide_month }}' - aide_weekday: '{{ amazon2cis_aide_cron.aide_weekday }}' - - - -# Warning Banner Content (issue, issue.net, motd) -amazon2cis_warning_banner: {{ amazon2cis_warning_banner }} -# End Banner - -# Set to 'true' if X Windows is needed in your environment -amazon2cis_xwindows_required: {{ amazon2cis_xwindows_required }} - -# Whether or not to run tasks related to auditing/patching the desktop environment -amazon2cis_gui: {{ amazon2cis_gui }} - +amazon2cis_tftp_client: {{ amazon2cis_tftp_client }} +#### +## Section 3 +#### +# Section 3 Variables +# 3.1.x # IPv6 required amazon2cis_ipv6_required: {{ amazon2cis_ipv6_required }} +# Setting this will stop ipv6 listening on ::1 and will remove from /etc/hosts +amazon2cis_ipv6_disable_localhost: false + +# service = true removes package - mask = true will just mask package +amazon2cis_bluetooth_service: {{ amazon2cis_bluetooth_service }} +amazon2cis_bluetooth_mask: {{ amazon2cis_bluetooth_mask }} + +# 3.3.x # System network parameters (host only OR host and router) amazon2cis_is_router: {{ amazon2cis_is_router }} -# Time Synchronization -amazon2cis_time_synchronization: {{ amazon2cis_time_synchronization }} - +# Firewall Service - either firewalld, iptables or nftables +# multiple options for removal or masking of services +# The firewall to be configured +amazon2cis_system_firewall: {{ amazon2cis_system_firewall }} +# Set the following to remove or mask - note will not effect system_firewall # set to none +amazon2cis_nftables: {{ amazon2cis_nfs_mask }} +amazon2cis_iptables: {{ amazon2cis_iptables }} +amazon2cis_firewalld: {{ amazon2cis_firewalld }} -amazon2cis_firewall: {{ amazon2cis_firewall }} -#amazon2cis_firewall: iptables -amazon2cis_default_firewall_zone: {{ amazon2cis_default_zone }} -amazon2cis_firewall_interface: -- ['enp0s3'] -- ['enp0s8'] +amazon2cis_firewall_interface: +- eth0 +#### +## Section 4 Variables +#### -### Section 4 -## auditd settings -amazon2cis_auditd: - space_left_action: {{ amazon2cis_auditd.space_left_action}} - action_mail_acct: {{ amazon2cis_auditd.action_mail_acct }} - admin_space_left_action: {{ amazon2cis_auditd.admin_space_left_action }} - max_log_file_action: {{ amazon2cis_auditd.max_log_file_action }} - auditd_backlog_limit: {{ amazon2cis_audit_backlog_limit }} +# SSH variables -## syslog -amazon2cis_runs_rsyslog: true -amazon2cis_rsyslog_listener: false -### Section 5 +amazon2cis_sshd: + clientalivecountmax: {{ amazon2cis_sshd.clientalivecountmax }} + # clientaliveinterval shoudl be between 1 and 900 + clientaliveinterval: {{ amazon2cis_sshd.clientaliveinterval }} + ciphers: {{ amazon2cis_sshd.ciphers }} + macs: {{ amazon2cis_sshd.macs }} + kex: {{ amazon2cis_sshd.kex }} amazon2cis_sshd_limited: false -#Note the following to understand precedence and layout -amazon2cis_sshd_access: - AllowUser: - AllowGroup: - DenyUser: - DenyGroup: - -amazon2cis_ssh_strong_ciphers: Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128- gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr +# Note the following to understand precedence and layout +{% if amazon2cis_sshd.allowusers is defined %} + - AllowUser {% for allowuser in amazon2cis_sshd.allowusers %}{{ allowuser }}{% endfor %} +{% endif %} +{% if amazon2cis_sshd.allowgroups is defined %} + - AllowGroup {% for allowgroup in amazon2cis_sshd.allowgroups %}{{ allowgroup }}{% endfor %} +{% endif %} +{% if amazon2cis_sshd.denyusers is defined %} + - DenyUser {% for denyuser in amazon2cis_sshd.denyusers %}{{ denyuser }}{% endfor %} +{% endif %} +{% if amazon2cis_sshd.denygroups is defined %} + - DenyGroup {% for denygroup in amazon2cis_sshd.denygroups %}{{ denygroup }}{% endfor %} +{% endif %} + amazon2cis_ssh_weak_ciphers: - 3des-cbc - aes128-cbc @@ -440,7 +593,11 @@ amazon2cis_ssh_weak_ciphers: - cast128-cbc - rijndael-cbc@lysator.liu.se -amazon2cis_ssh_strong_macs: MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2- 512,hmac-sha2-256 +amazon2cis_ssh_weak_kex: + - diffie-hellman-group1-sha1 + - diffie-hellman-group14-sha1 + - diffie-hellman-group-exchange-sha1 + amazon2cis_ssh_weak_macs: - hmac-md5 - hmac-md5-96 @@ -457,36 +614,42 @@ amazon2cis_ssh_weak_macs: - umac-64-etm@openssh.com - umac-128-etm@openssh.com -amazon2cis_ssh_strong_kex: KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman- group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 -amazon2cis_ssh_weak_kex: - - diffie-hellman-group1-sha1 - - diffie-hellman-group14-sha1 - - diffie-hellman-group-exchange-sha1 +## Sudo -amazon2cis_ssh_aliveinterval: "300" -amazon2cis_ssh_countmax: "3" +# Group to be used for su +# this group needs to exists groups will not be created for remediation this is considered sys admins -## PAM -amazon2cis_pam_password: - - minclass = 4 -amazon2cis_pam_passwd_retry: "3" +amazon2cis_sugroup: wheel +amazon2cis_sugroup_users: "" +amazon2cis_pwquality_minclass: true -## note this is to skip tests -amazon2cis_skip_pam_passwd_auth: true -amazon2cis_skip_pam_system_auth: true +amazon2cis_pass: + max_days: 365 + warn_age: 7 -# choose one of below -amazon2cis_pwhistory_so: "14" -amazon2cis_unix_so: false -amazon2cis_passwd_remember: "5" +#### +## Section 5 Variables +#### -# logins.def password settings +# Preferred method of logging +# Whether rsyslog or journald preferred method for local logging +amazon2cis_syslog: rsyslog +amazon2cis_rsyslog_ansiblemanaged: true +# Set if system is the log server +amazon2cis_system_is_log_server: false -amazon2cis_pass_max_days: {{ amazon2cis_pass.max_days }} -amazon2cis_pass_min_days: {{ amazon2cis_pass.min_days }} -amazon2cis_pass_warn_age: {{ amazon2cis_pass.warn_age }} +# AuditD +# auditd settings +amazon2cis_auditd: + max_log_file_action: keep_logs +# AIDE +# AIDE +amazon2cis_config_aide: {{ amazon2cis_config_aide }} +# aide setup via - cron, timer +amazon2cis_aide_scan: {{ amazon2cis_aide_scan }} -amazon2cis_sugroup: {{ amazon2cis_sugroup| default('wheel') }} -amazon2cis_sugroup_users: {{ amazon2cis_sugroup_users | default('root') }} +#### +## Section 6 variables +#### diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 24ca3c0..4f78f6b 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -1,80 +1,95 @@ +## This file is managed by Ansible, YOUR CHANGES WILL BE LOST! + # This template will set all of the auditd configurations via a handler in the role in one task instead of individually -{% if amazon2cis_rule_4_1_3 %} --a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change --a always,exit -F arch=b32 -S clock_settime -k time-change --a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change --a always,exit -F arch=b64 -S clock_settime -k time-change +{% if amazon2cis_rule_5_2_3_1 %} +-w /etc/sudoers -p wa -k scope +-w /etc/sudoers.d/ -p wa -k scope +{% endif %} +{% if amazon2cis_rule_5_2_3_2 %} +-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation +-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation +{% endif %} +{% if amazon2cis_rule_5_2_3_3 %} +-w {{ amazon2cis_sudolog_location }} -p wa -k sudo_log_file +{% endif %} +{% if amazon2cis_rule_5_2_3_4 %} +-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change +-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change -w /etc/localtime -p wa -k time-change {% endif %} -{% if amazon2cis_rule_4_1_4 %} +{% if amazon2cis_rule_5_2_3_5 %} +-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale +-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale +-w /etc/issue -p wa -k system-locale +-w /etc/issue.net -p wa -k system-locale +-w /etc/hosts -p wa -k system-locale +-w /etc/sysconfig/network -p wa -k system-locale +-w /etc/sysconfig/network-scripts/ -p wa -k system-locale +{% endif %} +{% if amazon2cis_rule_5_2_3_6 %} +{% for proc in priv_procs.stdout_lines -%} +-a always,exit -F path={{ proc }} -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k privileged +{% endfor %} +{% endif %} +{% if amazon2cis_rule_5_2_3_7 %} +-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=access +-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=access +-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=access +-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=access +{% endif %} +{% if amazon2cis_rule_5_2_3_8 %} -w /etc/group -p wa -k identity -w /etc/passwd -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity {% endif %} -{% if amazon2cis_rule_4_1_5 %} --a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale --a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale --w /etc/issue -p wa -k system-locale --w /etc/issue.net -p wa -k system-locale --w /etc/hosts -p wa -k system-locale --w /etc/sysconfig/network -p wa -k system-locale +{% if amazon2cis_rule_5_2_3_9 %} +-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod +-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod +-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod +-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod +-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod +-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=perm_mod {% endif %} -{% if amazon2cis_rule_4_1_6 %} --w /etc/selinux/ -p wa -k MAC-policy --w /usr/share/selinux/ -p wa -k MAC-policy +{% if amazon2cis_rule_5_2_3_10 %} +-a always,exit -F arch=b32 -S mount -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k mounts +-a always,exit -F arch=b64 -S mount -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k mounts +{% endif %} +{% if amazon2cis_rule_5_2_3_11 %} +-w /var/run/utmp -p wa -k session +-w /var/log/wtmp -p wa -k session +-w /var/log/btmp -p wa -k session {% endif %} -{% if amazon2cis_rule_4_1_7 %} +{% if amazon2cis_rule_5_2_3_12 %} -w /var/log/lastlog -p wa -k logins --w /var/run/faillock/ -p wa -k logins -{% endif %} -{% if amazon2cis_rule_4_1_8 %} --w /var/run/utmp -p wa -k session --w /var/log/wtmp -p wa -k logins --w /var/log/btmp -p wa -k logins -{% endif %} -{% if amazon2cis_rule_4_1_9 %} --a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod --a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod --a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod --a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod --a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod --a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod -{% endif %} -{% if amazon2cis_rule_4_1_10 %} --a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access --a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access --a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access --a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access -{% endif %} -{% if amazon2cis_rule_4_1_11 %} -{% for proc in amazon2cis_4_1_11_priv_procs.stdout_lines -%} --a always,exit -F path={{ proc }} -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -{% endfor %} +-w /var/run/faillock -p wa -k logins {% endif %} -{% if amazon2cis_rule_4_1_12 %} --a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts --a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts +{% if amazon2cis_rule_5_2_3_13 %} +-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=delete +-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -F key=delete {% endif %} -{% if amazon2cis_rule_4_1_13 %} --a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete --a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete +{% if amazon2cis_rule_5_2_3_14 %} +-w /etc/selinux/ -p wa -k MAC-policy +-w /usr/share/selinux/ -p wa -k MAC-policy {% endif %} -{% if amazon2cis_rule_4_1_14 %} --w /etc/sudoers -p wa -k scope --w /etc/sudoers.d/ -p wa -k scope +{% if amazon2cis_rule_5_2_3_15 %} +-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k perm_chng +{% endif %} +{% if amazon2cis_rule_5_2_3_16 %} +-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k perm_chng +{% endif %} +{% if amazon2cis_rule_5_2_3_17 %} +-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k perm_chng {% endif %} -{% if amazon2cis_rule_4_1_15 %} --a always,exit -F arch=b64 -C euid!=uid -F euid=0 -F auid>=1000 -F auid!=4294967295 -S execve -k actions --a always,exit -F arch=b32 -C euid!=uid -F euid=0 -F auid>=1000 -F auid!=4294967295 -S execve -k actions +{% if amazon2cis_rule_5_2_3_18 %} +-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k usermod {% endif %} -{% if amazon2cis_rule_4_1_16 %} --w /sbin/insmod -p x -k modules --w /sbin/rmmod -p x -k modules --w /sbin/modprobe -p x -k modules --a always,exit -F arch=b64 -S init_module -S delete_module -k modules +{% if amazon2cis_rule_5_2_3_19 %} +-a always,exit -F arch=b32 -S init_module,finit_module,delete_module,create_module,query_module -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k kernel_modules +-a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k kernel_modules +-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ amazon2cis_uid_min }} -F auid!=unset -k kernel_modules {% endif %} -{% if amazon2cis_rule_4_1_17 %} +{% if amazon2cis_rule_5_2_3_20 %} -e 2 {% endif %} diff --git a/vars/audit.yml b/vars/audit.yml new file mode 100644 index 0000000..bb50f6d --- /dev/null +++ b/vars/audit.yml @@ -0,0 +1,40 @@ +--- + +#### Audit Configuration Settings #### + +# Timeout for those cmds that take longer to run where timeout set +audit_cmd_timeout: 120000 + +# if get_audit_binary_method == download change accordingly +audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-" + +### Goss Audit Benchmark file ### +## managed by the control audit_content +# git +audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" +audit_git_version: "benchmark_{{ benchmark_version }}" + +## Goss configuration information +# Where the goss audit configuration will be stored - NOTE benchmark-audit is expected +audit_conf_dir: "{{ audit_conf_dest | default('/opt') }}/{{ benchmark }}-Audit" + +# If changed these can affect other products +pre_audit_outfile: "{{ audit_log_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" +post_audit_outfile: "{{ audit_log_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" + +## The following should not need changing + +### Audit binary settings ### +audit_bin_version: + release: v0.4.4 + AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' +audit_bin_path: /usr/local/bin/ +audit_bin: "{{ audit_bin_path }}goss" +audit_format: json + +audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" +audit_results: | + The audit results are: {{ pre_audit_summary }} + {% if not audit_only %}The post remediation audit results are: {{ post_audit_summary }}{% endif %} + + Full breakdown can be found in {{ audit_log_dir }} diff --git a/vars/main.yml b/vars/main.yml index a38c5fb..954ee36 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,2 +1,12 @@ --- -# vars file for . +# vars file for amazon linux 2 + +min_ansible_version: 2.11.1 + +reboot_required: false +change_requires_reboot: false +update_audit_template: false + +# Used to control warning summary +warn_control_list: "" +warn_count: 0