From 8863b52739b4036717d6d6d980ee392a78595306 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 26 Feb 2024 09:36:21 +0000 Subject: [PATCH 01/76] tidy up workflow and variables Signed-off-by: Mark Bolwell --- .github/ISSUE_TEMPLATE/bug_report.md | 33 ------ .../feature-request-or-enhancement.md | 21 ---- .github/ISSUE_TEMPLATE/question.md | 18 --- .github/pull_request_template.md | 12 -- .github/workflows/OS.tfvars | 9 -- .github/workflows/github_networks.tf | 53 --------- .github/workflows/github_vars.tfvars | 13 -- .github/workflows/linux_benchmark_testing.yml | 111 ------------------ .github/workflows/main.tf | 82 ------------- .github/workflows/terraform.tfvars | 6 - .github/workflows/variables.tf | 76 ------------ 11 files changed, 434 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature-request-or-enhancement.md delete mode 100644 .github/ISSUE_TEMPLATE/question.md delete mode 100644 .github/pull_request_template.md delete mode 100644 .github/workflows/OS.tfvars delete mode 100644 .github/workflows/github_networks.tf delete mode 100644 .github/workflows/github_vars.tfvars delete mode 100644 .github/workflows/linux_benchmark_testing.yml delete mode 100644 .github/workflows/main.tf delete mode 100644 .github/workflows/terraform.tfvars delete mode 100644 .github/workflows/variables.tf 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/OS.tfvars b/.github/workflows/OS.tfvars deleted file mode 100644 index 0285721..0000000 --- a/.github/workflows/OS.tfvars +++ /dev/null @@ -1,9 +0,0 @@ -# Amazon Linux 2 -ami_id = "ami-03e0b06f01d45a4eb" -ami_os = "AmazonLinux2" -ami_username = "ec2-user" -ami_user_home = "/home/ec2-user" -instance_tags = { - Name = "Amazon2-CIS" - Environment = "lockdown_github_repo_workflow" -} diff --git a/.github/workflows/github_networks.tf b/.github/workflows/github_networks.tf deleted file mode 100644 index 998cb76..0000000 --- a/.github/workflows/github_networks.tf +++ /dev/null @@ -1,53 +0,0 @@ -resource "aws_vpc" "Main" { - cidr_block = var.main_vpc_cidr - instance_tenancy = "default" - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-VPC" - } -} - -resource "aws_internet_gateway" "IGW" { - vpc_id = aws_vpc.Main.id - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-IGW" - } -} - -resource "aws_subnet" "publicsubnets" { - vpc_id = aws_vpc.Main.id - cidr_block = var.public_subnets - availability_zone = var.availability_zone - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-pubsub" - } -} - -resource "aws_subnet" "Main" { - vpc_id = aws_vpc.Main.id - availability_zone = var.availability_zone - cidr_block = var.private_subnets - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-prvsub" - } -} - -resource "aws_route_table" "PublicRT" { - vpc_id = aws_vpc.Main.id - route { - cidr_block = "0.0.0.0/0" - gateway_id = aws_internet_gateway.IGW.id - } - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-publicRT" - } -} - -resource "aws_route_table_association" "rt_associate_public" { - subnet_id = aws_subnet.Main.id - route_table_id = aws_route_table.PublicRT.id -} diff --git a/.github/workflows/github_vars.tfvars b/.github/workflows/github_vars.tfvars deleted file mode 100644 index 3ea5253..0000000 --- a/.github/workflows/github_vars.tfvars +++ /dev/null @@ -1,13 +0,0 @@ -// github_actions variables -// Resourced in github_networks.tf -// Declared in variables.tf -// - -namespace = "github_actions" -environment = "lockdown_github_repo_workflow" - -// Matching pair name found in AWS for keypairs PEM key -ami_key_pair_name = "github_actions" -main_vpc_cidr = "172.22.0.0/24" -public_subnets = "172.22.0.128/26" -private_subnets = "172.22.0.192/26" diff --git a/.github/workflows/linux_benchmark_testing.yml b/.github/workflows/linux_benchmark_testing.yml deleted file mode 100644 index d028118..0000000 --- a/.github/workflows/linux_benchmark_testing.yml +++ /dev/null @@ -1,111 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: linux_benchmark_pipeline - -# Controls when the action will run. -# Triggers the workflow on push or pull request -# events but only for the devel branch -on: # yamllint disable-line rule:truthy - pull_request_target: - types: [opened, reopened, synchronize] - branches: - - devel - - main - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' - -# 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: ubuntu-latest - - 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://discord.io/ansible-lockdown) as well. - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - env: - ENABLE_DEBUG: false - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, - # so your job can access it - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem - - ### Build out the server - - name: Terraform_Init - working-directory: .github/workflows - run: terraform init - - - name: Terraform_Validate - working-directory: .github/workflows - run: terraform validate - - - name: Terraform_Apply - working-directory: .github/workflows - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - run: terraform apply -var-file "OS.tfvars" -var-file "github_vars.tfvars" --auto-approve -input=false - - ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - working-directory: .github/workflows - run: cat hosts.yml - - # Aws deployments taking a while to come up insert sleep or playbook fails - - - name: Sleep for 60 seconds - run: sleep 60s - shell: bash - - # Run the ansible playbook - - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - - # Remove test system - User secrets to keep if necessary - - - name: Terraform_Destroy - working-directory: .github/workflows - if: always() && env.ENABLE_DEBUG == 'false' - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "OS.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main.tf b/.github/workflows/main.tf deleted file mode 100644 index 16dfdf6..0000000 --- a/.github/workflows/main.tf +++ /dev/null @@ -1,82 +0,0 @@ -provider "aws" { - profile = "" - region = var.aws_region -} - -// Create a security group with access to port 22 and port 80 open to serve HTTP traffic - - -resource "random_id" "server" { - keepers = { - # Generate a new id each time we switch to a new AMI id - ami_id = "${var.ami_id}" - } - - byte_length = 8 -} - -resource "aws_security_group" "github_actions" { - name = "${var.namespace}-${random_id.server.hex}-SG" - vpc_id = aws_vpc.Main.id - - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-SG" - } -} - -// instance setup - -resource "aws_instance" "testing_vm" { - ami = var.ami_id - availability_zone = var.availability_zone - associate_public_ip_address = true - key_name = var.ami_key_pair_name # This is the key as known in the ec2 key_pairs - instance_type = var.instance_type - tags = var.instance_tags - vpc_security_group_ids = [aws_security_group.github_actions.id] - subnet_id = aws_subnet.Main.id - root_block_device { - delete_on_termination = true - } -} - -// generate inventory file -resource "local_file" "inventory" { - filename = "./hosts.yml" - directory_permission = "0755" - file_permission = "0644" - content = < Date: Mon, 26 Feb 2024 09:38:24 +0000 Subject: [PATCH 02/76] updated git files Signed-off-by: Mark Bolwell --- .ansible-lint | 5 +-- .gitignore | 14 +++++++-- .pre-commit-config.yaml | 67 +++++++++++++++++++++++++++++++++++++++++ .yamllint | 53 +++++++++++++++++--------------- 4 files changed, 110 insertions(+), 29 deletions(-) create mode 100644 .pre-commit-config.yaml 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/.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..873f275 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,67 @@ +--- +##### 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 + args: [ '--baseline', '.config/.secrets.baseline' ] + exclude: .config/.gitleaks-report.json + +- repo: https://github.com/gitleaks/gitleaks + rev: v8.18.2 + hooks: + - id: gitleaks + args: ['--baseline-path', '.config/.gitleaks-report.json'] + +- repo: https://github.com/ansible-community/ansible-lint + rev: v24.2.0 + 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 From 13021cb31ebb50932c32c1d3cb6c83834cbe635f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 26 Feb 2024 09:41:53 +0000 Subject: [PATCH 03/76] removed arg warn Signed-off-by: Mark Bolwell --- handlers/main.yml | 9 +-------- tasks/post_remediation_audit.yml | 2 -- tasks/pre_remediation_audit.yml | 2 -- tasks/section_1/cis_1.1.x.yml | 2 -- tasks/section_1/cis_1.2.x.yml | 2 -- tasks/section_3/cis_3.1.x.yml | 2 -- tasks/section_6/cis_6.2.x.yml | 2 -- 7 files changed, 1 insertion(+), 20 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index bfc6e4a..ae1291a 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -10,18 +10,13 @@ - name: remount dev_shm command: mount -o remount /dev/shm - args: - warn: false - name: remount var_tmp command: mount -o remount /var/tmp - args: - warn: false - name: remount home command: mount -o remount /home - args: - warn: false + - name: systemd daemon reload systemd: daemon_reload: true @@ -61,8 +56,6 @@ command: /sbin/service auditd restart check_mode: false failed_when: false - args: - warn: false when: - not amazon2cis_skip_for_travis tags: diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index cff4432..fd1e9ec 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -3,8 +3,6 @@ - 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 }}" changed_when: true - vars: - warn: false - name: Post Audit | ensure audit files readable by users file: diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 3e0c4a6..53e66f8 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -79,8 +79,6 @@ - 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 }}" changed_when: true - vars: - warn: false - name: Pre Audit | Capture audit data if json format block: diff --git a/tasks/section_1/cis_1.1.x.yml b/tasks/section_1/cis_1.1.x.yml index 1f5bb8b..34190fa 100644 --- a/tasks/section_1/cis_1.1.x.yml +++ b/tasks/section_1/cis_1.1.x.yml @@ -250,8 +250,6 @@ 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 - args: - warn: false when: - amazon2cis_rule_1_1_22 tags: diff --git a/tasks/section_1/cis_1.2.x.yml b/tasks/section_1/cis_1.2.x.yml index ef6c99a..f555f4a 100644 --- a/tasks/section_1/cis_1.2.x.yml +++ b/tasks/section_1/cis_1.2.x.yml @@ -19,8 +19,6 @@ command: yum repolist changed_when: false register: amazon2cis_1_2_2_repolist - args: - warn: false - name: "AUDIT| 1.2.2 | AUDIT | Ensure package manager repositories are configured | Show repo list" debug: diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 3c17f66..7bafafe 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -28,8 +28,6 @@ failed_when: false check_mode: false register: amazon2_3_1_2_nmcli_available - args: - warn: false - name: "3.1.2 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled" command: nmcli radio wifi diff --git a/tasks/section_6/cis_6.2.x.yml b/tasks/section_6/cis_6.2.x.yml index 1a8b844..0bbb680 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -7,8 +7,6 @@ changed_when: false failed_when: false register: amazon2_6_2_1_shadow - args: - warn: false - name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords | Good News" debug: From c31fd92864e7569256790b8573bd26d4f5724e0d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 26 Feb 2024 10:51:08 +0000 Subject: [PATCH 04/76] lint fqcn Signed-off-by: Mark Bolwell --- defaults/main.yml | 5 +- handlers/main.yml | 28 +++++----- meta/main.yml | 3 +- site.yml | 6 +-- tasks/LE_audit_setup.yml | 4 +- tasks/check_prereqs.yml | 4 +- tasks/main.yml | 58 ++++++++++++-------- tasks/parse_etc_password.yml | 4 +- tasks/post_remediation_audit.yml | 12 ++--- tasks/pre_remediation_audit.yml | 31 +++++------ tasks/prelim.yml | 33 ++++++------ tasks/section_1/cis_1.1.1.x.yml | 12 ++--- tasks/section_1/cis_1.1.x.yml | 48 ++++++++--------- tasks/section_1/cis_1.2.x.yml | 10 ++-- tasks/section_1/cis_1.3.x.yml | 6 +-- tasks/section_1/cis_1.4.x.yml | 6 +-- tasks/section_1/cis_1.5.x.yml | 14 ++--- tasks/section_1/cis_1.6.x.yml | 19 ++++--- tasks/section_1/cis_1.7.x.yml | 12 ++--- tasks/section_1/cis_1.8.x.yml | 2 +- tasks/section_1/main.yml | 27 ++++++---- tasks/section_2/cis_2.1.1.x.yml | 18 +++---- tasks/section_2/cis_2.1.x.yml | 42 +++++++-------- tasks/section_2/cis_2.2.x.yml | 10 ++-- tasks/section_2/cis_2.3.yml | 2 +- tasks/section_2/main.yml | 12 +++-- tasks/section_3/cis_3.1.x.yml | 8 +-- tasks/section_3/cis_3.2.x.yml | 6 +-- tasks/section_3/cis_3.3.x.yml | 22 ++++---- tasks/section_3/cis_3.4.x.yml | 4 +- tasks/section_3/cis_3.5.1.x.yml | 20 +++---- tasks/section_3/cis_3.5.2.x.yml | 76 +++++++++++++------------- tasks/section_3/cis_3.5.3.1.x.yml | 6 +-- tasks/section_3/main.yml | 21 +++++--- tasks/section_4/cis_4.1.1.x.yml | 10 ++-- tasks/section_4/cis_4.1.2.x.yml | 12 ++--- tasks/section_4/cis_4.1.x.yml | 34 ++++++------ tasks/section_4/cis_4.2.1.x.yml | 30 +++++------ tasks/section_4/cis_4.2.2.x.yml | 6 +-- tasks/section_4/cis_4.2.x.yml | 6 +-- tasks/section_4/main.yml | 18 ++++--- tasks/section_5/cis_5.1.x.yml | 26 ++++----- tasks/section_5/cis_5.2.x.yml | 6 +-- tasks/section_5/cis_5.3.x.yml | 56 ++++++++++---------- tasks/section_5/cis_5.4.x.yml | 20 +++---- tasks/section_5/cis_5.5.1.x.yml | 22 ++++---- tasks/section_5/cis_5.5.x.yml | 12 ++--- tasks/section_5/cis_5.6.x.yml | 4 +- tasks/section_5/cis_5.7.x.yml | 4 +- tasks/section_5/main.yml | 24 ++++++--- tasks/section_6/cis_6.1.x.yml | 50 +++++++++--------- tasks/section_6/cis_6.2.x.yml | 88 +++++++++++++++---------------- tasks/section_6/main.yml | 6 ++- 53 files changed, 539 insertions(+), 486 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 91ff01c..2540b35 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -402,8 +402,7 @@ amazon2cis_system_is_log_server: false # Maxium audit log size in MB amazon2cis_maxauditlog_size: 10 - -amazon2cis_rsyslog_ansibleManaged: true +amazon2cis_rsyslog_ansiblemanaged: true # SSH variables amazon2cis_ssh_loglevel: INFO @@ -474,7 +473,7 @@ amazon2cis_rpm_audit_file: /var/tmp/rpm_file_check # amazon2_6.2.12 amazon2cis_no_world_write_adjust: true amazon2cis_passwd_label: "{{ (this_item | default(item)).id }}: {{ (this_item | default(item)).dir }}" -amazon2cis_dotperm_ansibleManaged: true +amazon2cis_dotperm_ansiblemanaged: true # SELinux policy amazon2cis_selinux_pol: targeted diff --git a/handlers/main.yml b/handlers/main.yml index ae1291a..a1fea0f 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,7 +1,7 @@ --- - name: systemd restart tmp.mount - systemd: + ansible.builtin.systemd: name: tmp.mount daemon_reload: true enabled: true @@ -9,42 +9,42 @@ state: reloaded - name: remount dev_shm - command: mount -o remount /dev/shm + ansible.builtin.command: mount -o remount /dev/shm - name: remount var_tmp - command: mount -o remount /var/tmp + ansible.builtin.command: mount -o remount /var/tmp - name: remount home - command: mount -o remount /home + ansible.builtin.command: mount -o remount /home - name: systemd daemon reload - systemd: + ansible.builtin.systemd: daemon_reload: true - name: grub2cfg - command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" + ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" - name: restart postfix - service: + ansible.builtin.service: name: postfix state: restarted - name: sysctl flush ipv6 route table - sysctl: + ansible.posix.sysctl: name: net.ipv6.route.flush value: '1' sysctl_set: true when: ansible_virtualization_type != "docker" - name: sysctl flush ipv4 route table - sysctl: + ansible.posix.sysctl: name: net.ipv4.route.flush value: '1' sysctl_set: true when: ansible_virtualization_type != "docker" - name: update auditd - template: + ansible.builtin.template: src: audit/99_auditd.rules.j2 dest: /etc/audit/rules.d/99_auditd.rules owner: root @@ -53,7 +53,7 @@ notify: restart auditd - name: restart auditd - command: /sbin/service auditd restart + ansible.builtin.command: /sbin/service auditd restart check_mode: false failed_when: false when: @@ -62,14 +62,14 @@ - skip_ansible_lint - name: grub2cfg - command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" + ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" - name: restart rsyslog - service: + ansible.builtin.service: name: rsyslog state: restarted - name: restart sshd - service: + ansible.builtin.service: name: sshd state: restarted diff --git a/meta/main.yml b/meta/main.yml index c4042ae..fe7d130 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,4 +1,5 @@ --- + galaxy_info: author: "DFed, George Nalen, Mark Bolwell" description: "Apply the Amazon Linux 2 CIS controls" @@ -17,7 +18,7 @@ galaxy_info: - security - cis - hardening - - Amazon + - 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..1012006 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -1,7 +1,7 @@ --- - name: Download audit binary - get_url: + ansible.builtin.get_url: url: "{{ goss_url }}" dest: "{{ audit_bin }}" owner: root @@ -12,7 +12,7 @@ - get_goss_file == 'download' - name: copy audit binary - copy: + ansible.builtin.copy: src: "{{ copy_goss_from_path }}" dest: "{{ audit_bin }}" mode: 0555 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..148d152 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: Check OS version and family - fail: + ansible.builtin.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' @@ -10,7 +10,7 @@ - always - name: Check ansible version - fail: + ansible.builtin.fail: msg: You must use ansible 2.9 or greater when: not ansible_version.full is version_compare('2.9', '>=') tags: @@ -19,7 +19,7 @@ - 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 @@ -27,7 +27,7 @@ - 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: @@ -36,75 +36,89 @@ tags: - rule_5.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 +- name: Run pre-remediation audit + ansible.builtin.import_tasks: + file: 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: flush handlers - meta: flush_handlers + ansible.builtin.meta: flush_handlers - name: run post_remediation audit - import_tasks: post_remediation_audit.yml + ansible.builtin.import_tasks: + file: post_remediation_audit.yml when: - run_audit tags: - run_audit - name: Show Audit Summary - debug: + ansible.builtin.debug: msg: "{{ audit_results.split('\n') }}" when: - run_audit diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index a686a57..5adc3b3 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -2,14 +2,14 @@ - 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 }}" diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index fd1e9ec..a0b7999 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,11 +1,11 @@ --- - 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 }}" + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" changed_when: true - name: Post Audit | ensure audit files readable by users - file: + ansible.builtin.file: path: "{{ item }}" mode: 0644 state: file @@ -16,12 +16,12 @@ - name: Post Audit | Capture audit data if json format block: - name: "capture data {{ post_audit_outfile }}" - command: "cat {{ post_audit_outfile }}" + ansible.builtin.command: "cat {{ post_audit_outfile }}" register: post_audit changed_when: false - name: Capture post-audit result - set_fact: + ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout | from_json |json_query(summary) }}" vars: summary: 'summary."summary-line"' @@ -31,12 +31,12 @@ - name: Post Audit | Capture audit data if documentation format block: - name: "Post Audit | capture data {{ post_audit_outfile }}" - command: "tail -2 {{ post_audit_outfile }}" + ansible.builtin.command: "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..1b0ac6b 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,14 +1,15 @@ --- - name: Pre Audit | Setup the audit - include_tasks: LE_audit_setup.yml + ansible.builtin.import_tasks: + file: LE_audit_setup.yml when: - setup_audit tags: - setup_audit - name: "Pre Audit | Ensure {{ audit_conf_dir }} exists" - file: + ansible.builtin.file: path: "{{ audit_conf_dir }}" state: directory mode: '0755' @@ -16,14 +17,14 @@ - name: Pre Audit | If using git for content set up block: - name: Pre Audit | Install git - package: + ansible.builtin.package: name: git state: present vars: ansible_python_interpreter: "{{ python2_bin }}" - name: Pre Audit | retrieve audit content files from git - git: + ansible.builtin.git: repo: "{{ audit_file_git }}" dest: "{{ audit_conf_dir }}" version: "{{ audit_git_version }}" @@ -31,14 +32,14 @@ - audit_content == 'git' - name: Pre Audit | copy to audit content files to server - copy: + ansible.builtin.copy: src: "{{ audit_local_copy }}" dest: "{{ audit_conf_dir }}" when: - audit_content == 'copy' - name: Pre Audit | get audit content from url - get_url: + ansible.builtin.get_url: url: "{{ audit_files_url }}" dest: "{{ audit_conf_dir }}" when: @@ -47,12 +48,12 @@ - name: Pre Audit | Check Goss is available block: - name: Pre Audit | Check for goss file - stat: + ansible.builtin.stat: path: "{{ audit_bin }}" register: goss_available - name: Pre Audit | If audit ensure goss is available - assert: + ansible.builtin.assert: msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" when: - not goss_available.stat.exists @@ -60,14 +61,14 @@ - run_audit - name: "Pre Audit | Check whether machine is UEFI-based" - stat: + ansible.builtin.stat: path: /sys/firmware/efi register: rhel8_efi_boot tags: - goss_template - name: Pre Audit | Copy ansible default vars values to test audit - template: + ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" mode: 0600 @@ -77,18 +78,18 @@ - goss_template - 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 }}" + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" changed_when: true - name: Pre Audit | Capture audit data if json format block: - name: "Pre Audit | capture data {{ pre_audit_outfile }}" - command: "cat {{ pre_audit_outfile }}" + ansible.builtin.command: "cat {{ pre_audit_outfile }}" changed_when: false register: pre_audit - 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"' @@ -98,12 +99,12 @@ - name: Pre Audit | Capture audit data if documentation format block: - name: "Pre Audit | capture data {{ pre_audit_outfile }}" - command: "tail -2 {{ pre_audit_outfile }}" + ansible.builtin.command: "tail -2 {{ 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_lines }}" when: - audit_format == "documentation" diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 3905a47..ce6bb74 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -1,19 +1,22 @@ --- + # Preliminary tasks that should always be run # List users in order to look files inside each home directory -- include_tasks: parse_etc_password.yml +- name: Import section 1 tasks + ansible.builtin.import_tasks: + file: parse_etc_password.yml when: - amazon2cis_section5 or amazon2cis_section6 - 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 @@ -21,7 +24,7 @@ - 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 @@ -29,7 +32,7 @@ - skip_ansible_lint - name: "PRELIM | Check whether machine is UEFI-based" - stat: + ansible.builtin.stat: path: /sys/firmware/efi register: amazon2cis_efi_boot @@ -37,7 +40,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,46 +48,46 @@ - 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" block: - name: "PRELIM | Section 1.6 | Ensure SELinux is installed" - package: + 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 + 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: + ansible.builtin.package: name: audit state: present vars: ansible_python_interpreter: /bin/python - name: "PRELIM | Section 5.1 | Configure cron" - package: + ansible.builtin.package: name: cronie state: present vars: @@ -93,7 +96,7 @@ ### 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/*'" + ansible.builtin.shell: "getent passwd {1000..65535} | cut -d: -f6 | sort -u | grep -v '/var/' | grep -v '/nonexistent/*' | grep -v '/run/*'" changed_when: false failed_when: false register: amazon2cis_6_2_8_getent @@ -102,7 +105,7 @@ - rule_6.2.8 - name: "PRELIM | 6.2.8 | Set fact for home directory paths for interactive users" - set_fact: + ansible.builtin.set_fact: amazon2cis_stig_interactive_homedir_results: "{{ amazon2cis_6_2_8_getent.stdout_lines }}" when: - amazon2cis_6_2_8_getent.stdout_lines is defined diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index cf45fd3..466e4e3 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -3,7 +3,7 @@ - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled" block: - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Edit modprobe config" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install cramfs(\\s|$)" line: "install cramfs /bin/true" @@ -11,7 +11,7 @@ mode: '0600' - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove cramfs module" - modprobe: + community.general.modprobe: name: cramfs state: absent when: @@ -28,7 +28,7 @@ - name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled" block: - name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Edit modprobe config" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install squashfs(\\s|$)" line: "install squashfs /bin/true" @@ -36,7 +36,7 @@ mode: '0600' - name: "1.1.1.2 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove squashfs module" - modprobe: + community.general.modprobe: name: squashfs state: absent when: @@ -53,7 +53,7 @@ - name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled" block: - name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled | Edit modprobe config" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install udf(\\s|$)" line: "install udf /bin/true" @@ -61,7 +61,7 @@ mode: '0600' - name: "1.1.1.3 | PATCH | Remove udf module" - modprobe: + community.general.modprobe: name: udf state: absent when: diff --git a/tasks/section_1/cis_1.1.x.yml b/tasks/section_1/cis_1.1.x.yml index 34190fa..53b654c 100644 --- a/tasks/section_1/cis_1.1.x.yml +++ b/tasks/section_1/cis_1.1.x.yml @@ -1,7 +1,7 @@ --- - name: "1.1.2 | PATCH | Ensure /tmp is configured" - systemd: + ansible.builtin.systemd: name: tmp.mount daemon_reload: true enabled: true @@ -21,7 +21,7 @@ "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" - mount: + ansible.posix.mount: name: /tmp src: "{{ item.device }}" fstype: "{{ item.fstype }}" @@ -52,7 +52,7 @@ 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: + ansible.posix.mount: name: /dev/shm src: tmpfs fstype: tmpfs @@ -76,13 +76,13 @@ - 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: + ansible.builtin.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: "Congradulations: /var is on a seperate partition" + ansible.builtin.debug: + msg: "Congratulations: /var is on a seperate partition" when: "'/var' in mount_names" when: - amazon2cis_rule_1_1_10 @@ -96,13 +96,13 @@ - 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: + ansible.builtin.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: "Congradulations: /var/tmp is on a seperate partition" + ansible.builtin.debug: + msg: "Congratulations: /var/tmp is on a seperate partition" when: "'/var/tmp' in mount_names" when: - amazon2cis_rule_1_1_11 @@ -117,7 +117,7 @@ "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: + ansible.posix.mount: name: /var/tmp src: "{{ item.device }}" fstype: "{{ item.fstype }}" @@ -147,12 +147,12 @@ - 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: + ansible.builtin.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: + ansible.builtin.debug: msg: "Congradulations: /var/log is on a seperate partition" when: "'/var/log' in mount_names" when: @@ -167,13 +167,13 @@ - 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: + ansible.builtin.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: "Congradulations: /var/log/audit is on a seperate partition" + ansible.builtin.debug: + msg: "Congratulations: /var/log/audit is on a seperate partition" when: "'/var/log/audit' in mount_names" when: - amazon2cis_rule_1_1_16 @@ -187,13 +187,13 @@ - 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: + ansible.builtin.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: "Congradulations: /home is on a seperate partition" + ansible.builtin.debug: + msg: "Congratulations: /home is on a seperate partition" when: "'/home' in mount_names" when: - amazon2cis_rule_1_1_17 @@ -205,7 +205,7 @@ - mounts - name: "1.1.18 | PATCH | Ensure nodev option set on /home partition" - mount: + ansible.posix.mount: name: /home src: "{{ item.device }}" fstype: "{{ item.fstype }}" @@ -230,7 +230,7 @@ "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: + ansible.builtin.debug: msg: "--> Not Applicable" changed_when: false when: @@ -247,7 +247,7 @@ - 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 + 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 when: @@ -262,7 +262,7 @@ - permissions - name: "1.1.23 | PATCH | Disable Automounting" - service: + ansible.builtin.service: name: autofs enabled: false when: @@ -280,7 +280,7 @@ - name: "1.1.24 | PATCH | Disable USB Storage" block: - name: "1.1.24 | PATCH | Disable USB Storage | Edit modprobe config" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/usb-storage.conf regexp: "^(#)?install usb-storage(\\s|$)" line: "install usb-storage /bin/true" @@ -288,7 +288,7 @@ create: true - name: "1.1.24 | PATCH | Remove USB Storage module | Remove usb-storage module" - modprobe: + community.general.modprobe: name: usb-storage state: absent when: diff --git a/tasks/section_1/cis_1.2.x.yml b/tasks/section_1/cis_1.2.x.yml index f555f4a..bbf3012 100644 --- a/tasks/section_1/cis_1.2.x.yml +++ b/tasks/section_1/cis_1.2.x.yml @@ -1,7 +1,7 @@ --- - 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 }} + 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 when: @@ -16,12 +16,12 @@ - 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 + ansible.builtin.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: + ansible.builtin.debug: msg: - "Please check against site policy repos listed below match expected:" - "{{ amazon2cis_1_2_2_repolist.stdout_lines }}" @@ -37,13 +37,13 @@ - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated" block: - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | find repo files" - find: + ansible.builtin.find: paths: /etc/yum.repos.d patterns: "*.repo" register: amazon2_1_2_3_yum_repos - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | set gpgcheck" - replace: + ansible.builtin.replace: path: "{{ item.path }}" regexp: "^gpgcheck=0" replace: "gpgcheck=1" diff --git a/tasks/section_1/cis_1.3.x.yml b/tasks/section_1/cis_1.3.x.yml index bcb51fb..3ce6b2a 100644 --- a/tasks/section_1/cis_1.3.x.yml +++ b/tasks/section_1/cis_1.3.x.yml @@ -3,12 +3,12 @@ - name: "1.3.1 | PATCH | Ensure AIDE is installed" block: - name: "1.3.1 | PATCH | Ensure AIDE is installed | Install" - package: + ansible.builtin.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' + ansible.builtin.command: /usr/sbin/aide --init -B 'database_out=file:/var/lib/aide/aide.db.gz' changed_when: false failed_when: false async: 45 @@ -28,7 +28,7 @@ - aide - name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked" - cron: + ansible.builtin.cron: name: Run AIDE integrity check minute: "{{ amazon2cis_aide_cron['aide_minute'] | default('0') }}" hour: "{{ amazon2cis_aide_cron['aide_hour'] | default('5') }}" diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 953e582..755119c 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -1,7 +1,7 @@ --- - name: "1.4.1 | PATCH | Ensure permissions on bootloader config are configured" - file: + ansible.builtin.file: path: "{{ amazon2cis_bootloader_file }}" owner: root group: root @@ -19,13 +19,13 @@ - 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: + ansible.builtin.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: + ansible.builtin.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' diff --git a/tasks/section_1/cis_1.5.x.yml b/tasks/section_1/cis_1.5.x.yml index 34b05aa..7a49945 100644 --- a/tasks/section_1/cis_1.5.x.yml +++ b/tasks/section_1/cis_1.5.x.yml @@ -3,7 +3,7 @@ - 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: + ansible.builtin.lineinfile: state: present dest: /etc/security/limits.conf regexp: '^#?\\*.*core' @@ -11,7 +11,7 @@ insertbefore: '^# End of file' - name: "1.5.1 | PATCH | Ensure core dumps are restricted | Set active kernel parameter" - sysctl: + ansible.posix.sysctl: name: fs.suid_dumpable value: '0' state: present @@ -20,7 +20,7 @@ ignoreerrors: true - name: "1.5.1 | PATCH | Ensure core dumps are restricted | coredump.conf" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/systemd/coredump.conf regexp: "{{ item.regex }}" line: "{{ item.line }}" @@ -42,13 +42,13 @@ - 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" + ansible.builtin.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.2 | PATCH | Ensure XD/NX support is enabled | Alert on non-active status" - debug: + ansible.builtin.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" @@ -62,7 +62,7 @@ - skip_ansible_lint - name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled" - sysctl: + ansible.posix.sysctl: name: kernel.randomize_va_space value: '2' state: present @@ -78,7 +78,7 @@ - rule_1.5.3 - name: "1.5.4 | PATCH | Ensure prelink is not installed" - package: + ansible.builtin.package: name: prelink state: absent vars: diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index d6dd56c..acffeb7 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -1,7 +1,7 @@ --- - name: "1.6.1.1 | PATCH | Ensure SELinux is installed" - package: + ansible.builtin.package: name: libselinux state: present vars: @@ -17,10 +17,9 @@ - selinux - name: "1.6.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration" - replace: + ansible.builtin.replace: dest: /etc/default/grub regexp: '(selinux|enforcing)\s*=\s*0\s*' - ignore_errors: true notify: grub2cfg when: - not amazon2cis_selinux_disable @@ -35,7 +34,7 @@ - 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: + ansible.posix.selinux: conf: /etc/selinux/config policy: "{{ amazon2cis_selinux_pol }}" state: "{{ amazon2cis_selinux_state }}" @@ -54,7 +53,7 @@ - selinux - name: "1.6.1.5 | PATCH | Ensure the SELinux state is enforcing" - selinux: + ansible.posix.selinux: conf: /etc/selinux/config policy: "{{ amazon2cis_selinux_pol }}" state: enforcing @@ -74,18 +73,18 @@ - 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 + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.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: @@ -98,7 +97,7 @@ - selinux - name: "1.6.1.7 | PATCH | Ensure SETroubleshoot is not installed" - package: + ansible.builtin.package: name: setroubleshoot state: absent vars: @@ -113,7 +112,7 @@ - selinux - name: "1.6.1.8 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" - package: + ansible.builtin.package: name: mcstrans state: absent vars: diff --git a/tasks/section_1/cis_1.7.x.yml b/tasks/section_1/cis_1.7.x.yml index 5f45722..8931303 100644 --- a/tasks/section_1/cis_1.7.x.yml +++ b/tasks/section_1/cis_1.7.x.yml @@ -1,7 +1,7 @@ --- - name: "1.7.1 | PATCH | Ensure message of the day is configured properly" - template: + ansible.builtin.template: src: etc/motd.j2 dest: /etc/motd owner: root @@ -17,7 +17,7 @@ - banner - name: "1.7.2 | PATCH | Ensure local login warning banner is configured properly" - template: + ansible.builtin.template: src: etc/issue.j2 dest: /etc/issue owner: root @@ -33,7 +33,7 @@ - banner - name: "1.7.3 | PATCH | Ensure remote login warning banner is configured properly" - template: + ansible.builtin.template: src: etc/issue.net.j2 dest: /etc/issue.net owner: root @@ -49,7 +49,7 @@ - banner - name: "1.7.4 | PATCH | Ensure permissions on /etc/motd are configured" - file: + ansible.builtin.file: path: /etc/motd state: file owner: root @@ -66,7 +66,7 @@ - permissions - name: "1.7.5 | PATCH | Ensure permissions on /etc/issue are configured" - file: + ansible.builtin.file: path: /etc/issue state: file owner: root @@ -83,7 +83,7 @@ - permissions - name: "1.7.6 | PATCH | Ensure permissions on /etc/issue.net are configured" - file: + ansible.builtin.file: path: /etc/issue.net state: file owner: root diff --git a/tasks/section_1/cis_1.8.x.yml b/tasks/section_1/cis_1.8.x.yml index c3323e6..9bdb0a3 100644 --- a/tasks/section_1/cis_1.8.x.yml +++ b/tasks/section_1/cis_1.8.x.yml @@ -1,7 +1,7 @@ --- - name: "1.8 | PATCH | Ensure updates, patches, and additional security software are installed" - package: + ansible.builtin.package: name: "*" state: latest vars: diff --git a/tasks/section_1/main.yml b/tasks/section_1/main.yml index 28e0c7d..a08250d 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -1,30 +1,39 @@ --- - 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 + ansible.builtin.import_tasks: + file: cis_1.1.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 + ansible.builtin.import_tasks: + file: 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 + ansible.builtin.import_tasks: + file: 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 index 9436b69..f174db6 100644 --- a/tasks/section_2/cis_2.1.1.x.yml +++ b/tasks/section_2/cis_2.1.1.x.yml @@ -3,20 +3,20 @@ - 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: + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.service: name: ntpd state: stopped enabled: false @@ -25,7 +25,7 @@ - amazon2cis_time_synchronization == "chrony" - name: "2.1.1.1 | PATCH | Ensure time synchronization is in use | service stop chrony" - service: + ansible.builtin.service: name: chronyds when: - "'chrony' in ansible_facts.packages" @@ -43,7 +43,7 @@ - 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: + ansible.builtin.template: src: chrony.conf.j2 dest: /etc/chrony.conf owner: root @@ -51,7 +51,7 @@ mode: 0644 - name: "2.1.1.2 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/sysconfig/chronyd regexp: "^(#)?OPTIONS" line: "OPTIONS=\"-u chrony\"" @@ -74,7 +74,7 @@ - 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: + ansible.builtin.template: src: ntp.conf.j2 dest: /etc/ntp.conf owner: root @@ -82,14 +82,14 @@ mode: 0644 - name: "2.1.1.3 | PATCH | Ensure ntp is configured | modify /etc/sysconfig/ntpd" - lineinfile: + ansible.builtin.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: + ansible.builtin.lineinfile: dest: /usr/lib/systemd/system/ntpd.service regexp: "^(#)?ExecStart" line: "ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS" diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index 9b9884f..6eb9af9 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -1,7 +1,7 @@ --- - name: "2.1.2 | PATCH | Ensure X11 Server components are not installed" - package: + ansible.builtin.package: state: absent name: - "@X Window System" @@ -21,13 +21,13 @@ - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed" block: - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - service: + ansible.builtin.service: name: avahi-daemon state: stopped enabled: false - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - package: + ansible.builtin.package: name: - avahi - avahi-autoipd @@ -45,7 +45,7 @@ - services - name: "2.1.4 | PATCH | Ensure CUPS is not installed" - package: + ansible.builtin.package: name: cups state: absent vars: @@ -63,7 +63,7 @@ - services - name: "2.1.5 | PATCH | Ensure DHCP Server is not installed" - package: + ansible.builtin.package: name: dhcpd state: absent vars: @@ -81,7 +81,7 @@ - services - name: "2.1.6 | PATCH | Ensure LDAP server is not installed" - package: + ansible.builtin.package: name: openldap-servers state: absent vars: @@ -99,7 +99,7 @@ - services - name: "2.1.7 | PATCH | Ensure dns server is not installed" - package: + ansible.builtin.package: name: bind state: absent vars: @@ -117,7 +117,7 @@ - services - name: "2.1.8 | PATCH | Ensure FTP server is not installed" - package: + ansible.builtin.package: name: vsftpd state: absent vars: @@ -135,7 +135,7 @@ - services - name: "2.1.9 | PATCH | Ensure HTTP server is not installed" - package: + ansible.builtin.package: name: httpd state: absent vars: @@ -153,7 +153,7 @@ - services - name: "2.1.10 | PATCH | Ensure IMAP and POP3 server is not installed" - package: + ansible.builtin.package: name: dovecot state: absent vars: @@ -171,7 +171,7 @@ - services - name: "2.1.11 | PATCH | Ensure Samba server is not installed" - package: + ansible.builtin.package: name: samba state: absent vars: @@ -189,7 +189,7 @@ - servicess - name: "2.1.12 | PATCH | Ensure HTTP Proxy server is not installed" - package: + ansible.builtin.package: name: squid state: absent vars: @@ -207,7 +207,7 @@ - services - name: "2.1.13 | PATCH | Ensure net-snmp is not installed" - package: + ansible.builtin.package: name: net-snmp state: absent vars: @@ -225,7 +225,7 @@ - services - name: "2.1.14 | PATCH | Ensure nis server is not installed" - package: + ansible.builtin.package: name: ypserv state: absent vars: @@ -243,7 +243,7 @@ - services - name: "2.1.15 | PATCH | Ensure telnet server is not installed" - package: + ansible.builtin.package: name: telnet-server state: absent vars: @@ -261,7 +261,7 @@ - services - name: "2.1.16 | PATCH | Ensure mail transfer agent is configured for local-only mode" - lineinfile: + ansible.builtin.lineinfile: path: /etc/postfix/main.cf regexp: "^(#)?inet_interfaces" line: "inet_interfaces = loopback-only" @@ -280,7 +280,7 @@ - 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: + ansible.builtin.package: name: nfs-utils state: absent vars: @@ -290,7 +290,7 @@ - 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: + ansible.builtin.systemd: name: nfs-server masked: true when: @@ -310,7 +310,7 @@ - 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: + ansible.builtin.package: name: rpcbind state: absent vars: @@ -320,7 +320,7 @@ - not amazon2cis_rpc_server - name: "2.1.18 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | rpcbind-server" - systemd: + ansible.builtin.systemd: name: rpcbind.socket masked: true when: @@ -338,7 +338,7 @@ - services - name: "2.1.19 | PATCH | Ensure rsync is not installed or the rsyncd services are masked" - package: + ansible.builtin.package: name: rsync state: absent vars: diff --git a/tasks/section_2/cis_2.2.x.yml b/tasks/section_2/cis_2.2.x.yml index cc870bb..d58e0d3 100644 --- a/tasks/section_2/cis_2.2.x.yml +++ b/tasks/section_2/cis_2.2.x.yml @@ -1,7 +1,7 @@ --- - name: "2.2.1 | PATCH | Ensure nis client is not installed" - package: + ansible.builtin.package: name: ypbind state: absent vars: @@ -18,7 +18,7 @@ - nis - name: "2.2.2 | PATCH | Ensure rsh client is not installed" - package: + ansible.builtin.package: name: rsh state: absent vars: @@ -35,7 +35,7 @@ - rsh - name: "2.2.3 | PATCH | Ensure talk client is not installed" - package: + ansible.builtin.package: name: talk state: absent vars: @@ -52,7 +52,7 @@ - talk - name: "2.2.4 | PATCH | Ensure telnet client is not installed" - package: + ansible.builtin.package: name: telnet state: absent vars: @@ -69,7 +69,7 @@ - telnet - name: "2.2.5 | PATCH | Ensure LDAP client is not installed" - package: + ansible.builtin.package: name: openldap-client state: absent vars: diff --git a/tasks/section_2/cis_2.3.yml b/tasks/section_2/cis_2.3.yml index 0161d35..f0f4fad 100644 --- a/tasks/section_2/cis_2.3.yml +++ b/tasks/section_2/cis_2.3.yml @@ -1,7 +1,7 @@ --- - name: "2.3 | audit | Ensure nonessential services are removed or masked" - debug: + ansible.builtin.debug: msg: "<----- not required" when: - amazon2cis_rule_2_3 diff --git a/tasks/section_2/main.yml b/tasks/section_2/main.yml index 66b5251..b62865a 100644 --- a/tasks/section_2/main.yml +++ b/tasks/section_2/main.yml @@ -1,13 +1,17 @@ --- - name: "SECTION | 2.1.1 | Time Synchronization" - include_tasks: cis_2.1.1.x.yml + ansible.builtin.import_tasks: + file: cis_2.1.1.x.yml - name: "SECTION | 2.1 | Special Purpose Services" - include_tasks: cis_2.1.x.yml + ansible.builtin.import_tasks: + file: cis_2.1.x.yml - name: "SECTION | 2.2 | Service Clients" - include_tasks: cis_2.2.x.yml + ansible.builtin.import_tasks: + file: cis_2.2.x.yml - name: "SECTION | 2.3 | Nonessential Services" - include_tasks: cis_2.3.yml + ansible.builtin.import_tasks: + file: cis_2.3.yml diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 7bafafe..b9e3a17 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -1,7 +1,7 @@ --- - name: "3.1.1 | PATCH | Disable IPv6" - sysctl: + ansible.posix.sysctl: name: "{{ item }}" value: '1' reload: true @@ -23,14 +23,14 @@ - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled" 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,7 +38,7 @@ 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" diff --git a/tasks/section_3/cis_3.2.x.yml b/tasks/section_3/cis_3.2.x.yml index 7951eab..a709928 100644 --- a/tasks/section_3/cis_3.2.x.yml +++ b/tasks/section_3/cis_3.2.x.yml @@ -2,7 +2,7 @@ - name: "3.2.1 | PATCH | Ensure IP forwarding is disabled" block: - name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv4" - sysctl: + ansible.posix.sysctl: name: net.ipv4.ip_forward value: '0' state: present @@ -11,7 +11,7 @@ notify: sysctl flush ipv4 route table - name: "AUTOMATED | 3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv6" - sysctl: + ansible.posix.sysctl: name: net.ipv6.conf.all.forwarding value: '0' state: present @@ -30,7 +30,7 @@ - rule_3.2.1 - name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true diff --git a/tasks/section_3/cis_3.3.x.yml b/tasks/section_3/cis_3.3.x.yml index dedc137..f9e6111 100644 --- a/tasks/section_3/cis_3.3.x.yml +++ b/tasks/section_3/cis_3.3.x.yml @@ -2,7 +2,7 @@ - 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: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -15,7 +15,7 @@ - { name: net.ipv4.conf.default.accept_source_route, value: 0 } - name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -39,7 +39,7 @@ - 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: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -52,7 +52,7 @@ - { name: net.ipv4.conf.default.accept_redirects, value: 0 } - name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -74,7 +74,7 @@ - sysctls - name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -95,7 +95,7 @@ - sysctl - name: "3.3.4 | PATCH | Ensure suspicious packets are logged" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -116,7 +116,7 @@ - sysctl - name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored" - sysctl: + ansible.posix.sysctl: name: net.ipv4.icmp_echo_ignore_broadcasts value: '1' state: present @@ -133,7 +133,7 @@ - sysctl - name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored" - sysctl: + ansible.posix.sysctl: name: net.ipv4.icmp_ignore_bogus_error_responses value: '1' state: present @@ -150,7 +150,7 @@ - sysctl - name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true @@ -171,7 +171,7 @@ - sysctl - name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled" - sysctl: + ansible.posix.sysctl: name: net.ipv4.tcp_syncookies value: '1' state: present @@ -188,7 +188,7 @@ - sysctl - name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted" - sysctl: + ansible.posix.sysctl: name: '{{ item.name }}' value: '{{ item.value }}' sysctl_set: true diff --git a/tasks/section_3/cis_3.4.x.yml b/tasks/section_3/cis_3.4.x.yml index b691e56..a7bbed1 100644 --- a/tasks/section_3/cis_3.4.x.yml +++ b/tasks/section_3/cis_3.4.x.yml @@ -1,7 +1,7 @@ --- - name: "3.4.1 | PATCH | Ensure DCCP is disabled" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install dccp(\\s|$)" line: "install dccp /bin/true" @@ -19,7 +19,7 @@ - dccp - name: "3.4.2 | PATCH | Ensure SCTP is disabled" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install sctp(\\s|$)" line: "install sctp /bin/true" diff --git a/tasks/section_3/cis_3.5.1.x.yml b/tasks/section_3/cis_3.5.1.x.yml index 8662ad7..8aa893b 100644 --- a/tasks/section_3/cis_3.5.1.x.yml +++ b/tasks/section_3/cis_3.5.1.x.yml @@ -1,7 +1,7 @@ --- - name: "3.5.1.1 | PATCH | Ensure FirewallD is installed" - package: + ansible.builtin.package: name: firewalld state: present vars: @@ -17,7 +17,7 @@ - firewalld - name: "3.5.1.2 | PATCH | Ensure iptables-services not installed with firewalld" - package: + ansible.builtin.package: name: iptables-services state: absent vars: @@ -33,7 +33,7 @@ - firewalld - name: "3.5.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld " - package: + ansible.builtin.package: name: nftables state: absent vars: @@ -49,7 +49,7 @@ - firewalld - name: "3.5.1.4 | PATCH | Ensure firewalld service is enabled and running" - systemd: + ansible.builtin.systemd: name: firewalld state: started enabled: true @@ -66,12 +66,12 @@ - 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 + ansible.builtin.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 }}" + ansible.builtin.command: firewall-cmd --set-default-zone="{{ amazon2cis_default_zone }}" when: - amazon2cis_3_5_1_5_current_default_zone.stdout != amazon2cis_default_zone when: @@ -86,13 +86,13 @@ - 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" + ansible.builtin.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: + ansible.builtin.debug: msg: - "The items below are the policies tied to the interfaces, please correct as needed" - "{{ amazon2cis_3_5_1_6_interfacepolicy.stdout_lines }}" @@ -108,13 +108,13 @@ - 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" + 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_5_1_7_servicesport - name: "3.5.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports" - debug: + ansible.builtin.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 }}" diff --git a/tasks/section_3/cis_3.5.2.x.yml b/tasks/section_3/cis_3.5.2.x.yml index 03d6e56..e81041c 100644 --- a/tasks/section_3/cis_3.5.2.x.yml +++ b/tasks/section_3/cis_3.5.2.x.yml @@ -1,7 +1,7 @@ --- - name: "3.5.2.1 | PATCH | Ensure nftables is installed" - package: + ansible.builtin.package: name: nftables state: present vars: @@ -17,7 +17,7 @@ - nftables - name: "3.5.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables" - package: + ansible.builtin.package: name: firewalld state: absent vars: @@ -33,7 +33,7 @@ - nftables - name: "3.5.2.3 | PATCH | Ensure iptables-services package is not installed" - package: + ansible.builtin.package: name: iptables-services state: absent vars: @@ -51,10 +51,10 @@ - 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 + ansible.builtin.command: iptables -F - name: "3.5.2.4 | PATCH | Ensure iptables are flushed | Flush IPv6 tables" - command: ip6tables -F + ansible.builtin.command: ip6tables -F when: - amazon2cis_ipv6_required when: @@ -71,13 +71,13 @@ - 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 + ansible.builtin.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: + ansible.builtin.debug: msg: - "Below are the current nft tables, please review" - "{{ amazon2cis_3_5_2_5_nft_tables.stdout_lines }}" @@ -85,7 +85,7 @@ - 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: + 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' @@ -94,7 +94,7 @@ - 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 }}" + ansible.builtin.command: nft create table inet "{{ amazon2cis_nft_tables_tableName }}" failed_when: false when: - amazon2cis_nft_tables_autoNewTable @@ -111,25 +111,25 @@ - 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' + ansible.builtin.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' + ansible.builtin.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' + ansible.builtin.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: + ansible.builtin.debug: msg: - "Below are the current INPUT chains" - "{{ amazon2cis_3_5_2_6_input_chains.stdout_lines }}" @@ -141,7 +141,7 @@ - not amazon2cis_nft_tables_autoChainCreate - name: "3.5.2.6 | PATCH | Ensure base chains exist | Create chains if needed" - command: "{{ item }}" + ansible.builtin.command: "{{ item }}" failed_when: false with_items: - nft create chain inet "{{ amazon2cis_nft_tables_tableName }}" input { type filter hook input priority 0 \; } @@ -163,35 +163,35 @@ - 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' + ansible.builtin.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' + ansible.builtin.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' + ansible.builtin.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 + ansible.builtin.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 + 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_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 + 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_5_2_7_ip6saddr.stdout' when: @@ -207,44 +207,44 @@ - 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' + 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_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' + 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_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 + 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_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 + 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_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 + 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_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 + 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_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 + 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_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 + 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_5_2_8_outconnectionrule.stdout' when: @@ -260,46 +260,46 @@ - 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' + ansible.builtin.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' + ansible.builtin.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' + ansible.builtin.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' + ansible.builtin.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 + 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_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 \; } + 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_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 \; } + 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_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 \; } + 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_5_2_9_outputpolicy.stdout' when: @@ -313,7 +313,7 @@ - nftables - name: "3.5.2.10 | PATCH | Ensure nftables service is enabled" - systemd: + ansible.builtin.systemd: name: nftables enabled: true when: @@ -327,7 +327,7 @@ - nftables - name: "3.5.2.11 | PATCH | Ensure nftables rules are permanent" - lineinfile: + ansible.builtin.lineinfile: path: /etc/sysconfig/nftables.conf state: present insertafter: EOF diff --git a/tasks/section_3/cis_3.5.3.1.x.yml b/tasks/section_3/cis_3.5.3.1.x.yml index b0d0e75..8080fd1 100644 --- a/tasks/section_3/cis_3.5.3.1.x.yml +++ b/tasks/section_3/cis_3.5.3.1.x.yml @@ -1,7 +1,7 @@ --- - name: "3.5.3.1.1 | PATCH | Ensure iptables packages are installed" - package: + ansible.builtin.package: name: "{{ item }}" state: present with_items: @@ -20,7 +20,7 @@ - iptables - name: "3.5.3.1.2 | PATCH | Ensure nftables is not installed with iptables" - package: + ansible.builtin.package: name: nftables state: absent vars: @@ -36,7 +36,7 @@ - iptables - name: "AUTOMATED | 3.5.3.1.3 | PATCH | Ensure firewalld is either not installed or masked with iptables" - package: + ansible.builtin.package: name: firewalld state: absent vars: diff --git a/tasks/section_3/main.yml b/tasks/section_3/main.yml index cecdfdf..2e14c83 100644 --- a/tasks/section_3/main.yml +++ b/tasks/section_3/main.yml @@ -1,28 +1,35 @@ --- - name: "SECTION | 3.1 | Disable unused network protocols and devices" - include_tasks: cis_3.1.x.yml + 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 + 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 + ansible.builtin.import_tasks: + file: cis_3.3.x.yml - name: "SECTION | 3.4 | Uncommon Network Protocols" - include_tasks: cis_3.4.x.yml + ansible.builtin.import_tasks: + file: cis_3.4.x.yml - name: "SECTION | 3.5.1 | Configure firewalld" - include_tasks: cis_3.5.1.x.yml + ansible.builtin.import_tasks: + file: cis_3.5.1.x.yml when: - amazon2cis_firewall == "firewalld" - name: "SECTION | 3.5.2 | Configure nftables" - include_tasks: cis_3.5.2.x.yml + ansible.builtin.import_tasks: + file: cis_3.5.2.x.yml when: - amazon2cis_firewall == "nftables" - name: "SECTION | 3.5.3.1.x | Configure iptables" - include_tasks: cis_3.5.3.1.x.yml + ansible.builtin.import_tasks: + file: cis_3.5.3.1.x.yml when: - amazon2cis_firewall == "iptables" diff --git a/tasks/section_4/cis_4.1.1.x.yml b/tasks/section_4/cis_4.1.1.x.yml index f8a7a3f..9f21f3b 100644 --- a/tasks/section_4/cis_4.1.1.x.yml +++ b/tasks/section_4/cis_4.1.1.x.yml @@ -1,6 +1,6 @@ --- - name: "4.1.1.1 | PATCH | Ensure auditd is installed" - package: + ansible.builtin.package: name: ['audit', 'audit-libs'] state: present notify: restart auditd @@ -16,7 +16,7 @@ - auditd - name: "4.1.1.2 | PATCH | Ensure auditd service is enabled and running" - service: + ansible.builtin.service: name: auditd state: started enabled: true @@ -34,13 +34,13 @@ - 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 GRUB_CMDLINE_LINUX= /etc/default/grub | cut -d'"' -f2 + ansible.builtin.shell: grep GRUB_CMDLINE_LINUX= /etc/default/grub | cut -d'"' -f2 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 audit setting already set" - replace: + ansible.builtin.replace: path: /etc/default/grub regexp: 'audit=([^\D]+)' replace: 'audit=1' @@ -48,7 +48,7 @@ when: "'audit=' 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 audit setting not already set" - lineinfile: + ansible.builtin.lineinfile: path: /etc/default/grub regexp: '^GRUB_CMDLINE_LINUX=' line: 'GRUB_CMDLINE_LINUX="{{ amazon2cis_4_1_1_3_grub_cmdline_linux.stdout }} audit=1"' diff --git a/tasks/section_4/cis_4.1.2.x.yml b/tasks/section_4/cis_4.1.2.x.yml index c4cbb65..8fbcf4c 100644 --- a/tasks/section_4/cis_4.1.2.x.yml +++ b/tasks/section_4/cis_4.1.2.x.yml @@ -1,7 +1,7 @@ --- - name: "4.1.2.1 | PATCH | Ensure audit log storage size is configured" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/audit/auditd.conf regexp: "^max_log_file( |=)" line: "max_log_file = {{ amazon2cis_maxauditlog_size }}" @@ -17,7 +17,7 @@ - auditd - name: "4.1.2.2 | PATCH | Ensure audit logs are not automatically deleted" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/audit/auditd.conf regexp: "^max_log_file_action" line: "max_log_file_action = {{ amazon2cis_auditd['max_log_file_action'] }}" @@ -33,7 +33,7 @@ - auditd - name: "4.1.2.3 | PATCH | Ensure system is disabled when audit logs are full" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/audit/auditd.conf regexp: "{{ item.regexp }}" line: "{{ item.line }}" @@ -55,13 +55,13 @@ - 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 'GRUB_CMDLINE_LINUX=' /etc/default/grub | cut -f2 -d'"' + ansible.builtin.shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | cut -f2 -d'"' 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 not configured" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/default/grub regexp: '^GRUB_CMDLINE_LINUX=' line: 'GRUB_CMDLINE_LINUX="{{ amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout }} audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}"' @@ -69,7 +69,7 @@ when: '"audit_backlog_limit" not in amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout' - name: "4.1.2.4 | PATCH | Ensure audit_backlog_limit is sufficient | Adjust audit_backlog_limit if exists" - replace: + ansible.builtin.replace: dest: /etc/default/grub regexp: 'audit_backlog_limit=([^\D]+)' replace: 'audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}' diff --git a/tasks/section_4/cis_4.1.x.yml b/tasks/section_4/cis_4.1.x.yml index 85a0a70..fc17f4b 100644 --- a/tasks/section_4/cis_4.1.x.yml +++ b/tasks/section_4/cis_4.1.x.yml @@ -1,7 +1,7 @@ --- - name: "4.1.3 | PATCH | Ensure events that modify date and time information are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -15,7 +15,7 @@ - rule_4.1.3 - name: "4.1.4 | PATCH | Ensure events that modify user/group information are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -29,7 +29,7 @@ - auditd - name: "4.1.5 | PATCH | Ensure events that modify the system's network environment are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -43,7 +43,7 @@ - auditd - name: "4.1.6 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -59,7 +59,7 @@ - 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 + ansible.builtin.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 @@ -67,7 +67,7 @@ - skip_ansible_lint - name: "4.1.7 | PATCH | Ensure login and logout events are collected | Set login and logout events" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -81,7 +81,7 @@ - auditd - name: "4.1.8 | PATCH | Ensure session initiation information is collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -95,7 +95,7 @@ - auditd - name: "4.1.9 | PATCH | Ensure discretionary access control permission modification events are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -109,7 +109,7 @@ - auditd - name: "4.1.10 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -125,13 +125,13 @@ - 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 + ansible.builtin.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: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -145,7 +145,7 @@ - auditd - name: "4.1.12 | PATCH | Ensure successful file system mounts are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -159,7 +159,7 @@ - rule_4.1.12 - name: "4.1.13 | PATCH | Ensure file deletion events by users are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -173,7 +173,7 @@ - auditd - name: "4.1.14 | PATCH | Ensure changes to system administration scope (sudoers) is collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -187,7 +187,7 @@ - auditd - name: "4.1.15 | PATCH | Ensure system administrator command executions (sudo) are collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -201,7 +201,7 @@ - auditd - name: "4.1.16 | PATCH | Ensure kernel module loading and unloading is collected" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd @@ -215,7 +215,7 @@ - auditd - name: "4.1.17 | PATCH | Ensure the audit configuration is immutable" - debug: + ansible.builtin.debug: msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules" changed_when: true notify: update auditd diff --git a/tasks/section_4/cis_4.2.1.x.yml b/tasks/section_4/cis_4.2.1.x.yml index 61eab66..ef7a959 100644 --- a/tasks/section_4/cis_4.2.1.x.yml +++ b/tasks/section_4/cis_4.2.1.x.yml @@ -1,7 +1,7 @@ --- - name: "4.2.1.1 | PATCH | Ensure rsyslog is installed" - package: + ansible.builtin.package: name: rsyslog state: present vars: @@ -16,7 +16,7 @@ - rsyslog - name: "4.2.1.2 | PATCH | Ensure rsyslog Service is enabled and running" - service: + ansible.builtin.service: name: rsyslog state: started enabled: true @@ -30,7 +30,7 @@ - rsyslog - name: "4.2.1.3 | PATCH | Ensure rsyslog default file permissions configured" - lineinfile: + ansible.builtin.lineinfile: dest: /etc/rsyslog.conf regexp: '^\$FileCreateMode' line: '$FileCreateMode 0640' @@ -47,20 +47,20 @@ - 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 + ansible.builtin.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: + ansible.builtin.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 + when: not amazon2cis_rsyslog_ansiblemanaged - name: "4.2.1.4 | PATCH | Ensure logging is configured | Set logging settings lineinfile" - lineinfile: + ansible.builtin.lineinfile: path: /etc/rsyslog.conf state: present regexp: "{{ item.regexp }}" @@ -79,10 +79,10 @@ loop_control: label: "{{ item.line }}" notify: restart rsyslog - when: amazon2cis_rsyslog_ansibleManaged + when: amazon2cis_rsyslog_ansiblemanaged - name: "4.2.1.4 | PATCH | Ensure logging is configured | Misc. log setting" - blockinfile: + ansible.builtin.blockinfile: path: /etc/rsyslog.conf state: present marker: "# {mark} MISC. LOG SETTINGS (ANSIBLE MANAGED)" @@ -93,10 +93,10 @@ *.*;mail.none;news.none /var/log/messages insertafter: '#### RULES ####' notify: restart rsyslog - when: amazon2cis_rsyslog_ansibleManaged + when: amazon2cis_rsyslog_ansiblemanaged - name: "4.2.1.4 | PATCH | Ensure logging is configured | Local log settings" - blockinfile: + ansible.builtin.blockinfile: path: /etc/rsyslog.conf state: present marker: "#{mark} LOCAL LOG SETTINGS (ANSIBLE MANAGED)" @@ -118,7 +118,7 @@ - rsyslog - name: "4.2.1.5 | PATCH | Ensure rsyslog is configured to send logs to a remote log host" - blockinfile: + ansible.builtin.blockinfile: path: /etc/rsyslog.conf state: present block: | @@ -143,7 +143,7 @@ - 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: + ansible.builtin.replace: path: /etc/rsyslog.conf regexp: '({{ item }})' replace: '#\1' @@ -155,7 +155,7 @@ - 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: + ansible.builtin.replace: path: /etc/rsyslog.conf regexp: '^#(.*{{ item }}.*)' replace: '\1' @@ -185,7 +185,7 @@ # - 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 "{}" + +# ansible.builtin.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: diff --git a/tasks/section_4/cis_4.2.2.x.yml b/tasks/section_4/cis_4.2.2.x.yml index cd3526b..de2906c 100644 --- a/tasks/section_4/cis_4.2.2.x.yml +++ b/tasks/section_4/cis_4.2.2.x.yml @@ -1,7 +1,7 @@ --- - name: "4.2.2.1 | PATCH | Ensure journald is configured to send logs to rsyslog" - lineinfile: + ansible.builtin.lineinfile: path: /etc/systemd/journald.conf regexp: '^[F|f]orward[T|t]o[S|s]yslog=' line: "ForwardToSyslog=yes" @@ -15,7 +15,7 @@ - journald - name: "4.2.2.2 | PATCH | Ensure journald is configured to compress large log files" - lineinfile: + ansible.builtin.lineinfile: path: /etc/systemd/journald.conf regexp: '^[C|c]ompress=' line: "Compress=yes" @@ -29,7 +29,7 @@ - journald - name: "4.2.2.3 | PATCH | Ensure journald is configured to write logfiles to persistent disk" - lineinfile: + ansible.builtin.lineinfile: path: /etc/systemd/journald.conf regexp: '^[S|s]torage=' line: "Storage=persistent" diff --git a/tasks/section_4/cis_4.2.x.yml b/tasks/section_4/cis_4.2.x.yml index 84ccadd..f0fdf54 100644 --- a/tasks/section_4/cis_4.2.x.yml +++ b/tasks/section_4/cis_4.2.x.yml @@ -3,12 +3,12 @@ - name: "4.2.3 | PATCH | Ensure logrotate is configured" block: - name: "4.2.3 | AUDIT | Ensure logrotate is configured" - find: + ansible.builtin.find: paths: /etc/logrotate.d/ register: amazon2cis_4_2_3_log_rotates - name: "4.2.3 | PATCH | Ensure logrotate is configured" - replace: + ansible.builtin.replace: path: "{{ item.path }}" regexp: '^(\s*)(daily|weekly|monthly|yearly)$' replace: "\\1{{ amazon2cis_logrotate }}" @@ -27,7 +27,7 @@ - logrotate - 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 "{}" + + ansible.builtin.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 when: diff --git a/tasks/section_4/main.yml b/tasks/section_4/main.yml index c540a05..b7bcabd 100644 --- a/tasks/section_4/main.yml +++ b/tasks/section_4/main.yml @@ -1,19 +1,25 @@ --- - name: "SECTION | 4.1.1 | Ensure auditing is enabled" - include_tasks: cis_4.1.1.x.yml + ansible.builtin.import_tasks: + file: cis_4.1.1.x.yml - name: "SECTION | 4.1.2.x | Configure Data Retention" - include_tasks: cis_4.1.2.x.yml + ansible.builtin.import_tasks: + file: cis_4.1.2.x.yml - name: "SECTION | 4.1.x | Misc" - include_tasks: cis_4.1.x.yml + ansible.builtin.import_tasks: + file: cis_4.1.x.yml - name: "SECTION | 4.2.x | Configure Logging" - include_tasks: cis_4.2.1.x.yml + ansible.builtin.import_tasks: + file: cis_4.2.1.x.yml - name: "SECTION | 4.2.2.x | Configure journald" - include_tasks: cis_4.2.2.x.yml + ansible.builtin.import_tasks: + file: cis_4.2.2.x.yml - name: "SECTION | 4.2.x | Misc. Logging settings" - include_tasks: cis_4.2.x.yml + ansible.builtin.import_tasks: + file: cis_4.2.x.yml diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 22b85a4..356cd29 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -1,7 +1,7 @@ --- - name: "5.1.1 | PATCH | Ensure cron daemon is enabled and running" - service: + ansible.builtin.service: name: crond state: started enabled: true @@ -15,7 +15,7 @@ - cron - name: "5.1.2 | PATCH | Ensure permissions on /etc/crontab are configured" - file: + ansible.builtin.file: dest: /etc/crontab owner: root group: root @@ -31,7 +31,7 @@ - cron - name: "5.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured" - file: + ansible.builtin.file: dest: /etc/cron.hourly state: directory owner: root @@ -48,7 +48,7 @@ - cron - name: "5.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured" - file: + ansible.builtin.file: dest: /etc/cron.daily state: directory owner: root @@ -65,7 +65,7 @@ - cron - name: "5.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured" - file: + ansible.builtin.file: dest: /etc/cron.weekly state: directory owner: root @@ -79,7 +79,7 @@ - rule_5.1.5 - name: "5.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured" - file: + ansible.builtin.file: dest: /etc/cron.monthly state: directory owner: root @@ -96,7 +96,7 @@ - cron - name: "5.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured" - file: + ansible.builtin.file: dest: /etc/cron.d state: directory owner: root @@ -115,17 +115,17 @@ - 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: + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.file: dest: /etc/cron.allow state: '{{ "file" if amazon2cis_5_1_8_p.stat.exists else "touch" }}' owner: root @@ -144,17 +144,17 @@ - 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: + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.file: dest: /etc/at.allow state: '{{ "file" if amazon2cis_5_1_9_p.stat.exists else "touch" }}' owner: root diff --git a/tasks/section_5/cis_5.2.x.yml b/tasks/section_5/cis_5.2.x.yml index 9c7e42f..929199b 100644 --- a/tasks/section_5/cis_5.2.x.yml +++ b/tasks/section_5/cis_5.2.x.yml @@ -1,7 +1,7 @@ --- - name: "5.2.1 | PATCH | Ensure sudo is installed" - package: + ansible.builtin.package: name: sudo state: present when: @@ -14,7 +14,7 @@ - sudo - name: "5.2.2 | PATCH | Ensure sudo commands use pty" - lineinfile: + ansible.builtin.lineinfile: path: /etc/sudoers line: 'Defaults use_pty' when: @@ -27,7 +27,7 @@ - sudo - name: "5.2.3 | PATCH | Ensure sudo log file exists" - lineinfile: + ansible.builtin.lineinfile: path: /etc/sudoers line: 'Defaults logfile="/var/log/sudo.log"' when: diff --git a/tasks/section_5/cis_5.3.x.yml b/tasks/section_5/cis_5.3.x.yml index 1e84d3a..6775670 100644 --- a/tasks/section_5/cis_5.3.x.yml +++ b/tasks/section_5/cis_5.3.x.yml @@ -1,7 +1,7 @@ --- - name: "5.3.1 | PATCH | Ensure permissions on /etc/ssh/sshd_config are configured" - file: + ansible.builtin.file: path: /etc/ssh/sshd_config state: file owner: root @@ -20,7 +20,7 @@ - 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: + ansible.builtin.find: paths: /etc/ssh patterns: 'ssh_host_*_key' recurse: true @@ -28,7 +28,7 @@ register: amazon2_5_3_2_priv_results - name: "5.3.2 | AUDIT | Ensure permissions on SSH private host key files are configured" - file: + ansible.builtin.file: path: "{{ item.path }}" owner: root group: root @@ -50,7 +50,7 @@ - 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: + ansible.builtin.find: paths: /etc/ssh patterns: 'ssh_host_*_key' recurse: true @@ -58,7 +58,7 @@ register: amazon2_5_3_3_pub_results - name: "5.3.3 | AUDIT | Ensure permissions on SSH public host key files are configured" - file: + ansible.builtin.file: path: "{{ item.path }}" owner: root group: root @@ -80,7 +80,7 @@ - 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: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^AllowUsers" line: AllowUsers {{ amazon2cis_sshd['allowusers'] }} @@ -88,7 +88,7 @@ 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: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^AllowGroups" line: AllowGroups {{ amazon2cis_sshd['allowgroups'] }} @@ -96,7 +96,7 @@ 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: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^DenyUsers" line: DenyUsers {{ amazon2cis_sshd['denyusers'] }} @@ -104,7 +104,7 @@ 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: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^DenyGroups" line: DenyGroups {{ amazon2cis_sshd['denygroups'] }} @@ -120,7 +120,7 @@ - ssh - name: "5.3.5 | PATCH | Ensure SSH LogLevel is appropriate" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#LogLevel|^LogLevel" line: 'LogLevel {{ amazon2cis_ssh_loglevel }}' @@ -135,7 +135,7 @@ - ssh - name: "5.3.6 | PATCH | Ensure SSH X11 forwarding is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#X11Forwarding|^X11Forwarding" line: 'X11Forwarding no' @@ -150,7 +150,7 @@ - ssh - name: "5.3.7 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^(#)?MaxAuthTries \d' line: "MaxAuthTries {{ amazon2_max_auth_tries }}" @@ -165,7 +165,7 @@ - ssh - name: "5.3.8 | PATCH | Ensure SSH IgnoreRhosts is enabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#IgnoreRhosts|^IgnoreRhosts" line: 'IgnoreRhosts yes' @@ -180,7 +180,7 @@ - ssh - name: "5.3.9 | PATCH | Ensure SSH HostbasedAuthentication is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: ^#HostbasedAuthentication|^HostbasedAuthentication" line: 'HostbasedAuthentication no' @@ -195,7 +195,7 @@ - ssh - name: "5.3.10 | PATCH | Ensure SSH root login is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#PermitRootLogin|^PermitRootLogin" line: 'PermitRootLogin no' @@ -210,7 +210,7 @@ - ssh - name: "5.3.11 | PATCH | Ensure SSH PermitEmptyPasswords is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords" line: 'PermitEmptyPasswords no' @@ -225,7 +225,7 @@ - ssh - name: "5.3.12 | PATCH | Ensure SSH PermitUserEnvironment is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#PermitUserEnvironment|^PermitUserEnvironment" line: 'PermitUserEnvironment no' @@ -240,7 +240,7 @@ - ssh - name: "5.3.13 | PATCH | Ensure only strong Ciphers are used" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^Cipherss' line: "Ciphers {{ amazon2cis_sshd['ciphers'] }}" @@ -255,7 +255,7 @@ - ssh - name: "5.3.14 | PATCH | Ensure only strong MAC algorithms are used" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^MACs' line: "MACs {{ amazon2cis_sshd['macs'] }}" @@ -270,7 +270,7 @@ - ssh - name: "5.3.15 | PATCH | Ensure only strong Key Exchange algorithms are used" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^KexAlgorithms' line: "KexAlgorithms {{ amazon2cis_sshd['kex'] }}" @@ -287,14 +287,14 @@ - 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: + ansible.builtin.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: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^ClientAliveCountMax' line: "ClientAliveCountMax 0" @@ -309,7 +309,7 @@ - ssh - name: "5.3.17 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#LoginGraceTime|^LoginGraceTime" line: "LoginGraceTime {{ amazon2cis_sshd['logingracetime'] }}" @@ -324,7 +324,7 @@ - ssh - name: "5.3.18 | PATCH | Ensure SSH warning banner is configured" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^Banner' line: 'Banner /etc/issue.net' @@ -339,7 +339,7 @@ - ssh - name: "5.3.19 | PATCH | Ensure SSH PAM is enabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#UsePAM|^UsePAM" line: 'UsePAM yes' @@ -354,7 +354,7 @@ - ssh - name: "5.3.20 | PATCH | Ensure SSH AllowTcpForwarding is disabled" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#AllowTcpForwarding|^AllowTcpForwarding" line: 'AllowTcpForwarding no' @@ -369,7 +369,7 @@ - ssh - name: "5.3.21 | PATCH | Ensure SSH MaxStartups is configured" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#MaxStartups|^MaxStartups" line: 'MaxStartups 10:30:60' @@ -384,7 +384,7 @@ - ssh - name: "5.3.22 | PATCH | Ensure SSH MaxSessions is limited" - lineinfile: + ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: "^#MaxSessions|^MaxSessions" line: 'MaxSessions {{ amazon2cis_ssh_maxsessions }}' diff --git a/tasks/section_5/cis_5.4.x.yml b/tasks/section_5/cis_5.4.x.yml index 729d68d..7e8a8bd 100644 --- a/tasks/section_5/cis_5.4.x.yml +++ b/tasks/section_5/cis_5.4.x.yml @@ -1,7 +1,7 @@ --- - name: "5.4.1 | PATCH | Ensure password creation requirements are configured" - lineinfile: + ansible.builtin.lineinfile: path: /etc/security/pwquality.conf regexp: '^{{ item.key }}' line: '{{ item.key }} = {{ item.value }}' @@ -23,7 +23,7 @@ 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: + ansible.builtin.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 }}" @@ -33,7 +33,7 @@ - "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: + ansible.builtin.lineinfile: path: /etc/pam.d/{{ item }} line: "auth [success=1 default=bad] pam_unix.so" insertafter: '^#?auth ?' @@ -42,7 +42,7 @@ - "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: + ansible.builtin.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 ?' @@ -51,7 +51,7 @@ - "password-auth" - name: "5.4.2 | PATCH | Ensure lockout for failed password attempts is configured | Add deny count and unlock times to authsucc" - lineinfile: + ansible.builtin.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 ?' @@ -60,7 +60,7 @@ - "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: + ansible.builtin.lineinfile: path: /etc/pam.d/{{ item }} line: "account required pam_faillock.so" insertbefore: '^#?account ?' @@ -71,7 +71,7 @@ - "password-auth" - name: "5.4.3 | PATCH | Ensure password hashing algorithm is SHA-512 | add sha512 settings" - lineinfile: + ansible.builtin.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 ?' @@ -80,7 +80,7 @@ - "password-auth" - name: "5.4.4 | PATCH | Ensure password reuse is limited | add remember settings" - lineinfile: + ansible.builtin.lineinfile: path: /etc/pam.d/{{ item }} line: "password required pam_pwhistory.so remember={{ amazon2cis_pam_faillock.remember }}" insertafter: '^#?password ?' @@ -95,7 +95,7 @@ "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: + ansible.builtin.copy: src: /etc/pam.d/{{ item }} dest: /etc/pam.d/{{ item }}-local remote_src: true @@ -109,7 +109,7 @@ - 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: + ansible.builtin.file: src: /etc/pam.d/{{ item }}-local dest: /etc/pam.d/{{ item }} state: link diff --git a/tasks/section_5/cis_5.5.1.x.yml b/tasks/section_5/cis_5.5.1.x.yml index f6715fd..41976f0 100644 --- a/tasks/section_5/cis_5.5.1.x.yml +++ b/tasks/section_5/cis_5.5.1.x.yml @@ -1,7 +1,7 @@ --- - name: "5.5.1.1 | PATCH | Ensure password expiration is 365 days or less" - lineinfile: + ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_MAX_DAYS' line: "PASS_MAX_DAYS {{ amazon2cis_pass['max_days'] }}" @@ -16,7 +16,7 @@ - password - name: "5.5.1.2 | PATCH | Ensure minimum days between password changes is configured" - lineinfile: + ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_MIN_DAYS' line: "PASS_MIN_DAYS {{ amazon2cis_pass['min_days'] }}" @@ -31,7 +31,7 @@ - password - name: "5.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more" - lineinfile: + ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_WARN_AGE' line: "PASS_WARN_AGE {{ amazon2cis_pass['warn_age'] }}" @@ -48,19 +48,19 @@ - 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: + ansible.builtin.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" + ansible.builtin.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 }}" + ansible.builtin.command: "chage --inactive {{ amazon2cis_inactivelock.lock_days }} {{ item }}" with_items: - "{{ amazon2_5_5_1_4_audit.stdout_lines }}" when: @@ -78,30 +78,30 @@ - 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)) + ansible.builtin.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}'" + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.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 }} + ansible.builtin.command: passwd --expire {{ item }} when: - amazon2cis_5_5_1_5_user_list | length > 0 - amazon2cis_futurepwchgdate_autofix diff --git a/tasks/section_5/cis_5.5.x.yml b/tasks/section_5/cis_5.5.x.yml index ae5f973..5299f60 100644 --- a/tasks/section_5/cis_5.5.x.yml +++ b/tasks/section_5/cis_5.5.x.yml @@ -3,7 +3,7 @@ - name: "5.5.2 | PATCH | Ensure system accounts are secured" block: - name: "5.5.2 | PATCH | Ensure system accounts are secured | Set nologin" - user: + ansible.builtin.user: name: "{{ item.id }}" shell: /usr/sbin/nologin with_items: @@ -20,7 +20,7 @@ label: "{{ item.id }}" - name: "5.5.2 | PATCH | Ensure system accounts are secured | Lock accounts" - user: + ansible.builtin.user: name: "{{ item.id }}" password_lock: true with_items: @@ -45,7 +45,7 @@ - accounts - name: "5.5.3 | PATCH | Ensure default group for the root account is GID 0" - user: + ansible.builtin.user: name: root group: "0" when: @@ -59,7 +59,7 @@ - root - name: "5.5.4 | PATCH | Ensure default user shell timeout is configured" - blockinfile: + ansible.builtin.blockinfile: path: "{{ item.dest }}" state: "{{ item.state }}" create: true @@ -85,13 +85,13 @@ - 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: + ansible.builtin.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: + ansible.builtin.replace: path: /etc/profile regexp: '(^\s+umask) 002' replace: '\1 027' diff --git a/tasks/section_5/cis_5.6.x.yml b/tasks/section_5/cis_5.6.x.yml index af2529c..d3b601a 100644 --- a/tasks/section_5/cis_5.6.x.yml +++ b/tasks/section_5/cis_5.6.x.yml @@ -3,13 +3,13 @@ - 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 + ansible.builtin.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: + ansible.builtin.debug: msg: - "These are the consoles with root login access, please review:" - "{{ amazon2_5_6_audit.stdout_lines }}" diff --git a/tasks/section_5/cis_5.7.x.yml b/tasks/section_5/cis_5.7.x.yml index e558c32..710b2b8 100644 --- a/tasks/section_5/cis_5.7.x.yml +++ b/tasks/section_5/cis_5.7.x.yml @@ -3,13 +3,13 @@ - 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: + ansible.builtin.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: + ansible.builtin.user: name: root groups: "{{ amazon2cis_sugroup | default('wheel') }}" when: diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index e17862a..40dd73e 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -1,25 +1,33 @@ --- - name: "SECTION | 5.1 | Configure time-based job schedulers" - include_tasks: cis_5.1.x.yml + ansible.builtin.import_tasks: + file: cis_5.1.x.yml - name: "SECTION | 5.2 | Configure sudo" - include_tasks: cis_5.2.x.yml + ansible.builtin.import_tasks: + file: cis_5.2.x.yml - name: "SECTION | 5.3 | Configure SSH Server" - include_tasks: cis_5.3.x.yml + ansible.builtin.import_tasks: + file: cis_5.3.x.yml - name: "SECTION | 5.4 | Configure PAM" - include_tasks: cis_5.4.x.yml + ansible.builtin.import_tasks: + file: cis_5.4.x.yml - name: "SECTION | 5.5.1.x | Set Shadow Password Suite Parameters" - include_tasks: cis_5.5.1.x.yml + ansible.builtin.import_tasks: + file: cis_5.5.1.x.yml - name: "SECTION | 5.5.x" - include_tasks: cis_5.5.x.yml + ansible.builtin.import_tasks: + file: cis_5.5.x.yml - name: "SECTION | 5.6.x" - include_tasks: cis_5.6.x.yml + ansible.builtin.import_tasks: + file: cis_5.6.x.yml - name: "SECTION | 5.7.x" - include_tasks: cis_5.7.x.yml + ansible.builtin.import_tasks: + file: cis_5.7.x.yml diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 4b906de..2acb604 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -3,7 +3,7 @@ - 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 + ansible.builtin.shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto changed_when: false failed_when: false register: amazon2cis_6_1_1_packages_rpm @@ -11,20 +11,20 @@ - skip_ansible_lint - name: "6.1.1 | AUDIT | Audit system file permissions | Add file discrepancy list to system" # noqa template-instead-of-copy - copy: + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.debug: msg: "Good News! There are no package descrepancies" when: amazon2cis_6_1_1_packages_rpm.stdout|length == 0 when: @@ -37,7 +37,7 @@ - permissions - name: "6.1.2 | PATCH | Ensure permissions on /etc/passwd are configured" - file: + ansible.builtin.file: path: /etc/passwd owner: root group: root @@ -52,7 +52,7 @@ - permissions - name: "6.1.3 | PATCH | Ensure permissions on /etc/passwd- are configured" - file: + ansible.builtin.file: path: /etc/passwd- owner: root group: root @@ -67,7 +67,7 @@ - permissions - name: "6.1.4 | PATCH | Ensure permissions on /etc/shadow are configured" - file: + ansible.builtin.file: path: /etc/shadow owner: root group: root @@ -82,7 +82,7 @@ - permissions - name: "6.1.5 | PATCH | Ensure permissions on /etc/shadow- are configured" - file: + ansible.builtin.file: path: /etc/shadow- owner: root group: root @@ -97,7 +97,7 @@ - permissions - name: "6.1.6 | PATCH | Ensure permissions on /etc/gshadow- are configured" - file: + ansible.builtin.file: path: /etc/gshadow- owner: root group: root @@ -112,7 +112,7 @@ - permissions - name: "6.1.7 | PATCH | Ensure permissions on /etc/gshadow are configured" - file: + ansible.builtin.file: path: /etc/gshadow owner: root group: root @@ -127,7 +127,7 @@ - permissions - name: "6.1.8 | PATCH | Ensure permissions on /etc/group are configured" - file: + ansible.builtin.file: path: /etc/group owner: root group: root @@ -142,7 +142,7 @@ - permissions - name: "6.1.9 | PATCH | Ensure permissions on /etc/group- are configured" - file: + ansible.builtin.file: path: /etc/group- owner: root group: root @@ -159,18 +159,18 @@ - 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 + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.file: path: '{{ item }}' mode: o-w state: touch @@ -191,7 +191,7 @@ - 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 + ansible.builtin.command: find "{{ item.mount }}" -xdev -nouser changed_when: false failed_when: false check_mode: false @@ -203,7 +203,7 @@ 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: + ansible.builtin.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 @@ -222,7 +222,7 @@ - name: "6.1.12 | PATCH | Ensure no ungrouped files or directories exist" 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 + ansible.builtin.command: find "{{ item.mount }}" -xdev -nogroup changed_when: false failed_when: false check_mode: false @@ -234,7 +234,7 @@ 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: + ansible.builtin.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') }}" @@ -251,7 +251,7 @@ - name: "6.1.13 | PATCH | Audit SUID executables" 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 + ansible.builtin.shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 changed_when: false failed_when: false register: amazon2_6_1_13_perms_results @@ -261,12 +261,12 @@ label: "{{ item.mount }}" - name: "6.1.13 | AUDIT | Audit SUID executables | Alert no SUID executables exist" - debug: + ansible.builtin.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.13 | AUDIT | Audit SUID executables | Alert SUID executables exist" - debug: + ansible.builtin.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 @@ -282,7 +282,7 @@ - name: "6.1.14 | PATCH | Audit SGID executables" 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 + ansible.builtin.shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000 changed_when: false failed_when: false register: amazon2_6_1_14_perms_results @@ -292,12 +292,12 @@ label: "{{ item.mount }}" - name: "6.1.14 | AUDIT | Audit SGID executables | Alert no SGID executables exist" - debug: + ansible.builtin.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.14 | AUDIT | Audit SGID executables | Alert SGID executables exist" - debug: + ansible.builtin.debug: msg: "Warning - Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}" with_items: - "{{ amazon2_6_1_14_perms_results.stdout_lines }}" diff --git a/tasks/section_6/cis_6.2.x.yml b/tasks/section_6/cis_6.2.x.yml index 0bbb680..610befc 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -3,18 +3,18 @@ - 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 + ansible.builtin.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: + ansible.builtin.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: + ansible.builtin.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" @@ -30,7 +30,7 @@ - accounts - name: "6.2.2 | PATCH | Ensure /etc/shadow password fields are not empty" - command: passwd -l {{ item }} + ansible.builtin.command: passwd -l {{ item }} changed_when: false failed_when: false with_items: @@ -48,19 +48,19 @@ - name: "6.2.3 | PATCH | Ensure all groups in /etc/passwd exist in /etc/group" 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}' + ansible.builtin.shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}' changed_when: false failed_when: false check_mode: false register: amazon2_6_2_3_passwd_gid_check - 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: + ansible.builtin.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.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: + ansible.builtin.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 @@ -76,18 +76,18 @@ - name: "6.2.4 | AUDIT | Ensure shadow group is empty" block: - name: "6.2.4 | AUDIT | Ensure shadow group is empty" - shell: "grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group" + ansible.builtin.shell: "grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group" changed_when: false failed_when: false register: amazon2_6_2_4_users_in_shadow_group - name: "6.2.4 | AUDIT | Ensure shadow group is empty | Print no user in shadow group" - debug: + ansible.builtin.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.4 | AUDIT | Ensure shadow group is empty | Print no user in shadow group" - debug: + ansible.builtin.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 when: @@ -102,18 +102,18 @@ - name: "6.2.5 | PATCH | Ensure no duplicate user names exist" 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" + 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_5_user_username_check - name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print message that no duplicate user names exist" - debug: + ansible.builtin.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.5 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names" - debug: + ansible.builtin.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 when: @@ -128,18 +128,18 @@ - name: "6.2.6 | PATCH | Ensure no duplicate group names exist" 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' + ansible.builtin.shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d' changed_when: false failed_when: false register: amazon2_6_2_6_group_group_check - name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist" - debug: + ansible.builtin.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.6 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" - debug: + ansible.builtin.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 when: @@ -154,18 +154,18 @@ - name: "6.2.7 | PATCH | Ensure no duplicate UIDs exist" 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" + 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_7_user_uid_check - name: "6.2.7 | AUDIT | Ensure no duplicate UIDs exist | Print message that no duplicate UIDs exist" - debug: + ansible.builtin.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.7 | AUDIT | Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs" - debug: + ansible.builtin.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 when: @@ -180,18 +180,18 @@ - name: "6.2.8 | PATCH | Ensure no duplicate GIDs exist" 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" + 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_8_user_user_check - name: "6.2.8 | AUDIT | Ensure no duplicate GIDs exist | Print message that no duplicate GID's exist" - debug: + ansible.builtin.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.8 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs" - debug: + ansible.builtin.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 when: @@ -204,7 +204,7 @@ - groups - name: "6.2.9 | PATCH | Ensure root is the only UID 0 account" - command: passwd -l {{ item }} + ansible.builtin.command: passwd -l {{ item }} changed_when: false failed_when: false with_items: @@ -223,32 +223,32 @@ - 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 ::' + ansible.builtin.shell: 'echo $PATH | grep ::' changed_when: false failed_when: amazon2_6_2_10_path_colon.rc == 0 register: amazon2_6_2_10_path_colon - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Determin colon end" - shell: 'echo $PATH | grep :$' + ansible.builtin.shell: 'echo $PATH | grep :$' changed_when: false failed_when: amazon2_6_2_10_path_colon_end.rc == 0 register: amazon2_6_2_10_path_colon_end - 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'" + ansible.builtin.shell: "/bin/bash --login -c 'env | grep ^PATH=' | grep ^PATH | sed -e 's/PATH=//' -e 's/::/:/' -e 's/:$//' -e 's/:/\\n/g'" changed_when: false failed_when: '"." in amazon2_6_2_10_dot_in_path.stdout_lines' register: amazon2_6_2_10_dot_in_path - name: "6.2.10 | AUDIT | Ensure root PATH Integrity | Alert on empty value, colon end, and dot in path" - debug: + ansible.builtin.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.10 | PATCH | Ensure root PATH Integrity (AUTOMATED) | Determine rights and owner" - file: + ansible.builtin.file: path: '{{ item }}' state: directory owner: root @@ -268,14 +268,14 @@ - 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: + 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 }}" - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - shell: find -H {{ item.0 | quote }} -not -type l -perm /027 + ansible.builtin.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 @@ -289,7 +289,7 @@ - item.1.exists - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - file: + ansible.builtin.file: path: "{{ item.0 }}" mode: a-st,g-w,o-rwx recurse: true @@ -305,7 +305,7 @@ # set default ACLs so the homedir has an effective umask of 0027 - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - acl: + ansible.posix.acl: path: "{{ item.0 }}" default: true state: present @@ -328,7 +328,7 @@ - accounts - name: "6.2.12 | PATCH | Ensure users own their home directories" - file: + ansible.builtin.file: path: "{{ item.dir }}" owner: "{{ item.id }}" state: directory @@ -349,13 +349,13 @@ - 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: + ansible.builtin.stat: 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 + ansible.builtin.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 @@ -370,7 +370,7 @@ - item.1.exists - name: "6.2.13 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive" - file: + ansible.builtin.file: path: "{{ item.0 }}" recurse: true mode: a-st,g-w,o-rwx @@ -386,7 +386,7 @@ # 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: + ansible.posix.acl: path: "{{ item.0 }}" default: true state: present @@ -412,27 +412,27 @@ - name: "6.2.14 | PATCH | Ensure users' dot files are not group or world-writable" 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 + ansible.builtin.shell: find /home/ -name "\.*" -perm /g+w,o+w changed_when: false failed_when: false register: amazon2cis_6_2_14_audit - name: "6.2.14 | AUDIT | Ensure users' dot files are not group or world-writable | Alert on files found" - debug: + ansible.builtin.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.14 | PATCH | Ensure users' dot files are not group or world-writable | Changes files if configured" - file: + ansible.builtin.file: path: '{{ item }}' mode: go-w with_items: - "{{ amazon2cis_6_2_14_audit.stdout_lines }}" when: - amazon2cis_6_2_14_audit.stdout | length > 0 - - amazon2cis_dotperm_ansibleManaged + - amazon2cis_dotperm_ansiblemanaged when: - amazon2cis_rule_6_2_14 tags: @@ -443,7 +443,7 @@ - permissions - name: "6.2.15 | PATCH | Ensure no users have .forward files" - file: + ansible.builtin.file: path: "~{{ item }}/.forward" state: absent with_items: @@ -458,7 +458,7 @@ - files - name: "6.2.16 | PATCH | Ensure no users have .netrc files" - file: + ansible.builtin.file: path: "~{{ item }}/.netrc" state: absent with_items: @@ -473,7 +473,7 @@ - files - name: "6.2.17 | PATCH | Ensure no users have .rhosts files" - file: + ansible.builtin.file: path: "~{{ item }}/.rhosts" state: absent with_items: 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 From 71c63e6ab4a01843a242485398c1dafbcfbd9901 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 26 Feb 2024 11:16:17 +0000 Subject: [PATCH 05/76] reboot option and warning Signed-off-by: Mark Bolwell --- defaults/main.yml | 4 ++++ handlers/main.yml | 5 +++++ tasks/warning_facts.yml | 20 ++++++++++++++++++++ vars/main.yml | 9 +++++++++ 4 files changed, 38 insertions(+) create mode 100644 tasks/warning_facts.yml diff --git a/defaults/main.yml b/defaults/main.yml index 2540b35..8326a84 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -24,6 +24,10 @@ benchmark_version: v2.0.0 # If set true uses the tmp.mount service else using fstab configuration amazon2cis_tmp_svc: true +# Ability to stop reboot from occuring until convenient +# set to true if ok to reboot +skip_reboot: false + ### Goss Audit run settings # Goss audit configuration settings at bottom of file diff --git a/handlers/main.yml b/handlers/main.yml index a1fea0f..12dc6d2 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -63,6 +63,7 @@ - name: grub2cfg ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" + notify: Change_requires_reboot - name: restart rsyslog ansible.builtin.service: @@ -73,3 +74,7 @@ ansible.builtin.service: name: sshd state: restarted + +- name: Change_requires_reboot + ansible.builtin.set_fact: + change_requires_reboot: true diff --git a/tasks/warning_facts.yml b/tasks/warning_facts.yml new file mode 100644 index 0000000..6e80487 --- /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 }} | AUDIT | 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/vars/main.yml b/vars/main.yml index a38c5fb..f08e8e2 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,2 +1,11 @@ --- # vars file for . + +min_ansible_version: 2.10.1 + +change_requires_reboot: false + +# Used to control warning summary +warn_control_list: "" +warn_count: 0 + From c82b0799af291bba6c3023a089fbfd3d37d598f2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 26 Feb 2024 11:16:50 +0000 Subject: [PATCH 06/76] update checks and reboot added Signed-off-by: Mark Bolwell --- tasks/main.yml | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 148d152..b36b39d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,18 +1,20 @@ --- - name: Check OS version and family - ansible.builtin.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 - ansible.builtin.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 @@ -109,6 +111,31 @@ - name: 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 + ansible.builtin.reboot: + when: + - change_requires_reboot + - not skip_reboot + + - name: POST | Warning a reboot required but skip option set + 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 + when: + - change_requires_reboot + - skip_reboot + + - name: "POST | Warning a reboot required but skip option set | warning count" + ansible.builtin.import_tasks: + file: warning_facts.yml + when: + - change_requires_reboot + - skip_reboot + vars: + warn_control_id: Reboot_required + - name: run post_remediation audit ansible.builtin.import_tasks: file: post_remediation_audit.yml From 87fb55cc6da379b4dc88d89a71d3fef46c14711f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 27 Feb 2024 12:33:22 +0000 Subject: [PATCH 07/76] section1 and 2 updates Signed-off-by: Mark Bolwell --- defaults/main.yml | 228 ++++++--- handlers/main.yml | 33 +- meta/main.yml | 5 +- tasks/section_1/cis_1.1.1.x.yml | 225 ++++++++- tasks/section_1/cis_1.1.2.1.x.yml | 56 +++ tasks/section_1/cis_1.1.2.2.x.yml | 56 +++ tasks/section_1/cis_1.1.2.3.x.yml | 53 +++ tasks/section_1/cis_1.1.2.4.x.yml | 53 +++ tasks/section_1/cis_1.1.2.5.x.yml | 56 +++ tasks/section_1/cis_1.1.2.6.x.yml | 56 +++ tasks/section_1/cis_1.1.2.7.x.yml | 56 +++ tasks/section_1/cis_1.1.x.yml | 301 ------------ tasks/section_1/cis_1.2.x.yml | 94 ++-- tasks/section_1/cis_1.3.x.yml | 52 +-- tasks/section_1/cis_1.4.x.x.yml | 47 ++ tasks/section_1/cis_1.4.x.yml | 78 +++- tasks/section_1/cis_1.5.x.yml | 169 ++++--- tasks/section_1/cis_1.6.x.yml | 170 ++++--- tasks/section_1/cis_1.7.x.yml | 100 ---- tasks/section_1/cis_1.8.x.yml | 16 - tasks/section_1/main.yml | 36 +- tasks/section_2/cis_2.1.1.x.yml | 106 ----- tasks/section_2/cis_2.1.x.yml | 388 +++------------- tasks/section_2/cis_2.2.x.yml | 748 ++++++++++++++++++++++++++++-- tasks/section_2/cis_2.3.x.yml | 86 ++++ tasks/section_2/cis_2.3.yml | 12 - tasks/section_2/main.yml | 12 +- tasks/warning_facts.yml | 2 +- 28 files changed, 2023 insertions(+), 1271 deletions(-) create mode 100644 tasks/section_1/cis_1.1.2.1.x.yml create mode 100644 tasks/section_1/cis_1.1.2.2.x.yml create mode 100644 tasks/section_1/cis_1.1.2.3.x.yml create mode 100644 tasks/section_1/cis_1.1.2.4.x.yml create mode 100644 tasks/section_1/cis_1.1.2.5.x.yml create mode 100644 tasks/section_1/cis_1.1.2.6.x.yml create mode 100644 tasks/section_1/cis_1.1.2.7.x.yml delete mode 100644 tasks/section_1/cis_1.1.x.yml create mode 100644 tasks/section_1/cis_1.4.x.x.yml delete mode 100644 tasks/section_1/cis_1.7.x.yml delete mode 100644 tasks/section_1/cis_1.8.x.yml delete mode 100644 tasks/section_2/cis_2.1.1.x.yml create mode 100644 tasks/section_2/cis_2.3.x.yml delete mode 100644 tasks/section_2/cis_2.3.yml diff --git a/defaults/main.yml b/defaults/main.yml index 8326a84..ad8ded7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -66,89 +66,128 @@ system_is_ec2: true # You must enable an entire section in order for the variables below to take effect. # 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_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_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 # 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 +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) @@ -311,33 +350,70 @@ amazon2cis_rule_6_2_15: true amazon2cis_rule_6_2_16: true amazon2cis_rule_6_2_17: true + +## Section 1 variables +# cis 1.4.1 +kernel_sysctl_file: /etc/sysctl.d/60-kernel_sysctl.conf + +## Section 2 variables +# 2.2.x # Service configuration booleans set true to keep service -amazon2cis_allow_autofs: false +# 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_cups_server: false +amazon2cis_avahi_mask: 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_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: true +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: true +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 -amazon2cis_nfs_rpc_server: false -amazon2cis_nfs_server: false -amazon2cis_rpc_server: false -amazon2cis_rsyncd_server: false # Service Clients -amazon2cis_ypbind_required: false -amazon2cis_rsh_required: false -amazon2cis_talk_required: false -amazon2cis_telnet_required: false +# 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 # System network parameters (host only OR host and router) amazon2cis_is_router: false diff --git a/handlers/main.yml b/handlers/main.yml index 12dc6d2..5ad693f 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -8,14 +8,35 @@ masked: false state: reloaded -- name: remount dev_shm - ansible.builtin.command: mount -o remount /dev/shm +- name: Remount dev_shm + ansible.posix.mount: + name: /dev/shm + state: remounted -- name: remount var_tmp - ansible.builtin.command: mount -o remount /var/tmp +- name: Remount home + ansible.posix.mount: + name: /home + state: remounted -- name: remount home - ansible.builtin.command: mount -o remount /home +- name: Remount var + ansible.posix.mount: + name: /var + state: remounted + +- name: Remount var_tmp + ansible.posix.mount: + name: /var/tmp + state: remounted + +- 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: diff --git a/meta/main.yml b/meta/main.yml index fe7d130..f295443 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -9,10 +9,9 @@ galaxy_info: role_name: amazon2_cis min_ansible_version: 2.10.1 platforms: - - name: Amazon + - name: Amazon Linux versions: - - "2017.03" - - "2017.09" + - "2" galaxy_tags: - system - security diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index 466e4e3..21a654a 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -1,8 +1,8 @@ --- -- 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" block: - - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Edit modprobe config" + - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install cramfs(\\s|$)" @@ -10,13 +10,20 @@ create: true mode: '0600' - - name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove cramfs module" + - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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 when: - amazon2cis_rule_1_1_1_1 - - ansible_connection != 'docker' tags: - level1 - automated @@ -24,35 +31,176 @@ - rule_1.1.1.1 - cramfs - modprobe + - NIST800-53R5_CM-7 -- 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" block: - - name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Edit modprobe config" + - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf - regexp: "^(#)?install squashfs(\\s|$)" - line: "install squashfs /bin/true" + regexp: "^(#)?install freevxfs(\\s|$)" + line: "install freevxfs /bin/true" create: true mode: '0600' - - name: "1.1.1.2 | PATCH | Ensure mounting of cramfs filesystems is disabled | Remove squashfs module" + - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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: squashfs + name: freevxfs state: absent when: - amazon2cis_rule_1_1_1_2 - - ansible_connection != 'docker' tags: - level1 - automated - patch - rule_1.1.1.2 + - cramfs + - modprobe + - NIST800-53R5_CM-7 + +- name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available" + block: + - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install hfs(\\s|$)" + line: "install hfs /bin/true" + create: true + mode: '0600' + + - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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 + when: + - amazon2cis_rule_1_1_1_3 + tags: + - level1 + - automated + - patch + - rule_1.1.1.3 + - hfs + - modprobe + - NIST800-53R5_CM-7 + +- name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available" + block: + - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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: + dest: /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 + when: + - amazon2cis_rule_1_1_1_4 + tags: + - level1 + - automated + - patch + - rule_1.1.1.4 + - hfsplus + - modprobe + - NIST800-53R5_CM-7 + +- name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available" + block: + - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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: + dest: /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 + when: + - amazon2cis_rule_1_1_1_5 + tags: + - level1 + - automated + - patch + - rule_1.1.1.5 + - jffs2 + - modprobe + - NIST800-53R5_CM-7 + +- name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available" + block: + - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /etc/modprobe.d/CIS.conf + regexp: "^(#)?install squashfs(\\s|$)" + line: "install squashfs /bin/true" + create: true + mode: '0600' + + - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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 + when: + - amazon2cis_rule_1_1_1_6 + tags: + - level2 + - automated + - patch + - rule_1.1.1.6 - squashfs - modprobe + - NIST800-53R5_CM-7 -- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled" +- name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available" block: - - name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled | Edit modprobe config" + - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: dest: /etc/modprobe.d/CIS.conf regexp: "^(#)?install udf(\\s|$)" @@ -60,17 +208,58 @@ create: true mode: '0600' - - name: "1.1.1.3 | PATCH | Remove udf module" + - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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 when: - - amazon2cis_rule_1_1_1_3 - - ansible_connection != 'docker' + - amazon2cis_rule_1_1_1_7 tags: - - level1 + - level2 - automated - patch - - rule_1.1.1.3 + - rule_1.1.1.7 - udf - modprobe + - NIST800-53R5_CM-7 + +- name: "1.1.1.8 | PATCH | Ensure udf kernel module is not available" + block: + - name: "1.1.1.8 | PATCH | Ensure usb-storage kernel module is not available | Edit modprobe config" + ansible.builtin.lineinfile: + dest: /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: + dest: /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 + when: + - amazon2cis_rule_1_1_1_8 + tags: + - level1 + - automated + - patch + - rule_1.1.1.8 + - usb + - modprobe + - NIST800-53R5_SI-3 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..ac9aab8 --- /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" + 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 + vars: + warn_control_id: '1.1.2.1.1' + required_mount: '/tmp' + 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 + +- 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" + 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 }}" + 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 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..7d3b67e --- /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" + 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 + vars: + warn_control_id: '1.1.2.2.1' + required_mount: '/dev/shm' + 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 + +- 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" + 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 }}" + 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 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..ef58f5d --- /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" + 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 + vars: + warn_control_id: '1.1.2.3.1' + required_mount: '/home' + 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 + +- 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 + 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 }}" + 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 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..7ca77d8 --- /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" + 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 + vars: + warn_control_id: '1.1.2.4.1' + required_mount: '/var' + 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 + +- 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 + 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 }}" + 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 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..23d15d8 --- /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" + 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 + vars: + warn_control_id: '1.1.2.5.1' + required_mount: '/var/tmp' + 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 + +- 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" + 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 }}" + 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 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..7f1b34c --- /dev/null +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -0,0 +1,56 @@ +--- + +- name: "1.1.2.6.1 | PATCH | Ensure /var/log is a seperate partition" + 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 + vars: + warn_control_id: '1.1.2.6.1' + required_mount: '/var/log' + 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 + +- 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" + 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 }}" + 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 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..5e70c7a --- /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" + 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 + vars: + warn_control_id: '1.1.2.7.1' + required_mount: '/var/log/audit' + 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 + +- 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" + 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 }}" + 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 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 53b654c..0000000 --- a/tasks/section_1/cis_1.1.x.yml +++ /dev/null @@ -1,301 +0,0 @@ ---- - -- name: "1.1.2 | PATCH | Ensure /tmp is configured" - ansible.builtin.systemd: - name: tmp.mount - daemon_reload: true - enabled: true - masked: false - state: started - when: - - amazon2cis_tmp_svc - - amazon2cis_rule_1_1_2 - tags: - - level1 - - automated - - patch - - rule_1.1.2 - - mounts - -- 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_4 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_3 %}noexec,{% endif %}{% if amazon2cis_rule_1_1_5 %}nosuid{% endif %} - notify: systemd restart tmp.mount - with_items: - - "{{ ansible_mounts }}" - loop_control: - label: "{{ item.device }}" - when: - - item.mount == "/tmp" - - amazon2cis_tmp_svc - - amazon2cis_rule_1_1_3 or - amazon2cis_rule_1_1_4 or - amazon2cis_rule_1_1_5 - tags: - - level1 - - automated - - patch - - rule_1.1.3 - - rule_1.1.4 - - rule_1.1.5 - - mounts - -- 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" - ansible.posix.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.posix.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" - ansible.builtin.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" - ansible.builtin.debug: - msg: "Congradulations: /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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.posix.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" - ansible.builtin.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" - 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 - 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" - ansible.builtin.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" - ansible.builtin.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" - community.general.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 bbf3012..4fcaa7b 100644 --- a/tasks/section_1/cis_1.2.x.yml +++ b/tasks/section_1/cis_1.2.x.yml @@ -12,50 +12,88 @@ - patch - rule_1.2.1 - gpg + - NIST800-53R5_SI-2 -- name: "1.2.2 | AUDIT | Ensure package manager repositories are configured" +- name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated" block: - - name: "1.2.2 | AUDIT | Ensure package manager repositories are configured | Get repo list" - ansible.builtin.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" - ansible.builtin.debug: - msg: - - "Please check against site policy repos listed below match expected:" - - "{{ amazon2cis_1_2_2_repolist.stdout_lines }}" - when: - - amazon2cis_rule_1_2_2 - tags: - - level1 - - automated - - patch - - rule_1.2.2 - - skip_ansible_lint - -- name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated" - block: - - name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | find repo files" + - 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" + - 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 }}" when: - - amazon2cis_rule_1_2_3 + - amazon2cis_rule_1_2_2 tags: - level1 - automated - patch + - rule_1.2.2 + - gpg + - NIST800-53R5_SI-2 + +- name: "1.2.3 | PATCH | Ensure repo_gpgcheck is globally activated" + ansible.builtin.replace: + path: /etc/yum.conf + regexp: ^repo_gpgcheck\s*=\s*0 + replace: "repo_gpgcheck=1" + when: + - amazon2cis_rule_1_2_3 + tags: + - level2 + - automated + - patch - rule_1.2.3 - gpg + - NIST800-53R5_SI-2 + +- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured" + 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 + vars: + warn_control_id: '1.2.4' + when: + - amazon2cis_rule_1_2_4 + tags: + - level1 + - automated + - patch + - rule_1.2.4 + - NIST800-53R5_SI-2 + +- name: "1.2.5 | PATCH | Ensure updates, patches, and additional security software are installed" + ansible.builtin.package: + name: "*" + state: latest + vars: + ansible_python_interpreter: /bin/python + when: + - amazon2cis_rule_1_2_5 + tags: + - level1 + - automated + - patch + - rule_1.2.5 + - NIST800-53R5_SI-2 diff --git a/tasks/section_1/cis_1.3.x.yml b/tasks/section_1/cis_1.3.x.yml index 3ce6b2a..2ed237c 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" +- name: "1.4.1 | PATCH | Ensure authentication required for single user mode" block: - - name: "1.3.1 | PATCH | Ensure AIDE is installed | Install" - ansible.builtin.package: - name: aide - state: installed + - name: "1.4.1 | PATCH | Ensure authentication required for single user mode | Emergency service" + ansible.builtin.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.3.1 | PATCH | Ensure AIDE is installed | started" - ansible.builtin.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.4.1 | PATCH | Ensure authentication required for single user mode | Rescue service" + ansible.builtin.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' when: - - amazon2cis_config_aide - - amazon2cis_rule_1_3_1 + - amazon2cis_rule_1_4_1 + - ansible_facts['distribution_major_version'] is version('2', '>=') tags: - level1 - automated - patch - - rule_1.3.1 - - aide - -- name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked" - ansible.builtin.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 + - rule_1.4.1 diff --git a/tasks/section_1/cis_1.4.x.x.yml b/tasks/section_1/cis_1.4.x.x.yml new file mode 100644 index 0000000..3ce6b2a --- /dev/null +++ b/tasks/section_1/cis_1.4.x.x.yml @@ -0,0 +1,47 @@ +--- + +- name: "1.3.1 | PATCH | Ensure AIDE is installed" + block: + - name: "1.3.1 | PATCH | Ensure AIDE is installed | Install" + ansible.builtin.package: + name: aide + state: installed + + - name: "1.3.1 | PATCH | Ensure AIDE is installed | started" + ansible.builtin.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 + when: + - amazon2cis_config_aide + - amazon2cis_rule_1_3_1 + tags: + - level1 + - automated + - patch + - rule_1.3.1 + - aide + +- name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked" + ansible.builtin.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 diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 755119c..114812d 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -1,39 +1,73 @@ --- -- name: "1.4.1 | PATCH | Ensure permissions on bootloader config are configured" - ansible.builtin.file: - path: "{{ amazon2cis_bootloader_file }}" - owner: root - group: root - mode: 0600 +- name: "1.4.1 | PATCH | Ensure address space layout randomization (ASLR) is enabled" + ansible.posix.sysctl: + name: kernel.randomize_va_space + value: '2' + state: present + reload: true + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ kernel_sysctl_file }}" when: - - amazon2cis_legacy_boot - amazon2cis_rule_1_4_1 tags: - level1 - automated - patch - rule_1.4.1 - - grub + - NIST800-53R5_CM-6 -- 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" - ansible.builtin.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" - ansible.builtin.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" + ansible.posix.sysctl: + name: kernel.yama.ptrace_scope + value: '1' + state: present + reload: true + sysctl_set: true + ignoreerrors: true + sysctl_file: "{{ kernel_sysctl_file }}" when: - amazon2cis_rule_1_4_2 - - ansible_facts['distribution_major_version'] is version('2', '>=') tags: - level1 - automated - patch - rule_1.4.2 + +- name: "1.4.3 | PATCH | Ensure core dump backtraces are disabled" + ansible.builtin.lineinfile: + dest: /etc/systemd/coredump.conf + regexp: ^ProcessSizeMax + line: ProcessSizeMax=0 + create: true + mode: '0644' + notify: systemd daemon reload + when: + - amazon2cis_rule_1_4_3 + tags: + - level1 + - automated + - patch + - rule_1.4.3 + - coredump + - NIST800-53R5_CM-6b + +- name: "1.4.4 | PATCH | Ensure core dump storage is disabled" + ansible.builtin.lineinfile: + dest: /etc/systemd/coredump.conf + regexp: ^Storage + line: Storage=none + create: true + mode: '0644' + notify: systemd daemon reload + when: + - amazon2cis_rule_1_4_4 + tags: + - level1 + - automated + - patch + - rule_1.4.4 + - coredump + + diff --git a/tasks/section_1/cis_1.5.x.yml b/tasks/section_1/cis_1.5.x.yml index 7a49945..36c52b6 100644 --- a/tasks/section_1/cis_1.5.x.yml +++ b/tasks/section_1/cis_1.5.x.yml @@ -1,92 +1,147 @@ --- -- 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" - ansible.builtin.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" + ansible.builtin.package: + name: libselinux + state: present + vars: + ansible_python_interpreter: /bin/python + 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 - - name: "1.5.1 | PATCH | Ensure core dumps are restricted | Set active kernel parameter" - ansible.posix.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" + ansible.builtin.replace: + path: /etc/default/grub + regexp: '{{ item }}' + replace: '' + loop: + - selinux=0 + - enforcing=0 + notify: grub2cfg + 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 - - name: "1.5.1 | PATCH | Ensure core dumps are restricted | coredump.conf" - ansible.builtin.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" + ansible.posix.selinux: + conf: /etc/selinux/config + policy: "{{ amazon2cis_selinux_pol }}" + state: "{{ amazon2cis_selinux_state }}" + vars: + ansible_python_interpreter: "{{ python2_bin }}" 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 -- name: "1.5.2 | PATCH | Ensure XD/NX support is enabled" +- name: "1.5.1.5 | PATCH | Ensure the SELinux state is enforcing" + ansible.posix.selinux: + conf: /etc/selinux/config + policy: "{{ amazon2cis_selinux_pol }}" + state: enforcing + vars: + ansible_python_interpreter: "{{ python2_bin }}" + 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 + +- name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist" block: - - name: "1.5.2 | PATCH | Ensure XD/NX support is enabled | Get NX/DX status" - ansible.builtin.shell: dmesg|grep -E "NX|XD" | grep " active" + - 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_2_nx_dx_status + register: amazon2cis_1_5_1_6_unconf_services - - name: "1.5.2 | PATCH | Ensure XD/NX support is enabled | Alert on non-active status" + - name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist | Message on unconfined services" ansible.builtin.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" + 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 + vars: + warn_control_id: '1.5.1.6' 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 -- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled" - ansible.posix.sysctl: - name: kernel.randomize_va_space - value: '2' - state: present - reload: true - sysctl_set: true - ignoreerrors: true +- name: "1.5.1.7 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" + ansible.builtin.package: + name: mcstrans + state: absent + vars: + ansible_python_interpreter: /bin/python when: - - amazon2cis_rule_1_5_3 + - amazon2cis_rule_1_5_1_7 tags: - level1 - automated - patch - - rule_1.5.3 + - rule_1.5.1.7 + - mcstrans + - NIST800-53R5_SI-4 -- name: "1.5.4 | PATCH | Ensure prelink is not installed" +- name: "1.5.1.8 | PATCH | Ensure SETroubleshoot is not installed" ansible.builtin.package: - name: prelink + name: setroubleshoot state: absent vars: ansible_python_interpreter: /bin/python 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 + + diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index acffeb7..00d2a2a 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -1,127 +1,115 @@ --- -- name: "1.6.1.1 | PATCH | Ensure SELinux is installed" - ansible.builtin.package: - name: libselinux - state: present - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.1 | PATCH | Ensure message of the day is configured properly" + ansible.builtin.template: + src: etc/motd.j2 + dest: /etc/motd + owner: root + group: root + mode: '0644' 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 -- name: "1.6.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration" - ansible.builtin.replace: - dest: /etc/default/grub - regexp: '(selinux|enforcing)\s*=\s*0\s*' - notify: grub2cfg +- name: "1.6.2 | PATCH | Ensure local login warning banner is configured properly" + ansible.builtin.template: + src: etc/issue.j2 + dest: /etc/issue + owner: root + group: root + mode: '0644' 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 -- name: | - "1.6.1.3 | PATCH | Ensure SELinux policy is configured - 1.6.1.4 | PATCH | Ensure the SELinux state is enforcing or permissive" - ansible.posix.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" + ansible.builtin.template: + src: etc/issue.net.j2 + dest: /etc/issue.net + owner: root + group: root + mode: '0644' 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 -- name: "1.6.1.5 | PATCH | Ensure the SELinux state is enforcing" - ansible.posix.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" + ansible.builtin.file: + path: /etc/motd + state: file + owner: root + group: root + mode: '0644' 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 -- name: "1.6.1.7 | PATCH | Ensure SETroubleshoot is not installed" - ansible.builtin.package: - name: setroubleshoot - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.5 | PATCH | Ensure permissions on /etc/issue are configured" + ansible.builtin.file: + path: /etc/issue + state: file + owner: root + group: root + mode: '0644' 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 -- name: "1.6.1.8 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" - ansible.builtin.package: - name: mcstrans - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "1.6.6 | PATCH | Ensure permissions on /etc/issue.net are configured" + ansible.builtin.file: + path: /etc/issue.net + state: file + owner: root + group: root + mode: '0644' 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 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 8931303..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 9bdb0a3..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" - ansible.builtin.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 a08250d..c1df0a2 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -4,9 +4,33 @@ ansible.builtin.import_tasks: file: cis_1.1.1.x.yml -- name: "SECTION | 1.1 | FileSystem Configuration" +- name: "SECTION | 1.1.2.1.x | FileSystem Configuration /tmp" ansible.builtin.import_tasks: - file: cis_1.1.x.yml + 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" ansible.builtin.import_tasks: @@ -29,11 +53,3 @@ ansible.builtin.import_tasks: file: cis_1.6.x.yml when: not amazon2cis_selinux_disable - -- name: "SECTION | 1.7 | Command Line Warning Banners" - ansible.builtin.import_tasks: - file: cis_1.7.x.yml - -- name: "SECTION | 1.8 | Ensure updates, patches, and additional security software are installed" - ansible.builtin.import_tasks: - file: 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 f174db6..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 6eb9af9..aa17d5a 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -1,356 +1,86 @@ --- -- name: "2.1.2 | PATCH | Ensure X11 Server components are not installed" - ansible.builtin.package: - state: absent - name: - - "@X Window System" - - "xorg-x11*" - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_xwindows_required - - amazon2cis_rule_2_1_2 - tags: - - level1 - - automated - - patch - - rule_2.1.2 - - xwindowss - -- name: "2.1.3 | PATCH | Ensure Avahi Server is not installed" - block: - - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - ansible.builtin.service: - name: avahi-daemon - state: stopped - enabled: false - - - name: "2.1.3 | PATCH | Ensure Avahi Server is not installed | disabled" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" +- name: "2.1.1 | PATCH | Ensure time synchronization is in use" block: - - name: "2.1.17 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | nfs-utils " + - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service install" ansible.builtin.package: - name: nfs-utils - state: absent + name: "{{ amazon2cis_time_synchronization }}" + state: present vars: ansible_python_interpreter: /bin/python + + - 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.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_nfs_server + - "'ntp' in ansible_facts.packages" + - amazon2cis_time_synchronization == "chrony" - - name: "2.1.17 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | nfs-server " - ansible.builtin.systemd: - name: nfs-server - 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_nfs_server + - "'chrony' in ansible_facts.packages" + - amazon2cis_time_synchronization == "ntp" when: - - "'nfs-utils' in ansible_facts.packages" - - amazon2cis_rule_2_1_17 + - amazon2cis_rule_2_1_1 + - not amazon2cis_system_is_container tags: - level1 - automated - patch - - rule_2.1.17 - - nfs - - services + - rule_2.1.1 + - ntp + - chrony + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 -- 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" - ansible.builtin.package: - name: rpcbind - state: absent - vars: - ansible_python_interpreter: /bin/python - when: - - not amazon2cis_nfs_rpc_server - - not amazon2cis_rpc_server - - name: "2.1.18 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | rpcbind-server" - ansible.builtin.systemd: - name: rpcbind.socket - masked: true - when: - - amazon2cis_nfs_rpc_server - - not amazon2cis_rpc_server +- name: "2.1.2 | PATCH | Ensure chrony is configured | modify /etc/chrony.conf" + ansible.builtin.template: + src: chrony.conf.j2 + dest: /etc/chrony.conf + owner: root + group: root + mode: '0644' when: - - "'rpcbind' in ansible_facts.packages" - - amazon2cis_rule_2_1_18 + - amazon2cis_rule_2_1_2 + - amazon2cis_time_synchronization == "chrony" + - not amazon2cis_system_is_container tags: - level1 - automated - patch - - rule_2.1.18 - - rpc - - services + - rule_2.1.2 + - ntp + - chrony + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 -- name: "2.1.19 | PATCH | Ensure rsync is not installed or the rsyncd services are masked" - ansible.builtin.package: - name: rsync - state: absent - vars: - ansible_python_interpreter: /bin/python +- name: "2.1.3 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" + ansible.builtin.lineinfile: + path: /etc/sysconfig/chronyd + regexp: OPTIONS=\"(.*)(?!-u chrony)(.*)" + line: OPTIONS="\1\2 -u chrony" + create: true + backrefs: true + mode: '0644' when: - - not amazon2cis_rsyncd_server - - "'rsync' in ansible_facts.packages" - - amazon2cis_rule_2_1_19 + - amazon2cis_rule_2_1_3 + - amazon2cis_time_synchronization == "chrony" + - not amazon2cis_system_is_container tags: - level1 - automated - patch - - rule_2.1.19 - - rsync - - services + - rule_2.1.3 + - ntp + - chrony diff --git a/tasks/section_2/cis_2.2.x.yml b/tasks/section_2/cis_2.2.x.yml index d58e0d3..8bea335 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" - ansible.builtin.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 + - "'autofs' in ansible_facts.packages" 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: + - 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" - ansible.builtin.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: false + state: stopped + 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 + - "'avahi' in ansible_facts.packages or 'avahi-autopd' in ansible_facts.packages" 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 + ansible.builtin.package: + name: + - avahi-autoipd + - avahi + state: absent -- name: "2.2.3 | PATCH | Ensure talk client is not installed" - ansible.builtin.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: false + state: stopped + 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" + - "'dhcp-server' 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: + - 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" - ansible.builtin.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: false + state: stopped + 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 + - "'bind' in ansible_facts.packages" - amazon2cis_rule_2_2_4 tags: - - level1 + - level1-server + - level1-workstation - automated - patch + - dns + - NIST800-53R5_CM-7 - rule_2.2.4 + block: + - name: "2.2.4 | PATCH | Ensure dns server services are not in use | Remove package" + when: + - not amazon2cis_dns_server + - not amazon2cis_dns_mask + ansible.builtin.package: + name: bind + state: absent + + - 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: false + state: stopped + masked: true + +- name: "2.2.5 | PATCH | Ensure dnsmasq server services are not in use" + when: + - "'dnsmasq' in ansible_facts.packages" + - amazon2cis_rule_2_2_5 + tags: + - level1-server + - level1-workstation + - automated + - patch + - dns + - NIST800-53R5_CM-7 + - rule_2.2.5 + block: + - name: "2.2.5 | PATCH | Ensure dnsmasq server services are not in use | Remove package" + when: + - 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: false + state: stopped + masked: true + +- name: "2.2.6 | PATCH | Ensure samba file server services are not in use" + when: + - "'samba' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + +- name: "2.2.7 | PATCH | Ensure ftp server services are not in use" + when: + - "'ftp' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + +- name: "2.2.8 | PATCH | Ensure message access server services are not in use" + when: + - "'dovecot' in ansible_facts.packages or 'cyrus-imapd' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + 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: + - "'nfs-utils' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + +- name: "2.2.10 | PATCH | Ensure nis server services are not in use" + when: + - "'ypserv' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + +- name: "2.2.11 | PATCH | Ensure print server services are not in use" + when: + - "'cups' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + loop: + - "cups.socket" + - "cups.service" + +- name: "2.2.12 | PATCH | Ensure rpcbind services are not in use" + when: + - "'rpcbind' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + loop: + - rpcbind.service + - rpcbind.socket + +- name: "2.2.13 | PATCH | Ensure rsync services are not in use" + when: + - "'rsync-daemon' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + loop: + - 'rsyncd.socket' + - 'rsyncd.service' + +- name: "2.2.14 | PATCH | Ensure snmp services are not in use" + when: + - "'net-snmp' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + +- name: "2.2.15 | PATCH | Ensure telnet server services are not in use" + when: + - "'telnet-server' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true -- name: "2.2.5 | PATCH | Ensure LDAP client is not installed" +- name: "2.2.16 | PATCH | Ensure tftp server services are not in use" + when: + - "'tftp-server' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + masked: true + loop: + - 'tftp.socket' + - 'tftp.service' + +- name: "2.2.17 | PATCH | Ensure web proxy server services are not in use" + when: + - "'squid' in ansible_facts.packages" + - 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: + - not amazon2cis_squid_server + - not amazon2cis_squid_mask + ansible.builtin.package: + name: tftp-server + 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: false + state: stopped + 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: + - not amazon2cis_httpd_server + - not amazon2cis_httpd_mask + - "'httpd' in ansible_facts.packages" + ansible.builtin.package: + name: httpd + state: absent + + - name: "2.2.18 | PATCH | Ensure web server services are not in use | Remove nginx server" + when: + - not amazon2cis_nginx_server + - not amazon2cis_nginx_mask + - "'nginx' in ansible_facts.packages" + 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: false + state: stopped + 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: false + state: stopped + masked: true + +- name: "2.2.19 | PATCH | Ensure xinetd services are not in use" + when: + - "'xinetd' in ansible_facts.packages" + - 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: + - 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: false + state: stopped + 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: openldap-client + name: xorg-x11-server-common state: absent - vars: - ansible_python_interpreter: /bin/python + +- name: "2.2.21 | PATCH | Ensure mail transfer agents are configured for local-only mode" when: - - not amazon2cis_openldap_clients_required - - "'openldap-client' in ansible_facts.packages" - - amazon2cis_rule_2_2_5 + - not amazon2cis_is_mail_server + - "'postfix' in ansible_facts.packages" + - amazon2cis_rule_2_2_21 tags: - - level1 + - level1-server + - level1-workstation - automated - patch - - rule_2.2.5 - - ldap_client + - 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 f0f4fad..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" - ansible.builtin.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 b62865a..70d0b5e 100644 --- a/tasks/section_2/main.yml +++ b/tasks/section_2/main.yml @@ -1,17 +1,13 @@ --- -- name: "SECTION | 2.1.1 | Time Synchronization" - ansible.builtin.import_tasks: - file: cis_2.1.1.x.yml - -- name: "SECTION | 2.1 | Special Purpose Services" +- name: "SECTION | 2.1.x | Time Synchronization" ansible.builtin.import_tasks: file: cis_2.1.x.yml -- name: "SECTION | 2.2 | Service Clients" +- name: "SECTION | 2.1 | Special Purpose Services" ansible.builtin.import_tasks: file: cis_2.2.x.yml -- name: "SECTION | 2.3 | Nonessential Services" +- name: "SECTION | 2.3 | Service Clients" ansible.builtin.import_tasks: - file: cis_2.3.yml + file: cis_2.3.x.yml diff --git a/tasks/warning_facts.yml b/tasks/warning_facts.yml index 6e80487..3032b7c 100644 --- a/tasks/warning_facts.yml +++ b/tasks/warning_facts.yml @@ -14,7 +14,7 @@ # # 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 }} | AUDIT | Set fact for manual task warning." +- 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 }}" From 6ae08b3e25bb54a50923c1b0406a4cebd04a8b05 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 Feb 2024 10:54:40 +0000 Subject: [PATCH 08/76] updated and aligned for v3 Signed-off-by: Mark Bolwell --- defaults/main.yml | 137 ++++++++---- tasks/section_1/cis_1.1.1.x.yml | 94 ++++---- tasks/section_1/cis_1.1.2.1.x.yml | 44 ++-- tasks/section_1/cis_1.1.2.2.x.yml | 44 ++-- tasks/section_1/cis_1.1.2.3.x.yml | 44 ++-- tasks/section_1/cis_1.1.2.4.x.yml | 44 ++-- tasks/section_1/cis_1.1.2.5.x.yml | 44 ++-- tasks/section_1/cis_1.1.2.6.x.yml | 45 ++-- tasks/section_1/cis_1.1.2.7.x.yml | 44 ++-- tasks/section_1/cis_1.2.x.yml | 58 ++--- tasks/section_1/cis_1.3.x.yml | 22 +- tasks/section_1/cis_1.4.x.yml | 50 ++--- tasks/section_1/cis_1.5.x.yml | 94 ++++---- tasks/section_1/cis_1.6.x.yml | 50 ++--- tasks/section_2/cis_2.1.x.yml | 43 ++-- tasks/section_3/cis_3.1.x.yml | 76 ++++++- tasks/section_3/cis_3.2.x.yml | 144 ++++++++---- tasks/section_3/cis_3.3.x.yml | 360 +++++++++++++++++++----------- tasks/section_3/cis_3.4.1.x.yml | 131 +++++++++++ tasks/section_3/cis_3.4.2.x.yml | 94 ++++++++ tasks/section_3/cis_3.4.3.x.yml | 334 +++++++++++++++++++++++++++ tasks/section_3/cis_3.4.4.1.x.yml | 21 ++ tasks/section_3/cis_3.4.4.2.x.yml | 179 +++++++++++++++ tasks/section_3/cis_3.4.4.3.x.yml | 193 ++++++++++++++++ tasks/section_3/cis_3.4.x.yml | 37 --- tasks/section_3/cis_3.5.1.x.yml | 128 ----------- tasks/section_3/cis_3.5.2.x.yml | 343 ---------------------------- tasks/section_3/cis_3.5.3.1.x.yml | 52 ----- tasks/section_3/main.yml | 39 ++-- vars/main.yml | 1 - 30 files changed, 1827 insertions(+), 1162 deletions(-) create mode 100644 tasks/section_3/cis_3.4.1.x.yml create mode 100644 tasks/section_3/cis_3.4.2.x.yml create mode 100644 tasks/section_3/cis_3.4.3.x.yml create mode 100644 tasks/section_3/cis_3.4.4.1.x.yml create mode 100644 tasks/section_3/cis_3.4.4.2.x.yml create mode 100644 tasks/section_3/cis_3.4.4.3.x.yml delete mode 100644 tasks/section_3/cis_3.4.x.yml delete mode 100644 tasks/section_3/cis_3.5.1.x.yml delete mode 100644 tasks/section_3/cis_3.5.2.x.yml delete mode 100644 tasks/section_3/cis_3.5.3.1.x.yml diff --git a/defaults/main.yml b/defaults/main.yml index ad8ded7..f48880c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -93,7 +93,7 @@ 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/ +# /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 @@ -191,10 +191,18 @@ 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 @@ -204,29 +212,48 @@ 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 +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 Logging and Auditing (Configure System Accounting (auditd) and Configure Logging) @@ -350,12 +377,20 @@ amazon2cis_rule_6_2_15: true amazon2cis_rule_6_2_16: true amazon2cis_rule_6_2_17: true - ## Section 1 variables # cis 1.4.1 kernel_sysctl_file: /etc/sysctl.d/60-kernel_sysctl.conf ## Section 2 variables +amazon2cis_time_synchronization_servers: + - 0.pool.ntp.org + - 1.pool.ntp.org + - 2.pool.ntp.org + - 3.pool.ntp.org + +amazon2cis_chrony_server_options: "minpoll 8" +amazon2cis_ntp_server_options: "iburst" + # 2.2.x # Service configuration booleans set true to keep service # Service configuration @@ -415,33 +450,39 @@ amazon2cis_ypbind_required: false # Same package as NIS server amazon2cis_telnet_required: false amazon2cis_tftp_client: false -# System network parameters (host only OR host and router) -amazon2cis_is_router: false - +## Section 3 Variables +# 3.1.x # IPv6 required amazon2cis_ipv6_required: false +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 -# Whether or not to run tasks related to auditing/patching the desktop environment -amazon2cis_gui: false - -# Set to 'true' if X Windows is needed in your environment -amazon2cis_xwindows_required: false - -# Time Synchronization - Either chrony or ntp -amazon2cis_time_synchronization: chrony - -amazon2cis_time_synchronization_servers: - - 0.pool.ntp.org - - 1.pool.ntp.org - - 2.pool.ntp.org - - 3.pool.ntp.org - -amazon2cis_chrony_server_options: "minpoll 8" -amazon2cis_ntp_server_options: "iburst" +# service = true removes package - mask = true will just mask package +amazon2cis_bluetooth_service: true +amazon2cis_bluetooth_mask: false -# Firewall Service - either firewalld or iptables -amazon2cis_firewall: firewalld -amazon2cis_default_zone: public +# 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 + +# 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 + +# 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 # AIDE amazon2cis_config_aide: true diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index 21a654a..b67a6e7 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -1,6 +1,16 @@ --- - 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 cramfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -22,18 +32,18 @@ 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 + - 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 - -- name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available" block: - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -55,18 +65,18 @@ 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_2 + - amazon2cis_rule_1_1_1_3 tags: - level1 - automated - patch - - rule_1.1.1.2 - - cramfs + - rule_1.1.1.3 + - hfs - modprobe - NIST800-53R5_CM-7 - -- name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available" block: - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -88,18 +98,18 @@ 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_3 + - amazon2cis_rule_1_1_1_4 tags: - level1 - automated - patch - - rule_1.1.1.3 - - hfs + - rule_1.1.1.4 + - hfsplus - modprobe - NIST800-53R5_CM-7 - -- name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available" block: - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -121,18 +131,18 @@ 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_4 + - amazon2cis_rule_1_1_1_5 tags: - level1 - automated - patch - - rule_1.1.1.4 - - hfsplus + - rule_1.1.1.5 + - jffs2 - modprobe - NIST800-53R5_CM-7 - -- name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available" block: - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -154,18 +164,18 @@ 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_5 + - amazon2cis_rule_1_1_1_6 tags: - - level1 + - level2 - automated - patch - - rule_1.1.1.5 - - jffs2 + - rule_1.1.1.6 + - squashfs - modprobe - NIST800-53R5_CM-7 - -- name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available" block: - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -187,18 +197,18 @@ 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_6 + - amazon2cis_rule_1_1_1_7 tags: - level2 - automated - patch - - rule_1.1.1.6 - - squashfs + - rule_1.1.1.7 + - udf - modprobe - NIST800-53R5_CM-7 - -- name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available" block: - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: @@ -220,18 +230,18 @@ 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_7 + - amazon2cis_rule_1_1_1_8 tags: - - level2 + - level1 - automated - patch - - rule_1.1.1.7 - - udf + - rule_1.1.1.8 + - usb - modprobe - - NIST800-53R5_CM-7 - -- name: "1.1.1.8 | PATCH | Ensure udf kernel module is not available" + - 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: @@ -253,13 +263,3 @@ community.general.modprobe: name: usb-storage state: absent - when: - - amazon2cis_rule_1_1_1_8 - tags: - - level1 - - automated - - patch - - rule_1.1.1.8 - - usb - - modprobe - - NIST800-53R5_SI-3 diff --git a/tasks/section_1/cis_1.1.2.1.x.yml b/tasks/section_1/cis_1.1.2.1.x.yml index ac9aab8..7613365 100644 --- a/tasks/section_1/cis_1.1.2.1.x.yml +++ b/tasks/section_1/cis_1.1.2.1.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.1.1 | PATCH | Ensure /tmp is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.1.1' - required_mount: '/tmp' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_1_1 @@ -22,22 +11,22 @@ - 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" - 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 }}" when: - item.mount == "/tmp" - amazon2cis_tmp_svc @@ -54,3 +43,14 @@ - 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 index 7d3b67e..64c47af 100644 --- a/tasks/section_1/cis_1.1.2.2.x.yml +++ b/tasks/section_1/cis_1.1.2.2.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.2.1 | PATCH | Ensure /dev/shm is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.2.1' - required_mount: '/dev/shm' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_2_1 @@ -22,22 +11,22 @@ - 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" - 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 }}" when: - item.mount == "/dev/shm" - amazon2cis_tmp_svc @@ -54,3 +43,14 @@ - 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 index ef58f5d..39f88be 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.3.1 | PATCH | Ensure /home is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.3.1' - required_mount: '/home' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_3_1 @@ -22,21 +11,21 @@ - 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 - 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 }}" when: - item.mount == "/home" - amazon2cis_tmp_svc @@ -51,3 +40,14 @@ - 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 index 7ca77d8..03bda37 100644 --- a/tasks/section_1/cis_1.1.2.4.x.yml +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.4.1 | PATCH | Ensure /var is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.4.1' - required_mount: '/var' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_4_1 @@ -22,21 +11,21 @@ - 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 - 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 }}" when: - item.mount == "/var" - amazon2cis_tmp_svc @@ -51,3 +40,14 @@ - 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 index 23d15d8..c24fccd 100644 --- a/tasks/section_1/cis_1.1.2.5.x.yml +++ b/tasks/section_1/cis_1.1.2.5.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.5.1 | PATCH | Ensure /var/tmp is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.5.1' - required_mount: '/var/tmp' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_5_1 @@ -22,22 +11,22 @@ - 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" - 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 }}" when: - item.mount == "/var/tmp" - amazon2cis_tmp_svc @@ -54,3 +43,14 @@ - 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 index 7f1b34c..f419f77 100644 --- a/tasks/section_1/cis_1.1.2.6.x.yml +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.6.1 | PATCH | Ensure /var/log is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.6.1' - required_mount: '/var/log' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_6_1 @@ -22,22 +11,23 @@ - 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" - 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 }}" when: - item.mount == "/var/log" - amazon2cis_tmp_svc @@ -54,3 +44,14 @@ - 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 index 5e70c7a..c789524 100644 --- a/tasks/section_1/cis_1.1.2.7.x.yml +++ b/tasks/section_1/cis_1.1.2.7.x.yml @@ -1,17 +1,6 @@ --- - name: "1.1.2.7.1 | PATCH | Ensure /var/log/audit is a seperate partition" - 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 - vars: - warn_control_id: '1.1.2.7.1' - required_mount: '/var/log/audit' when: - required_mount not in mount_names - amazon2cis_rule_1_1_2_7_1 @@ -22,22 +11,22 @@ - 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" - 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 }}" when: - item.mount == "/var/log/audit" - amazon2cis_tmp_svc @@ -54,3 +43,14 @@ - 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.2.x.yml b/tasks/section_1/cis_1.2.x.yml index 4fcaa7b..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" - 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 when: - amazon2cis_rule_1_2_1 tags: @@ -13,8 +10,20 @@ - 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 | PATCH | Ensure gpgcheck is globally activated" + when: + - amazon2cis_rule_1_2_2 + tags: + - level1 + - automated + - patch + - rule_1.2.2 + - gpg + - NIST800-53R5_SI-2 block: - name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated | find repo files" ansible.builtin.find: @@ -31,32 +40,33 @@ - "{{ 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_2 + - amazon2cis_rule_1_2_3 tags: - - level1 + - level2 - automated - patch - - rule_1.2.2 + - rule_1.2.3 - gpg - NIST800-53R5_SI-2 - -- name: "1.2.3 | PATCH | Ensure repo_gpgcheck is globally activated" 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_3 + - amazon2cis_rule_1_2_4 tags: - - level2 + - level1 - automated - patch - - rule_1.2.3 - - gpg + - rule_1.2.4 - NIST800-53R5_SI-2 - -- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured" + 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 @@ -72,23 +82,8 @@ - name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Warn Count" ansible.builtin.import_tasks: file: warning_facts.yml - vars: - warn_control_id: '1.2.4' - when: - - amazon2cis_rule_1_2_4 - tags: - - level1 - - automated - - patch - - rule_1.2.4 - - NIST800-53R5_SI-2 - name: "1.2.5 | PATCH | Ensure updates, patches, and additional security software are installed" - ansible.builtin.package: - name: "*" - state: latest - vars: - ansible_python_interpreter: /bin/python when: - amazon2cis_rule_1_2_5 tags: @@ -97,3 +92,8 @@ - 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 2ed237c..8f94a3e 100644 --- a/tasks/section_1/cis_1.3.x.yml +++ b/tasks/section_1/cis_1.3.x.yml @@ -1,23 +1,23 @@ --- -- name: "1.4.1 | PATCH | Ensure authentication required for single user mode" +- name: "1.3.1 | PATCH | Ensure authentication required for single user mode" + when: + - amazon2cis_rule_1_3_1 + - ansible_facts['distribution_major_version'] is version('2', '>=') + tags: + - level1 + - automated + - patch + - rule_1.3.1 block: - - name: "1.4.1 | PATCH | Ensure authentication required for single user mode | Emergency service" + - name: "1.3.1 | PATCH | Ensure authentication required for single user mode | Emergency service" ansible.builtin.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.1 | PATCH | Ensure authentication required for single user mode | Rescue service" + - name: "1.3.1 | PATCH | Ensure authentication required for single user mode | Rescue service" ansible.builtin.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' - when: - - amazon2cis_rule_1_4_1 - - ansible_facts['distribution_major_version'] is version('2', '>=') - tags: - - level1 - - automated - - patch - - rule_1.4.1 diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 114812d..29040b3 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -1,14 +1,6 @@ --- - name: "1.4.1 | PATCH | Ensure address space layout randomization (ASLR) is enabled" - ansible.posix.sysctl: - name: kernel.randomize_va_space - value: '2' - state: present - reload: true - sysctl_set: true - ignoreerrors: true - sysctl_file: "{{ kernel_sysctl_file }}" when: - amazon2cis_rule_1_4_1 tags: @@ -17,16 +9,16 @@ - patch - rule_1.4.1 - NIST800-53R5_CM-6 - -- name: "1.4.2 | PATCH | Ensure ptrace_scope is restricted" ansible.posix.sysctl: - name: kernel.yama.ptrace_scope - value: '1' + 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 ptrace_scope is restricted" when: - amazon2cis_rule_1_4_2 tags: @@ -34,15 +26,16 @@ - 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" - ansible.builtin.lineinfile: - dest: /etc/systemd/coredump.conf - regexp: ^ProcessSizeMax - line: ProcessSizeMax=0 - create: true - mode: '0644' - notify: systemd daemon reload when: - amazon2cis_rule_1_4_3 tags: @@ -52,15 +45,15 @@ - rule_1.4.3 - coredump - NIST800-53R5_CM-6b - -- name: "1.4.4 | PATCH | Ensure core dump storage is disabled" + notify: systemd daemon reload ansible.builtin.lineinfile: dest: /etc/systemd/coredump.conf - regexp: ^Storage - line: Storage=none + regexp: ^ProcessSizeMax + line: ProcessSizeMax=0 create: true mode: '0644' - notify: systemd daemon reload + +- name: "1.4.4 | PATCH | Ensure core dump storage is disabled" when: - amazon2cis_rule_1_4_4 tags: @@ -69,5 +62,10 @@ - patch - rule_1.4.4 - coredump - - + notify: systemd daemon reload + ansible.builtin.lineinfile: + dest: /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 36c52b6..c3de2be 100644 --- a/tasks/section_1/cis_1.5.x.yml +++ b/tasks/section_1/cis_1.5.x.yml @@ -1,11 +1,6 @@ --- - name: "1.5.1.1 | PATCH | Ensure SELinux is installed" - ansible.builtin.package: - name: libselinux - state: present - vars: - ansible_python_interpreter: /bin/python when: - not amazon2cis_selinux_disable - amazon2cis_rule_1_5_1_1 @@ -17,16 +12,13 @@ - 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.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration" - ansible.builtin.replace: - path: /etc/default/grub - regexp: '{{ item }}' - replace: '' - loop: - - selinux=0 - - enforcing=0 - notify: grub2cfg when: - not amazon2cis_selinux_disable - amazon2cis_rule_1_5_1_2 @@ -38,16 +30,18 @@ - selinux - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 + notify: grub2cfg + ansible.builtin.replace: + path: /etc/default/grub + regexp: '{{ item }}' + replace: '' + loop: + - selinux=0 + - enforcing=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" - ansible.posix.selinux: - conf: /etc/selinux/config - policy: "{{ amazon2cis_selinux_pol }}" - state: "{{ amazon2cis_selinux_state }}" - vars: - ansible_python_interpreter: "{{ python2_bin }}" when: - not amazon2cis_selinux_disable - amazon2cis_rule_1_5_1_3 @@ -61,14 +55,14 @@ - selinux - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - -- name: "1.5.1.5 | PATCH | Ensure the SELinux state is enforcing" + vars: + ansible_python_interpreter: "{{ python2_bin }}" ansible.posix.selinux: conf: /etc/selinux/config policy: "{{ amazon2cis_selinux_pol }}" - state: enforcing - vars: - ansible_python_interpreter: "{{ python2_bin }}" + state: "{{ amazon2cis_selinux_state }}" + +- name: "1.5.1.5 | PATCH | Ensure the SELinux state is enforcing" when: - not amazon2cis_selinux_disable - not amazon2cis_selinux_state == "permissive" @@ -81,8 +75,26 @@ - 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.1.6 | AUDIT | Ensure no unconfined services exist" + when: + - amazon2cis_rule_1_5_1_6 + tags: + - level1 + - automated + - 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 @@ -98,25 +110,8 @@ - name: "1.5.1.6 | AUDIT | Ensure no unconfined services exist | Warn Count" ansible.builtin.import_tasks: file: warning_facts.yml - vars: - warn_control_id: '1.5.1.6' - when: - - amazon2cis_rule_1_5_1_6 - tags: - - level1 - - automated - - audit - - rule_1.5.1.6 - - selinux - - NIST800-53R5_AC-3 - - NIST800-53R5_MP-2 - name: "1.5.1.7 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed" - ansible.builtin.package: - name: mcstrans - state: absent - vars: - ansible_python_interpreter: /bin/python when: - amazon2cis_rule_1_5_1_7 tags: @@ -126,13 +121,13 @@ - rule_1.5.1.7 - mcstrans - NIST800-53R5_SI-4 - -- name: "1.5.1.8 | PATCH | Ensure SETroubleshoot is not installed" - ansible.builtin.package: - name: setroubleshoot - state: absent 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_1_8 tags: @@ -143,5 +138,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 00d2a2a..4296d8f 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -1,12 +1,6 @@ --- - name: "1.6.1 | PATCH | Ensure message of the day is configured properly" - ansible.builtin.template: - src: etc/motd.j2 - dest: /etc/motd - owner: root - group: root - mode: '0644' when: - amazon2cis_rule_1_6_1 tags: @@ -18,14 +12,14 @@ - NIST800-53R5_CM-1 - NIST800-53R5_CM-3 - NIST800-53R5_CM-6 - -- name: "1.6.2 | PATCH | Ensure local login warning banner is configured properly" ansible.builtin.template: - src: etc/issue.j2 - dest: /etc/issue + src: etc/motd.j2 + dest: /etc/motd owner: root group: root mode: '0644' + +- name: "1.6.2 | PATCH | Ensure local login warning banner is configured properly" when: - amazon2cis_rule_1_6_2 tags: @@ -37,14 +31,14 @@ - NIST800-53R5_CM-1 - NIST800-53R5_CM-3 - NIST800-53R5_CM-6 - -- name: "1.6.3 | PATCH | Ensure remote login warning banner is configured properly" ansible.builtin.template: - src: etc/issue.net.j2 - dest: /etc/issue.net + src: etc/issue.j2 + dest: /etc/issue owner: root group: root mode: '0644' + +- name: "1.6.3 | PATCH | Ensure remote login warning banner is configured properly" when: - amazon2cis_rule_1_6_3 tags: @@ -56,14 +50,14 @@ - NIST800-53R5_CM-1 - NIST800-53R5_CM-3 - NIST800-53R5_CM-6 - -- name: "1.6.4 | PATCH | Ensure permissions on /etc/motd are configured" - ansible.builtin.file: - path: /etc/motd - state: file + ansible.builtin.template: + src: etc/issue.net.j2 + dest: /etc/issue.net owner: root group: root mode: '0644' + +- name: "1.6.4 | PATCH | Ensure permissions on /etc/motd are configured" when: - amazon2cis_rule_1_6_4 tags: @@ -75,14 +69,14 @@ - permissions - NIST800-53R5_MP-2 - NIST800-53R5_AC-3 - -- name: "1.6.5 | PATCH | Ensure permissions on /etc/issue are configured" ansible.builtin.file: - path: /etc/issue + path: /etc/motd state: file owner: root group: root mode: '0644' + +- name: "1.6.5 | PATCH | Ensure permissions on /etc/issue are configured" when: - amazon2cis_rule_1_6_5 tags: @@ -94,14 +88,14 @@ - permissions - NIST800-53R5_MP-2 - NIST800-53R5_AC-3 - -- name: "1.6.6 | PATCH | Ensure permissions on /etc/issue.net are configured" ansible.builtin.file: - path: /etc/issue.net + path: /etc/issue state: file owner: root group: root mode: '0644' + +- name: "1.6.6 | PATCH | Ensure permissions on /etc/issue.net are configured" when: - amazon2cis_rule_1_6_6 tags: @@ -113,3 +107,9 @@ - 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_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index aa17d5a..f3975b3 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -1,6 +1,18 @@ --- - name: "2.1.1 | PATCH | Ensure time synchronization is in use" + when: + - amazon2cis_rule_2_1_1 + - not amazon2cis_system_is_container + tags: + - level1 + - automated + - patch + - rule_2.1.1 + - ntp + - chrony + - NIST800-53R5_AU-3 + - NIST800-53R5_AU-12 block: - name: "2.1.1 | PATCH | Ensure time synchronization is in use | service install" ansible.builtin.package: @@ -30,42 +42,40 @@ when: - "'chrony' in ansible_facts.packages" - amazon2cis_time_synchronization == "ntp" + +- name: "2.1.2 | PATCH | Ensure chrony is configured | modify /etc/chrony.conf" when: - - amazon2cis_rule_2_1_1 + - amazon2cis_rule_2_1_2 + - amazon2cis_time_synchronization == "chrony" - not amazon2cis_system_is_container tags: - level1 - automated - patch - - rule_2.1.1 + - rule_2.1.2 - ntp - chrony - NIST800-53R5_AU-3 - NIST800-53R5_AU-12 - - -- name: "2.1.2 | PATCH | Ensure chrony is configured | modify /etc/chrony.conf" 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: - - amazon2cis_rule_2_1_2 + - amazon2cis_rule_2_1_3 - amazon2cis_time_synchronization == "chrony" - not amazon2cis_system_is_container tags: - level1 - automated - patch - - rule_2.1.2 + - rule_2.1.3 - ntp - chrony - - NIST800-53R5_AU-3 - - NIST800-53R5_AU-12 - -- name: "2.1.3 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd" ansible.builtin.lineinfile: path: /etc/sysconfig/chronyd regexp: OPTIONS=\"(.*)(?!-u chrony)(.*)" @@ -73,14 +83,3 @@ create: true backrefs: true mode: '0644' - when: - - amazon2cis_rule_2_1_3 - - amazon2cis_time_synchronization == "chrony" - - not amazon2cis_system_is_container - tags: - - level1 - - automated - - patch - - rule_2.1.3 - - ntp - - chrony diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index b9e3a17..cb5478d 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -1,14 +1,6 @@ --- - name: "3.1.1 | PATCH | Disable IPv6" - ansible.posix.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 @@ -19,8 +11,45 @@ - 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" ansible.builtin.command: rpm -q NetworkManager @@ -42,11 +71,34 @@ 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 a709928..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" - ansible.posix.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" - ansible.posix.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" - 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.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 f9e6111..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" - 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.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" - ansible.posix.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" + - name: "3.3.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding" ansible.posix.sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true + 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" + - 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: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true - state: present - reload: true + 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" ansible.posix.sysctl: - name: '{{ item.name }}' - value: '{{ item.value }}' + 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" + - 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: '{{ item.name }}' - value: '{{ item.value }}' - sysctl_set: true + 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" + - 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" - 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 + - 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" + - 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 }}' + 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" + - 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: net.ipv4.tcp_syncookies + 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" +- 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: '{{ item.name }}' - value: '{{ item.value }}' + 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..e245819 --- /dev/null +++ b/tasks/section_3/cis_3.4.1.x.yml @@ -0,0 +1,131 @@ +--- + +- 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: + - "'iptables-services' in ansible_facts.packages" + - amazon2cis_system_firewall == "firewalld" + - amazon2cis_iptables == "mask" + ansible.builtin.systemd: + name: "{{ item }}" + masked: true + state: stopped + loop: + - iptables-services + - ip6tables-services + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | firewalld" + when: + - "'nftables' in ansible_facts.packages" + - amazon2cis_system_firewall == "firewalld" + - amazon2cis_nftables == "mask" + ansible.builtin.systemd: + name: nftables + masked: true + state: stopped + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | iptables" + when: + - "'nftables' in ansible_facts.packages" + - amazon2cis_system_firewall == "iptables" + - amazon2cis_iptables == "mask" + ansible.builtin.systemd: + name: nftables + masked: true + state: stopped + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | iptables" + when: + - "'firewalld' in ansible_facts.packages" + - amazon2cis_system_firewall == "iptables" + - amazon2cis_firewalld == "mask" + ansible.builtin.systemd: + name: nftables + masked: true + state: stopped + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables" + when: + - "'iptables-services' in ansible_facts.packages" + - amazon2cis_system_firewall == "nftables" + - amazon2cis_iptables == "mask" + ansible.builtin.systemd: + name: "{{ item }}" + masked: true + state: stopped + loop: + - iptables-services + - ip6tables-services + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables" + when: + - "'firewalld' in ansible_facts.packages" + - amazon2cis_system_firewall == "nftables" + - amazon2cis_firewalld == "mask" + ansible.builtin.systemd: + name: firewalld + masked: true + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_firewall }} package installed" + when: "amazon2cis_firewall not in ansible_facts.packages" + ansible.builtin.package: + name: "{{ amazon2cis_firewall }}" + state: present + + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_firewall }} started and enabled" + ansible.builtin.systemd: + name: "{{ amazon2cis_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 not in item" + - 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 not in item" + - 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 not in item" + - 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 a7bbed1..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" - ansible.builtin.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" - ansible.builtin.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 8aa893b..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" - ansible.builtin.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" - ansible.builtin.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 " - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - 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_5_1_7_servicesport - - - name: "3.5.1.7 | 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_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 e81041c..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.command: iptables -F - - - name: "3.5.2.4 | PATCH | Ensure iptables are flushed | Flush IPv6 tables" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - 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' - 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - 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 \; } - 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - 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_5_2_7_ipsaddr.stdout' - - - name: "3.5.2.7 | PATCH | Ensure 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_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" - 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_5_2_8_inconnectionrule - - - name: "3.5.2.8 | AUDIT | Ensure 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_5_2_8_outconnectionrule - - - name: "3.5.2.8 | PATCH | Ensure 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_5_2_8_inconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure 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_5_2_8_inconnectionrule.stdout' - - - name: "3.5.2.8 | PATCH | Ensure 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_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" - 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_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" - 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_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" - 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_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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - 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_5_2_9_sshallowcheck.stdout' - - - name: "3.5.2.9 | PATCH | Ensure 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_5_2_9_inputpolicy.stdout' - - - name: "3.5.2.9 | PATCH | Ensure 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_5_2_9_forwardpolicy.stdout' - - - name: "3.5.2.9 | PATCH | Ensure 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_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" - ansible.builtin.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" - ansible.builtin.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 8080fd1..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 2e14c83..ccb87cd 100644 --- a/tasks/section_3/main.yml +++ b/tasks/section_3/main.yml @@ -1,35 +1,48 @@ --- -- name: "SECTION | 3.1 | Disable unused network protocols and devices" +- 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)" +- 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)" +- 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" +- name: "SECTION | 3.4.1 | Configure host based firewall" ansible.builtin.import_tasks: - file: cis_3.4.x.yml + file: cis_3.4.1.x.yml -- name: "SECTION | 3.5.1 | Configure firewalld" - ansible.builtin.import_tasks: - file: cis_3.5.1.x.yml +- name: "SECTION | 3.4.2 | Configure firewalld" when: - amazon2cis_firewall == "firewalld" - -- name: "SECTION | 3.5.2 | Configure nftables" ansible.builtin.import_tasks: - file: cis_3.5.2.x.yml + file: cis_3.4.2.x.yml + +- name: "SECTION | 3.4.3 | Configure nftables" when: - amazon2cis_firewall == "nftables" + ansible.builtin.import_tasks: + file: cis_3.4.3.x.yml + +- name: "SECTION | 3.4.4.1.x | Configure iptables software" + when: + - amazon2cis_firewall == "iptables" + ansible.builtin.import_tasks: + file: cis_3.4.4.1.x.yml -- name: "SECTION | 3.5.3.1.x | Configure iptables" +- name: "SECTION | 3.4.4.2.x | Configure iptables" + when: + - amazon2cis_firewall == "iptables" ansible.builtin.import_tasks: - file: cis_3.5.3.1.x.yml + file: cis_3.4.4.2.x.yml + +- name: "SECTION | 3.4.4.3.x | Configure ip6tables" when: - amazon2cis_firewall == "iptables" + - amazon2cis_ipv6_required + ansible.builtin.import_tasks: + file: cis_3.4.4.3.x.yml diff --git a/vars/main.yml b/vars/main.yml index f08e8e2..e5d97cf 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -8,4 +8,3 @@ change_requires_reboot: false # Used to control warning summary warn_control_list: "" warn_count: 0 - From 5aa4a13674f188d2f885fdeb6846fe081196ceea Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 10:31:44 +0000 Subject: [PATCH 09/76] v3_updates Signed-off-by: Mark Bolwell --- defaults/main.yml | 427 ++++++++++++------ tasks/main.yml | 91 ++-- tasks/post.yml | 43 ++ tasks/prelim.yml | 24 + tasks/section_4/cis_4.1.1.x.yml | 64 --- tasks/section_4/cis_4.1.2.x.yml | 85 ---- tasks/section_4/cis_4.1.x.x.yml | 194 ++++++++ tasks/section_4/cis_4.1.x.yml | 229 ---------- tasks/section_4/cis_4.2.1.x.yml | 197 -------- tasks/section_4/cis_4.2.2.x.yml | 43 -- tasks/section_4/cis_4.2.x.yml | 494 ++++++++++++++++++++- tasks/section_4/cis_4.3.x.yml | 153 +++++++ tasks/section_4/cis_4.4.1.x.yml | 30 ++ tasks/section_4/cis_4.4.2.1.x.yml | 244 ++++++++++ tasks/section_4/cis_4.4.2.2.x.yml | 150 +++++++ tasks/section_4/cis_4.4.2.3.x.yml | 118 +++++ tasks/section_4/cis_4.4.2.4.x.yml | 83 ++++ tasks/section_4/cis_4.5.1.x.yml | 188 ++++++++ tasks/section_4/cis_4.5.2.x.yml | 99 +++++ tasks/section_4/cis_4.5.3.x.yml | 68 +++ tasks/section_4/main.yml | 44 +- tasks/section_5/cis_5.1.1.x.yml | 210 +++++++++ tasks/section_5/cis_5.1.2.x.yml | 197 ++++++++ tasks/section_5/cis_5.1.3.yml | 30 ++ tasks/section_5/cis_5.1.4.yml | 37 ++ tasks/section_5/cis_5.1.x.yml | 170 ------- tasks/section_5/cis_5.2.1.x.yml | 139 ++++++ tasks/section_5/cis_5.2.2.x.yml | 81 ++++ tasks/section_5/cis_5.2.3.x.yml | 299 +++++++++++++ tasks/section_5/cis_5.2.4.x.yml | 179 ++++++++ tasks/section_5/cis_5.2.x.yml | 40 -- tasks/section_5/cis_5.3.x.yml | 453 ++++--------------- tasks/section_5/cis_5.4.x.yml | 131 ------ tasks/section_5/cis_5.5.1.x.yml | 118 ----- tasks/section_5/cis_5.5.x.yml | 105 ----- tasks/section_5/cis_5.6.x.yml | 24 - tasks/section_5/cis_5.7.x.yml | 22 - tasks/section_5/main.yml | 40 +- tasks/section_6/cis_6.1.x.yml | 467 +++++++++++-------- tasks/section_6/cis_6.2.x.yml | 691 ++++++++++++++--------------- templates/audit/99_auditd.rules.j2 | 135 +++--- vars/main.yml | 4 +- 42 files changed, 4208 insertions(+), 2432 deletions(-) create mode 100644 tasks/post.yml delete mode 100644 tasks/section_4/cis_4.1.1.x.yml delete mode 100644 tasks/section_4/cis_4.1.2.x.yml create mode 100644 tasks/section_4/cis_4.1.x.x.yml delete mode 100644 tasks/section_4/cis_4.1.x.yml delete mode 100644 tasks/section_4/cis_4.2.1.x.yml delete mode 100644 tasks/section_4/cis_4.2.2.x.yml create mode 100644 tasks/section_4/cis_4.3.x.yml create mode 100644 tasks/section_4/cis_4.4.1.x.yml create mode 100644 tasks/section_4/cis_4.4.2.1.x.yml create mode 100644 tasks/section_4/cis_4.4.2.2.x.yml create mode 100644 tasks/section_4/cis_4.4.2.3.x.yml create mode 100644 tasks/section_4/cis_4.4.2.4.x.yml create mode 100644 tasks/section_4/cis_4.5.1.x.yml create mode 100644 tasks/section_4/cis_4.5.2.x.yml create mode 100644 tasks/section_4/cis_4.5.3.x.yml create mode 100644 tasks/section_5/cis_5.1.1.x.yml create mode 100644 tasks/section_5/cis_5.1.2.x.yml create mode 100644 tasks/section_5/cis_5.1.3.yml create mode 100644 tasks/section_5/cis_5.1.4.yml delete mode 100644 tasks/section_5/cis_5.1.x.yml create mode 100644 tasks/section_5/cis_5.2.1.x.yml create mode 100644 tasks/section_5/cis_5.2.2.x.yml create mode 100644 tasks/section_5/cis_5.2.3.x.yml create mode 100644 tasks/section_5/cis_5.2.4.x.yml delete mode 100644 tasks/section_5/cis_5.2.x.yml delete mode 100644 tasks/section_5/cis_5.4.x.yml delete mode 100644 tasks/section_5/cis_5.5.1.x.yml delete mode 100644 tasks/section_5/cis_5.5.x.yml delete mode 100644 tasks/section_5/cis_5.6.x.yml delete mode 100644 tasks/section_5/cis_5.7.x.yml diff --git a/defaults/main.yml b/defaults/main.yml index f48880c..5a1ccaa 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -51,9 +51,11 @@ run_audit: 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 @@ -64,7 +66,10 @@ system_is_ec2: true # 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 @@ -150,7 +155,9 @@ amazon2cis_rule_1_6_1_4: true amazon2cis_rule_1_6_1_5: true amazon2cis_rule_1_6_1_6: true -# Section 2 rules +## +## Section 2 rules +## # Section 2 is Services (inetd Services, Special Purpose Services, and Service Clients) # Time Service (Chrony) @@ -189,7 +196,9 @@ amazon2cis_rule_2_3_3: true amazon2cis_rule_2_3_4: true amazon2cis_rule_2_3_5: true -# Section 3 rules +## +## 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 @@ -255,93 +264,163 @@ 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 Logging and Auditing (Configure System Accounting (auditd) and Configure Logging) +## +## 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_2_2_1_3: true +amazon2cis_rule_4_2_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_2_2_2_3: true +amazon2cis_rule_4_2_2_2_4: true +amazon2cis_rule_4_4_2_2_5: true +amazon2cis_rule_4_2_2_2_6: true +amazon2cis_rule_4_2_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_2_2_3_3: true +amazon2cis_rule_4_2_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_2_2_4_3: true +amazon2cis_rule_4_2_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 + +# 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 -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 + +# 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 # Section 6 rules # Section 6 is System Maintenance (System File Permissions and User and Group Settings) @@ -381,6 +460,11 @@ amazon2cis_rule_6_2_17: true # cis 1.4.1 kernel_sysctl_file: /etc/sysctl.d/60-kernel_sysctl.conf +# Warning Banner Content (issue, issue.net, motd) +amazon2cis_warning_banner: | + Authorized uses only. All activity may be monitored and reported. +# End Banner + ## Section 2 variables amazon2cis_time_synchronization_servers: - 0.pool.ntp.org @@ -484,59 +568,21 @@ amazon2cis_nft_tables_tablename: cis # Allow creation of chains amazon2cis_nft_tables_autochaincreate: 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: '*' - -## 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 - -# 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" - -# 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 - -# AMZN LNX-4.2.1.4/4.2.1.5 remote and destation log server name -amazon2cis_remote_log_server: logagg.example.com - -# AMZN LNX-4.2.1.6 -amazon2cis_system_is_log_server: false - -# Maxium audit log size in MB -amazon2cis_maxauditlog_size: 10 - -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!! @@ -545,9 +591,15 @@ amazon2cis_sshd: # denyusers: # denygroups: +amazon2cis_ssh_maxsessions: 10 +amazon2cis_ssh_maxauthtries: 4 + + +## Sudo +amazon2cis_sudolog_location: "/var/log/sudo.log" # pam variables amazon2cis_pam_faillock: - attempts: 5 + deny: 5 interval: 900 unlock_time: 900 fail_for_root: "no" @@ -556,53 +608,138 @@ 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 +# Seeting minclass true means set via min class else will use the pwquality list below +amazon2cis_pwquality_minclass: true +amazon2cis_pwquality_minclass_value: '4' # Not less than 4 +amazon2cis_pwquality: + - key: '#minclass' + value: "{{ ubtu22cis_pwquality_minclass_value }}" + - key: 'minlen' + value: '14' # 14 or more required + - 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: true # Accounts listed below will not have INACTIVE field set in shadow file + +# Allow synmic 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 amazon2cis_pass: - max_days: 90 + max_days: 365 min_days: 1 warn_age: 7 -# 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 -# 5.6 Group to be used for su +# 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 -# amazon2_6.1.1 +## 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: email + max_log_file_action: keep_logs + +# 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 + +## Remove suid/sgid from files +amazon2cis_suid_adjust: false +amazon2cis_sgid_adjust: false + +# 6.2.12 +amazon2cis_dotperm_ansiblemanaged: true -# Warning Banner Content (issue, issue.net, motd) -amazon2cis_warning_banner: | - Authorized uses only. All activity may be monitored and reported. -# End Banner ### Goss binary settings ### goss_version: diff --git a/tasks/main.yml b/tasks/main.yml index b36b39d..ee201d4 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -18,6 +18,24 @@ 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" @@ -52,13 +70,24 @@ - prelim_tasks - always -- name: Run pre-remediation audit - ansible.builtin.import_tasks: - file: pre_remediation_audit.yml +- 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 - name: Gather the package facts ansible.builtin.package_facts: @@ -108,46 +137,40 @@ tags: - amazon2cis_section6 -- name: flush handlers - ansible.builtin.meta: flush_handlers +- name: Run auditd logic + when: + - update_audit_template + tags: + - always + ansible.builtin.import_tasks: + file: auditd.yml -- name: POST | reboot system if changes require it and not skipped - block: - - name: POST | Reboot system if changes require it and not skipped - ansible.builtin.reboot: - when: - - change_requires_reboot - - not skip_reboot - - - name: POST | Warning a reboot required but skip option set - 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 - when: - - change_requires_reboot - - skip_reboot - - - name: "POST | Warning a reboot required but skip option set | warning count" - ansible.builtin.import_tasks: - file: warning_facts.yml - when: - - change_requires_reboot - - skip_reboot - vars: - warn_control_id: Reboot_required - -- name: run post_remediation audit +- name: Run post remediation tasks + tags: + - post_tasks + - always ansible.builtin.import_tasks: - file: post_remediation_audit.yml + file: post.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 - ansible.builtin.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/post.yml b/tasks/post.yml new file mode 100644 index 0000000..d981fcf --- /dev/null +++ b/tasks/post.yml @@ -0,0 +1,43 @@ +--- +# Post tasks + +- name: POST | Perform DNF package cleanup + ansible.builtin.dnf: + 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/prelim.yml b/tasks/prelim.yml index ce6bb74..500e3da 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -31,6 +31,30 @@ tags: - skip_ansible_lint +- name: "PRELIM | Gather interactive user ID min and max" + when: + - amazon2cis_uid_info_dynamic + tags: + - 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" ansible.builtin.stat: path: /sys/firmware/efi 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 9f21f3b..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.shell: grep GRUB_CMDLINE_LINUX= /etc/default/grub | cut -d'"' -f2 - 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 audit setting already set" - ansible.builtin.replace: - path: /etc/default/grub - regexp: 'audit=([^\D]+)' - replace: 'audit=1' - notify: grub2cfg - when: "'audit=' 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 audit setting not already set" - ansible.builtin.lineinfile: - path: /etc/default/grub - regexp: '^GRUB_CMDLINE_LINUX=' - line: 'GRUB_CMDLINE_LINUX="{{ amazon2cis_4_1_1_3_grub_cmdline_linux.stdout }} audit=1"' - notify: grub2cfg - when: "'audit=' not 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 8fbcf4c..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | cut -f2 -d'"' - 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 not configured" - ansible.builtin.lineinfile: - dest: /etc/default/grub - regexp: '^GRUB_CMDLINE_LINUX=' - line: 'GRUB_CMDLINE_LINUX="{{ amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout }} audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}"' - notify: grub2cfg - when: '"audit_backlog_limit" not in amazon2cis_4_1_2_4_grub_cmdline_linux_settings.stdout' - - - name: "4.1.2.4 | PATCH | Ensure audit_backlog_limit is sufficient | Adjust audit_backlog_limit if exists" - ansible.builtin.replace: - dest: /etc/default/grub - regexp: 'audit_backlog_limit=([^\D]+)' - replace: 'audit_backlog_limit={{ amazon2cis_audit_backlog_limit }}' - notify: grub2cfg - when: '"audit_backlog_limit" 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..756f5dd --- /dev/null +++ b/tasks/section_4/cis_4.1.x.x.yml @@ -0,0 +1,194 @@ +--- + +- 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 fc17f4b..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 ef7a959..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" -# ansible.builtin.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 de2906c..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 f0fdf54..7c1b625 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" + - name: "4.2.2 | AUDIT | Ensure permissions on SSH private host key files are configured" ansible.builtin.find: - paths: /etc/logrotate.d/ - register: amazon2cis_4_2_3_log_rotates + 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" - ansible.builtin.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.4 | PATCH | Ensure permissions on all logfiles are configured" - ansible.builtin.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.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 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..a1b3f5a --- /dev/null +++ b/tasks/section_4/cis_4.3.x.yml @@ -0,0 +1,153 @@ +--- + +- 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: + backrefs: true + path: /etc/sudoers + regexp: ^(?i)(#|)\s*Defaults(.*)use_pty(.*) + line: 'Defaults \1 \2 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: + backrefs: true + path: /etc/sudoers + regexp: ^(?i)(#|)\s*Defaults(.*)logfile=.*\b(.*) + line: 'Defaults \1 \2 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 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..cf757f3 --- /dev/null +++ b/tasks/section_4/cis_4.4.2.1.x.yml @@ -0,0 +1,244 @@ +--- + +- 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_succeed" + community.general.pamd: + name: "{{ item }}" + type: auth + control: requisite + module_path: pam_succeed_if.so + state: before + 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_succeed" + 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 | 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.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_succeed" + 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 | 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.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_succeed" + 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 | 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 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..18f6759 --- /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: sufficient + module_path: pam_unix.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 = {{ ubtu22cis_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..23595de --- /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: '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: '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..f552054 --- /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\2 + 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: \1\2 use_authtok + 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..d3dc6da --- /dev/null +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -0,0 +1,188 @@ +--- + +- 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 | force user password change" + when: amazon2cis_force_user_passwd_change + ansible.builtin.shell: awk -F '( $3<'"{{ amazon2cis_uid_min }}"' && $1 != "nfsnobody" && $1 != "nobody") { print $1 }' /etc/passwd | xargs -n 1 chage -d 0 + +- 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 != 'root') or (not amazon2cis_uses_root) + +- 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 + 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 + - "'30' 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 | AUDIT | Ensure all users last password change date is in the past | capture default state" + ansible.builtin.shell: useradd -D | grep INACTIVE + changed_when: false + failed_when: amazon2cis_users_inactive_def.rc not in [ 0, 1 ] + register: amazon2cis_users_inactive_def + + - name: "4.5.1.5 | PATCH | Ensure all users last password change date is in the past | change default" + when: + - amazon2cis_users_inactive_def is defined + - "'30' not in amazon2cis_users_inactive_def.stdout" + ansible.builtin.shell: useradd -D -f {{ amazon2cis_pass['inactive'] }} + + - 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..fce795f --- /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 b7bcabd..00bf9e9 100644 --- a/tasks/section_4/main.yml +++ b/tasks/section_4/main.yml @@ -1,25 +1,45 @@ --- -- name: "SECTION | 4.1.1 | Ensure auditing is enabled" +- name: "SECTION | 4.1.x.x | Configure Job Schedulers" ansible.builtin.import_tasks: - file: cis_4.1.1.x.yml + file: cis_4.1.x.x.yml -- name: "SECTION | 4.1.2.x | Configure Data Retention" +- name: "SECTION | 4.2.x | Configure SSH Server" ansible.builtin.import_tasks: - file: cis_4.1.2.x.yml + file: cis_4.2.x.yml -- name: "SECTION | 4.1.x | Misc" +- name: "SECTION | 4.3.x | Configure Privilege Escalation" ansible.builtin.import_tasks: - file: cis_4.1.x.yml + file: cis_4.3.x.yml -- name: "SECTION | 4.2.x | Configure Logging" +- name: "SECTION | 4.4.1.x | Configure PAM software" ansible.builtin.import_tasks: - file: cis_4.2.1.x.yml + file: cis_4.4.1.x.yml -- name: "SECTION | 4.2.2.x | Configure journald" +- name: "SECTION | 4.4.2.1.x | Configure pam_faillock" ansible.builtin.import_tasks: - file: cis_4.2.2.x.yml + file: cis_4.4.2.1.x.yml -- name: "SECTION | 4.2.x | Misc. Logging settings" +- name: "SECTION | 4.4.2.2.x | Configure pam_pwquality" ansible.builtin.import_tasks: - file: cis_4.2.x.yml + 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..417c9ad --- /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: rhel_09_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:" + - "{{ rhel_09_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 356cd29..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.file: - dest: /etc/cron.deny - state: absent - - - name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Check if cron.allow exists" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.file: - dest: /etc/at.deny - state: absent - - - name: "5.1.9 | AUDIT | Ensure at is restricted to authorized users | Check if at.allow exists" - ansible.builtin.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" - ansible.builtin.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..c3aa4f4 --- /dev/null +++ b/tasks/section_5/cis_5.2.1.x.yml @@ -0,0 +1,139 @@ +--- + +- 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=' /etc/default/grub | sed 's/.$//' + 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: + path: /etc/default/grub + regexp: 'audit=.' + replace: 'audit=1' + + - 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=' + line: '{{ amazon2cis_5_2_1_2_grub_cmdline_linux.stdout }} audit=1"' + + - name: "5.2.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get grubby" + ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit=1\b' + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_5_2_1_2_grubby_audit + + - name: "5.2.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Update grubby" + when: "'audit=1' not in amazon2cis_5_2_1_2_grubby_audit.stdout" + ansible.builtin.shell: grubby --update-kernel ALL --args '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=' /etc/default/grub | sed 's/.$//' + 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" + ansible.builtin.replace: + path: /etc/default/grub + regexp: 'audit_backlog_limit=\d+' + replace: 'audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}' + when: "'audit_backlog_limit=' in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" + + - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Add audit_backlog_limit setting if missing" + ansible.builtin.lineinfile: + path: /etc/default/grub + regexp: '^GRUB_CMDLINE_LINUX=' + line: '{{ amazon2cis_5_2_1_3_grub_cmdline_linux.stdout }} audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}"' + when: "'audit_backlog_limit=' not in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" + + - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Get grubby" + ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit=1\b' + changed_when: false + failed_when: false + check_mode: false + register: amazon2cis_5_2_1_3_grubby_audit + + - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Update grubby" + when: "amazon2cis_audit_back_log_limit not in amazon2cis_5_2_1_3_grubby_backlog.stdout" + ansible.builtin.shell: "grubby --update-kernel ALL --args '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..ff14ad1 --- /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 | PATCH | 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 | PATCH | 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 | PATCH | Ensure use of privileged commands is collected" + 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..2918181 --- /dev/null +++ b/tasks/section_5/cis_5.2.4.x.yml @@ -0,0 +1,179 @@ +--- + +- 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 | discover file" + ansible.builtin.shell: grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }' + changed_when: false + register: audit_discovered_logfile + + - 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 929199b..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 6775670..7eb2c19 100644 --- a/tasks/section_5/cis_5.3.x.yml +++ b/tasks/section_5/cis_5.3.x.yml @@ -1,399 +1,96 @@ --- -- name: "5.3.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 +- 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.file: - path: "{{ item.path }}" - owner: root - group: root - mode: 0600 - with_items: - - "{{ amazon2_5_3_3_pub_results.files }}" - loop_control: - label: "{{ item.path }}" + - 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 } + +- name: "5.3.3 | Ensure cryptographic mechanisms are used to protect the integrity of audit tools" when: - amazon2cis_rule_5_3_3 + - not system_is_ec2 tags: - - level1 - - automated + - level1-server + - level1-workstation + - aide + - file_integrity - 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.lineinfile: - path: /etc/ssh/sshd_config - regexp: '^ClientAliveCountMax' - line: "ClientAliveCountMax 0" - 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 + ansible.builtin.blockinfile: + path: /etc/aide.conf + marker: "# {mark} Audit tools - CIS benchmark - Ansible-lockdown" + block: | + /sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512 + validate: aide -D --config %s 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 7e8a8bd..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 41976f0..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 5299f60..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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 d3b601a..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" - ansible.builtin.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" - ansible.builtin.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 710b2b8..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" - ansible.builtin.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" - ansible.builtin.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 40dd73e..016585f 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -1,33 +1,41 @@ --- -- name: "SECTION | 5.1 | Configure time-based job schedulers" +# 5.1 Configure Logging +- name: "SECTION | 5.1.1.x | Configure rsyslog" + when: rhel8cis_syslog == 'rsyslog' ansible.builtin.import_tasks: - file: cis_5.1.x.yml + file: cis_5.1.1.x.yml -- name: "SECTION | 5.2 | Configure sudo" +- name: "SECTION | 5.1.2.x | Configure journald" + when: rhel8cis_syslog == 'journald' ansible.builtin.import_tasks: - file: cis_5.2.x.yml + file: cis_5.1.2.x.yml -- name: "SECTION | 5.3 | Configure SSH Server" +- name: "SECTION | 5.1.3 | Configure logile perms" ansible.builtin.import_tasks: - file: cis_5.3.x.yml + file: cis_5.1.3.yml + +- name: "SECTION | 5.1.4 | Configure logrotate" + ansible.builtin.import_tasks: + file: cis_5.1.4.yml -- name: "SECTION | 5.4 | Configure PAM" +# 5.2 Configure System Accounting (auditd) +- name: "SECTION | 5.2.1 | Ensure auditing is enabled" ansible.builtin.import_tasks: - file: cis_5.4.x.yml + file: cis_5.2.1.x.yml -- name: "SECTION | 5.5.1.x | Set Shadow Password Suite Parameters" +- name: "SECTION | 5.2.2 | Configure Data Retention" ansible.builtin.import_tasks: - file: cis_5.5.1.x.yml + file: cis_5.2.2.x.yml -- name: "SECTION | 5.5.x" +- name: "SECTION | 5.2.3.x | Configure auditd rules" ansible.builtin.import_tasks: - file: cis_5.5.x.yml + file: cis_5.2.3.x.yml -- name: "SECTION | 5.6.x" +- name: "SECTION | 5.2.3.x | Audit file permissions" ansible.builtin.import_tasks: - file: cis_5.6.x.yml + file: cis_5.2.3.x.yml -- name: "SECTION | 5.7.x" +- name: "SECTION | 5.3.x | Aide" ansible.builtin.import_tasks: - file: cis_5.7.x.yml + 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 2acb604..a4b1eca 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" - ansible.builtin.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 - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" + - 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" + - 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" + - rule_6.1.3 ansible.builtin.file: - path: /etc/shadow + 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" + - rule_6.1.4 ansible.builtin.file: - path: /etc/shadow- + 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" + - rule_6.1.5 ansible.builtin.file: - path: /etc/gshadow- + 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" + - rule_6.1.6 ansible.builtin.file: - path: /etc/gshadow + 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" + - rule_6.1.7 ansible.builtin.file: - path: /etc/group + 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" + - rule_6.1.8 ansible.builtin.file: - path: /etc/group- + 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" - ansible.builtin.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" - ansible.builtin.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)" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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: rhel_08_6_1_11_perms_results + + - name: "6.1.11 | PATCH | Adjust world-writable files if they exist (Configurable)" + when: + - rhel_08_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: "{{ rhel_08_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" + - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Warning" + when: + - rhel_08_6_1_11_perms_results.stdout_lines is defined + - not amazon2cis_no_world_write_adjust ansible.builtin.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 + msg: "Warning!! - WorldWritable files have been found" + + - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Warn Count" + when: + - rhel_08_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" - ansible.builtin.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" - ansible.builtin.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" + - 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 - 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 + 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" - ansible.builtin.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.14 | AUDIT | Audit SGID executables | Alert no SGID executables exist" + - 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.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.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: + - "{{ 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: "Good news! We have not found any SGID executable files on your system" - when: amazon2_6_1_14_perms_results.stdout is not defined + 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.14 | AUDIT | Audit SGID executables | Alert SGID executables exist" + - 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 - Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}" - with_items: - - "{{ amazon2_6_1_14_perms_results.stdout_lines }}" - when: amazon2_6_1_14_perms_results.stdout is defined + 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 610befc..8e3ff94 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -1,488 +1,451 @@ --- -- name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords" +- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords" + when: + - amazon2cis_rule_6_2_1 + tags: + - level1-server + - level1-workstation + - automated + - audit + - NIST800-53R5_IA-5 + - rule_6.2.1 + - user_accounts + vars: + warn_control_id: '6.2.1' block: - - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadow passwords" - ansible.builtin.shell: sed -e 's/^\([a-zA-Z0-9_]*\):[^:]*:/\1:x:/' -i /etc/passwd + - 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: amazon2_6_2_1_shadow - - - name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords | Good News" - ansible.builtin.debug: - msg: "Good News!! No Unshadowed passwords have been found" - when: amazon2_6_2_1_shadow.stdout | length == 0 + register: amazon2cis_6_2_1_nonshadowed_users - - name: "6.2.1 | PATCH | Ensure accounts in /etc/passwd use shadow passwords | Alert on no shadow passwords" + - 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: - - "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 - when: - - amazon2cis_rule_6_2_1 - tags: - - level1 - - automated - - patch - - rule_6.2.1 - - accounts + - "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.2 | PATCH | Ensure /etc/shadow password fields are not empty" - ansible.builtin.command: passwd -l {{ item }} - changed_when: false - failed_when: false - with_items: - - "{{ empty_password_accounts.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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.4 | AUDIT | Ensure shadow group is empty | Print no user in shadow group" + - 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: "Good News! There are no users in the shadow group" - when: amazon2_6_2_4_users_in_shadow_group.stdout | length == 0 + 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" - ansible.builtin.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.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 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" - ansible.builtin.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" + - 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: "Good News! There are no duplicate user names in the system" - when: amazon2_6_2_5_user_username_check.stdout | length == 0 + 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" - ansible.builtin.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" - ansible.builtin.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.6 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist" + - 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: "Good News! There are no duplicate group names in the system" - when: amazon2_6_2_6_group_group_check.stdout | length == 0 + 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 warning about users with duplicate group names" - ansible.builtin.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.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 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" - ansible.builtin.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.7 | AUDIT | Ensure no duplicate UIDs exist | Print message that no duplicate UIDs exist" + - 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: "Good News! There are no duplicate UID's in the system" - when: amazon2_6_2_7_user_uid_check.stdout | length == 0 + 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 warning about users with duplicate UIDs" - ansible.builtin.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.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 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" - ansible.builtin.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" + - 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: "Good News! There are no duplicate GIDs in the system" - when: amazon2_6_2_8_user_user_check.stdout | length == 0 + 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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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" + - 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: rhel_09_6_2_10_home_dir_perms + loop: "{{ interactive_users_home.stdout_lines }}" - - name: "6.2.11 | PATCH | Ensure all users' home directories exist" - ansible.builtin.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: "{{ rhel_09_6_2_10_home_dir_perms.results }}" loop_control: - label: "{{ item.0 }}" - when: - - ansible_check_mode - - item.1.exists + label: "{{ item }}" - - name: "6.2.11 | PATCH | Ensure all users' home directories exist" + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | own their home directories" + when: + - 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.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 }}" + 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" + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set group ACL" ansible.posix.acl: - path: "{{ item.0 }}" + 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 + loop: "{{ interactive_users_home.stdout_lines }}" + when: not system_is_container -- name: "6.2.12 | PATCH | Ensure users own their home directories" - ansible.builtin.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 - -- 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" - ansible.builtin.stat: - 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" - ansible.builtin.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" - ansible.builtin.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" + - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set other ACL" ansible.posix.acl: - path: "{{ item.0 }}" + path: "{{ item }}" 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 }}" + when: not system_is_container + +- 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" + - 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.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 - - name: "6.2.14 | AUDIT | Ensure users' dot files are not group or world-writable | Alert on files found" ansible.builtin.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 + 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" - ansible.builtin.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_6_2_11_audit.stdout | length > 0 - amazon2cis_dotperm_ansiblemanaged - when: - - amazon2cis_rule_6_2_14 - tags: - - level1 - - automated - - patch - - rule_6.2.14 - - permissions -- name: "6.2.15 | PATCH | Ensure no users have .forward files" - ansible.builtin.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" - ansible.builtin.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" - ansible.builtin.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 + ansible.builtin.import_tasks: + file: warning_facts.yml + + - 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/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 19eb0be..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 exit,always -F arch=b64 -C euid!=uid -F euid=0 -Fauid>=1000 -F auid!=4294967295 -S execve -k actions --a exit,always -F arch=b32 -C euid!=uid -F euid=0 -Fauid>=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/main.yml b/vars/main.yml index e5d97cf..5992f64 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,7 +1,7 @@ --- -# vars file for . +# vars file for amazon linux 2 -min_ansible_version: 2.10.1 +min_ansible_version: 2.11.1 change_requires_reboot: false From 615a594782cb21f3cd7a5727b66f3b711a11f8b4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 10:31:54 +0000 Subject: [PATCH 10/76] audit_only_updates Signed-off-by: Mark Bolwell --- tasks/LE_audit_setup.yml | 34 +++++++---- tasks/audit_only.yml | 30 ++++++++++ tasks/post_remediation_audit.yml | 28 +++++---- tasks/pre_remediation_audit.yml | 99 +++++++++++++++++--------------- 4 files changed, 123 insertions(+), 68 deletions(-) create mode 100644 tasks/audit_only.yml diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 1012006..b7c0b9b 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -1,22 +1,34 @@ --- -- name: Download audit binary +- name: Pre Audit Setup | Set audit package name + block: + - name: Pre Audit Setup | Set audit package name | 64bit + when: ansible_machine == "x86_64" + ansible.builtin.set_fact: + audit_pkg_arch_name: AMD64 + + - name: Pre Audit Setup | Set audit package name | ARM64 + when: ansible_machine == "arm64" + ansible.builtin.set_fact: + audit_pkg_arch_name: ARM64 + +- name: Pre Audit Setup | Download audit binary + when: + - get_audit_binary_method == 'download' ansible.builtin.get_url: - url: "{{ goss_url }}" + url: "{{ audit_bin_url }}{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" owner: root group: root - checksum: "{{ goss_version.checksum }}" - mode: 0555 - when: - - get_goss_file == 'download' + checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" + mode: '0555' -- name: copy audit binary +- name: Pre Audit Setup | Copy audit binary + when: + - get_audit_binary_method == 'copy' ansible.builtin.copy: - src: "{{ copy_goss_from_path }}" + src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" - mode: 0555 + mode: '0555' owner: root group: root - when: - - get_goss_file == '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/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index a0b7999..eb01bc7 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" +- name: Post Audit | Run post_remediation {{ benchmark }} audit ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + AUDIT_FILE: goss.yml - name: Post Audit | ensure audit files readable by users 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 }}" - ansible.builtin.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 ansible.builtin.set_fact: - post_audit_summary: "{{ post_audit.stdout | from_json |json_query(summary) }}" + 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 }}" - ansible.builtin.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 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 1b0ac6b..5f2560e 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,110 +1,119 @@ --- -- name: Pre Audit | Setup the audit - ansible.builtin.import_tasks: - file: 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" +- 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 + - 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 + - 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 +- name: Pre Audit Setup | Copy to audit content files to server + when: + - audit_content == 'copy' ansible.builtin.copy: src: "{{ audit_local_copy }}" - dest: "{{ audit_conf_dir }}" + dest: "{{ audit_conf_dest }}" + mode: preserve + +- name: Pre Audit Setup | Unarchive audit content files on server when: - - audit_content == 'copy' + - audit_content == 'archived' + ansible.builtin.unarchive: + src: "{{ audit_conf_copy }}" + dest: "{{ audit_conf_dir }}" -- name: Pre Audit | get audit content from url +- name: Pre Audit Setup | Get audit content from url + when: + - audit_content == 'get_url' ansible.builtin.get_url: url: "{{ audit_files_url }}" dest: "{{ audit_conf_dir }}" - when: - - audit_content == 'get_url' -- 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 + - 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 + - name: Pre Audit Setup | If audit ensure goss is available ansible.builtin.assert: + that: goss_available.stat.exists msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - when: - - not goss_available.stat.exists + +- name: Pre Audit Setup | Copy ansible default vars values to test audit when: - run_audit - -- name: "Pre Audit | Check whether machine is UEFI-based" - ansible.builtin.stat: - path: /sys/firmware/efi - register: rhel8_efi_boot tags: - goss_template - -- name: Pre Audit | Copy ansible default vars values to test audit + - run_audit ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" - mode: 0600 - when: - - run_audit - tags: - - goss_template + mode: '0600' -- name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" +- name: Pre Audit | Run pre_remediation {{ benchmark }} audit ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + 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 }}" - ansible.builtin.command: "cat {{ pre_audit_outfile }}" - changed_when: false + - name: 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 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 }}" - ansible.builtin.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 + - 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: + file: audit_only.yml From 620cdc65883f0744deddd46fdfb076ac23d0c295 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 11:11:42 +0000 Subject: [PATCH 11/76] updated audit Signed-off-by: Mark Bolwell --- defaults/main.yml | 71 +++++++++++++++++++++++++++-------------------- vars/audit.yml | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 vars/audit.yml diff --git a/defaults/main.yml b/defaults/main.yml index 5a1ccaa..8db5e3c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -19,35 +19,12 @@ 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 +benchmark_version: v3.0.0 # Ability to stop reboot from occuring until convenient # set to true if ok to reboot skip_reboot: false -### 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 - -# how to get audit files onto host options -# options are git/copy/get_url -audit_content: git - -# 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 #### - # Change to false if using EFI boot changes 1.1.1.4 to stop vfat amazon2cis_legacy_boot: true @@ -62,6 +39,38 @@ amazon2cis_skip_for_travis: false amazon2cis_system_is_container: false system_is_ec2: true +########################################## +### Goss is required on the remote host ### +## Refer to vars/auditd.yml for any 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 + +# 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 +fetch_audit_files: false +# Path to copy the files to will create dir structure +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 + +# how to get audit files onto host options +# options are git/copy/get_url other e.g. if you wish to run from already downloaded conf +audit_content: git + +# 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 + +### End Goss enablements #### + # 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. @@ -103,13 +112,13 @@ 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 +# /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 +# /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 @@ -457,6 +466,10 @@ amazon2cis_rule_6_2_16: true amazon2cis_rule_6_2_17: true ## Section 1 variables + +# If set true uses the tmp.mount service else using fstab configuration +amazon2cis_tmp_svc: true + # cis 1.4.1 kernel_sysctl_file: /etc/sysctl.d/60-kernel_sysctl.conf @@ -594,7 +607,6 @@ amazon2cis_sshd: amazon2cis_ssh_maxsessions: 10 amazon2cis_ssh_maxauthtries: 4 - ## Sudo amazon2cis_sudolog_location: "/var/log/sudo.log" # pam variables @@ -611,7 +623,8 @@ amazon2cis_inactivelock: 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 -# Seeting minclass true means set via min class else will use the pwquality list below + +# Setting minclass true - mincalls used instead of seperated values amazon2cis_pwquality_minclass: true amazon2cis_pwquality_minclass_value: '4' # Not less than 4 amazon2cis_pwquality: @@ -652,7 +665,6 @@ amazon2cis_pass: min_days: 1 warn_age: 7 - # 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: @@ -740,7 +752,6 @@ amazon2cis_sgid_adjust: false # 6.2.12 amazon2cis_dotperm_ansiblemanaged: true - ### Goss binary settings ### goss_version: release: v0.3.21 diff --git a/vars/audit.yml b/vars/audit.yml new file mode 100644 index 0000000..250a600 --- /dev/null +++ b/vars/audit.yml @@ -0,0 +1,54 @@ +--- + +#### Audit Configuration Settings #### + +# This variable specifies the timeout (in ms) for audit commands that +# take a very long time: if a command takes too long to complete, +# it will be forcefully terminated after the specified duration. +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-" + +## 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 + +### 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 }}" + +# archive or copy: +audit_conf_copy: "some path to copy from" + +# get_url: +audit_files_url: "some url maybe s3?" + +## Goss configuration information +# Where the goss configs and outputs are stored +audit_out_dir: '/opt' +# Where the goss audit configuration will be stored +audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" + +# If changed these can affect other products +pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" +post_audit_outfile: "{{ audit_out_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 pre remediation results are: {{ pre_audit_summary }}. + The post remediation results are: {{ post_audit_summary }}. + Full breakdown can be found in {{ audit_out_dir }} From 1310ee4f143da93ee58a804c5187fb0aa5352556 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 11:11:52 +0000 Subject: [PATCH 12/76] Added auditd post file Signed-off-by: Mark Bolwell --- tasks/auditd.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tasks/auditd.yml 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 From a091ad4af81c02e2c3309ea461ce3ae27b0131b7 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 11:11:57 +0000 Subject: [PATCH 13/76] lint Signed-off-by: Mark Bolwell --- tasks/main.yml | 1 - tasks/prelim.yml | 1 - tasks/section_4/cis_4.1.x.x.yml | 1 - tasks/section_4/cis_4.3.x.yml | 1 - 4 files changed, 4 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index ee201d4..b0960b2 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -173,4 +173,3 @@ - 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/prelim.yml b/tasks/prelim.yml index 500e3da..dcebf09 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -54,7 +54,6 @@ amazon2cis_uid_min: "{{ amazon2cis_min_uid.stdout | string }}" amazon2cis_uid_max: "{{ amazon2cis_max_uid.stdout | string }}" - - name: "PRELIM | Check whether machine is UEFI-based" ansible.builtin.stat: path: /sys/firmware/efi diff --git a/tasks/section_4/cis_4.1.x.x.yml b/tasks/section_4/cis_4.1.x.x.yml index 756f5dd..72c76e6 100644 --- a/tasks/section_4/cis_4.1.x.x.yml +++ b/tasks/section_4/cis_4.1.x.x.yml @@ -162,7 +162,6 @@ group: root mode: '0600' - - name: "4.1.2.1 | PATCH | Ensure at is restricted to authorized users" when: - amazon2cis_rule_4_1_2_1 diff --git a/tasks/section_4/cis_4.3.x.yml b/tasks/section_4/cis_4.3.x.yml index a1b3f5a..ece3fbe 100644 --- a/tasks/section_4/cis_4.3.x.yml +++ b/tasks/section_4/cis_4.3.x.yml @@ -150,4 +150,3 @@ path: /etc/pam.d/su regexp: '^(#)?auth\s+required\s+pam_wheel\.so' line: 'auth required pam_wheel.so use_uid group={{ amazon2cis_sugroup }}' - From b04665e72186a370ad58de42fbf58063ca756549 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 14:03:14 +0000 Subject: [PATCH 14/76] fix firewall variable Signed-off-by: Mark Bolwell --- tasks/section_3/cis_3.4.1.x.yml | 16 ++++++++-------- tasks/section_3/main.yml | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tasks/section_3/cis_3.4.1.x.yml b/tasks/section_3/cis_3.4.1.x.yml index e245819..d953905 100644 --- a/tasks/section_3/cis_3.4.1.x.yml +++ b/tasks/section_3/cis_3.4.1.x.yml @@ -92,21 +92,21 @@ name: firewalld masked: true - - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_firewall }} package installed" - when: "amazon2cis_firewall not in ansible_facts.packages" + - 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_firewall }}" + name: "{{ amazon2cis_system_firewall }}" state: present - - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ amazon2cis_firewall }} started and enabled" + - 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_firewall }}" + 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 not in item" + - amazon2cis_system_firewall != "nftables" - amazon2cis_nftables == "remove" ansible.builtin.package: name: nftables @@ -114,7 +114,7 @@ - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | remove iptables" when: - - "amazon2cis_system_firewall not in item" + - amazon2cis_system_firewall != "iptables" - amazon2cis_iptables == "remove" ansible.builtin.package: name: @@ -124,7 +124,7 @@ - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | remove firewalld" when: - - "amazon2cis_system_firewall not in item" + - amazon2cis_system_firewall != "firewalld" - amazon2cis_firewalld == "remove" ansible.builtin.package: name: firewalld diff --git a/tasks/section_3/main.yml b/tasks/section_3/main.yml index ccb87cd..2c02c83 100644 --- a/tasks/section_3/main.yml +++ b/tasks/section_3/main.yml @@ -18,31 +18,31 @@ - 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.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.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_firewall == "iptables" + - 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_firewall == "iptables" + - amazon2cis_system_firewall == "iptables" - amazon2cis_ipv6_required ansible.builtin.import_tasks: file: cis_3.4.4.3.x.yml From b404200540785355d0f9820e2bb44b286967a5dc Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 14:03:47 +0000 Subject: [PATCH 15/76] fix layout 4.2.16 Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_4/cis_4.2.x.yml b/tasks/section_4/cis_4.2.x.yml index 7c1b625..1e3873a 100644 --- a/tasks/section_4/cis_4.2.x.yml +++ b/tasks/section_4/cis_4.2.x.yml @@ -368,7 +368,7 @@ ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: ^(?i)(#|)\s*maxauthtries - line: 'MaxAuthTries{{ amazon2cis_ssh_maxauthtries }}' + line: 'MaxAuthTries {{ amazon2cis_ssh_maxauthtries }}' validate: 'sshd -t -f %s' - name: "4.2.17 | PATCH | Ensure sshd MaxSessions is configured" From 9b96b9e0c33bae5dc460ecee381af4083d1a0847 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 14:04:15 +0000 Subject: [PATCH 16/76] updated requirements Signed-off-by: Mark Bolwell --- handlers/main.yml | 28 +++++++++++++++++++++------- tasks/post.yml | 4 ++-- tasks/prelim.yml | 45 ++++++++++++++++++++------------------------- vars/main.yml | 2 ++ 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 5ad693f..9148e24 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -45,24 +45,38 @@ - name: grub2cfg ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" -- name: restart postfix +- name: Restart_postfix ansible.builtin.service: name: postfix state: restarted -- name: sysctl flush ipv6 route table +- name: Sysctl_flush_ipv4_routes ansible.posix.sysctl: - name: net.ipv6.route.flush + name: net.ipv4.route.flush value: '1' sysctl_set: true - when: ansible_virtualization_type != "docker" + ignore_errors: true # noqa ignore-errors + when: + - not system_is_container -- name: sysctl flush ipv4 route table +- name: Sysctl_flush_ipv6_routes ansible.posix.sysctl: - name: net.ipv4.route.flush + name: net.ipv6.route.flush value: '1' sysctl_set: true - when: ansible_virtualization_type != "docker" + ignore_errors: true # noqa ignore-errors + when: + - not system_is_container + +- 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 ansible.builtin.template: diff --git a/tasks/post.yml b/tasks/post.yml index d981fcf..e8951b5 100644 --- a/tasks/post.yml +++ b/tasks/post.yml @@ -1,8 +1,8 @@ --- # Post tasks -- name: POST | Perform DNF package cleanup - ansible.builtin.dnf: +- name: POST | Perform yum package cleanup + ansible.builtin.package: autoremove: true changed_when: false diff --git a/tasks/prelim.yml b/tasks/prelim.yml index dcebf09..23876d5 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -2,12 +2,14 @@ # Preliminary tasks that should always be run # List users in order to look files inside each home directory -- name: Import section 1 tasks +- name: Parse etc password ansible.builtin.import_tasks: file: parse_etc_password.yml when: - amazon2cis_section5 or amazon2cis_section6 + tags: + - always - name: "PRELIM | List users accounts" ansible.builtin.command: "awk -F: '{print $1}' /etc/passwd" @@ -86,51 +88,44 @@ 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" + - 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" + - name: "PRELIM | Section 1.5 | Ensure firewalld_t is set to permissive" 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)" +- 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" +- 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" - ansible.builtin.shell: "getent passwd {1000..65535} | cut -d: -f6 | sort -u | grep -v '/var/' | grep -v '/nonexistent/*' | grep -v '/run/*'" - changed_when: false - failed_when: false - register: amazon2cis_6_2_8_getent - tags: - - skip_ansible_lint - - rule_6.2.8 - -- name: "PRELIM | 6.2.8 | Set fact for home directory paths for interactive users" - ansible.builtin.set_fact: - amazon2cis_stig_interactive_homedir_results: "{{ amazon2cis_6_2_8_getent.stdout_lines }}" - when: - - amazon2cis_6_2_8_getent.stdout_lines is defined - tags: - - rule_6.2.8 diff --git a/vars/main.yml b/vars/main.yml index 5992f64..954ee36 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -3,7 +3,9 @@ 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: "" From 5125d721f3d4c07a0cf75a6d1bb8bbbf3f44e336 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 16:49:12 +0000 Subject: [PATCH 17/76] improve idempotency Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 23876d5..bda6a66 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -97,7 +97,14 @@ - policycoreutils-python state: present + - 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 From 05964f6d9c953bddf03b5f69ef7ab85a285f018b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 16:49:27 +0000 Subject: [PATCH 18/76] fix rule numbers Signed-off-by: Mark Bolwell --- tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index b0960b2..9a9fba7 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -52,9 +52,9 @@ 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 - name: Run pre-reqs ansible.builtin.import_tasks: From 7ca66aaf634d211004e9a3ea0d0b6176155ed20a Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 16:49:38 +0000 Subject: [PATCH 19/76] fix logic Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.4.2.1.x.yml | 93 ++++++++----------------------- 1 file changed, 24 insertions(+), 69 deletions(-) diff --git a/tasks/section_4/cis_4.4.2.1.x.yml b/tasks/section_4/cis_4.4.2.1.x.yml index cf757f3..2bc7746 100644 --- a/tasks/section_4/cis_4.4.2.1.x.yml +++ b/tasks/section_4/cis_4.4.2.1.x.yml @@ -42,11 +42,11 @@ 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 %}' + 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 @@ -55,21 +55,21 @@ "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_succeed" + 4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_default" community.general.pamd: name: "{{ item }}" type: auth - control: requisite - module_path: pam_succeed_if.so - state: before + control: sufficient + module_path: pam_unix.so + state: after new_type: auth - new_control: [default=die] + 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 %}' + 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 @@ -111,34 +111,19 @@ control: required module_path: pam_faillock.so state: args_present - module_arguments: 'deny={{ amazon2cis_pam_faillock[deny] }}' + 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_succeed" + - name: "4.4.2.1.2 | PATCH | Ensure password failed attempts lockout is configured | auth_default" community.general.pamd: name: "{{ item }}" type: auth - control: required + 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.2 | PATCH | Ensure password failed attempts lockout is configured | 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: '' + module_arguments: 'deny={{ amazon2cis_pam_faillock.deny }}' loop: - system-auth - password-auth @@ -161,34 +146,19 @@ control: required module_path: pam_faillock.so state: args_present - module_arguments: 'unlock_time={{ amazon2cis_pam_faillock[unlock_time] }}' + 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_succeed" + - name: "4.4.2.1.3 | PATCH | Ensure password unlock time is configured | auth_default" community.general.pamd: name: "{{ item }}" type: auth - control: required + 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.3 | PATCH | Ensure password unlock time is configured | 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: '' + module_arguments: 'unlock_time={{ amazon2cis_pam_faillock.unlock_time }}' loop: - system-auth - password-auth @@ -216,29 +186,14 @@ - system-auth - password-auth - - name: "4.4.2.1.4 | PATCH | Ensure password failed attempts lockout includes root account | auth_succeed" + - 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: required + control: '[default=die]' 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 | 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 From 855344f6dc35ea6e1830c22b3cd4d705a4e88a75 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 16:50:02 +0000 Subject: [PATCH 20/76] updated control Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.4.2.2.x.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks/section_4/cis_4.4.2.2.x.yml b/tasks/section_4/cis_4.4.2.2.x.yml index 18f6759..27cb4aa 100644 --- a/tasks/section_4/cis_4.4.2.2.x.yml +++ b/tasks/section_4/cis_4.4.2.2.x.yml @@ -17,14 +17,14 @@ community.general.pamd: name: "{{ item }}" type: password - control: sufficient - module_path: pam_unix.so + 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' + local_users_only' loop: - system-auth - password-auth @@ -37,7 +37,7 @@ module_path: pam_pwquality.so state: args_present module_arguments: 'try_first_pass - local_users_only' + local_users_only' loop: - system-auth - password-auth @@ -90,7 +90,7 @@ ansible.builtin.lineinfile: path: /etc/security/pwquality.conf regexp: ^minclass - line: "minclass = {{ ubtu22cis_pwquality_minclass_value }}" + line: "minclass = {{ amazon2cis_pwquality_minclass_value }}" when: amazon2cis_pwquality_minclass - name: "4.4.2.2.4 | PATCH | Ensure password complexity is configured | seperated values" From 85ef7253925bc729654cfefbf33c0f8efdaa0aee Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:48:58 +0000 Subject: [PATCH 21/76] updated Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.1.1.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.1.1.x.yml b/tasks/section_5/cis_5.1.1.x.yml index 417c9ad..a97b606 100644 --- a/tasks/section_5/cis_5.1.1.x.yml +++ b/tasks/section_5/cis_5.1.1.x.yml @@ -85,13 +85,13 @@ changed_when: false failed_when: false check_mode: false - register: rhel_09_5_1_1_5_audit + 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:" - - "{{ rhel_09_5_1_1_5_audit.stdout_lines }}" + - "{{ 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 From 8c636967faee0b4f9d50a265a9ac439c2be06db9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:49:16 +0000 Subject: [PATCH 22/76] updated 4.5.1.1 Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.5.1.x.yml | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml index d3dc6da..4553a93 100644 --- a/tasks/section_4/cis_4.5.1.x.yml +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -25,9 +25,20 @@ regexp: ^(?i)(#|)\s*ENCRYPT_METHOD line: "ENCRYPT_METHOD {{ amazon2cis_encryption | upper }}" - - name: "4.5.1.1 | PATCH | Ensure strong password hashing algorithm is configured | force user password change" + - 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" && $1 != "nobody") { print $1 }' /etc/passwd | xargs -n 1 chage -d 0 + 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: "xargs -n 1 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: @@ -110,16 +121,19 @@ - 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 + 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 + - ansible.builtin.debug: + msg: "{{ amazon2cis_users_inactive_def.stdout }}" + - name: "4.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | change default" when: - amazon2cis_users_inactive_def is defined - - "'30' not in amazon2cis_users_inactive_def.stdout" - ansible.builtin.shell: useradd -D -f {{ amazon2cis_pass['inactive'] }} + - (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: | @@ -132,7 +146,7 @@ when: - amazon2cis_users_inactive is defined - amazon2cis_users_inactive.stdout | length > 0 - ansible.builtin.shell: chage --inactive {{ amazon2cis_pass['inactive'] }} {{ item }} + 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" @@ -148,18 +162,6 @@ vars: warn_control_id: '4.5.1.5' block: - - name: "4.5.1.5 | AUDIT | Ensure all users last password change date is in the past | capture default state" - ansible.builtin.shell: useradd -D | grep INACTIVE - changed_when: false - failed_when: amazon2cis_users_inactive_def.rc not in [ 0, 1 ] - register: amazon2cis_users_inactive_def - - - name: "4.5.1.5 | PATCH | Ensure all users last password change date is in the past | change default" - when: - - amazon2cis_users_inactive_def is defined - - "'30' not in amazon2cis_users_inactive_def.stdout" - ansible.builtin.shell: useradd -D -f {{ amazon2cis_pass['inactive'] }} - - 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 }}" From 60cbf6e138f802a1636b9afe40b5203164cbb5c0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:49:26 +0000 Subject: [PATCH 23/76] fix loop Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.4.2.4.x.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tasks/section_4/cis_4.4.2.4.x.yml b/tasks/section_4/cis_4.4.2.4.x.yml index f552054..4976162 100644 --- a/tasks/section_4/cis_4.4.2.4.x.yml +++ b/tasks/section_4/cis_4.4.2.4.x.yml @@ -17,9 +17,9 @@ path: "/etc/pam.d/{{ item }}" regexp: (.*pam_unix.so.*)nullok(.*) line: \1\2 - loop: - - system-auth - - password-auth + loop: + - system-auth + - password-auth - name: "4.4.2.4.2 | PATCH | Ensure pam_unix does not include remember" when: @@ -37,9 +37,9 @@ path: "/etc/pam.d/{{ item }}" regexp: (.*pam_unix.so.*)remember(.*) line: \1\2 - loop: - - system-auth - - password-auth + loop: + - system-auth + - password-auth - name: "4.4.2.4.3 | PATCH | Ensure pam_unix includes a strong password hashing algorithm" when: @@ -57,9 +57,9 @@ path: "/etc/pam.d/{{ item }}" regexp: (.*pam_unix.so.*)(md5|bigcrypt|sha256|blowfish)(.*) line: \1\2 sha512 - loop: - - system-auth - - password-auth + loop: + - system-auth + - password-auth - name: "4.4.2.4.4 | PATCH | Ensure pam_unix includes use_authtok" when: @@ -76,8 +76,8 @@ ansible.builtin.lineinfile: backrefs: true path: "/etc/pam.d/{{ item }}" - regexp: (.*pam_unix.so.*)use_authtok(.*) - line: \1\2 use_authtok - loop: - - system-auth - - password-auth + regexp: (.*pam_unix.so.*)(use_authtok)(.*) + line: \1use_authtok\3 + loop: + - system-auth + - password-auth From 5056ba2973426b6f57d7589ac59c8651a51cfc40 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:49:38 +0000 Subject: [PATCH 24/76] updated authtok Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.4.2.3.x.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/section_4/cis_4.4.2.3.x.yml b/tasks/section_4/cis_4.4.2.3.x.yml index 23595de..4a1f246 100644 --- a/tasks/section_4/cis_4.4.2.3.x.yml +++ b/tasks/section_4/cis_4.4.2.3.x.yml @@ -30,20 +30,20 @@ new_type: password new_control: required new_module_path: pam_pwhistory.so - module_arguments: 'authtok' + 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 + 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: 'authtok' + module_arguments: 'use_authtok' loop: - system-auth - password-auth From 6e0652b56b2443aa9b60500acb2136b030dc4b8e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:49:48 +0000 Subject: [PATCH 25/76] fix typo Signed-off-by: Mark Bolwell --- tasks/section_5/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index 016585f..64aa75e 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -2,12 +2,12 @@ # 5.1 Configure Logging - name: "SECTION | 5.1.1.x | Configure rsyslog" - when: rhel8cis_syslog == '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: rhel8cis_syslog == 'journald' + when: amazon2cis_syslog == 'journald' ansible.builtin.import_tasks: file: cis_5.1.2.x.yml From 19c2d0bef4fc8cd4b4cc85cb5d935eec578c00c7 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:50:13 +0000 Subject: [PATCH 26/76] updated grub handler Signed-off-by: Mark Bolwell --- handlers/main.yml | 7 ++++++- tasks/section_1/cis_1.5.x.yml | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 9148e24..70fcffb 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -42,7 +42,7 @@ ansible.builtin.systemd: daemon_reload: true -- name: grub2cfg +- name: Rebuild_grub ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" - name: Restart_postfix @@ -68,6 +68,11 @@ when: - not system_is_container +- name: Restart_rsyslog + ansible.builtin.service: + name: rsyslog + state: restarted + - name: Restart_journald ansible.builtin.service: name: systemd-journald diff --git a/tasks/section_1/cis_1.5.x.yml b/tasks/section_1/cis_1.5.x.yml index c3de2be..4cdb265 100644 --- a/tasks/section_1/cis_1.5.x.yml +++ b/tasks/section_1/cis_1.5.x.yml @@ -30,7 +30,7 @@ - selinux - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - notify: grub2cfg + notify: Rebuild_grub ansible.builtin.replace: path: /etc/default/grub regexp: '{{ item }}' From e44118834172c66d71ae6ca2011d3e39aa7e68c8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 17:50:36 +0000 Subject: [PATCH 27/76] updated prelim passwd parse Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index bda6a66..8c30b14 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -5,9 +5,6 @@ - name: Parse etc password ansible.builtin.import_tasks: file: parse_etc_password.yml - when: - - amazon2cis_section5 or - amazon2cis_section6 tags: - always From 05d7dc064d903934ad633c3b7a8baf3db0f25fb8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 22:47:43 +0000 Subject: [PATCH 28/76] fixed Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.2.1.x.yml | 6 +++--- tasks/section_5/cis_5.3.x.yml | 23 ----------------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/tasks/section_5/cis_5.2.1.x.yml b/tasks/section_5/cis_5.2.1.x.yml index c3aa4f4..fd0f063 100644 --- a/tasks/section_5/cis_5.2.1.x.yml +++ b/tasks/section_5/cis_5.2.1.x.yml @@ -110,14 +110,14 @@ when: "'audit_backlog_limit=' not in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Get grubby" - ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit=1\b' + ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit_backlog_limit\b' changed_when: false failed_when: false check_mode: false - register: amazon2cis_5_2_1_3_grubby_audit + register: amazon2cis_5_2_1_3_grubby_backlog - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Update grubby" - when: "amazon2cis_audit_back_log_limit not in amazon2cis_5_2_1_3_grubby_backlog.stdout" + when: (amazon2cis_audit_back_log_limit | string) not in amazon2cis_5_2_1_3_grubby_backlog.stdout ansible.builtin.shell: "grubby --update-kernel ALL --args 'audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}'" - name: "5.2.1.4 | PATCH | Ensure auditd service is enabled" diff --git a/tasks/section_5/cis_5.3.x.yml b/tasks/section_5/cis_5.3.x.yml index 7eb2c19..a8d1f50 100644 --- a/tasks/section_5/cis_5.3.x.yml +++ b/tasks/section_5/cis_5.3.x.yml @@ -71,26 +71,3 @@ loop: - { name: 'aidecheck.service' } - { name: 'aidecheck.timer', state: started } - -- name: "5.3.3 | Ensure cryptographic mechanisms are used to protect the integrity of audit tools" - when: - - amazon2cis_rule_5_3_3 - - not system_is_ec2 - tags: - - level1-server - - level1-workstation - - aide - - file_integrity - - patch - - rule_5.3.3 - ansible.builtin.blockinfile: - path: /etc/aide.conf - marker: "# {mark} Audit tools - CIS benchmark - Ansible-lockdown" - block: | - /sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512 - /sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512 - /sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 - /sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 - /sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 - /sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512 - validate: aide -D --config %s From 7eae1ecd5cf20755ae6a3f278908d03d111f18b0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 22:47:53 +0000 Subject: [PATCH 29/76] updated Signed-off-by: Mark Bolwell --- handlers/main.yml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 70fcffb..a21d0e8 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -90,16 +90,22 @@ owner: root group: root mode: 0600 - notify: restart auditd + notify: Restart_auditd -- name: restart auditd - ansible.builtin.command: /sbin/service auditd restart - check_mode: false - failed_when: false +- 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: 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 ansible.builtin.command: /sbin/grub2-mkconfig -o "{{ amazon2cis_bootloader_file }}" From 14897b1f9e845015a38d9a9f58d771f4f9521c69 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 29 Feb 2024 22:48:05 +0000 Subject: [PATCH 30/76] aligned Signed-off-by: Mark Bolwell --- defaults/main.yml | 64 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 8db5e3c..7b09232 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 @@ -21,6 +17,9 @@ python2_bin: /bin/python2.7 benchmark: AMAZON2-CIS benchmark_version: v3.0.0 +## Ability to skip the os check +os_check: true + # Ability to stop reboot from occuring until convenient # set to true if ok to reboot skip_reboot: false @@ -157,12 +156,12 @@ amazon2cis_rule_1_5_1_7: true amazon2cis_rule_1_5_1_8: true # Command line banner warnings -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: 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 @@ -331,35 +330,36 @@ 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_2_2_1_3: true -amazon2cis_rule_4_2_2_1_4: 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_2_2_2_3: true -amazon2cis_rule_4_2_2_2_4: 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_2_2_2_6: true -amazon2cis_rule_4_2_2_2_7: 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_2_2_3_3: true -amazon2cis_rule_4_2_2_3_4: 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_2_2_4_3: true -amazon2cis_rule_4_2_2_4_4: 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 @@ -431,6 +431,10 @@ amazon2cis_rule_5_2_3_19: true amazon2cis_rule_5_2_3_20: true amazon2cis_rule_5_2_3_21: true +# Aide +amazon2cis_rule_5_3_1: true +amazon2cis_rule_5_3_2: true + # Section 6 rules # Section 6 is System Maintenance (System File Permissions and User and Group Settings) amazon2cis_rule_6_1_1: true @@ -479,6 +483,7 @@ amazon2cis_warning_banner: | # End Banner ## Section 2 variables +amazon2cis_time_synchronization: chrony amazon2cis_time_synchronization_servers: - 0.pool.ntp.org - 1.pool.ntp.org @@ -551,6 +556,7 @@ amazon2cis_tftp_client: false # 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 @@ -609,6 +615,13 @@ amazon2cis_ssh_maxauthtries: 4 ## 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: deny: 5 @@ -623,15 +636,13 @@ amazon2cis_inactivelock: 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: 'minlen' - value: '14' # 14 or more required - key: 'dcredit' value: '-1' # not 0 or greater - key: 'ucredit' @@ -664,6 +675,7 @@ amazon2cis_pass: max_days: 365 min_days: 1 warn_age: 7 + inactive: 30 # should not be 0 or -1 (little details in control) # Session timeout setting file (TMOUT setting can be set in multiple files) # Timeout value is in seconds. (60 seconds * 10 = 600) @@ -673,12 +685,8 @@ amazon2cis_shell_session_timeout: # 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 -amazon2cis_int_gid: 1000 - -# Group to be used for su -# this group needs to exists groups will not be created for remediation this is considered sys admins +amazon2cis_root_umask: '0027' # 0027 or more restrictive -# amazon2cis_sugroup: sugroup ## Section 5 Variables From e51cf1edc291b8257bb3ab45ea5e3957b6ce9b40 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 08:24:51 +0000 Subject: [PATCH 31/76] disruption high added Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index 7b09232..96595f6 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -38,6 +38,8 @@ 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 ########################################## ### Goss is required on the remote host ### ## Refer to vars/auditd.yml for any other settings ## From 3f8ba31a3c9dcb9960fa6b287c8eab757073a635 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 08:25:08 +0000 Subject: [PATCH 32/76] remove skip lint var update Signed-off-by: Mark Bolwell --- tasks/main.yml | 2 -- tasks/prelim.yml | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 9a9fba7..e154316 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -43,8 +43,6 @@ changed_when: false failed_when: sugroup_exists.rc >= 2 register: sugroup_exists - tags: - - skip_ansible_lint - name: Check sugroup if defined exists before continuing ansible.builtin.assert: diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 8c30b14..11e6ed5 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -19,16 +19,12 @@ changed_when: false check_mode: false register: empty_password_accounts - tags: - - skip_ansible_lint - name: "PRELIM | Gather UID 0 accounts other than root" 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 - tags: - - skip_ansible_lint + register: amazon2cis_uid_zero_accounts_except_root - name: "PRELIM | Gather interactive user ID min and max" when: From 9fb1b84fc7cb3064c9a374942a21dd9d0b73127e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 08:28:09 +0000 Subject: [PATCH 33/76] fix notify Signed-off-by: Mark Bolwell --- tasks/section_3/cis_3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index cb5478d..88168a2 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -4,7 +4,7 @@ when: - not amazon2cis_ipv6_required - amazon2cis_rule_3_1_1 - notify: sysctl flush ipv6 route table + notify: Sysctl_flush_ipv6_routes tags: - level2 - manual From 2f4f9fe33a1bbf40a204227499e9e22877582de6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 09:44:13 +0000 Subject: [PATCH 34/76] Updated README Signed-off-by: Mark Bolwell --- README.md | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1aa1f7e..eac4f79 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) - libselinux-python - python3-rpm (package used by py3 to use the rpm pkg) + - jmespath ## Role Variables From 536fb0c9bc2129fcb383900c8a50d2d1e3878928 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 09:44:26 +0000 Subject: [PATCH 35/76] Enabled 2.11 compatible Signed-off-by: Mark Bolwell --- collections/requirements.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/collections/requirements.yml b/collections/requirements.yml index 4a418ef..a3db554 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -1,8 +1,16 @@ --- collections: -- name: community.general -- name: community.crypto + - name: community.general + source: https://github.com/ansible-collections/community.general + type: git + + - 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 -- name: ansible.posix From 7b76f479e26ad2ac0176de7fd6abb60c693288f4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 09:44:51 +0000 Subject: [PATCH 36/76] updated optional controls Signed-off-by: Mark Bolwell --- defaults/main.yml | 17 ++++++++++++++ tasks/prelim.yml | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index 96595f6..7ed44cb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -40,6 +40,7 @@ system_is_ec2: true # Some tasks can have a signifcant impact on a system ensure you agree amazon2cis_disruption_high: true + ########################################## ### Goss is required on the remote host ### ## Refer to vars/auditd.yml for any other settings ## @@ -495,6 +496,10 @@ amazon2cis_time_synchronization_servers: amazon2cis_chrony_server_options: "minpoll 8" amazon2cis_ntp_server_options: "iburst" +## Optional settings not part of CIS but can assist systems +# Disable ipv6 on Chrony if ipv6 not required +amazon2cis_ipv6_chrony_disable: false + # 2.2.x # Service configuration booleans set true to keep service # Service configuration @@ -592,6 +597,7 @@ amazon2cis_nft_tables_autochaincreate: false ## Section 4 Variables # SSH variables + ## Can be VERBOSE or INFO amazon2cis_ssh_loglevel: INFO # amazon2cis_ssh_maxsessions is the max number of sessions @@ -615,6 +621,10 @@ amazon2cis_sshd: 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 @@ -726,6 +736,13 @@ amazon2cis_auditd: admin_space_left_action: email max_log_file_action: keep_logs +# This can be used to configure other keys in auditd.conf +amazon2cis_auditd_extra_conf: {} +# Example: +# amazon2cis_auditd_extra_conf: +# admin_space_left: '10%' + + # AIDE # aide setup via - cron, timer amazon2cis_aide_scan: cron diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 11e6ed5..ca6bae8 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -129,3 +129,63 @@ state: present vars: ansible_python_interpreter: /bin/python + +- 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 + 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: + - 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 | Optional | Configure other keys for auditd.conf + when: + - amazon2cis_auditd_extra_conf.keys() | length > 0 + - amazon2cis_level_2 + tags: + - 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() }}" From 80fe150113b0285858c11ce2a1fc65bdd5437694 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 09:45:02 +0000 Subject: [PATCH 37/76] removed container Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.2.x.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tasks/section_6/cis_6.2.x.yml b/tasks/section_6/cis_6.2.x.yml index 8e3ff94..f51315d 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -385,7 +385,6 @@ permissions: rx state: present loop: "{{ interactive_users_home.stdout_lines }}" - when: not system_is_container - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set other ACL" ansible.posix.acl: @@ -395,7 +394,6 @@ permissions: 0 state: present loop: "{{ interactive_users_home.stdout_lines }}" - when: not system_is_container - name: "6.2.11 | PATCH | Ensure local interactive user dot files access is configured" when: @@ -427,7 +425,6 @@ 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" @@ -436,7 +433,6 @@ when: - amazon2cis_6_2_11_audit.stdout | length > 0 - amazon2cis_dotperm_ansiblemanaged - ansible.builtin.import_tasks: file: warning_facts.yml @@ -444,7 +440,6 @@ when: - amazon2cis_6_2_11_audit.stdout | length > 0 - amazon2cis_dotperm_ansiblemanaged - ansible.builtin.file: path: '{{ item }}' mode: go-w From f3611a36f672d8cbd67041342a6eddbffe10f0ad Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 09:54:12 +0000 Subject: [PATCH 38/76] updated Signed-off-by: Mark Bolwell --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index eac4f79..73cdc20 100644 --- a/README.md +++ b/README.md @@ -105,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 @@ -122,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 @@ -135,7 +133,3 @@ 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 - -This repo originated from work done by [Sam Doran](https://github.com/samdoran/ansible-role-stig) From 562d164a551e009ac0cd8cab177192410c5e4c72 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 11:19:39 +0000 Subject: [PATCH 39/76] improve idempotency Signed-off-by: Mark Bolwell --- tasks/section_2/cis_2.1.x.yml | 23 +++++++++----- tasks/section_4/cis_4.4.2.4.x.yml | 4 +-- tasks/section_5/cis_5.2.1.x.yml | 50 ++++++++++--------------------- 3 files changed, 34 insertions(+), 43 deletions(-) diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index f3975b3..e789af5 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -76,10 +76,19 @@ - rule_2.1.3 - ntp - chrony - ansible.builtin.lineinfile: - path: /etc/sysconfig/chronyd - regexp: OPTIONS=\"(.*)(?!-u chrony)(.*)" - line: OPTIONS="\1\2 -u chrony" - create: true - backrefs: true - mode: '0644' + 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_4/cis_4.4.2.4.x.yml b/tasks/section_4/cis_4.4.2.4.x.yml index 4976162..ca341f5 100644 --- a/tasks/section_4/cis_4.4.2.4.x.yml +++ b/tasks/section_4/cis_4.4.2.4.x.yml @@ -15,8 +15,8 @@ ansible.builtin.lineinfile: backrefs: true path: "/etc/pam.d/{{ item }}" - regexp: (.*pam_unix.so.*)nullok(.*) - line: \1\2 + regexp: (.*pam_unix.so.*)(nullok)(.*) + line: \1\3 loop: - system-auth - password-auth diff --git a/tasks/section_5/cis_5.2.1.x.yml b/tasks/section_5/cis_5.2.1.x.yml index fd0f063..4b07f19 100644 --- a/tasks/section_5/cis_5.2.1.x.yml +++ b/tasks/section_5/cis_5.2.1.x.yml @@ -41,7 +41,7 @@ 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=' /etc/default/grub | sed 's/.$//' + ansible.builtin.shell: grep "GRUB_CMDLINE_LINUX_DEFAULT=" /etc/default/grub | cut -f2 -d'"' changed_when: false failed_when: false check_mode: false @@ -50,27 +50,18 @@ - 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: - path: /etc/default/grub - regexp: 'audit=.' + 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=' - line: '{{ amazon2cis_5_2_1_2_grub_cmdline_linux.stdout }} audit=1"' - - - name: "5.2.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get grubby" - ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit=1\b' - changed_when: false - failed_when: false - check_mode: false - register: amazon2cis_5_2_1_2_grubby_audit - - - name: "5.2.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Update grubby" - when: "'audit=1' not in amazon2cis_5_2_1_2_grubby_audit.stdout" - ansible.builtin.shell: grubby --update-kernel ALL --args 'audit=1' + 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: @@ -89,36 +80,27 @@ 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=' /etc/default/grub | sed 's/.$//' + 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: - path: /etc/default/grub - regexp: 'audit_backlog_limit=\d+' + dest: /etc/default/grub + regexp: 'audit_backlog_limit=([0-9]+)' replace: 'audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}' - when: "'audit_backlog_limit=' in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" + 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=' - line: '{{ amazon2cis_5_2_1_3_grub_cmdline_linux.stdout }} audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}"' - when: "'audit_backlog_limit=' not in amazon2cis_5_2_1_3_grub_cmdline_linux.stdout" - - - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Get grubby" - ansible.builtin.shell: grubby --info=ALL | grep -Po '\baudit_backlog_limit\b' - changed_when: false - failed_when: false - check_mode: false - register: amazon2cis_5_2_1_3_grubby_backlog - - - name: "5.2.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Update grubby" - when: (amazon2cis_audit_back_log_limit | string) not in amazon2cis_5_2_1_3_grubby_backlog.stdout - ansible.builtin.shell: "grubby --update-kernel ALL --args 'audit_backlog_limit={{ amazon2cis_audit_back_log_limit }}'" + 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: From 81c0ad94d7283aeb57a0ab72f6ba4de9aceb4dd2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 1 Mar 2024 11:32:25 +0000 Subject: [PATCH 40/76] removed container checks Signed-off-by: Mark Bolwell --- defaults/main.yml | 1 - handlers/main.yml | 4 ---- tasks/section_2/cis_2.1.x.yml | 3 --- 3 files changed, 8 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 7ed44cb..c188c28 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -35,7 +35,6 @@ 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 diff --git a/handlers/main.yml b/handlers/main.yml index a21d0e8..3006f91 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -56,8 +56,6 @@ value: '1' sysctl_set: true ignore_errors: true # noqa ignore-errors - when: - - not system_is_container - name: Sysctl_flush_ipv6_routes ansible.posix.sysctl: @@ -65,8 +63,6 @@ value: '1' sysctl_set: true ignore_errors: true # noqa ignore-errors - when: - - not system_is_container - name: Restart_rsyslog ansible.builtin.service: diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index e789af5..f029ff5 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -3,7 +3,6 @@ - name: "2.1.1 | PATCH | Ensure time synchronization is in use" when: - amazon2cis_rule_2_1_1 - - not amazon2cis_system_is_container tags: - level1 - automated @@ -47,7 +46,6 @@ when: - amazon2cis_rule_2_1_2 - amazon2cis_time_synchronization == "chrony" - - not amazon2cis_system_is_container tags: - level1 - automated @@ -68,7 +66,6 @@ when: - amazon2cis_rule_2_1_3 - amazon2cis_time_synchronization == "chrony" - - not amazon2cis_system_is_container tags: - level1 - automated From 1796359075bbef49029eab7d8e85c7894ae3edd4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 4 Mar 2024 14:24:23 +0000 Subject: [PATCH 41/76] updated for galaxy_ng reqs Signed-off-by: Mark Bolwell --- meta/main.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meta/main.yml b/meta/main.yml index f295443..42cde67 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,13 +1,13 @@ --- 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 Linux versions: @@ -17,6 +17,8 @@ galaxy_info: - security - cis - hardening + - benchmark + - compliance - amazonlinux - complianceascode collections: From 8308ad99849232dee4913cafbd23547b4948247c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 4 Mar 2024 15:14:04 +0000 Subject: [PATCH 42/76] updated Credits Signed-off-by: Mark Bolwell --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 73cdc20..b89d07e 100644 --- a/README.md +++ b/README.md @@ -133,3 +133,7 @@ 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 and Thanks + +Massive thanks to the fantastic community and all its members. From 51a87f4af863b96c6aa4c821aba9f04548fa8267 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 11 Mar 2024 16:58:24 +0000 Subject: [PATCH 43/76] tidy up Signed-off-by: Mark Bolwell --- defaults/main.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index c188c28..feda43a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -593,7 +593,9 @@ amazon2cis_nft_tables_tablename: cis # Allow creation of chains amazon2cis_nft_tables_autochaincreate: false +## ## Section 4 Variables +## # SSH variables @@ -698,8 +700,9 @@ amazon2cis_futurepwchgdate_autofix: true amazon2cis_root_umask: '0027' # 0027 or more restrictive - +## ## Section 5 Variables +## # Preferred method of logging # Whether rsyslog or journald preferred method for local logging From 52e26f697f9e8cf4cf49fef2e666a9f199bef33f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 12 Mar 2024 15:45:35 +0000 Subject: [PATCH 44/76] fixed 5.2.4.x sections and prelim Signed-off-by: Mark Bolwell --- defaults/main.yml | 12 ++++++++++ tasks/prelim.yml | 40 +++++++++++++++++++++++++++++++++ tasks/section_5/cis_5.2.4.x.yml | 5 ----- tasks/section_5/main.yml | 4 ++-- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index feda43a..1801ad4 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -433,6 +433,18 @@ 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 diff --git a/tasks/prelim.yml b/tasks/prelim.yml index ca6bae8..f5a5d51 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -123,6 +123,46 @@ vars: ansible_python_interpreter: /bin/python +- 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 diff --git a/tasks/section_5/cis_5.2.4.x.yml b/tasks/section_5/cis_5.2.4.x.yml index 2918181..7fbeab6 100644 --- a/tasks/section_5/cis_5.2.4.x.yml +++ b/tasks/section_5/cis_5.2.4.x.yml @@ -38,11 +38,6 @@ - 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 | discover file" - ansible.builtin.shell: grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }' - changed_when: false - register: audit_discovered_logfile - - 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 }}" diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index 64aa75e..e1b7e99 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -32,9 +32,9 @@ ansible.builtin.import_tasks: file: cis_5.2.3.x.yml -- name: "SECTION | 5.2.3.x | Audit file permissions" +- name: "SECTION | 5.2.4.x | Audit file permissions" ansible.builtin.import_tasks: - file: cis_5.2.3.x.yml + file: cis_5.2.4.x.yml - name: "SECTION | 5.3.x | Aide" ansible.builtin.import_tasks: From 0b97ec7e20c82a2d42a2a51d51af98379e648e17 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 12 Mar 2024 15:45:50 +0000 Subject: [PATCH 45/76] fixed vars for arch naming for bin Signed-off-by: Mark Bolwell --- tasks/LE_audit_setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index b7c0b9b..1b5ba8a 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -3,12 +3,12 @@ - name: Pre Audit Setup | Set audit package name block: - name: Pre Audit Setup | Set audit package name | 64bit - when: ansible_machine == "x86_64" + when: ansible_facts.machine == "x86_64" ansible.builtin.set_fact: audit_pkg_arch_name: AMD64 - name: Pre Audit Setup | Set audit package name | ARM64 - when: ansible_machine == "arm64" + when: ansible_facts.machine == "aarch64" ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 From 8dfc933848411121faeefdadab53ef25d0d6b60d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 14 Mar 2024 08:08:55 +0000 Subject: [PATCH 46/76] add levels and audit setting Signed-off-by: Mark Bolwell --- defaults/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 1801ad4..a087a86 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -40,6 +40,10 @@ 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 + ########################################## ### Goss is required on the remote host ### ## Refer to vars/auditd.yml for any other settings ## @@ -747,7 +751,7 @@ amazon2cis_auditd: disk_full_action: halt action_mail_acct: root space_left_action: email - admin_space_left_action: email + admin_space_left_action: single max_log_file_action: keep_logs # This can be used to configure other keys in auditd.conf From 2bd36ed5ef31f64ebd59544dc095cd6162688c3f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 14 Mar 2024 08:09:09 +0000 Subject: [PATCH 47/76] improve controls Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.3.x.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tasks/section_4/cis_4.3.x.yml b/tasks/section_4/cis_4.3.x.yml index ece3fbe..848ccbc 100644 --- a/tasks/section_4/cis_4.3.x.yml +++ b/tasks/section_4/cis_4.3.x.yml @@ -25,10 +25,9 @@ - sudo - NIST800-53R5_AC-6 ansible.builtin.lineinfile: - backrefs: true path: /etc/sudoers - regexp: ^(?i)(#|)\s*Defaults(.*)use_pty(.*) - line: 'Defaults \1 \2 use_pty' + 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" @@ -43,10 +42,9 @@ - NIST800-53R5_AU-3 - NIST800-53R5_AU-12 ansible.builtin.lineinfile: - backrefs: true path: /etc/sudoers - regexp: ^(?i)(#|)\s*Defaults(.*)logfile=.*\b(.*) - line: 'Defaults \1 \2 logfile="{{ amazon2cis_sudolog_location }}"' + 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" @@ -106,8 +104,8 @@ when: amazon2cis_4_3_6_timeout_files.stdout | length == 0 ansible.builtin.lineinfile: path: /etc/sudoers - regexp: 'Defaults timestamp_timeout=' - line: "Defaults timestamp_timeout={{ amazon2cis_sudo_timestamp_timeout }}" + 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" From 74921cc43dacc353ea15728605310a08fc7e113c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 14 Mar 2024 08:09:26 +0000 Subject: [PATCH 48/76] aligned with audit Signed-off-by: Mark Bolwell --- templates/ansible_vars_goss.yml.j2 | 811 +++++++++++++++++------------ 1 file changed, 487 insertions(+), 324 deletions(-) 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 +#### From ae6e4e9b7ca8ea3b0ca2a194957b5214c1ca4b72 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 18 Mar 2024 14:51:18 +0000 Subject: [PATCH 49/76] remove audit entries moved to vars Signed-off-by: Mark Bolwell --- defaults/main.yml | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index a087a86..655e686 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -796,49 +796,3 @@ amazon2cis_sgid_adjust: false # 6.2.12 amazon2cis_dotperm_ansiblemanaged: true - -### 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 }} From 9f5ba29191c08ec7c401149cacf2ae2ea1ce2050 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 18 Mar 2024 14:59:06 +0000 Subject: [PATCH 50/76] file not required Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.4.x.x.yml | 47 --------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 tasks/section_1/cis_1.4.x.x.yml diff --git a/tasks/section_1/cis_1.4.x.x.yml b/tasks/section_1/cis_1.4.x.x.yml deleted file mode 100644 index 3ce6b2a..0000000 --- a/tasks/section_1/cis_1.4.x.x.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -- name: "1.3.1 | PATCH | Ensure AIDE is installed" - block: - - name: "1.3.1 | PATCH | Ensure AIDE is installed | Install" - ansible.builtin.package: - name: aide - state: installed - - - name: "1.3.1 | PATCH | Ensure AIDE is installed | started" - ansible.builtin.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 - when: - - amazon2cis_config_aide - - amazon2cis_rule_1_3_1 - tags: - - level1 - - automated - - patch - - rule_1.3.1 - - aide - -- name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked" - ansible.builtin.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 From 0334eebc6a3c35e7f2a2ebc2dc0582ed6fce20fb Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 18 Mar 2024 15:22:43 +0000 Subject: [PATCH 51/76] updated Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.5.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml index 4553a93..e073e07 100644 --- a/tasks/section_4/cis_4.5.1.x.yml +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -27,7 +27,7 @@ - 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" + 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 From 42e616043d55b96d1e36bc6b59c9e9a0eb01ae63 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 18 Mar 2024 15:30:47 +0000 Subject: [PATCH 52/76] updated 4.5.1.1 Signed-off-by: Mark Bolwell --- tasks/section_4/cis_4.5.1.x.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml index e073e07..827b7af 100644 --- a/tasks/section_4/cis_4.5.1.x.yml +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -36,9 +36,8 @@ when: - amazon2cis_force_user_passwd_change - amazon2cis_4_5_1_1_user_crypt_password.stdout | length > 0 - ansible.builtin.shell: "xargs -n 1 chage -d 0 {{ item }}" - loop: - - amazon2cis_4_5_1_1_user_crypt_password.stdout_lines + 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: From 1dac122b501b904f0c193f0bebb5dcf5ff78be05 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 18 Mar 2024 15:49:36 +0000 Subject: [PATCH 53/76] changed default not to force passwd change Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 655e686..b3e0b79 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -687,7 +687,7 @@ 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: true +amazon2cis_force_user_passwd_change: false # Accounts listed below will not have INACTIVE field set in shadow file # Allow synmic discovery of user accounts minimum and maximun from /etc/login.defs From d30df1d9a7d359e2630ee1a89e9a7b27ba0d6623 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 20 Mar 2024 10:02:22 +0000 Subject: [PATCH 54/76] updated workflow for v3 Signed-off-by: Mark Bolwell --- .../workflows/devel_pipeline_validation.yml | 138 ++++++++++++++++++ .../workflows/main_pipeline_validation.yml | 127 ++++++++++++++++ .github/workflows/update_galaxy.yml | 32 ++-- 3 files changed, 280 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/devel_pipeline_validation.yml create mode 100644 .github/workflows/main_pipeline_validation.yml diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml new file mode 100644 index 0000000..c4d7a08 --- /dev/null +++ b/.github/workflows/devel_pipeline_validation.yml @@ -0,0 +1,138 @@ +--- + + name: Devel pipeline + + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - devel + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + + # 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: ubuntu-latest + + 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: ubuntu-latest + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + + steps: + - name: Clone ${{ github.event.repository.name }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + # 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 + + - name: Add_ssh_key + working-directory: .github/workflows + env: + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" + run: | + mkdir .ssh + chmod 700 .ssh + echo $PRIVATE_KEY > .ssh/github_actions.pem + chmod 600 .ssh/github_actions.pem + + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + 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 }} + + - name: Terraform_Init + id: init + run: terraform 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: Terraform_Validate + id: validate + run: terraform 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: Terraform_Apply + id: apply + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + run: terraform apply -var-file "github_vars.tfvars" -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 for 60 seconds + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + uses: arillso/action.playbook@master + with: + playbook: site.yml + inventory: .github/workflows/github_linux_IaC/hosts.yml + galaxy_file: collections/requirements.yml + private_key: ${{ secrets.SSH_PRV_KEY }} + # verbose: 3 + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + + # Remove test system - User secrets to keep if necessary + + - name: Terraform_Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml new file mode 100644 index 0000000..6fa4c58 --- /dev/null +++ b/.github/workflows/main_pipeline_validation.yml @@ -0,0 +1,127 @@ +--- + + name: Main pipeline + + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - main + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + + # A workflow run is made up of one or more jobs + # that can run sequentially or in parallel + jobs: + + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: ubuntu-latest + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + + steps: + - name: Clone ${{ github.event.repository.name }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + # 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 + + - name: Add_ssh_key + working-directory: .github/workflows + env: + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" + run: | + mkdir .ssh + chmod 700 .ssh + echo $PRIVATE_KEY > .ssh/github_actions.pem + chmod 600 .ssh/github_actions.pem + + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + 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 }} + + - name: Terraform_Init + id: init + run: terraform 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: Terraform_Validate + id: validate + run: terraform 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: Terraform_Apply + id: apply + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + run: terraform apply -var-file "github_vars.tfvars" -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 for 60 seconds + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + uses: arillso/action.playbook@master + with: + playbook: site.yml + inventory: .github/workflows/github_linux_IaC/hosts.yml + galaxy_file: collections/requirements.yml + private_key: ${{ secrets.SSH_PRV_KEY }} + # verbose: 3 + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + + # Remove test system - User secrets to keep if necessary + + - name: Terraform_Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + run: terraform destroy -var-file "github_vars.tfvars" -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 }} From 92a411d7d6e3c9fb56207861c33de0eb45d84881 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 22 Mar 2024 17:38:10 +0000 Subject: [PATCH 55/76] updated maks logic and values Signed-off-by: Mark Bolwell --- defaults/main.yml | 4 +- tasks/section_2/cis_2.2.x.yml | 122 ++++++++++++++++---------------- tasks/section_3/cis_3.4.1.x.yml | 27 +++---- 3 files changed, 77 insertions(+), 76 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index b3e0b79..8fb102f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -539,13 +539,13 @@ 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: true +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: true +amazon2cis_rpc_server: false amazon2cis_rpc_mask: true amazon2cis_rsync_server: false amazon2cis_rsync_mask: false diff --git a/tasks/section_2/cis_2.2.x.yml b/tasks/section_2/cis_2.2.x.yml index 8bea335..2de60ba 100644 --- a/tasks/section_2/cis_2.2.x.yml +++ b/tasks/section_2/cis_2.2.x.yml @@ -3,7 +3,6 @@ - name: "2.2.1 | PATCH | Ensure autofs services are not in use" when: - amazon2cis_rule_2_2_1 - - "'autofs' in ansible_facts.packages" tags: - level1-server - level2-workstation @@ -15,6 +14,7 @@ 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: @@ -28,14 +28,13 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: autofs - enabled: false - state: stopped + 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: - amazon2cis_rule_2_2_2 - - "'avahi' in ansible_facts.packages or 'avahi-autopd' in ansible_facts.packages" tags: - level1-server - level2-workstation @@ -49,6 +48,7 @@ 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 @@ -62,8 +62,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ ('avahi' in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ ('avahi' in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - avahi-daemon.socket @@ -71,7 +71,6 @@ - name: "2.2.3 | PATCH | Ensure dhcp server services are not in use" when: - - "'dhcp-server' in ansible_facts.packages" - amazon2cis_rule_2_2_3 tags: - level1-server @@ -84,6 +83,7 @@ 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: @@ -97,8 +97,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + 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 @@ -106,7 +106,6 @@ - name: "2.2.4 | PATCH | Ensure dns server services are not in use" when: - - "'bind' in ansible_facts.packages" - amazon2cis_rule_2_2_4 tags: - level1-server @@ -119,6 +118,7 @@ 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: @@ -132,13 +132,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: named.service - enabled: false - state: stopped + 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: - - "'dnsmasq' in ansible_facts.packages" - amazon2cis_rule_2_2_5 tags: - level1-server @@ -151,6 +150,7 @@ 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: @@ -164,13 +164,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: dnsmasq.service - enabled: false - state: stopped + 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: - - "'samba' in ansible_facts.packages" - amazon2cis_rule_2_2_6 tags: - level1-server @@ -184,6 +183,7 @@ 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: @@ -197,13 +197,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: smb.service - enabled: false - state: stopped + 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: - - "'ftp' in ansible_facts.packages" - amazon2cis_rule_2_2_7 tags: - level1-server @@ -217,6 +216,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: @@ -230,13 +230,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: vsftpd.service - enabled: false - state: stopped + 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: - - "'dovecot' in ansible_facts.packages or 'cyrus-imapd' in ansible_facts.packages" - amazon2cis_rule_2_2_8 tags: - level1-server @@ -251,6 +250,7 @@ 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: @@ -266,8 +266,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - "dovecot.socket" @@ -276,7 +276,6 @@ - name: "2.2.9 | PATCH | Ensure network file system services are not in use" when: - - "'nfs-utils' in ansible_facts.packages" - amazon2cis_rule_2_2_9 tags: - level1-server @@ -291,6 +290,7 @@ 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: @@ -304,13 +304,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: nfs-server.service - enabled: false - state: stopped + 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: - - "'ypserv' in ansible_facts.packages" - amazon2cis_rule_2_2_10 tags: - level1-server @@ -324,6 +323,7 @@ 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: @@ -336,13 +336,12 @@ - amazon2cis_nis_mask ansible.builtin.systemd: name: ypserv.service - enabled: false - state: stopped + 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: - - "'cups' in ansible_facts.packages" - amazon2cis_rule_2_2_11 tags: - level1-server @@ -354,6 +353,7 @@ 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: @@ -367,8 +367,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - "cups.socket" @@ -376,7 +376,6 @@ - name: "2.2.12 | PATCH | Ensure rpcbind services are not in use" when: - - "'rpcbind' in ansible_facts.packages" - amazon2cis_rule_2_2_12 tags: - level1-server @@ -390,6 +389,7 @@ 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: @@ -403,8 +403,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - rpcbind.service @@ -412,7 +412,6 @@ - name: "2.2.13 | PATCH | Ensure rsync services are not in use" when: - - "'rsync-daemon' in ansible_facts.packages" - amazon2cis_rule_2_2_13 tags: - level1-server @@ -426,6 +425,7 @@ 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: @@ -439,8 +439,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - 'rsyncd.socket' @@ -448,7 +448,6 @@ - name: "2.2.14 | PATCH | Ensure snmp services are not in use" when: - - "'net-snmp' in ansible_facts.packages" - amazon2cis_rule_2_2_14 tags: - level1-server @@ -461,6 +460,7 @@ 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: @@ -474,13 +474,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: snmpd.service - enabled: false - state: stopped + 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: - - "'telnet-server' in ansible_facts.packages" - amazon2cis_rule_2_2_15 tags: - level1-server @@ -494,6 +493,7 @@ 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: @@ -507,13 +507,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: telnet.socket - enabled: false - state: stopped + 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: - - "'tftp-server' in ansible_facts.packages" - amazon2cis_rule_2_2_16 tags: - level1-server @@ -526,6 +525,7 @@ 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: @@ -539,8 +539,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: "{{ item }}" - enabled: false - state: stopped + enabled: "{{ (item in ansible_facts.packages) | ternary(false, omit) }}" + state: "{{ (item in ansible_facts.packages) | ternary('stopped', omit) }}" masked: true loop: - 'tftp.socket' @@ -548,7 +548,6 @@ - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use" when: - - "'squid' in ansible_facts.packages" - amazon2cis_rule_2_2_17 tags: - level1-server @@ -562,10 +561,11 @@ 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: tftp-server + name: squid state: absent - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use | Mask service" @@ -575,8 +575,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: squid.service - enabled: false - state: stopped + 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" @@ -595,18 +595,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 - - "'httpd' in ansible_facts.packages" 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 - - "'nginx' in ansible_facts.packages" ansible.builtin.package: name: nginx state: absent @@ -619,8 +619,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: httpd.service - enabled: false - state: stopped + 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" @@ -631,13 +631,12 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: ngnix.service - enabled: false - state: stopped + 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: - - "'xinetd' in ansible_facts.packages" - amazon2cis_rule_2_2_19 tags: - level1-server @@ -650,6 +649,7 @@ 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: @@ -663,8 +663,8 @@ notify: Systemd_daemon_reload ansible.builtin.systemd: name: xinetd.service - enabled: false - state: stopped + 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" diff --git a/tasks/section_3/cis_3.4.1.x.yml b/tasks/section_3/cis_3.4.1.x.yml index d953905..80ed970 100644 --- a/tasks/section_3/cis_3.4.1.x.yml +++ b/tasks/section_3/cis_3.4.1.x.yml @@ -29,68 +29,69 @@ block: - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | firewalld" when: - - "'iptables-services' in ansible_facts.packages" - amazon2cis_system_firewall == "firewalld" - amazon2cis_iptables == "mask" ansible.builtin.systemd: name: "{{ item }}" masked: true - state: stopped + 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: - - "'nftables' in ansible_facts.packages" - amazon2cis_system_firewall == "firewalld" - amazon2cis_nftables == "mask" ansible.builtin.systemd: name: nftables masked: true - state: stopped + 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: - - "'nftables' in ansible_facts.packages" - amazon2cis_system_firewall == "iptables" - - amazon2cis_iptables == "mask" + - amazon2cis_nftables == "mask" ansible.builtin.systemd: name: nftables masked: true - state: stopped + 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: - - "'firewalld' in ansible_facts.packages" - amazon2cis_system_firewall == "iptables" - amazon2cis_firewalld == "mask" ansible.builtin.systemd: - name: nftables + name: firewalld masked: true - state: stopped + 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: - - "'iptables-services' in ansible_facts.packages" - amazon2cis_system_firewall == "nftables" - amazon2cis_iptables == "mask" ansible.builtin.systemd: name: "{{ item }}" masked: true - state: stopped + 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: - - "'firewalld' in ansible_facts.packages" - 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" From 7bb0c2fa7f440a0adb89093b5a0d319fa6d2784c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 22 Mar 2024 17:39:56 +0000 Subject: [PATCH 56/76] lint updates Signed-off-by: Mark Bolwell --- defaults/main.yml | 1 - tasks/section_4/cis_4.5.1.x.yml | 3 --- 2 files changed, 4 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 8fb102f..d9f095a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -760,7 +760,6 @@ amazon2cis_auditd_extra_conf: {} # amazon2cis_auditd_extra_conf: # admin_space_left: '10%' - # AIDE # aide setup via - cron, timer amazon2cis_aide_scan: cron diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml index 827b7af..5179207 100644 --- a/tasks/section_4/cis_4.5.1.x.yml +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -125,9 +125,6 @@ failed_when: amazon2cis_users_inactive_def.rc not in [ 0, 1 ] register: amazon2cis_users_inactive_def - - ansible.builtin.debug: - msg: "{{ amazon2cis_users_inactive_def.stdout }}" - - name: "4.5.1.4 | PATCH | Ensure inactive password lock is 30 days or less | change default" when: - amazon2cis_users_inactive_def is defined From 9fcb5583610600c042720882edcc79a708b6f51d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 22 Mar 2024 17:47:43 +0000 Subject: [PATCH 57/76] updates Signed-off-by: Mark Bolwell --- .pre-commit-config.yaml | 5 +---- collections/requirements.yml | 1 - tasks/parse_etc_password.yml | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 873f275..88d4f0d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,17 +33,14 @@ repos: rev: v1.4.0 hooks: - id: detect-secrets - args: [ '--baseline', '.config/.secrets.baseline' ] - exclude: .config/.gitleaks-report.json - repo: https://github.com/gitleaks/gitleaks rev: v8.18.2 hooks: - id: gitleaks - args: ['--baseline-path', '.config/.gitleaks-report.json'] - repo: https://github.com/ansible-community/ansible-lint - rev: v24.2.0 + rev: v24.2.1 hooks: - id: ansible-lint name: Ansible-lint diff --git a/collections/requirements.yml b/collections/requirements.yml index a3db554..996e799 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -13,4 +13,3 @@ collections: - name: ansible.posix source: https://github.com/ansible-collections/ansible.posix type: git - diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 5adc3b3..547b721 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -16,7 +16,7 @@ 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 From 6bf65cd8b3dc852b11cb33cb3a1619c9287ab493 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 15 Apr 2024 10:01:51 +0100 Subject: [PATCH 58/76] updated audit Signed-off-by: Mark Bolwell --- defaults/main.yml | 39 ++++++++++++++++++++++++-------- tasks/LE_audit_setup.yml | 12 +++++----- tasks/post_remediation_audit.yml | 8 +++---- tasks/pre_remediation_audit.yml | 38 ++++++++++++++++--------------- vars/audit.yml | 32 ++++++++------------------ 5 files changed, 68 insertions(+), 61 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index d9f095a..ad7346b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -44,37 +44,56 @@ amazon2cis_disruption_high: true amazon2cis_level_1: true amazon2cis_level_2: true -########################################## +########################################### ### Goss is required on the remote host ### -## Refer to vars/auditd.yml for any other settings ## +### 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 +## 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 +### 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 +# 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/get_url other e.g. if you wish to run from already downloaded conf +# options are git/copy/archive/get_url other e.g. if you wish to run from already downloaded conf audit_content: git -# 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 +# 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' -### End Goss enablements #### +### Goss Settings ## +####### END ######## # These variables correspond with the CIS rule IDs or paragraph numbers defined in # the CIS benchmark documents. diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 1b5ba8a..7ef94b4 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -3,18 +3,16 @@ - name: Pre Audit Setup | Set audit package name block: - name: Pre Audit Setup | Set audit package name | 64bit - when: ansible_facts.machine == "x86_64" ansible.builtin.set_fact: audit_pkg_arch_name: AMD64 + when: ansible_facts.machine == "x86_64" - name: Pre Audit Setup | Set audit package name | ARM64 - when: ansible_facts.machine == "aarch64" ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 + when: ansible_facts.machine == "arm64" - name: Pre Audit Setup | Download audit binary - when: - - get_audit_binary_method == 'download' ansible.builtin.get_url: url: "{{ audit_bin_url }}{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" @@ -22,13 +20,15 @@ group: root checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" mode: '0555' + when: + - get_audit_binary_method == 'download' - name: Pre Audit Setup | Copy audit binary - when: - - get_audit_binary_method == 'copy' ansible.builtin.copy: src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" mode: '0555' owner: root group: root + when: + - get_audit_binary_method == 'copy' diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index eb01bc7..b3111c8 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,11 +1,11 @@ --- - name: Post Audit | Run post_remediation {{ benchmark }} audit - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" + 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_out_dir }}" + AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" AUDIT_FILE: goss.yml - name: Post Audit | ensure audit files readable by users @@ -22,7 +22,7 @@ - audit_format == "json" block: - name: capture data {{ post_audit_outfile }} - ansible.builtin.shell: cat {{ post_audit_outfile }} + ansible.builtin.shell: "cat {{ post_audit_outfile }}" register: post_audit changed_when: false @@ -37,7 +37,7 @@ - audit_format == "documentation" block: - name: Post Audit | capture data {{ post_audit_outfile }} - ansible.builtin.shell: tail -2 {{ post_audit_outfile }} + ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" register: post_audit changed_when: false diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 5f2560e..d0137e8 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -33,23 +33,25 @@ when: - audit_content == 'copy' ansible.builtin.copy: - src: "{{ audit_local_copy }}" + src: "{{ audit_conf_source }}" dest: "{{ audit_conf_dest }}" mode: preserve - name: Pre Audit Setup | Unarchive audit content files on server when: - - audit_content == 'archived' + - audit_content == 'archive' ansible.builtin.unarchive: - src: "{{ audit_conf_copy }}" - dest: "{{ audit_conf_dir }}" + src: "{{ audit_conf_source }}" + dest: "{{ audit_conf_dest }}" - name: Pre Audit Setup | Get audit content from url when: - audit_content == 'get_url' - ansible.builtin.get_url: - url: "{{ audit_files_url }}" - dest: "{{ audit_conf_dir }}" + 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 Setup | Check Goss is available when: @@ -61,35 +63,36 @@ register: goss_available - name: Pre Audit Setup | If audit ensure goss is available + when: + - not goss_available.stat.exists ansible.builtin.assert: - that: goss_available.stat.exists msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - name: Pre Audit Setup | Copy ansible default vars values to test audit - when: - - run_audit tags: - goss_template - run_audit + when: + - run_audit ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" mode: '0600' - name: Pre Audit | Run pre_remediation {{ benchmark }} audit - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" + 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_out_dir }}" + 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: capture data {{ pre_audit_outfile }} - ansible.builtin.shell: cat {{ pre_audit_outfile }} + - name: Pre Audit | Capture data {{ pre_audit_outfile }} + ansible.builtin.shell: "cat {{ pre_audit_outfile }}" register: pre_audit changed_when: false @@ -103,8 +106,8 @@ when: - audit_format == "documentation" block: - - name: Pre Audit | capture data {{ pre_audit_outfile }} | documentation format - ansible.builtin.shell: 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 @@ -115,5 +118,4 @@ - name: Audit_Only | Run Audit Only when: - audit_only - ansible.builtin.import_tasks: - file: audit_only.yml + ansible.builtin.import_tasks: audit_only.yml diff --git a/vars/audit.yml b/vars/audit.yml index 250a600..bb50f6d 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -2,40 +2,25 @@ #### Audit Configuration Settings #### -# This variable specifies the timeout (in ms) for audit commands that -# take a very long time: if a command takes too long to complete, -# it will be forcefully terminated after the specified duration. +# 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-" -## 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 - ### 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 }}" -# archive or copy: -audit_conf_copy: "some path to copy from" - -# get_url: -audit_files_url: "some url maybe s3?" - ## Goss configuration information -# Where the goss configs and outputs are stored -audit_out_dir: '/opt' -# Where the goss audit configuration will be stored -audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" +# 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_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" -post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" +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 @@ -49,6 +34,7 @@ audit_format: json audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.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 }} + 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 }} From ab0dfb7e99f7af5b86c3cd54fd99319675a51d2d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 6 Jun 2024 16:17:07 +0100 Subject: [PATCH 59/76] pipelineupdates Signed-off-by: Mark Bolwell --- .../workflows/devel_pipeline_validation.yml | 77 +++++++++-------- .../workflows/main_pipeline_validation.yml | 82 +++++++++++-------- 2 files changed, 89 insertions(+), 70 deletions(-) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index c4d7a08..3fef732 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -1,6 +1,6 @@ --- - name: Devel pipeline + name: Devel pipeline (tofu) on: # yamllint disable-line rule:truthy pull_request_target: @@ -13,13 +13,21 @@ - '**.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: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/first-interaction@main @@ -32,21 +40,22 @@ # This workflow contains a single job that tests the playbook playbook-test: # The type of runner that the job will run on - runs-on: ubuntu-latest + 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" defaults: run: shell: bash working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows steps: - - name: Clone ${{ github.event.repository.name }} + + - name: Git clone the lockdown repository to test uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} # Pull in terraform code for linux servers - name: Clone GitHub IaC plan @@ -54,17 +63,21 @@ with: repository: ansible-lockdown/github_linux_IaC path: .github/workflows/github_linux_IaC + ref: self_hosted - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem + # 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: arn:aws:iam::817651307868:role/Ansible_Lockdown_Environment + role-session-name: GitHub_to_AWS_via_FederatedOIDC + aws-region: ${{ env.AWS_REGION }} + + - name: Clone ${{ github.event.repository.name }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - name: DEBUG - Show IaC files if: env.ENABLE_DEBUG == 'true' @@ -78,30 +91,28 @@ OSVAR: ${{ vars.OSVAR }} benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Terraform_Init + - name: Tofu init id: init - run: terraform 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: Terraform_Validate + - name: Tofu validate id: validate - run: terraform 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: Terraform_Apply + - name: Tofu apply id: apply env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false ## Debug Section - name: DEBUG - Show Ansible hostfile @@ -110,29 +121,23 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep for 60 seconds + - name: Sleep period of time run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/github_linux_IaC/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" + ANSIBLE_VERSION: "2.16.6" + run: | + /opt/ansible_"${ANSIBLE_VERSION}"_venv/bin/ansible-playbook -i .github/workflows/hosts.yml --private-key ~/.ssh/le_runner site.yml # Remove test system - User secrets to keep if necessary - - name: Terraform_Destroy + - name: Tofu Destroy if: always() && env.ENABLE_DEBUG == 'false' env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index 6fa4c58..4febe88 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -14,28 +14,46 @@ - '**.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: ubuntu-latest + 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" defaults: run: shell: bash working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows steps: - - name: Clone ${{ github.event.repository.name }} + + - name: Git clone the lockdown repository to test uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} # Pull in terraform code for linux servers - name: Clone GitHub IaC plan @@ -43,17 +61,21 @@ with: repository: ansible-lockdown/github_linux_IaC path: .github/workflows/github_linux_IaC + ref: self_hosted - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem + # 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: arn:aws:iam::817651307868:role/Ansible_Lockdown_Environment + role-session-name: GitHub_to_AWS_via_FederatedOIDC + aws-region: ${{ env.AWS_REGION }} + + - name: Clone ${{ github.event.repository.name }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - name: DEBUG - Show IaC files if: env.ENABLE_DEBUG == 'true' @@ -67,30 +89,28 @@ OSVAR: ${{ vars.OSVAR }} benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Terraform_Init + - name: Tofu init id: init - run: terraform 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: Terraform_Validate + - name: Tofu validate id: validate - run: terraform 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: Terraform_Apply + - name: Tofu apply id: apply env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false ## Debug Section - name: DEBUG - Show Ansible hostfile @@ -99,29 +119,23 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep for 60 seconds + - name: Sleep period of time run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/github_linux_IaC/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" + ANSIBLE_VERSION: "2.16.6" + run: | + /opt/ansible_"${ANSIBLE_VERSION}"_venv/bin/ansible-playbook -i .github/workflows/hosts.yml --private-key ~/.ssh/le_runner site.yml # Remove test system - User secrets to keep if necessary - - name: Terraform_Destroy + - name: Tofu Destroy if: always() && env.ENABLE_DEBUG == 'false' env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false From c415011694b987cfc092b89bed243be4cff18c7f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 6 Jun 2024 16:17:28 +0100 Subject: [PATCH 60/76] typo tidyup Signed-off-by: Mark Bolwell --- README.md | 2 +- tasks/section_6/cis_6.1.x.yml | 10 +++++----- tasks/section_6/cis_6.2.x.yml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b89d07e..a68bec9 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Further details can be seen in the [Changelog](./ChangeLog.md) - 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 diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index a4b1eca..fc052eb 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -201,17 +201,17 @@ 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: rhel_08_6_1_11_perms_results + register: amazon2cis_6_1_11_perms_results - name: "6.1.11 | PATCH | Adjust world-writable files if they exist (Configurable)" when: - - rhel_08_6_1_11_perms_results.stdout_lines is defined + - 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: "{{ rhel_08_6_1_11_perms_results.stdout_lines }}" + 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 @@ -220,14 +220,14 @@ - name: "6.1.11 | AUDIT | Ensure world writable files and directories are secured | Warning" when: - - rhel_08_6_1_11_perms_results.stdout_lines is defined + - 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: - - rhel_08_6_1_11_perms_results.stdout_lines is defined + - amazon2cis_6_1_11_perms_results.stdout_lines is defined - not amazon2cis_no_world_write_adjust 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 f51315d..0fd6486 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -350,7 +350,7 @@ - name: "6.2.10 | AUDIT | Ensure local interactive user home directories exist | get perms stat" ansible.builtin.stat: path: "{{ item }}" - register: rhel_09_6_2_10_home_dir_perms + register: amazon2cis_6_2_10_home_dir_perms loop: "{{ interactive_users_home.stdout_lines }}" - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | set perms if needed" @@ -358,7 +358,7 @@ path: "{{ item.stat.path }}" state: directory mode: g-w,o-rwx - loop: "{{ rhel_09_6_2_10_home_dir_perms.results }}" + loop: "{{ amazon2cis_6_2_10_home_dir_perms.results }}" loop_control: label: "{{ item }}" From 623319b924547f5c03118e50db56cd9f22aeac84 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 6 Jun 2024 16:17:56 +0100 Subject: [PATCH 61/76] audit moved to prelim Signed-off-by: Mark Bolwell --- tasks/main.yml | 19 ------------------- tasks/prelim.yml | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index e154316..3aecdf3 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -68,25 +68,6 @@ - prelim_tasks - always -- 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 - - name: Gather the package facts ansible.builtin.package_facts: manager: auto diff --git a/tasks/prelim.yml b/tasks/prelim.yml index f5a5d51..12974f1 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -1,4 +1,22 @@ --- +- 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 From 49d4df72db9b206cd74ed3959717928fefc8460b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 6 Jun 2024 16:18:10 +0100 Subject: [PATCH 62/76] control tidy up Signed-off-by: Mark Bolwell --- defaults/main.yml | 10 +++++++++- handlers/main.yml | 2 +- tasks/section_4/cis_4.5.1.x.yml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index ad7346b..6defeb2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -44,6 +44,10 @@ amazon2cis_disruption_high: true 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 ### @@ -709,7 +713,7 @@ amazon2cis_encryption: sha512 amazon2cis_force_user_passwd_change: false # Accounts listed below will not have INACTIVE field set in shadow file -# Allow synmic discovery of user accounts minimum and maximun from /etc/login.defs +# 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 @@ -719,6 +723,10 @@ 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: 365 min_days: 1 diff --git a/handlers/main.yml b/handlers/main.yml index 3006f91..e19637d 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -38,7 +38,7 @@ name: /var/log/audit state: remounted -- name: systemd daemon reload +- name: Systemd_daemon_reload ansible.builtin.systemd: daemon_reload: true diff --git a/tasks/section_4/cis_4.5.1.x.yml b/tasks/section_4/cis_4.5.1.x.yml index 5179207..9c28584 100644 --- a/tasks/section_4/cis_4.5.1.x.yml +++ b/tasks/section_4/cis_4.5.1.x.yml @@ -76,7 +76,7 @@ loop: "{{ amazon2cis_4_5_1_2_max_days.stdout_lines }}" when: - amazon2cis_disruption_high - - (item != 'root') or (not amazon2cis_uses_root) + - item not in amazon2cis_user_skip_list - name: "4.5.1.3 | PATCH | Ensure password expiration warning days is 7 or more" when: From 92e8581e4db8faae51114d55615f7215ef6d9a41 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 7 Jun 2024 11:17:40 +0100 Subject: [PATCH 63/76] updated file Signed-off-by: Mark Bolwell --- .../workflows/devel_pipeline_validation.yml | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 3fef732..3850ccc 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -56,6 +56,8 @@ - name: Git clone the lockdown repository to test uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} # Pull in terraform code for linux servers - name: Clone GitHub IaC plan @@ -70,26 +72,25 @@ - name: configure aws credentials uses: aws-actions/configure-aws-credentials@main with: - role-to-assume: arn:aws:iam::817651307868:role/Ansible_Lockdown_Environment - role-session-name: GitHub_to_AWS_via_FederatedOIDC + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} aws-region: ${{ env.AWS_REGION }} - - name: Clone ${{ github.event.repository.name }} - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - - 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 @@ -112,6 +113,8 @@ 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 @@ -121,7 +124,7 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep period of time + - name: Sleep to allow system to come up run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook @@ -131,7 +134,7 @@ ANSIBLE_DEPRECATION_WARNINGS: "false" ANSIBLE_VERSION: "2.16.6" run: | - /opt/ansible_"${ANSIBLE_VERSION}"_venv/bin/ansible-playbook -i .github/workflows/hosts.yml --private-key ~/.ssh/le_runner site.yml + /opt/ansible_"${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 @@ -140,4 +143,6 @@ 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 From 6bf964101dcc8f0d0f93b6507121160b8558c672 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 7 Jun 2024 11:43:09 +0100 Subject: [PATCH 64/76] updated with correct handler name Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.4.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 29040b3..cec5ac4 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -45,7 +45,7 @@ - rule_1.4.3 - coredump - NIST800-53R5_CM-6b - notify: systemd daemon reload + notify: Systemd_daemon_reload ansible.builtin.lineinfile: dest: /etc/systemd/coredump.conf regexp: ^ProcessSizeMax @@ -62,7 +62,7 @@ - patch - rule_1.4.4 - coredump - notify: systemd daemon reload + notify: Systemd_daemon_reload ansible.builtin.lineinfile: dest: /etc/systemd/coredump.conf regexp: ^Storage From d8002e865bc436f6fde6f5cfc703ca8c948f57be Mon Sep 17 00:00:00 2001 From: uk-bolly Date: Fri, 7 Jun 2024 16:52:20 +0100 Subject: [PATCH 65/76] V3 updates - workflow updates (#3) * Add logic to IAC branch Signed-off-by: Mark Bolwell * Add logic to IAC branch Signed-off-by: Mark Bolwell * Add logic to IAC branch Signed-off-by: Mark Bolwell * Add logic to IAC branch Signed-off-by: Mark Bolwell * Tidy up of naming Signed-off-by: Mark Bolwell * Workflow alignment Signed-off-by: Mark Bolwell * Updated Signed-off-by: Mark Bolwell * ability to change ansible version Signed-off-by: Mark Bolwell * tidy up Signed-off-by: Mark Bolwell * ability to change ansible version Signed-off-by: Mark Bolwell --------- Signed-off-by: Mark Bolwell --- .../workflows/devel_pipeline_validation.yml | 21 ++++++++--- .../workflows/main_pipeline_validation.yml | 37 +++++++++++++------ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 3850ccc..e02fe1f 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -1,6 +1,6 @@ --- - name: Devel pipeline (tofu) + name: Devel pipeline on: # yamllint disable-line rule:truthy pull_request_target: @@ -45,7 +45,8 @@ ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} # Imported as a variable by terraform TF_VAR_repository: ${{ github.event.repository.name }} - AWS_REGION : "us-east-1" + AWS_REGION: "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} defaults: run: shell: bash @@ -59,13 +60,24 @@ 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: self_hosted + 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 @@ -132,9 +144,8 @@ env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" - ANSIBLE_VERSION: "2.16.6" run: | - /opt/ansible_"${ANSIBLE_VERSION}"_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + /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 diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index 4febe88..4a5adc9 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -44,6 +44,7 @@ # 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 @@ -54,6 +55,18 @@ - 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 @@ -61,33 +74,32 @@ with: repository: ansible-lockdown/github_linux_IaC path: .github/workflows/github_linux_IaC - ref: self_hosted + 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: arn:aws:iam::817651307868:role/Ansible_Lockdown_Environment - role-session-name: GitHub_to_AWS_via_FederatedOIDC + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} aws-region: ${{ env.AWS_REGION }} - - name: Clone ${{ github.event.repository.name }} - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - - 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 @@ -110,6 +122,8 @@ 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 @@ -119,7 +133,7 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep period of time + - name: Sleep to allow system to come up run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook @@ -127,9 +141,8 @@ env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" - ANSIBLE_VERSION: "2.16.6" run: | - /opt/ansible_"${ANSIBLE_VERSION}"_venv/bin/ansible-playbook -i .github/workflows/hosts.yml --private-key ~/.ssh/le_runner site.yml + /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 @@ -138,4 +151,6 @@ 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 From 38f53b87003b8013354b7efe337235baff410495 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 10 Jun 2024 15:47:07 +0100 Subject: [PATCH 66/76] added for legacy pipeline while new pipeline implemented Signed-off-by: Mark Bolwell --- .github/workflows/OS.tfvars | 9 +++++++++ .github/workflows/github_vars.tfvars | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 .github/workflows/OS.tfvars create mode 100644 .github/workflows/github_vars.tfvars diff --git a/.github/workflows/OS.tfvars b/.github/workflows/OS.tfvars new file mode 100644 index 0000000..0285721 --- /dev/null +++ b/.github/workflows/OS.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" +instance_tags = { + Name = "Amazon2-CIS" + Environment = "lockdown_github_repo_workflow" +} diff --git a/.github/workflows/github_vars.tfvars b/.github/workflows/github_vars.tfvars new file mode 100644 index 0000000..3ea5253 --- /dev/null +++ b/.github/workflows/github_vars.tfvars @@ -0,0 +1,13 @@ +// github_actions variables +// Resourced in github_networks.tf +// Declared in variables.tf +// + +namespace = "github_actions" +environment = "lockdown_github_repo_workflow" + +// Matching pair name found in AWS for keypairs PEM key +ami_key_pair_name = "github_actions" +main_vpc_cidr = "172.22.0.0/24" +public_subnets = "172.22.0.128/26" +private_subnets = "172.22.0.192/26" From 273aa22aabf7c0018600e0af14016c2bf259cc2d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 10 Jun 2024 15:54:23 +0100 Subject: [PATCH 67/76] added for legacy pipeline while new pipeline implemented Signed-off-by: Mark Bolwell --- .github/workflows/AMAZON2.tfvars | 9 ++ .github/workflows/github_network.tf | 53 +++++++++ .github/workflows/linux_benchmark_testing.yml | 111 ++++++++++++++++++ .github/workflows/main.tf | 81 +++++++++++++ .github/workflows/terraform.tfvars | 6 + .github/workflows/variables.tfvars | 76 ++++++++++++ 6 files changed, 336 insertions(+) create mode 100644 .github/workflows/AMAZON2.tfvars create mode 100644 .github/workflows/github_network.tf create mode 100644 .github/workflows/linux_benchmark_testing.yml create mode 100644 .github/workflows/main.tf create mode 100644 .github/workflows/terraform.tfvars create mode 100644 .github/workflows/variables.tfvars 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/github_network.tf b/.github/workflows/github_network.tf new file mode 100644 index 0000000..5001dc2 --- /dev/null +++ b/.github/workflows/github_network.tf @@ -0,0 +1,53 @@ +resource "aws_vpc" "Main" { + cidr_block = var.main_vpc_cidr + instance_tenancy = "default" + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-VPC" + } +} + +resource "aws_internet_gateway" "IGW" { + vpc_id = aws_vpc.Main.id + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-IGW" + } +} + +resource "aws_subnet" "publicsubnets" { + vpc_id = aws_vpc.Main.id + cidr_block = var.public_subnets + availability_zone = var.availability_zone + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-pubsub" + } +} + +resource "aws_subnet" "Main" { + vpc_id = aws_vpc.Main.id + availability_zone = var.availability_zone + cidr_block = var.private_subnets + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-prvsub" + } +} + +resource "aws_route_table" "PublicRT" { + vpc_id = aws_vpc.Main.id + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.IGW.id + } + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-publicRT" + } +} + +resource "aws_route_table_association" "rt_associate_public" { + subnet_id = aws_subnet.Main.id + route_table_id = aws_route_table.PublicRT.id +} diff --git a/.github/workflows/linux_benchmark_testing.yml b/.github/workflows/linux_benchmark_testing.yml new file mode 100644 index 0000000..9cc43d8 --- /dev/null +++ b/.github/workflows/linux_benchmark_testing.yml @@ -0,0 +1,111 @@ +i# This is a basic workflow to help you get started with Actions + +name: linux_benchmark_pipeline + +# Controls when the action will run. +# Triggers the workflow on push or pull request +# events but only for the devel branch +on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - devel + - main + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + +# 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: ubuntu-latest + + 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://discord.io/ansible-lockdown) as well. + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + env: + ENABLE_DEBUG: false + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, + # so your job can access it + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Add_ssh_key + working-directory: .github/workflows + env: + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" + run: | + mkdir .ssh + chmod 700 .ssh + echo $PRIVATE_KEY > .ssh/github_actions.pem + chmod 600 .ssh/github_actions.pem + + ### Build out the server + - name: Terraform_Init + working-directory: .github/workflows + run: terraform init + + - name: Terraform_Validate + working-directory: .github/workflows + run: terraform validate + + - name: Terraform_Apply + working-directory: .github/workflows + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: terraform apply -var-file "OS.tfvars" -var-file "github_vars.tfvars" --auto-approve -input=false + + ## Debug Section + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + working-directory: .github/workflows + run: cat hosts.yml + + # Aws deployments taking a while to come up insert sleep or playbook fails + + - name: Sleep for 60 seconds + run: sleep 60s + shell: bash + + # Run the ansible playbook + - name: Run_Ansible_Playbook + uses: arillso/action.playbook@master + with: + playbook: site.yml + inventory: .github/workflows/hosts.yml + galaxy_file: collections/requirements.yml + private_key: ${{ secrets.SSH_PRV_KEY }} + # verbose: 3 + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + + # Remove test system - User secrets to keep if necessary + + - name: Terraform_Destroy + working-directory: .github/workflows + if: always() && env.ENABLE_DEBUG == 'false' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: terraform destroy -var-file "github_vars.tfvars" -var-file "OS.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main.tf b/.github/workflows/main.tf new file mode 100644 index 0000000..c6a84a8 --- /dev/null +++ b/.github/workflows/main.tf @@ -0,0 +1,81 @@ +provider "aws" { + profile = "" + region = var.aws_region +} + +// Create a security group with access to port 22 and port 80 open to serve HTTP traffic + + +resource "random_id" "server" { + keepers = { + # Generate a new id each time we switch to a new AMI id + ami_id = "${var.ami_id}" + } + + byte_length = 8 +} + +resource "aws_security_group" "github_actions" { + name = "${var.namespace}-${random_id.server.hex}-SG" + vpc_id = aws_vpc.Main.id + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + tags = { + Environment = "${var.environment}" + Name = "${var.namespace}-SG" + } +} + +// instance setup + +resource "aws_instance" "testing_vm" { + ami = var.ami_id + availability_zone = var.availability_zone + associate_public_ip_address = true + key_name = var.ami_key_pair_name # This is the key as known in the ec2 key_pairs + instance_type = var.instance_type + tags = var.instance_tags + vpc_security_group_ids = [aws_security_group.github_actions.id] + subnet_id = aws_subnet.Main.id + root_block_device { + delete_on_termination = true + } +} + +// generate inventory file +resource "local_file" "inventory" { + filename = "./hosts.yml" + directory_permission = "0755" + file_permission = "0644" + content = < Date: Mon, 10 Jun 2024 15:56:16 +0100 Subject: [PATCH 68/76] added for legacy pipeline while new pipeline implemented Signed-off-by: Mark Bolwell --- .github/workflows/{variables.tfvars => variables.tf} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{variables.tfvars => variables.tf} (97%) diff --git a/.github/workflows/variables.tfvars b/.github/workflows/variables.tf similarity index 97% rename from .github/workflows/variables.tfvars rename to .github/workflows/variables.tf index e03b49c..16bc9f6 100644 --- a/.github/workflows/variables.tfvars +++ b/.github/workflows/variables.tf @@ -1,4 +1,4 @@ -i// Taken from the OSname.tfvars +// Taken from the OSname.tfvars variable "aws_region" { description = "AWS region" From 420e62bb91eef1382d3a349e865a7bd8c35f6a31 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 11 Jun 2024 13:29:25 +0100 Subject: [PATCH 69/76] added vars to skip Signed-off-by: Mark Bolwell --- .github/workflows/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.tf b/.github/workflows/main.tf index c6a84a8..28a945f 100644 --- a/.github/workflows/main.tf +++ b/.github/workflows/main.tf @@ -77,5 +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 } From 3e24f070cb72d181291bb8ed739620d2ffc893ae Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 11 Jun 2024 13:30:59 +0100 Subject: [PATCH 70/76] lint Signed-off-by: Mark Bolwell --- .github/workflows/github_vars.tfvars | 2 +- .github/workflows/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/main.tf b/.github/workflows/main.tf index 28a945f..f39036f 100644 --- a/.github/workflows/main.tf +++ b/.github/workflows/main.tf @@ -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 + amazon2cis_rule_4_5_2_4: false # Don't set root password EOF } From 566c2f0ce9a4e656ff7c6346fc6b501ea3bdaf9f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 11 Jun 2024 16:22:01 +0100 Subject: [PATCH 71/76] Tidy up and lint Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.1.1.x.yml | 32 ++++++++++++++++---------------- tasks/section_1/cis_1.3.x.yml | 4 ++-- tasks/section_1/cis_1.4.x.yml | 4 ++-- tasks/section_4/cis_4.5.2.x.yml | 2 +- tasks/section_5/cis_5.2.3.x.yml | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index b67a6e7..b2021a4 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -14,7 +14,7 @@ block: - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install cramfs(\\s|$)" line: "install cramfs /bin/true" create: true @@ -22,7 +22,7 @@ - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist cramfs(\\s|$)" line: "blacklist cramfs" create: true @@ -47,7 +47,7 @@ block: - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install freevxfs(\\s|$)" line: "install freevxfs /bin/true" create: true @@ -55,7 +55,7 @@ - name: "1.1.1.2 | PATCH | Ensure freevxfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist freevxfs(\\s|$)" line: "blacklist freevxfs" create: true @@ -80,7 +80,7 @@ block: - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install hfs(\\s|$)" line: "install hfs /bin/true" create: true @@ -88,7 +88,7 @@ - name: "1.1.1.3 | PATCH | Ensure hfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist hfs(\\s|$)" line: "blacklist hfs" create: true @@ -113,7 +113,7 @@ block: - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install hfsplus(\\s|$)" line: "install hfsplus /bin/true" create: true @@ -121,7 +121,7 @@ - name: "1.1.1.4 | PATCH | Ensure hfsplus kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist hfsplus(\\s|$)" line: "blacklist hfsplus" create: true @@ -146,7 +146,7 @@ block: - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install jffs2(\\s|$)" line: "install jffs2 /bin/true" create: true @@ -154,7 +154,7 @@ - name: "1.1.1.5 | PATCH | Ensure jffs2 kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist jffs2(\\s|$)" line: "blacklist jffs2" create: true @@ -179,7 +179,7 @@ block: - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install squashfs(\\s|$)" line: "install squashfs /bin/true" create: true @@ -187,7 +187,7 @@ - name: "1.1.1.6 | PATCH | Ensure squashfs kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist squashfs(\\s|$)" line: "blacklist squashfs" create: true @@ -212,7 +212,7 @@ block: - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install udf(\\s|$)" line: "install udf /bin/true" create: true @@ -220,7 +220,7 @@ - name: "1.1.1.7 | PATCH | Ensure udf kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist udf(\\s|$)" line: "blacklist udf" create: true @@ -245,7 +245,7 @@ block: - name: "1.1.1.8 | PATCH | Ensure usb-storage kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/CIS.conf + path: /etc/modprobe.d/CIS.conf regexp: "^(#)?install usb-storage(\\s|$)" line: "install usb-storage /bin/true" create: true @@ -253,7 +253,7 @@ - name: "1.1.1.8 | PATCH | Ensure usb-storage kernel module is not available | Edit modprobe config" ansible.builtin.lineinfile: - dest: /etc/modprobe.d/blacklist.conf + path: /etc/modprobe.d/blacklist.conf regexp: "^(#)?blacklist usb-storage(\\s|$)" line: "blacklist usb-storage" create: true diff --git a/tasks/section_1/cis_1.3.x.yml b/tasks/section_1/cis_1.3.x.yml index 8f94a3e..4d8f5fb 100644 --- a/tasks/section_1/cis_1.3.x.yml +++ b/tasks/section_1/cis_1.3.x.yml @@ -12,12 +12,12 @@ block: - name: "1.3.1 | PATCH | Ensure authentication required for single user mode | Emergency service" ansible.builtin.lineinfile: - dest: /usr/lib/systemd/system/emergency.service + 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.1 | PATCH | Ensure authentication required for single user mode | Rescue service" ansible.builtin.lineinfile: - dest: /usr/lib/systemd/system/rescue.service + 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 cec5ac4..f72b247 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -47,7 +47,7 @@ - NIST800-53R5_CM-6b notify: Systemd_daemon_reload ansible.builtin.lineinfile: - dest: /etc/systemd/coredump.conf + path: /etc/systemd/coredump.conf regexp: ^ProcessSizeMax line: ProcessSizeMax=0 create: true @@ -64,7 +64,7 @@ - coredump notify: Systemd_daemon_reload ansible.builtin.lineinfile: - dest: /etc/systemd/coredump.conf + path: /etc/systemd/coredump.conf regexp: ^Storage line: Storage=none create: true diff --git a/tasks/section_4/cis_4.5.2.x.yml b/tasks/section_4/cis_4.5.2.x.yml index fce795f..c1c47e6 100644 --- a/tasks/section_4/cis_4.5.2.x.yml +++ b/tasks/section_4/cis_4.5.2.x.yml @@ -68,7 +68,7 @@ loop_control: label: "{{ item.id }}" - - name: "4.5.2.3 | PATCH | | Ensure system accounts are secured | Lock accounts" + - name: "4.5.2.3 | PATCH | Ensure system accounts are secured | Lock accounts" when: - item.id != "root" - item.id != "sync" diff --git a/tasks/section_5/cis_5.2.3.x.yml b/tasks/section_5/cis_5.2.3.x.yml index ff14ad1..ef6c914 100644 --- a/tasks/section_5/cis_5.2.3.x.yml +++ b/tasks/section_5/cis_5.2.3.x.yml @@ -77,14 +77,14 @@ - auditd - rule_5.2.3.6 block: - - name: "5.2.3.6 | PATCH | Ensure use of privileged commands is collected" + - 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 | PATCH | Ensure use of privileged commands is collected" + - 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 From e6ce41c156c66994340e50c0b1f741bef417e8a1 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 11 Jun 2024 16:32:37 +0100 Subject: [PATCH 72/76] fix title of 5.2.3.6 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.2.3.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/cis_5.2.3.x.yml b/tasks/section_5/cis_5.2.3.x.yml index ef6c914..3039afb 100644 --- a/tasks/section_5/cis_5.2.3.x.yml +++ b/tasks/section_5/cis_5.2.3.x.yml @@ -65,7 +65,7 @@ ansible.builtin.set_fact: update_audit_template: true -- name: "5.2.3.6 | PATCH | Ensure use of privileged commands is collected" +- name: "5.2.3.6 | AUDIT | Ensure use of privileged commands is collected" when: - amazon2cis_rule_5_2_3_6 tags: From aaf5d7025e7219fa15e110baf1e97db1b62be4a1 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 18 Jun 2024 15:16:07 +0100 Subject: [PATCH 73/76] updated variables Signed-off-by: Mark Bolwell --- .github/workflows/variables.tf | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/variables.tf b/.github/workflows/variables.tf index 16bc9f6..6458a43 100644 --- a/.github/workflows/variables.tf +++ b/.github/workflows/variables.tf @@ -18,13 +18,9 @@ variable "instance_type" { type = string } -variable "instance_tags" { - description = "Tags to set for instances" - type = map(string) -} - variable "ami_key_pair_name" { description = "Name of key pair in AWS thats used" + default = "Lockdown_enterprise_workflow-sshkey" type = string } @@ -35,7 +31,7 @@ variable "ami_os" { variable "ami_id" { description = "AMI ID reference" - type = string + type = string } variable "ami_username" { @@ -50,27 +46,34 @@ variable "ami_user_home" { variable "namespace" { description = "Name used across all tags" + default = "Lockdown_enterprise_workflow" type = string } variable "environment" { description = "Env Name used across all tags" type = string + default = "Ansible_Lockdown_Environment" } -// taken from github_vars.tfvars & +variable "benchmark_os" { + description = "The benchmark OS thats being tested" + type = string +} -variable "main_vpc_cidr" { - description = "Private cidr block to be used for vpc" +variable "benchmark_type" { + description = "The benchmark OS thats being tested" type = string } -variable "public_subnets" { - description = "public subnet cidr block" +variable "vpc_secgrp_id" { + description = "The id of the vpc security group for the runner" type = string + sensitive = true } -variable "private_subnets" { - description = "private subnet cidr block" +variable "privsubnet_id" { + description = "The id of the private subnet for the runner vpc" type = string + sensitive = true } From 02c2c8000aecce468b732d62a2797bf0d977eeb0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 18 Jun 2024 15:38:59 +0100 Subject: [PATCH 74/76] tidy up workflows Signed-off-by: Mark Bolwell --- .github/workflows/AMAZON2.tfvars | 3 - .github/workflows/OS.tfvars | 9 -- .github/workflows/github_network.tf | 53 --------- .github/workflows/github_vars.tfvars | 13 -- .github/workflows/linux_benchmark_testing.yml | 111 ------------------ .github/workflows/terraform.tfvars | 6 - 6 files changed, 195 deletions(-) delete mode 100644 .github/workflows/OS.tfvars delete mode 100644 .github/workflows/github_network.tf delete mode 100644 .github/workflows/github_vars.tfvars delete mode 100644 .github/workflows/linux_benchmark_testing.yml delete mode 100644 .github/workflows/terraform.tfvars diff --git a/.github/workflows/AMAZON2.tfvars b/.github/workflows/AMAZON2.tfvars index fc635fb..3c51061 100644 --- a/.github/workflows/AMAZON2.tfvars +++ b/.github/workflows/AMAZON2.tfvars @@ -4,6 +4,3 @@ 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/OS.tfvars b/.github/workflows/OS.tfvars deleted file mode 100644 index 0285721..0000000 --- a/.github/workflows/OS.tfvars +++ /dev/null @@ -1,9 +0,0 @@ -# Amazon Linux 2 -ami_id = "ami-03e0b06f01d45a4eb" -ami_os = "AmazonLinux2" -ami_username = "ec2-user" -ami_user_home = "/home/ec2-user" -instance_tags = { - Name = "Amazon2-CIS" - Environment = "lockdown_github_repo_workflow" -} diff --git a/.github/workflows/github_network.tf b/.github/workflows/github_network.tf deleted file mode 100644 index 5001dc2..0000000 --- a/.github/workflows/github_network.tf +++ /dev/null @@ -1,53 +0,0 @@ -resource "aws_vpc" "Main" { - cidr_block = var.main_vpc_cidr - instance_tenancy = "default" - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-VPC" - } -} - -resource "aws_internet_gateway" "IGW" { - vpc_id = aws_vpc.Main.id - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-IGW" - } -} - -resource "aws_subnet" "publicsubnets" { - vpc_id = aws_vpc.Main.id - cidr_block = var.public_subnets - availability_zone = var.availability_zone - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-pubsub" - } -} - -resource "aws_subnet" "Main" { - vpc_id = aws_vpc.Main.id - availability_zone = var.availability_zone - cidr_block = var.private_subnets - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-prvsub" - } -} - -resource "aws_route_table" "PublicRT" { - vpc_id = aws_vpc.Main.id - route { - cidr_block = "0.0.0.0/0" - gateway_id = aws_internet_gateway.IGW.id - } - tags = { - Environment = "${var.environment}" - Name = "${var.namespace}-publicRT" - } -} - -resource "aws_route_table_association" "rt_associate_public" { - subnet_id = aws_subnet.Main.id - route_table_id = aws_route_table.PublicRT.id -} diff --git a/.github/workflows/github_vars.tfvars b/.github/workflows/github_vars.tfvars deleted file mode 100644 index b8d1f5e..0000000 --- a/.github/workflows/github_vars.tfvars +++ /dev/null @@ -1,13 +0,0 @@ -// github_actions variables -// Resourced in github_networks.tf -// Declared in variables.tf -// - -namespace = "github_actions" -environment = "lockdown_github_repo_workflow" - -// Matching pair name found in AWS for keypairs PEM key -ami_key_pair_name = "github_actions" -main_vpc_cidr = "172.22.0.0/24" -public_subnets = "172.22.0.128/26" -private_subnets = "172.22.0.192/26" diff --git a/.github/workflows/linux_benchmark_testing.yml b/.github/workflows/linux_benchmark_testing.yml deleted file mode 100644 index 9cc43d8..0000000 --- a/.github/workflows/linux_benchmark_testing.yml +++ /dev/null @@ -1,111 +0,0 @@ -i# This is a basic workflow to help you get started with Actions - -name: linux_benchmark_pipeline - -# Controls when the action will run. -# Triggers the workflow on push or pull request -# events but only for the devel branch -on: # yamllint disable-line rule:truthy - pull_request_target: - types: [opened, reopened, synchronize] - branches: - - devel - - main - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' - -# 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: ubuntu-latest - - 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://discord.io/ansible-lockdown) as well. - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - env: - ENABLE_DEBUG: false - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, - # so your job can access it - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem - - ### Build out the server - - name: Terraform_Init - working-directory: .github/workflows - run: terraform init - - - name: Terraform_Validate - working-directory: .github/workflows - run: terraform validate - - - name: Terraform_Apply - working-directory: .github/workflows - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - run: terraform apply -var-file "OS.tfvars" -var-file "github_vars.tfvars" --auto-approve -input=false - - ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - working-directory: .github/workflows - run: cat hosts.yml - - # Aws deployments taking a while to come up insert sleep or playbook fails - - - name: Sleep for 60 seconds - run: sleep 60s - shell: bash - - # Run the ansible playbook - - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - - # Remove test system - User secrets to keep if necessary - - - name: Terraform_Destroy - working-directory: .github/workflows - if: always() && env.ENABLE_DEBUG == 'false' - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "OS.tfvars" --auto-approve -input=false diff --git a/.github/workflows/terraform.tfvars b/.github/workflows/terraform.tfvars deleted file mode 100644 index 3111378..0000000 --- a/.github/workflows/terraform.tfvars +++ /dev/null @@ -1,6 +0,0 @@ -// vars should be loaded by OSname.tfvars -availability_zone = "us-east-1b" -aws_region = "us-east-1" -ami_os = var.ami_os -ami_username = var.ami_username -instance_tags = var.instance_tags From aed789e6ee4234fffa46d6c1cbbf8e07d6a6e5a4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 10 Jul 2024 08:38:29 +0100 Subject: [PATCH 75/76] updated thanks to @papapenguin on discord community Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.1.2.3.x.yml | 2 +- templates/etc/systemd/system/tmp.mount.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml index 39f88be..5365584 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -25,7 +25,7 @@ - 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 + 1.1.2.3.3 | PATCH | Ensure nosuid option set on /home partition" when: - item.mount == "/home" - amazon2cis_tmp_svc diff --git a/templates/etc/systemd/system/tmp.mount.j2 b/templates/etc/systemd/system/tmp.mount.j2 index 1200d47..f7c4b23 100644 --- a/templates/etc/systemd/system/tmp.mount.j2 +++ b/templates/etc/systemd/system/tmp.mount.j2 @@ -15,7 +15,7 @@ After=swap.target What=tmpfs Where=/tmp Type=tmpfs -Options=mode=1777,strictatime,{% if amazon2cis_rule_1_1_3 %}noexec,{% endif %}{% if amazon2cis_rule_1_1_4 %}nodev,{% endif %}{% if amazon2cis_rule_1_1_5 %}nosuid{% endif %} +Options=mode=1777,strictatime,{% 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 %} # Make 'systemctl enable tmp.mount' work: [Install] From 12c0312920fe62ca9c434f7be11883a4b76286db Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 10 Jul 2024 08:42:30 +0100 Subject: [PATCH 76/76] updated audit summary wording Signed-off-by: Mark Bolwell --- vars/audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/audit.yml b/vars/audit.yml index bb50f6d..d41ef37 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -34,7 +34,7 @@ audit_format: json audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" audit_results: | - The audit results are: {{ pre_audit_summary }} + The {% if not audit_only %}pre remediation{% endif %} 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 }}