diff --git a/ansible/.gitignore b/ansible/.gitignore index a7197ff4c..1cabb8ad8 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -58,6 +58,10 @@ roles/* !roles/squid/** !roles/tuned/ !roles/tuned/** +!roles/sssd/ +!roles/sssd/** +!roles/sshd/ +!roles/sshd/** !roles/compute_init/ !roles/compute_init/** !roles/k3s/ diff --git a/ansible/bootstrap.yml b/ansible/bootstrap.yml index e2497d9c6..88d9274b3 100644 --- a/ansible/bootstrap.yml +++ b/ansible/bootstrap.yml @@ -110,6 +110,15 @@ policy: "{{ selinux_policy }}" register: sestatus +- hosts: sshd + tags: sshd + gather_facts: no + become: yes + tasks: + - name: Configure sshd + import_role: + name: sshd + - hosts: dnf_repos become: yes tasks: diff --git a/ansible/fatimage.yml b/ansible/fatimage.yml index 9a8828a35..e5de38edf 100644 --- a/ansible/fatimage.yml +++ b/ansible/fatimage.yml @@ -54,6 +54,11 @@ name: freeipa tasks_from: client-install.yml when: "'freeipa_client' in group_names" + - name: Install sssd + import_role: + name: sssd + tasks_from: install.yml + when: "'sssd' in group_names" # - import_playbook: filesystems.yml: - name: Install nfs packages diff --git a/ansible/iam.yml b/ansible/iam.yml index 0286b9df3..857b8f840 100644 --- a/ansible/iam.yml +++ b/ansible/iam.yml @@ -40,3 +40,12 @@ import_role: name: freeipa tasks_from: users.yml + +- hosts: sssd + become: yes + gather_facts: no + tags: sssd + tasks: + - name: Configure sssd + import_role: + name: sssd diff --git a/ansible/roles/basic_users/README.md b/ansible/roles/basic_users/README.md index 4b75100ca..65fdd2c4c 100644 --- a/ansible/roles/basic_users/README.md +++ b/ansible/roles/basic_users/README.md @@ -24,6 +24,7 @@ Role Variables - An additional key `sudo` may optionally be specified giving a string (possibly multiline) defining sudo rules to be templated. - Any other keys may present for other purposes (i.e. not used by this role). - `basic_users_groups`: Optional, default empty list. A list of mappings defining information for each group. Mapping keys/values are passed through as parameters to [ansible.builtin.group](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/group_module.html) and default values are as given there. +- `basic_users_override_sssd`: Optional bool, default false. Whether to disable `sssd` when ensuring users/groups exist with this role. Permits creating local users/groups even if they clash with users provided via sssd (e.g. from LDAP). Ignored if host is not in group `sssd` as well. Note with this option active `sssd` will be stopped and restarted each time this role is run. Dependencies ------------ diff --git a/ansible/roles/basic_users/defaults/main.yml b/ansible/roles/basic_users/defaults/main.yml index 9f34bdf4c..e6c6eafaa 100644 --- a/ansible/roles/basic_users/defaults/main.yml +++ b/ansible/roles/basic_users/defaults/main.yml @@ -7,3 +7,4 @@ basic_users_userdefaults: shell: "{{'/sbin/nologin' if 'control' in group_names else omit }}" basic_users_users: [] basic_users_groups: [] +basic_users_override_sssd: false diff --git a/ansible/roles/basic_users/tasks/main.yml b/ansible/roles/basic_users/tasks/main.yml index c27d024b4..c6733fb89 100644 --- a/ansible/roles/basic_users/tasks/main.yml +++ b/ansible/roles/basic_users/tasks/main.yml @@ -7,7 +7,16 @@ label: "{{ item.name }}" when: - "item.state | default('present') == 'absent'" - + +- name: Stop sssd if required + systemd: + name: sssd + state: stopped + register: _stop_sssd + when: + - "'sssd' in group_names" + - basic_users_override_sssd | bool + - name: Create groups ansible.builtin.group: "{{ item }}" loop: "{{ basic_users_groups }}" @@ -19,6 +28,12 @@ label: "{{ item.name }} [{{ item.state | default('present') }}]" register: basic_users_info +- name: Restart sssd if required + systemd: + name: sssd + state: started + when: _stop_sssd is changed + - name: Write supplied public key as authorized for SSH access authorized_key: user: "{{ item.name }}" diff --git a/ansible/roles/sshd/README.md b/ansible/roles/sshd/README.md new file mode 100644 index 000000000..0fac1d189 --- /dev/null +++ b/ansible/roles/sshd/README.md @@ -0,0 +1,9 @@ +# sshd + +Configure sshd. + +## Role variables + +- `sshd_password_authentication`: Optional bool. Whether to enable password login. Default `false`. +- `sshd_conf_src`: Optional string. Path to sshd configuration template. Default is in-role template. +- `sshd_conf_dest`: Optional string. Path to destination for sshd configuration file. Default is `/etc/ssh/sshd_config.d/10-ansible.conf` which overides `50-{cloud-init,redhat}` files, if present. diff --git a/ansible/roles/sshd/defaults/main.yml b/ansible/roles/sshd/defaults/main.yml new file mode 100644 index 000000000..672305799 --- /dev/null +++ b/ansible/roles/sshd/defaults/main.yml @@ -0,0 +1,3 @@ +sshd_password_authentication: false +sshd_conf_src: sshd.conf.j2 +sshd_conf_dest: /etc/ssh/sshd_config.d/10-ansible.conf diff --git a/ansible/roles/sshd/handlers/main.yml b/ansible/roles/sshd/handlers/main.yml new file mode 100644 index 000000000..e11aa7801 --- /dev/null +++ b/ansible/roles/sshd/handlers/main.yml @@ -0,0 +1,4 @@ +- name: Restart sshd + systemd: + name: sshd + state: restarted diff --git a/ansible/roles/sshd/tasks/configure.yml b/ansible/roles/sshd/tasks/configure.yml new file mode 100644 index 000000000..8aafb5c19 --- /dev/null +++ b/ansible/roles/sshd/tasks/configure.yml @@ -0,0 +1,15 @@ +- name: Template sshd configuration + # NB: If parameters are defined multiple times the first value wins; + # The default /etc/ssh/sshd_config has + # Include /etc/ssh/sshd_config.d/*.conf + # early on, which is generally held to be the correct approach, so adding + # values to the end of that file won't work + template: + src: "{{ sshd_conf_src }}" + dest: "{{ sshd_conf_dest }}" + owner: root + group: root + mode: u=rw,go= + validate: sshd -t -f %s + notify: + - Restart sshd diff --git a/ansible/roles/sshd/tasks/main.yml b/ansible/roles/sshd/tasks/main.yml new file mode 100644 index 000000000..84f493457 --- /dev/null +++ b/ansible/roles/sshd/tasks/main.yml @@ -0,0 +1 @@ +- import_tasks: configure.yml diff --git a/ansible/roles/sshd/templates/sshd.conf.j2 b/ansible/roles/sshd/templates/sshd.conf.j2 new file mode 100644 index 000000000..2746f0642 --- /dev/null +++ b/ansible/roles/sshd/templates/sshd.conf.j2 @@ -0,0 +1,2 @@ +# {{ ansible_managed }} +PasswordAuthentication {{ 'yes' if sshd_password_authentication | bool else 'no' }} diff --git a/ansible/roles/sssd/README.md b/ansible/roles/sssd/README.md new file mode 100644 index 000000000..da4e63f31 --- /dev/null +++ b/ansible/roles/sssd/README.md @@ -0,0 +1,18 @@ +# sssd + +Install and configure [sssd](https://sssd.io/docs/introduction.html). + + +## Role variables + +The only required configuration is to create a [sssd.conf](https://www.mankier.com/5/sssd.conf) template at the location specified by `sssd_conf_src`. + +- `sssd_packages`: Optional list. Packages to install. +- `sssd_ldap_install`: Optional bool. Whether to install packages enabling SSSD to authenticate against LDAP. Default `false`. +- `sssd_ldap_packages`: Optional list. Packages to install when using `sssd_ldap_install`. +- `sssd_enable_mkhomedir`: Optional bool. Whether to enable creation of home directories on login. Default `false`. +- `sssd_mkhomedir_packages`: Optional list. Packages to install when using `sssd_enable_mkhomedir`. +- `sssd_conf_src`: Optional string. Path to `sssd.conf` template. Default (which must be created) is `{{ appliances_environment_root }}/files/sssd.conf.j2`. +- `sssd_conf_dest`: Optional string. Path to destination for `sssd.conf`. Default `/etc/sssd/sssd.conf`. +- `sssd_started`: Optional bool. Whether `sssd` service should be started. +- `sssd_enabled`: Optional bool. Whether `sssd` service should be enabled. diff --git a/ansible/roles/sssd/defaults/main.yml b/ansible/roles/sssd/defaults/main.yml new file mode 100644 index 000000000..5bc58c990 --- /dev/null +++ b/ansible/roles/sssd/defaults/main.yml @@ -0,0 +1,12 @@ +sssd_packages: + - sssd-common +sssd_install_ldap: false +sssd_ldap_packages: + - sssd-ldap +sssd_enable_mkhomedir: false +sssd_mkhomedir_packages: + - oddjob-mkhomedir +sssd_conf_src: "{{ appliances_environment_root }}/files/sssd.conf.j2" +sssd_conf_dest: /etc/sssd/sssd.conf +sssd_started: true +sssd_enabled: true diff --git a/ansible/roles/sssd/handlers/main.yml b/ansible/roles/sssd/handlers/main.yml new file mode 100644 index 000000000..72c36e736 --- /dev/null +++ b/ansible/roles/sssd/handlers/main.yml @@ -0,0 +1,5 @@ +- name: Restart sssd + systemd: + name: sssd + state: restarted + when: sssd_started | bool diff --git a/ansible/roles/sssd/tasks/configure.yml b/ansible/roles/sssd/tasks/configure.yml new file mode 100644 index 000000000..ae636e9dd --- /dev/null +++ b/ansible/roles/sssd/tasks/configure.yml @@ -0,0 +1,28 @@ +- name: Manage sssd.conf configuration + template: + src: "{{ sssd_conf_src }}" + dest: "{{ sssd_conf_dest }}" + owner: root + group: root + mode: u=rw,go= + notify: "Restart sssd" + +- meta: flush_handlers + +- name: Ensure sssd service state + systemd: + name: sssd + state: "{{ 'started' if sssd_started | bool else 'stopped' }}" + enabled: "{{ sssd_enabled | bool }}" + +- name: Get current authselect configuration + command: authselect current --raw + changed_when: false + failed_when: + - _authselect_current.rc != 0 + - "'No existing configuration detected' not in _authselect_current.stdout" + register: _authselect_current # stdout: sssd with-mkhomedir + +- name: Configure nsswitch and PAM for SSSD + command: "authselect select sssd --force{% if sssd_enable_mkhomedir | bool %} with-mkhomedir{% endif %}" + when: "'sssd' not in _authselect_current.stdout" diff --git a/ansible/roles/sssd/tasks/install.yml b/ansible/roles/sssd/tasks/install.yml new file mode 100644 index 000000000..97aa82a2f --- /dev/null +++ b/ansible/roles/sssd/tasks/install.yml @@ -0,0 +1,13 @@ +- name: Ensure sssd packages are installed + dnf: + name: "{{ sssd_packages + sssd_ldap_packages if (sssd_install_ldap | bool) else [] }}" + +- name: Control if sssd should start on boot + # Needs to be done here to prevent starting after image build, is enabled by default + systemd: + name: sssd + enabled: "{{ sssd_enabled | bool }}" + +- name: Ensure mkhomedir packages are installed if required + dnf: + name: "{{ sssd_mkhomedir_packages }}" diff --git a/ansible/roles/sssd/tasks/main.yml b/ansible/roles/sssd/tasks/main.yml new file mode 100644 index 000000000..2b65e84b4 --- /dev/null +++ b/ansible/roles/sssd/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: install.yml +- import_tasks: configure.yml diff --git a/environments/.stackhpc/inventory/extra_groups b/environments/.stackhpc/inventory/extra_groups index 7c9a7c774..2531b803e 100644 --- a/environments/.stackhpc/inventory/extra_groups +++ b/environments/.stackhpc/inventory/extra_groups @@ -31,3 +31,7 @@ compute [squid:children] # Install squid into fat image builder + +[sssd:children] +# Install sssd into fat image +builder diff --git a/environments/.stackhpc/inventory/group_vars/builder.yml b/environments/.stackhpc/inventory/group_vars/builder.yml index 5130e9d84..10b15adac 100644 --- a/environments/.stackhpc/inventory/group_vars/builder.yml +++ b/environments/.stackhpc/inventory/group_vars/builder.yml @@ -1,3 +1,5 @@ +#update_enable: false # Can uncomment for speed debugging non-update related build issues +sssd_install_ldap: true # include sssd-ldap package in fatimage # update_enable: false # Can uncomment for speed debugging non-update related build issues # Uncomment below to use CI pulp servers diff --git a/environments/.stackhpc/terraform/cluster_image.auto.tfvars.json b/environments/.stackhpc/terraform/cluster_image.auto.tfvars.json index 47681ea8a..3c1e19058 100644 --- a/environments/.stackhpc/terraform/cluster_image.auto.tfvars.json +++ b/environments/.stackhpc/terraform/cluster_image.auto.tfvars.json @@ -1,6 +1,6 @@ { "cluster_image": { - "RL8": "openhpc-RL8-250108-1703-e515b902", - "RL9": "openhpc-RL9-250108-1703-e515b902" + "RL8": "openhpc-RL8-250109-1444-ecea8219", + "RL9": "openhpc-RL9-250109-1444-ecea8219" } } diff --git a/environments/common/inventory/group_vars/all/sshd.yaml b/environments/common/inventory/group_vars/all/sshd.yaml new file mode 100644 index 000000000..5d4ed228f --- /dev/null +++ b/environments/common/inventory/group_vars/all/sshd.yaml @@ -0,0 +1 @@ +sshd_password_authentication: "{{ sssd_install_ldap | default(false) | bool }}" diff --git a/environments/common/inventory/group_vars/builder/defaults.yml b/environments/common/inventory/group_vars/builder/defaults.yml index b43d9f03c..dae4edd9a 100644 --- a/environments/common/inventory/group_vars/builder/defaults.yml +++ b/environments/common/inventory/group_vars/builder/defaults.yml @@ -22,4 +22,6 @@ squid_cache_disk: 0 # just needs to be defined squid_cache_mem: 0 tuned_started: false tuned_enabled: false +sssd_started: false +sssd_enabled: false appliances_mode: build diff --git a/environments/common/inventory/groups b/environments/common/inventory/groups index cbc69d800..1d756ed66 100644 --- a/environments/common/inventory/groups +++ b/environments/common/inventory/groups @@ -13,9 +13,6 @@ login control compute -[eessi:children] -# Hosts on which EESSI stack should be configured - [hpctests:children] # Login group to use for running mpi-based testing. login @@ -79,9 +76,6 @@ cluster # Hosts to install firewalld on - see ansible/roles/filewalld fail2ban -[block_devices] -# Superset of hosts to configure filesystems on - see ansible/roles/block_devices/README.md - [basic_users] # Add `openhpc` group to add slurm users via creation of users on each node. @@ -118,12 +112,18 @@ freeipa_client [cuda] # Hosts to install NVIDIA CUDA on - see ansible/roles/cuda/README.md +[eessi] +# Hosts on which EESSI stack should be configured + [resolv_conf] # Allows defining nameservers in /etc/resolv.conf - see ansible/roles/resolv_conf/README.md [proxy] # Hosts to configure http/s proxies - see ansible/roles/proxy/README.md +[manila] +# Hosts to configure for manila fileshares + [persist_hostkeys] # Hosts to persist hostkeys for across reimaging. NB: Requires appliances_state_dir on hosts. @@ -136,6 +136,12 @@ freeipa_client [ansible_init] # Hosts to run linux-anisble-init +[sssd] +# Hosts to configure sssd on + +[sshd] +# Hosts where the OpenSSH server daemon should be configured + [compute_init] # EXPERIMENTAL: Compute hosts to enable joining cluster on boot on diff --git a/environments/common/layouts/everything b/environments/common/layouts/everything index d3b8fe040..4293cbca0 100644 --- a/environments/common/layouts/everything +++ b/environments/common/layouts/everything @@ -60,6 +60,7 @@ cluster # Hosts to install NVIDIA CUDA on - see ansible/roles/cuda/README.md [eessi:children] +# Hosts on which EESSI stack should be configured openhpc [resolv_conf] @@ -83,9 +84,15 @@ openondemand # Hosts to run TuneD configuration [ansible_init:children] -# Hosts to run ansible-init +# Hosts to run linux-anisble-init cluster +[sssd] +# Hosts to configure sssd on + +[sshd] +# Hosts where the OpenSSH server daemon should be configured + [compute_init:children] # EXPERIMENTAL: Compute hosts to enable joining cluster on boot on compute