Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved configuration of functional accounts on chaperone machines. #748

Merged
merged 11 commits into from
Mar 6, 2023
9 changes: 5 additions & 4 deletions roles/envsync/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@
create: false
become: true

- name: 'Deploy script to verify and if necessary fix prmissions of the environment managed by the envsync account.'
- name: 'Deploy script to verify and if necessary fix permissions of the environment managed by the envsync account.'
ansible.builtin.template:
src: 'templates/hpc-environment-permissions.bash'
dest: '/root/hpc-environment-permissions.bash'
owner: 'root'
group: 'root'
mode: '0644'
mode: '0750'
scimerman marked this conversation as resolved.
Show resolved Hide resolved
become: true

- name: 'Create cron job to execute script to verify and if necessary fix prmissions of the environment managed by the envsync account.'
Expand All @@ -96,7 +96,8 @@
hour: '04'
minute: '04'
user: 'root'
job: '/bin/bash /root/hpc-environment-permissions.bash'
job: |
/bin/bash -c '/root/hpc-environment-permissions.bash | /bin/logger'
cron_file: 'hpc-environment-permissions'
become: true

Expand All @@ -108,7 +109,7 @@
minute: '05'
user: "{{ envsync_user }}"
job: |
/usr/bin/sg '{{ envsync_group }}' -c '/bin/bash -c "export SOURCE_HPC_ENV="True"; . ~/.bashrc; hpc-environment-sync.bash -a"'
/usr/bin/sg '{{ envsync_group }}' -c '/bin/bash -c "export SOURCE_HPC_ENV="True"; . ~/.bashrc; hpc-environment-sync.bash -a | /bin/logger"'
cron_file: 'hpc-environment-sync'
become: true
...
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function manageConfig() {
#
log4Bash 'DEBUG' "${LINENO}" "${FUNCNAME[0]:-main}" '0' "Appending the public key of the Certificate Authority (CA) to ${HOME}/.ssh/known_hosts ..."
printf '%s\n' \
"@cert-authority {{ known_hosts_hostnames }} {{ lookup('file', ssh_host_signer_ca_private_key+'.pub') }} for {{ slurm_cluster_name }}" \
"@cert-authority {{ known_hosts_hostnames }} {{ lookup('file', ssh_host_signer_ca_private_key + '.pub') }} for {{ slurm_cluster_name }}" \
> "${HOME}/.ssh/known_hosts.new"
if [[ -e "${HOME}/.ssh/known_hosts" ]]; then
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Open a terminal and copy paste the following commands:
# Create new known_hosts file and append the UMCG HPC CA's public key.
#
printf '%s\n' \
"@cert-authority {{ known_hosts_hostnames }} {{ lookup('file', ssh_host_signer_ca_private_key+'.pub') }} for {{ slurm_cluster_name }}" \
"@cert-authority {{ known_hosts_hostnames }} {{ lookup('file', ssh_host_signer_ca_private_key + '.pub') }} for {{ slurm_cluster_name }}" \
> "${HOME}/.ssh/known_hosts.new"
if [[ -e "${HOME}/.ssh/known_hosts" ]]; then
#
Expand Down
28 changes: 28 additions & 0 deletions roles/regular_users/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
known_hosts_hostnames: "\
{% for jumphost in groups['jumphost'] | default([]) %}\
{{ jumphost }}*,\
{% for network_id in ip_addresses[jumphost] %}\
{% if ip_addresses[jumphost][network_id]['fqdn'] is defined and
ip_addresses[jumphost][network_id]['fqdn'] == 'NXDOMAIN' %}\
{{ ip_addresses[jumphost][network_id]['address'] }},\
{% endif %}\
{% endfor %}\
{% endfor %}\
{% for dthost in groups['data_transfer'] | default([]) %}\
*{{ dthost }}*,\
{% for network_id in ip_addresses[dthost] %}\
{% if ip_addresses[dthost][network_id]['fqdn'] is defined and
ip_addresses[dthost][network_id]['fqdn'] == 'NXDOMAIN' %}\
{{ ip_addresses[dthost][network_id]['address'] }},\
{% endif %}\
{% endfor %}\
{% endfor %}\
{% for adminhost in groups['administration'] | default([]) %}\
*{{ adminhost }},\
{% endfor %}\
{% for dochost in groups['docs'] | default([]) %}\
*{{ dochost }},\
{% endfor %}\
*{{ stack_prefix }}-*"
...
74 changes: 74 additions & 0 deletions roles/regular_users/tasks/functional_accounts_on_chaperones.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
#
# On most systems we already added relevant code to /ets/skel/ to create a proper .bashrc
# when a home dir is created, but on chaperones we do not control /etc/skel and
# even if we could, that won't fix .bashrc if the home dir already exists
# or functionality to load modules was lost or needs an update.
#
- name: Create ~/.ssh dir and subdirs.
ansible.builtin.file:
path: "/home/{{ item.0.user }}/{{ item.1 }}"
state: 'directory'
owner: "{{ item.0.user }}"
group: "{{ item.0.user }}"
mode: '0700'
vars:
ssh_client_dirs:
- '.ssh'
- '.ssh/tmp'
- '.ssh/conf.d'
loop: "{{ regular_users | product(ssh_client_dirs) | list }}"
become: true

- name: 'Configure ssh client config file ~/.ssh/config to include ~/.ssh/conf.d dir.'
ansible.builtin.lineinfile:
path: "/home/{{ item.user }}/.ssh/config"
owner: "{{ item.user }}"
group: "{{ item.user }}"
mode: '0600'
create: true
insertbefore: BOF
regexp: '(?i)^#?Include'
line: 'Include conf.d/*'
with_items: "{{ regular_users }}"
become: true

- name: "Create ~/.ssh/conf.d/{{ slurm_cluster_name }} config file."
ansible.builtin.template:
src: ssh_client_config.j2
dest: "/home/{{ item.user }}/.ssh/conf.d/{{ slurm_cluster_name }}"
owner: "{{ item.user }}"
group: "{{ item.user }}"
mode: '0600'
with_items: "{{ regular_users }}"
become: true

- name: "Add {{ slurm_cluster_name }} settings to ssh client ~/.ssh/known_hosts file."
ansible.builtin.lineinfile:
path: "/home/{{ item.user }}/.ssh/known_hosts"
owner: "{{ item.user }}"
group: "{{ item.user }}"
mode: '0600'
create: true
insertbefore: BOF
regexp: '(?i)^#?@cert-authority .* for {{ slurm_cluster_name }}$'
line: "@cert-authority {{ known_hosts_hostnames }} {{ lookup('file', ssh_host_signer_ca_private_key + '.pub') }} for {{ slurm_cluster_name }}"
with_items: "{{ regular_users }}"
become: true

- name: 'Insert/update block into ~/.bashrc to ensure we can load modules.'
ansible.builtin.blockinfile:
path: "/home/{{ item.user }}/.bashrc"
block: |
if [ -f "/apps/modules//modules.bashrc" ]; then
source "/apps/modules//modules.bashrc"
fi
marker: "# {mark} ANSIBLE MANAGED BLOCK - Setup environment for Lua, Lmod & EasyBuild."
insertbefore: '# User specific aliases and functions'
create: false
owner: "{{ item.user }}"
group: "{{ item.user }}"
mode: '0600'
with_items: "{{ regular_users }}"
become: true
...
5 changes: 5 additions & 0 deletions roles/regular_users/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@
- inventory_hostname in groups['chaperone'] | default([])
- remote_users_in_local_groups is defined

- name: 'Configure functional local accounts on chaperones.'
ansible.builtin.include_tasks:
file: functional_accounts_on_chaperones.yml
when:
- inventory_hostname in groups['chaperone'] | default([])
...
64 changes: 64 additions & 0 deletions roles/regular_users/templates/ssh_client_config.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#jinja2: trim_blocks:False
#
# Host settings.
#
Host {% for jumphost in groups['jumphost'] %}{{ jumphost }}* {% endfor %}{% raw %}{% endraw %}
#
# Default account name when not specified explicitly.
#
User {{ item.user }}
#
# Prevent timeouts
#
ServerAliveInterval 60
ServerAliveCountMax 5
#
# We use public-private key pairs for authentication.
# Do not use password based authentication as fallback,
# which may be confusing and won't work anyway.
#
IdentityFile "~/.ssh/id_ed25519"
PasswordAuthentication No
#
# Multiplex connections to
# * reduce lag when logging in to the same host in a second terminal
# * reduce the amount of connections that are made to prevent excessive DNS lookups
# and to prevent getting blocked by a firewall, because it thinks we are executing a DoS attack.
#
# Name/location of sockets for connection multiplexing are configured using the ControlPath directive.
# In the ControlPath directive %C expands to a hashed value of %l_%h_%p_%r, where:
# %l = local hostname
# %h = remote hostname
# %p = remote port
# %r = remote username
# This makes sure that the ControlPath is
# * a unique socket that is local to machine on which the sessions are created,
# which means it works with home dirs from a shared network file system.
# (as sockets cannot be shared by servers.)
# * not getting to long as the hash has a fixed size not matter how long %l_%h_%p_%r was.
#
ControlMaster auto
ControlPath ~/.ssh/tmp/%C
ControlPersist 1m
#
# Expand short jumphost names to FQDN or IP address.
#
{% for jumphost in groups['jumphost'] %}
{%- set network_id = ip_addresses[jumphost]
| dict2items
| json_query('[?value.fqdn].key')
| first -%}
{%- if ip_addresses[jumphost][network_id]['fqdn'] == 'NXDOMAIN' -%}
{%- set ssh_hostname = ip_addresses[jumphost][network_id]['address'] -%}
{%- else -%}
{%- set ssh_hostname = ip_addresses[jumphost][network_id]['fqdn'] -%}
{%- endif -%}
Host {{ jumphost }}
HostName {{ ssh_hostname }}
HostKeyAlias {{ jumphost }}
{% endfor -%}
#
# Double-hop SSH settings to connect via specific jumphosts.
#
Host {% for jumphost in groups['jumphost'] %}{{ jumphost }}+* {% endfor %}{% raw %}{% endraw %}
ProxyCommand ssh -x -q $(echo "${JUMPHOST_USER:-%r}")@$(echo %h | sed 's/+[^+]*$//'){% if stack_domain | length %}.{{ stack_domain }}{% endif %} -W $(echo %h | sed 's/^[^+]*+//'):%p