diff --git a/ansible/.gitignore b/ansible/.gitignore index 2ceeb596b..d2f173b29 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -58,4 +58,13 @@ roles/* !roles/squid/** !roles/tuned/ !roles/tuned/** - +!roles/sssd/ +!roles/sssd/** +!roles/kerberos/ +!roles/kerberos/** +!roles/ldap/ +!roles/ldap/** +!roles/cacerts/ +!roles/cacerts/** +!roles/sshd/ +!roles/sshd/** diff --git a/ansible/adhoc/collect-kerberos-keytabs.yml b/ansible/adhoc/collect-kerberos-keytabs.yml new file mode 100644 index 000000000..cd2836172 --- /dev/null +++ b/ansible/adhoc/collect-kerberos-keytabs.yml @@ -0,0 +1,25 @@ +--- + +- hosts: login + vars: + keytab_dest_path: "{{ appliances_environment_root }}/files/{{ inventory_hostname }}/krb5.keytab" + tasks: + - name: Ensure output directory exists + file: + state: directory + path: "{{ keytab_dest_path | dirname }}" + run_once: true + delegate_to: localhost + + - name: Slurp keytab + ansible.builtin.fetch: + src: /etc/krb5.keytab + dest: "{{ keytab_dest_path }}" + flat: yes + become: true + when: keytab_dest_path is not exists + notify: Remind to encrypt keytab + handlers: + - name: Remind to encrypt keytab + debug: + msg: "Please remember to encrypt {{ keytab_dest_path }}" diff --git a/ansible/bootstrap.yml b/ansible/bootstrap.yml index e8e2713a5..d49296ba3 100644 --- a/ansible/bootstrap.yml +++ b/ansible/bootstrap.yml @@ -111,6 +111,22 @@ register: sestatus # --- tasks after here require access to package repos --- +- hosts: cacerts + tags: cacerts + gather_facts: false + tasks: + - name: Install custom cacerts + import_role: + name: cacerts + +- hosts: sshd + tags: sshd + gather_facts: false + tasks: + - name: Configure sshd + import_role: + name: sshd + - hosts: squid tags: squid gather_facts: yes diff --git a/ansible/fatimage.yml b/ansible/fatimage.yml index 58e1d72c7..343c91b21 100644 --- a/ansible/fatimage.yml +++ b/ansible/fatimage.yml @@ -34,6 +34,21 @@ tasks_from: client-install.yml when: "'freeipa_client' in group_names" + - name: Configure kerberos + import_role: + tasks_from: install.yml + name: kerberos + + - name: Configure ldap + import_role: + tasks_from: install.yml + name: ldap + + - name: Configure SSSD + import_role: + tasks_from: install.yml + name: sssd + # - import_playbook: filesystems.yml: - name: Install nfs packages dnf: diff --git a/ansible/iam.yml b/ansible/iam.yml index 0286b9df3..60e9c4b7e 100644 --- a/ansible/iam.yml +++ b/ansible/iam.yml @@ -40,3 +40,39 @@ import_role: name: freeipa tasks_from: users.yml + +- hosts: kerberos_client + tags: + - users + - kerberos + - kerberos_client + tasks: + - name: Configure kerberos + import_role: + # Fix me: Split install/configure + #tasks_from: ... + name: kerberos + +- hosts: ldap_client + tags: + - users + - ldap + - ldap_client + tasks: + - name: Configure ldap + import_role: + # Fix me: Split install/configure + #tasks_from: ... + name: ldap + +- hosts: sssd + tags: + - users + - sssd + become: yes + tasks: + - name: Configure SSSD + import_role: + # Fix me: Split install/configure + #tasks_from: ... + name: sssd diff --git a/ansible/roles/cacerts/tasks/install.yml b/ansible/roles/cacerts/tasks/install.yml new file mode 100644 index 000000000..cdf2cfd43 --- /dev/null +++ b/ansible/roles/cacerts/tasks/install.yml @@ -0,0 +1,9 @@ +--- + +- name: Install dependencies + ansible.builtin.package: + name: "{{ item }}" + state: present + become: true + with_items: + - ca-certificates diff --git a/ansible/roles/cacerts/tasks/main.yml b/ansible/roles/cacerts/tasks/main.yml new file mode 100644 index 000000000..849683c38 --- /dev/null +++ b/ansible/roles/cacerts/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: install.yml +- import_tasks: runtime.yml diff --git a/ansible/roles/cacerts/tasks/runtime.yml b/ansible/roles/cacerts/tasks/runtime.yml new file mode 100644 index 000000000..f123da07d --- /dev/null +++ b/ansible/roles/cacerts/tasks/runtime.yml @@ -0,0 +1,15 @@ +--- + +- name: Copy all certificates + copy: + src: "{{ item }}" + dest: /etc/pki/ca-trust/source/anchors + owner: root + mode: 0644 + with_fileglob: + - "{{ appliances_environment_root }}/cacerts" + become: true + +- name: Update trust store + command: update-ca-trust extract + become: true \ No newline at end of file diff --git a/ansible/roles/kerberos/defaults/main.yml b/ansible/roles/kerberos/defaults/main.yml new file mode 100644 index 000000000..6dc751498 --- /dev/null +++ b/ansible/roles/kerberos/defaults/main.yml @@ -0,0 +1,2 @@ +--- +kerberos_key_tab_path: "{{ appliances_environment_root }}/files/{{ inventory_hostname }}/krb5.keytab" \ No newline at end of file diff --git a/ansible/roles/kerberos/tasks/install.yml b/ansible/roles/kerberos/tasks/install.yml new file mode 100644 index 000000000..a995a3298 --- /dev/null +++ b/ansible/roles/kerberos/tasks/install.yml @@ -0,0 +1,12 @@ +--- + + +- name: Install dependencies + ansible.builtin.package: + name: "{{ item }}" + state: present + become: true + with_items: + - krb5-workstation + - krb5-libs + - realmd diff --git a/ansible/roles/kerberos/tasks/main.yml b/ansible/roles/kerberos/tasks/main.yml new file mode 100644 index 000000000..849683c38 --- /dev/null +++ b/ansible/roles/kerberos/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: install.yml +- import_tasks: runtime.yml diff --git a/ansible/roles/kerberos/tasks/runtime.yml b/ansible/roles/kerberos/tasks/runtime.yml new file mode 100644 index 000000000..9c65ea394 --- /dev/null +++ b/ansible/roles/kerberos/tasks/runtime.yml @@ -0,0 +1,31 @@ +--- + +- name: Assert that kerberos keytab exists + assert: + that: kerberos_key_tab_path is exists + # FIXME: make this non client specific + fail_msg: >- + Please enroll the node with: + sudo realm join --computer-ou OU= + --computer-name {{ inventory_hostname }} -v + -U swinst + --automatic-id-mapping=no << AD realm >> + +- name: Copy keytab into place + ansible.builtin.copy: + src: "{{ kerberos_key_tab_path }}" + dest: /etc/krb5.keytab + owner: root + group: root + mode: "0644" + become: true + +- name: Template configuration file + ansible.builtin.template: + src: "{{ appliances_environment_root }}/templates/krb5.conf.j2" + dest: /etc/krb5.conf + owner: root + group: root + mode: "0644" + become: true + register: kerberos_config diff --git a/ansible/roles/ldap/tasks/install.yml b/ansible/roles/ldap/tasks/install.yml new file mode 100644 index 000000000..680ed18e3 --- /dev/null +++ b/ansible/roles/ldap/tasks/install.yml @@ -0,0 +1,11 @@ +--- + + +- name: Install dependencies + ansible.builtin.package: + name: "{{ item }}" + state: present + become: true + with_items: + - sssd-ldap + - openldap-clients diff --git a/ansible/roles/ldap/tasks/main.yml b/ansible/roles/ldap/tasks/main.yml new file mode 100644 index 000000000..849683c38 --- /dev/null +++ b/ansible/roles/ldap/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: install.yml +- import_tasks: runtime.yml diff --git a/ansible/roles/sshd/defaults/main.yml b/ansible/roles/sshd/defaults/main.yml new file mode 100644 index 000000000..c815738f5 --- /dev/null +++ b/ansible/roles/sshd/defaults/main.yml @@ -0,0 +1,2 @@ +# Whether or not to enable password login +sshd_password_authentication: false \ No newline at end of file diff --git a/ansible/roles/sshd/handlers/main.yml b/ansible/roles/sshd/handlers/main.yml new file mode 100644 index 000000000..c0e4086bc --- /dev/null +++ b/ansible/roles/sshd/handlers/main.yml @@ -0,0 +1,5 @@ +- name: "Restart sshd" + service: + name: "sshd" + state: "restarted" + become: true \ No newline at end of file diff --git a/ansible/roles/sshd/tasks/install.yml b/ansible/roles/sshd/tasks/install.yml new file mode 100644 index 000000000..8ea2eb054 --- /dev/null +++ b/ansible/roles/sshd/tasks/install.yml @@ -0,0 +1,9 @@ +--- + +- name: Install dependencies + ansible.builtin.package: + name: "{{ item }}" + state: present + become: true + with_items: + - openssh-server diff --git a/ansible/roles/sshd/tasks/main.yml b/ansible/roles/sshd/tasks/main.yml new file mode 100644 index 000000000..849683c38 --- /dev/null +++ b/ansible/roles/sshd/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: install.yml +- import_tasks: runtime.yml diff --git a/ansible/roles/sshd/tasks/runtime.yml b/ansible/roles/sshd/tasks/runtime.yml new file mode 100644 index 000000000..bd0ffec01 --- /dev/null +++ b/ansible/roles/sshd/tasks/runtime.yml @@ -0,0 +1,12 @@ +--- + +- name: Disallow SSH password authentication + lineinfile: + dest: /etc/ssh/sshd_config + regexp: "^PasswordAuthentication" + line: "PasswordAuthentication {{ 'yes' if sshd_password_authentication | bool else 'no' }}" + state: present + validate: sshd -t -f %s + notify: + - Restart sshd + become: true diff --git a/ansible/roles/sssd/README.md b/ansible/roles/sssd/README.md new file mode 100644 index 000000000..adc3a0575 --- /dev/null +++ b/ansible/roles/sssd/README.md @@ -0,0 +1,65 @@ +SSSD Role +========= + +This is the ansible SSSD role commonly used to configure infrastructure and servers. +It's very basic - just getting the authentication sources right for LDAP, and that's all. + +As such, it's typically paired with the nearby openldap role. + +Role Variables +-------------- + +The role takes one main config, sssd_config: + + sssd_config: + 'sssd': + 'config_file_version': '2' + 'debug_level': '5' + 'reconnection_retries': '3' + 'services': 'nss, pam' + 'domains': 'cam' + 'domain/example': + 'auth_provider': 'ldap' + 'ldap_id_use_start_tls': 'False' + 'chpass_provider': 'ldap' + 'cache_credentials': 'True' + 'krb5_realm': 'EXAMPLE.COM' + 'ldap_search_base': "dc=example,dc=com" + 'id_provider': 'ldap' + 'ldap_uri': "ldaps://ldap.example.com" + 'krb5_kdcip': 'kerberos.example.com' + 'ldap_enumeration_refresh_timeout': '43200' + 'ldap_purge_cache_timeout': '0' + 'enumerate': 'true' + + +Example Playbook +---------------- + +- name: "Configure SSSD client for user directory/authentication" + hosts: "all" + gather_facts: no + any_errors_fatal: true + become: true + + roles: + - role: "sssd" + sssd_config: + 'sssd': + 'config_file_version': '2' + 'debug_level': '5' + 'reconnection_retries': '3' +... + + +License +------- + +BSD + +Author Information +------------------ + +Original author: Matt Raso-Barnett + +Current maintainer: Gwen Dawes diff --git a/ansible/roles/sssd/defaults/main.yml b/ansible/roles/sssd/defaults/main.yml new file mode 100644 index 000000000..8cd13e2fa --- /dev/null +++ b/ansible/roles/sssd/defaults/main.yml @@ -0,0 +1,11 @@ +--- +# Package state; use `present` to make sure it's installed, or `latest` +# if you want to upgrade or switch versions using a new repo. +sssd_packages_state: present + +# Choose if you want to enable the pam_mkhomedir module to auto-create +# user home directories on successful login +sssd_enable_mkhomedir: false + +# Default sssd configuration template +sssd_conf_template: "sssd.conf.j2" diff --git a/ansible/roles/sssd/handlers/main.yml b/ansible/roles/sssd/handlers/main.yml new file mode 100644 index 000000000..836b63e62 --- /dev/null +++ b/ansible/roles/sssd/handlers/main.yml @@ -0,0 +1,19 @@ +--- +- name: "Restart sssd" + debug: msg="checking config first" + changed_when: True + notify: + - "Check sssd configuration" + - "Restart sssd - after config check" + +- name: "Check sssd configuration" + command: "sssctl config-check" + register: result + changed_when: "result.rc != 0" + check_mode: no + +- name: "Restart sssd - after config check" + service: + name: "{{ sssd_service }}" + state: "restarted" + diff --git a/ansible/roles/sssd/meta/main.yml b/ansible/roles/sssd/meta/main.yml new file mode 100644 index 000000000..227ad9c34 --- /dev/null +++ b/ansible/roles/sssd/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/ansible/roles/sssd/tasks/configure.yml b/ansible/roles/sssd/tasks/configure.yml new file mode 100644 index 000000000..5a241b4d7 --- /dev/null +++ b/ansible/roles/sssd/tasks/configure.yml @@ -0,0 +1,14 @@ +--- +- name: "Manage sssd.conf configuration" + template: + src: "{{ sssd_conf_template }}" + dest: "{{ sssd_conf_path }}" + owner: root + group: root + mode: 0600 + when: sssd_config is defined + notify: "Restart sssd" + +# TODO: Make idempotent +- name: "Configure nsswitch and pam for SSSD via authconfig" + command: "authselect select sssd{% if sssd_enable_mkhomedir | bool %} with-mkhomedir{% endif %}" diff --git a/ansible/roles/sssd/tasks/install-Rocky.yml b/ansible/roles/sssd/tasks/install-Rocky.yml new file mode 100644 index 000000000..89ed1c2e7 --- /dev/null +++ b/ansible/roles/sssd/tasks/install-Rocky.yml @@ -0,0 +1,11 @@ +--- +- name: "Ensure sssd packages are installed" + package: + name: "{{ sssd_packages }}" + state: "{{ sssd_packages_state }}" + +- name: "Ensure mkhomedir packages are installed if requested" + package: + name: "{{ sssd_mkhomedir_packages }}" + state: "{{ sssd_packages_state }}" + when: sssd_enable_mkhomedir | bool diff --git a/ansible/roles/sssd/tasks/install.yml b/ansible/roles/sssd/tasks/install.yml new file mode 100644 index 000000000..e8e063a73 --- /dev/null +++ b/ansible/roles/sssd/tasks/install.yml @@ -0,0 +1,4 @@ +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- include_tasks: "install-{{ ansible_os_family }}.yml" \ No newline at end of file diff --git a/ansible/roles/sssd/tasks/main.yml b/ansible/roles/sssd/tasks/main.yml new file mode 100644 index 000000000..296522ef9 --- /dev/null +++ b/ansible/roles/sssd/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- include_tasks: "install.yml" + +- include_tasks: "runtime.yml" + diff --git a/ansible/roles/sssd/tasks/runtime.yml b/ansible/roles/sssd/tasks/runtime.yml new file mode 100644 index 000000000..fcdaccc0e --- /dev/null +++ b/ansible/roles/sssd/tasks/runtime.yml @@ -0,0 +1,7 @@ +--- +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- include_tasks: "configure.yml" + +- include_tasks: "service.yml" diff --git a/ansible/roles/sssd/tasks/service.yml b/ansible/roles/sssd/tasks/service.yml new file mode 100644 index 000000000..528d8b52f --- /dev/null +++ b/ansible/roles/sssd/tasks/service.yml @@ -0,0 +1,12 @@ +--- +- name: "Manage sssd service" + service: + name: "{{ sssd_service }}" + state: "{{ sssd_state }}" + enabled: "{{ sssd_enabled }}" + +- name: "Ensure oddjob is started" + service: + name: oddjobd + state: started + enabled: "{{ sssd_enable_mkhomedir }}" diff --git a/ansible/roles/sssd/templates/sssd.conf.j2 b/ansible/roles/sssd/templates/sssd.conf.j2 new file mode 100644 index 000000000..79bbb20c3 --- /dev/null +++ b/ansible/roles/sssd/templates/sssd.conf.j2 @@ -0,0 +1,11 @@ +# {{ ansible_managed }} + +{% for section in sssd_config.keys() %} +[{{ section }}] +{% if sssd_config[section] %} +{% for key, value in sssd_config[section].items() %} +{{ key }} = {{ value }} +{% endfor %} +{% endif %} + +{% endfor %} diff --git a/ansible/roles/sssd/tests/inventory b/ansible/roles/sssd/tests/inventory new file mode 100644 index 000000000..878877b07 --- /dev/null +++ b/ansible/roles/sssd/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/ansible/roles/sssd/tests/test.yml b/ansible/roles/sssd/tests/test.yml new file mode 100644 index 000000000..68d8a6656 --- /dev/null +++ b/ansible/roles/sssd/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ansible-sssd \ No newline at end of file diff --git a/ansible/roles/sssd/vars/RedHat.yml b/ansible/roles/sssd/vars/RedHat.yml new file mode 100644 index 000000000..a517d3edd --- /dev/null +++ b/ansible/roles/sssd/vars/RedHat.yml @@ -0,0 +1,14 @@ +--- +sssd_packages: + - 'sssd' + - 'sssd-tools' + - 'authconfig' + +sssd_mkhomedir_packages: + - 'oddjob-mkhomedir' + +sssd_conf_path: '/etc/sssd/sssd.conf' + +sssd_service: 'sssd' +sssd_state: 'started' +sssd_enabled: true diff --git a/ansible/roles/sssd/vars/Rocky.yml b/ansible/roles/sssd/vars/Rocky.yml new file mode 100644 index 000000000..a517d3edd --- /dev/null +++ b/ansible/roles/sssd/vars/Rocky.yml @@ -0,0 +1,14 @@ +--- +sssd_packages: + - 'sssd' + - 'sssd-tools' + - 'authconfig' + +sssd_mkhomedir_packages: + - 'oddjob-mkhomedir' + +sssd_conf_path: '/etc/sssd/sssd.conf' + +sssd_service: 'sssd' +sssd_state: 'started' +sssd_enabled: true diff --git a/ansible/roles/sssd/vars/main.yml b/ansible/roles/sssd/vars/main.yml new file mode 100644 index 000000000..82239487b --- /dev/null +++ b/ansible/roles/sssd/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ansible-sssd \ No newline at end of file diff --git a/ansible/site.yml b/ansible/site.yml index bb379399d..0d558384f 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -44,4 +44,4 @@ - import_tasks: cleanup.yml - community.general.shutdown: -... \ No newline at end of file +... diff --git a/environments/.gitignore b/environments/.gitignore new file mode 100644 index 000000000..c3ff48abc --- /dev/null +++ b/environments/.gitignore @@ -0,0 +1,2 @@ +*/logs/** +*/hpctests/** 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..dd7811403 --- /dev/null +++ b/environments/common/inventory/group_vars/all/sshd.yaml @@ -0,0 +1,3 @@ +--- + +sshd_password_authentication: "{{ 'ldap_client' in group_names or 'kerberos_client' in group_names }}" \ No newline at end of file diff --git a/environments/common/inventory/groups b/environments/common/inventory/groups index ea0bebebc..db82f3f4b 100644 --- a/environments/common/inventory/groups +++ b/environments/common/inventory/groups @@ -134,4 +134,27 @@ freeipa_client # Hosts to run TuneD configuration [ansible_init] -# Hosts to run linux-anisble-init \ No newline at end of file +# Hosts to run linux-anisble-init + +[kerberos_client] +# When using Kerberos for authentication. For example: +#[kerberos_client:children] +#login + +[ldap_client] +# When using LDAP instead of kerberos for authentication E.g +#[ldap_client:children] +#compute +#control + +[sssd:children] +kerberos_client +ldap_client + +[cacerts:children] +# Adds certificates under APPLIANCES_ENVIORNMENT_ROOT/cacerts to system trust store. +openhpc + +[sshd:children] +# Hosts where the OpenSSH server daemon should be configured +openhpc