diff --git a/ansible/roles/openondemand/README.md b/ansible/roles/openondemand/README.md index 3727d21b2..7c379af58 100644 --- a/ansible/roles/openondemand/README.md +++ b/ansible/roles/openondemand/README.md @@ -10,7 +10,8 @@ This uses the [osc.ood](https://github.com/OSC/ood-ansible) Ansible role to prov - The `openondemand` node, i.e. the node which will host the Open Ondemand server/portal must: - Have the slurm packages (e.g. `sinfo` etc) installed and be able to contact the Slurm controller (e.g. add this node to the `login` group). - Have access to any cluster shared filesystems. -- Open Ondemand's authentication maps authenticated users (e.g. via OIDC) to local users on the `openondemand` node (see `openondemand_mapping_users`). You must therefore ensure that whatever is providing users for the cluster covers the `openondemand` node, e.g. if using `basic_users` role ensure the group for this includes the `openondemand` group. +- Open Ondemand's authentication maps authenticated users (e.g. via OIDC) to local users on the `openondemand` node. + Therefore whatever mechanism provides cluster users (e.g. `basic_users`, `freeipa`, `ldap` via sssd) must cover the `openondemand` node. ## Role Variables @@ -27,10 +28,8 @@ This uses the [osc.ood](https://github.com/OSC/ood-ansible) Ansible role to prov See the Open Ondemand [Authentication docs](https://osc.github.io/ood-documentation/latest/authentication/overview.html) for an overview of the authentication process. -- `openondemand_auth`: Required. Authentication method, either `'oidc'` or `'basic_pam'`. See relevant subsection below. -- `openondemand_mapping_users`: Required for `openondemand_auth=='oidc'`. A list of dicts defining mappings between remote authenticated usernames and local system usernames - see the Open Ondemand [user mapping docs](https://osc.github.io/ood-documentation/latest/authentication/overview/map-user.html). Each dict should have the following keys: - - `name`: A local (existing) user account - - `openondemand_username`: The remote authenticated username. See also `openondemand_oidc_remote_user_claim` if using OIDC authentication. +- `openondemand_auth`: Required. Authentication method, either `'oidc'`, `dex` +or `'basic_pam'`. See relevant subsection below. #### OIDC authentication @@ -45,6 +44,33 @@ The following variables are active when `openondemand_auth` is `oidc`. This role The OIDC provider should be configured to redirect to `https://{{ openondemand_servername }}/oidc` with scopes as appropriate for `openondemand_oidc_scope`. +When using OIDC the remote user must be mapped to a local Linux user. The default +is to map the entire remote user claim string to the local username. See the +Open Ondemand [user mapping docs](https://osc.github.io/ood-documentation/latest/authentication/overview/map-user.html) +for more. The [osc.ood role](https://github.com/OSC/ood-ansible) variables such +as `user_map_match` may be set directly if necessary. + +#### DEX authentication +This runs DEX on the Open Ondemand host to provide an OIDC endpoint which federates +from some other identity provider. Generally no OIDC configuration is required. +Dex configuration can be provided using the `dex_settings` [osc.ood role](https://github.com/OSC/ood-ansible) +variable. + +**IMPORTANT** This takes a string of yaml, not actual yaml. E.g.: + +```yaml +dex_settings: | + dex: + connectors: + - type: ldap + id: ldap + name: LDAP + ... +``` + +See comments above for OIDC regarding remote user mapping. For LDAP the default +mapping is likely to be sufficent. + #### Basic/PAM authentication This option uses HTTP Basic Authentication (i.e. browser prompt) to get a username and password. This is then checked against an existing local user using PAM. Note that HTTPS is configured by default, so the password is protected in transit, although there are [other](https://security.stackexchange.com/a/990) security concerns with Basic Authentication. diff --git a/ansible/roles/openondemand/defaults/main.yml b/ansible/roles/openondemand/defaults/main.yml index ecb5a8d12..14a7c910c 100644 --- a/ansible/roles/openondemand/defaults/main.yml +++ b/ansible/roles/openondemand/defaults/main.yml @@ -1,8 +1,8 @@ --- # Authentication: -openondemand_auth: # "oidc" or "basic_pam" -openondemand_mapping_users: [] +openondemand_auth: # "oidc", "dex" or "basic_pam" + ## Variables for `openondemand_auth=oidc` : openondemand_oidc_client_id: openondemand_oidc_client_secret: @@ -52,23 +52,28 @@ openondemand_auth_defaults: OIDCScope: "{{ openondemand_oidc_scope }}" OIDCRemoteUserClaim: "{{ openondemand_oidc_remote_user_claim }}" httpd_auth: # ood_portal.yml.j2 - - "AuthType openid-connect" - - "Require valid-user" - - "ProxyPreserveHost On" # see under https://grafana.com/blog/2022/02/08/grafana-7.5.15-and-8.3.5-released-with-moderate-severity-security-fixes/ - user_map_cmd: /opt/ood/ood_auth_map/bin/ood_auth_map.mapfile - user_map_match: none + - 'AuthType openid-connect' + - 'Require valid-user' + - 'ProxyPreserveHost On' # see under https://grafana.com/blog/2022/02/08/grafana-7.5.15-and-8.3.5-released-with-moderate-severity-security-fixes/ + # Defaults for dex + dex: + oidc_uri: /oidc # has to be set separately to trigger oidc integration! + # *DON'T* set ood_auth_openidc - that will be provided automatically + httpd_auth: + - 'AuthType openid-connect' + - 'Require valid-user' + - 'ProxyPreserveHost On' # see under https://grafana.com/blog/2022/02/08/grafana-7.5.15-and-8.3.5-released-with-moderate-severity-security-fixes/ + # Defaults for basic/PAM auth - see https://osc.github.io/ood-documentation/latest/authentication/pam.html basic_pam: httpd_auth: # ood_portal.yml.j2 - "AuthType Basic" - 'AuthName "Open OnDemand"' - - "AuthBasicProvider PAM" - - "AuthPAMService ood" - - "Require valid-user" - - "ProxyPreserveHost On" # see under https://grafana.com/blog/2022/02/08/grafana-7.5.15-and-8.3.5-released-with-moderate-severity-security-fixes/ - user_map_cmd: null - user_map_match: ".*" + - 'AuthBasicProvider PAM' + - 'AuthPAMService ood' + - 'Require valid-user' + - 'ProxyPreserveHost On' # see under https://grafana.com/blog/2022/02/08/grafana-7.5.15-and-8.3.5-released-with-moderate-severity-security-fixes/ # The below mapping is used to override osc.ood defaults. Keys are osc.ood variable names. # If you need to override *these* defaults (i.e. this role's vars are not sufficent) just set the corresponding osc.ood var as normal. @@ -93,12 +98,8 @@ openondemand_osc_ood_defaults: - SSLCompression off - SSLSessionTickets Off - # User mapping: - user_map_cmd: "{{ openondemand_auth_defaults[openondemand_auth | lower].user_map_cmd }}" - user_map_match: "{{ openondemand_auth_defaults[openondemand_auth | lower].user_map_match }}" - # Auth: - oidc_uri: "{{ openondemand_auth_defaults.oidc.oidc_uri if (openondemand_auth | lower) == 'oidc' else none }}" + oidc_uri: "{{ openondemand_auth_defaults.oidc.oidc_uri if (openondemand_auth | lower) in ['oidc', 'dex'] else none }}" ood_auth_openidc: "{{ openondemand_auth_defaults.oidc.ood_auth_openidc if (openondemand_auth | lower) == 'oidc' else none }}" httpd_auth: "{{ openondemand_auth_defaults[openondemand_auth | lower].httpd_auth }}" diff --git a/ansible/roles/openondemand/tasks/main.yml b/ansible/roles/openondemand/tasks/main.yml index 6fb6edb88..9ee9043f6 100644 --- a/ansible/roles/openondemand/tasks/main.yml +++ b/ansible/roles/openondemand/tasks/main.yml @@ -1,6 +1,7 @@ --- - name: Set osc.ood variables from this role's defaults if no overriding inventory var ansible.builtin.set_fact: + # NB: When condition is important - some configurations require undefined vars "{{ item.key }}": "{{ lookup('vars', item.key, default=item.value) }}" loop: "{{ openondemand_osc_ood_defaults | dict2items }}" when: (item.key in hostvars[inventory_hostname]) or (item.value) @@ -98,24 +99,6 @@ dest: /etc/ood/config/pun/html/missing_home_directory.html mode: "0644" -- name: Create mapping directory - ansible.builtin.file: - path: /etc/grid-security - state: directory - owner: root - group: apache - mode: u=rwX,g=rX,o= - when: openondemand_mapping_users - -- name: Create mapping file - ansible.builtin.template: - dest: /etc/grid-security/grid-mapfile - src: grid-mapfile.j2 - owner: root - group: apache - mode: u=rw,g=r,o= - when: openondemand_mapping_users - - name: Create app directories for dashboard links ansible.builtin.file: path: /var/www/ood/apps/sys/{{ item.app_name | default(item.name) }} @@ -130,12 +113,13 @@ mode: "0644" loop: "{{ openondemand_dashboard_links }}" -# - name: Ensure ondemand-dex is running and active -# service: -# name: ondemand-dex -# enabled: yes -# state: stopped -# when: false +- name: Ensure ondemand-dex is running/enabled/restarted for config changes + # Can be dropped once on a version including https://github.com/OSC/ood-ansible/pull/272 + ansible.builtin.systemd: + name: ondemand-dex + enabled: yes + state: restarted + when: openondemand_auth | lower == "dex" # - name: Copy site images # copy: