From b471a034a4e57254cdf14d9d8c5afdedbc751578 Mon Sep 17 00:00:00 2001 From: irl Date: Sat, 8 Nov 2025 20:56:53 +0000 Subject: [PATCH 1/4] feat(podman_nginx): configure firewalld --- .../tasks/{check_subid.yml => check_users.yml} | 0 roles/podman_nginx/defaults/main.yml | 1 + roles/podman_nginx/tasks/main.yml | 11 +++++++++++ 3 files changed, 12 insertions(+) rename roles/podman_host/tasks/{check_subid.yml => check_users.yml} (100%) diff --git a/roles/podman_host/tasks/check_subid.yml b/roles/podman_host/tasks/check_users.yml similarity index 100% rename from roles/podman_host/tasks/check_subid.yml rename to roles/podman_host/tasks/check_users.yml diff --git a/roles/podman_nginx/defaults/main.yml b/roles/podman_nginx/defaults/main.yml index d32720b..66a3f98 100644 --- a/roles/podman_nginx/defaults/main.yml +++ b/roles/podman_nginx/defaults/main.yml @@ -8,3 +8,4 @@ podman_nginx_podman_rootless_user: nginx # podman_nginx_systemd_service_target: podman_nginx_systemd_service_requires: [] podman_nginx_additional_volumes: [] +podman_nginx_firewalld_zone: public \ No newline at end of file diff --git a/roles/podman_nginx/tasks/main.yml b/roles/podman_nginx/tasks/main.yml index b92cf32..7308833 100644 --- a/roles/podman_nginx/tasks/main.yml +++ b/roles/podman_nginx/tasks/main.yml @@ -1,4 +1,15 @@ --- +- name: Podman Nginx | PATCH | Open firewall for http and https services + ansible.posix.firewalld: + zone: "{{ podman_nginx_firewalld_zone }}" + service: "{{ item }}" + permanent: true + immediate: true + state: enabled + with_items: + - http + - https + - name: Podman Nginx | PATCH | Create service configuration directories ansible.builtin.file: path: "/home/{{ podman_nginx_podman_rootless_user }}/{{ item }}" From 7792cac0c7df2d72785bac8752ae4d236545ff3b Mon Sep 17 00:00:00 2001 From: irl Date: Sat, 8 Nov 2025 20:57:43 +0000 Subject: [PATCH 2/4] feat(podman_host): do not create local users and assume a user exists For SR2's usage, these users will exist because they have been created in FreeIPA along with their subids. --- roles/podman_host/tasks/check_users.yml | 51 +++++++++---------------- roles/podman_host/tasks/main.yml | 32 +++++++--------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/roles/podman_host/tasks/check_users.yml b/roles/podman_host/tasks/check_users.yml index 7ce0ddd..4520729 100644 --- a/roles/podman_host/tasks/check_users.yml +++ b/roles/podman_host/tasks/check_users.yml @@ -1,41 +1,26 @@ --- - name: Podman Host | AUDIT | Gather rootless user facts - ansible.builtin.user: - name: "{{ _podman_host_rootless_user }}" + ansible.builtin.getent: + database: passwd + key: "{{ _podman_host_rootless_user }}" register: _podman_host_rootless_user_facts -- name: Podman Host | AUDIT | Resolve name of user's primary group - ansible.builtin.getent: - database: group - key: "{{ _podman_host_rootless_user_facts.group }}" - register: _podman_host_rootless_user_group +- debug: + msg: "{{ _podman_host_rootless_user_facts }}" -- name: Podman Host | AUDIT | Check if user is in subuid file - ansible.builtin.lineinfile: - path: /etc/subuid - regexp: '^{{ _podman_host_rootless_user }}:.*$' - state: absent - register: _podman_host_uid_line_found - check_mode: true - failed_when: false - changed_when: false - -- name: Podman Host | AUDIT | Check if group is in subgid file - ansible.builtin.lineinfile: - path: /etc/subgid - regexp: '^{{ _podman_host_rootless_user_group.ansible_facts.getent_group | first }}:.*$' - state: absent - register: _podman_host_gid_line_found - check_mode: true - failed_when: false - changed_when: false - -- name: Podman Host | AUDIT | Assert that user is in subuid file exactly once +- name: Podman Host | AUDIT | Ensure the rootless user exists ansible.builtin.assert: that: - - _podman_host_uid_line_found.found == 1 + - _podman_host_rootless_user in _podman_host_rootless_user_facts.ansible_facts.getent_passwd.keys() + fail_msg: "User '{{ _podman_host_rootless_user }}' does not exist on this host." + +- name: Podman Host | AUDIT | Ensure the rootless user has subuids defined + ansible.builtin.command: + cmd: "getsubids {{ _podman_host_rootless_user }}" + changed_when: false + +- name: Podman Host | AUDIT | Ensure the rootless user has subgids defined + ansible.builtin.command: + cmd: "getsubids -g {{ _podman_host_rootless_user }}" + changed_when: false -- name: Podman Host | AUDIT | Assert that group is in subgid file exactly once - ansible.builtin.assert: - that: - - _podman_host_gid_line_found.found == 1 diff --git a/roles/podman_host/tasks/main.yml b/roles/podman_host/tasks/main.yml index 2e9b601..26c6cdc 100644 --- a/roles/podman_host/tasks/main.yml +++ b/roles/podman_host/tasks/main.yml @@ -1,13 +1,22 @@ --- -- name: Podman Host | PRELIM | Ensure the rootless users are defined and are not root +- name: Podman Host | AUDIT | Ensure the rootless users are defined and are not root ansible.builtin.assert: that: - podman_host_rootless_users | length > 0 - '"root" not in podman_host_rootless_users' -- name: Podman Host | AUDIT | Ensure that subuid and subgid are defined for the users +- name: Podman Host | PATCH | Install Podman + ansible.builtin.dnf: + name: + - podman + - container-selinux + - shadow-utils-subid # for getsubids + state: latest + become: true + +- name: Podman Host | AUDIT | Ensure that users exist and have subids configured ansible.builtin.include_tasks: - file: check_subid.yml + file: check_users.yml vars: _podman_host_rootless_user: "{{ item }}" with_items: "{{ podman_host_rootless_users }}" @@ -21,17 +30,10 @@ reload: true become: true -- name: Podman Host | PATCH | Create users for rootless podman - ansible.builtin.user: - name: "{{ item }}" - become: true - with_items: "{{ podman_host_rootless_users }}" - -- name: Podman Host | PATCH | Set XDG_RUNTIME_DIR in .profile for rootless users +- name: Podman Host | PATCH | Set XDG_RUNTIME_DIR in .bash_profile for rootless users ansible.builtin.lineinfile: path: "/home/{{ item }}/.bash_profile" line: "export XDG_RUNTIME_DIR=/run/user/$(id -u)" - create: false become: true become_user: "{{ item }}" with_items: "{{ podman_host_rootless_users }}" @@ -46,14 +48,6 @@ become: true with_items: "{{ podman_host_rootless_users }}" -- name: Podman Host | PATCH | Install Podman - ansible.builtin.dnf: - name: - - podman - - container-selinux - state: latest - become: true - - name: Podman Host | PATCH | Create users quadlets directory ansible.builtin.file: path: "/home/{{ item }}/.config/containers/systemd" From ec972f9470bdf1c865f143a74a267fab4ea55d3d Mon Sep 17 00:00:00 2001 From: irl Date: Sat, 8 Nov 2025 20:59:45 +0000 Subject: [PATCH 3/4] feat(baseline): enable with-subid feature for sssd --- roles/baseline/tasks/ipaclient.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/roles/baseline/tasks/ipaclient.yml b/roles/baseline/tasks/ipaclient.yml index 2150f90..e301e96 100644 --- a/roles/baseline/tasks/ipaclient.yml +++ b/roles/baseline/tasks/ipaclient.yml @@ -11,11 +11,12 @@ changed_when: false - name: FreeIPA Client | PATCH | Apply authselect profile with sssd, sudo, and mkhomedir if not set - ansible.builtin.command: authselect select sssd with-sudo with-mkhomedir --force + ansible.builtin.command: authselect select sssd with-sudo with-mkhomedir with-subid --force when: > 'Profile ID: sssd' not in _baseline_freeipa_authselect_status.stdout or 'with-sudo' not in _baseline_freeipa_authselect_status.stdout or - 'with-mkhomedir' not in _baseline_freeipa_authselect_status.stdout + 'with-mkhomedir' not in _baseline_freeipa_authselect_status.stdout or + 'with-subid' not in _baseline_freeipa_authselect_status.stdout - name: FreeIPA Client | PATCH | Enable oddjobd.service (for with-mkhomedir feature) ansible.builtin.systemd_service: From 78aad663e6a0559baa998148a55eca902d48c410 Mon Sep 17 00:00:00 2001 From: irl Date: Sat, 8 Nov 2025 21:00:18 +0000 Subject: [PATCH 4/4] feat(baseline): move freeipa related lockdown overrides to role from playbook --- playbooks/core_services.yml | 20 -------------------- roles/baseline/tasks/lockdown.yml | 8 ++++++++ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/playbooks/core_services.yml b/playbooks/core_services.yml index 60fa95c..351cb30 100644 --- a/playbooks/core_services.yml +++ b/playbooks/core_services.yml @@ -16,18 +16,8 @@ - python3-acme - python3-zipp - python3-pyOpenSSL - # 2.1 Configure Server Services - # These services are required by FreeIPA. - rhel9cis_autofs_services: true # TODO: can we mask it? This is required by FreeIPA but we don't use it. rhel9cis_dns_server: true rhel9cis_httpd_server: true - # 2.2 Configure Client Services - # These services are required by FreeIPA. - rhel9cis_openldap_clients_required: true - # 5.3.2 Configure authselect - # ipaservers are part of Linux Identity Management. Joining your host to an IdM - # domain automatically configures SSSD authentication on your host. - rhel9cis_allow_authselect_updates: false # TODO: Restricted umask breaks FreeIPA roles rhel9cis_rule_5_4_2_6: false rhel9cis_rule_5_4_3_3: false @@ -41,16 +31,6 @@ hosts: - keycloak become: true - vars: - rhel9cis_autofs_services: true # TODO: can we mask it? This is required by FreeIPA but we don't use it. - # 2.2 Configure Client Services - # These services are required by FreeIPA. - rhel9cis_openldap_clients_required: true - # 5.3.2 Configure authselect - # ipaservers are part of Linux Identity Management. Joining your host to an IdM - # domain automatically configures SSSD authentication on your host. - rhel9cis_allow_authselect_updates: false - podman_host_rootless_users: ["identity"] roles: - role: sr2c.core.baseline tags: bootstrap diff --git a/roles/baseline/tasks/lockdown.yml b/roles/baseline/tasks/lockdown.yml index 9a11528..5ddbc22 100644 --- a/roles/baseline/tasks/lockdown.yml +++ b/roles/baseline/tasks/lockdown.yml @@ -22,4 +22,12 @@ rhel9cis_syslog: rsyslog rhel9cis_time_synchronization_servers: "{{ baseline_ntp_servers }}" rhel9cis_warning_banner: "{{ baseline_warning_banner }}" + rhel9cis_autofs_services: true # TODO: can we mask it? This is required by FreeIPA but we don't use it. + # 2.2 Configure Client Services + # These services are required by FreeIPA. + rhel9cis_openldap_clients_required: true + # 5.3.2 Configure authselect + # ipaservers are part of Linux Identity Management. Joining your host to an IdM + # domain automatically configures SSSD authentication on your host. + rhel9cis_allow_authselect_updates: false when: (ansible_distribution == "Rocky") and (ansible_distribution_major_version == "9")