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 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/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/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 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: 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 }}"