From b01d9178d0ed008ac4e9cc8dad3a753c8ae36ad1 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 1 Mar 2018 11:07:43 +0100 Subject: [PATCH 01/14] evolinux-users: split AllowGroups/AllowUsers modes If an AllowGroups directive is found or when using Debian 9+, we use the AllowGroups directive and comment AllowUsers that may be already present. When adding a user, we make sure that the allowed group exists and the use is in that group, to be sure that at least this user is allowed to connect. In other situations, we use the AllowUsers directive. --- CHANGELOG.md | 1 + evolinux-base/tasks/ssh.yml | 4 +- evolinux-users/defaults/main.yml | 3 ++ evolinux-users/tasks/ssh.yml | 68 +++-------------------------- evolinux-users/tasks/ssh_groups.yml | 65 +++++++++++++++++++++++++++ evolinux-users/tasks/ssh_users.yml | 53 ++++++++++++++++++++++ 6 files changed, 130 insertions(+), 64 deletions(-) create mode 100644 evolinux-users/tasks/ssh_groups.yml create mode 100644 evolinux-users/tasks/ssh_users.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 12c19b85..169554c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ The **patch** part changes incrementally at each release. * elasticsearch: RESTART_ON_UPGRADE is configurable (default: `true`) * elasticsearch: use ES_TMPDIR variable for custom tmpdir, (from `/etc/default/elasticsearch` instead of changing `/etc/elesticsearch/jvm.options`). * evolinux-base: Exec the firewall tasks sooner (to avoid dependency issues) +* evolinux-users: split AllowGroups/AllowUsers modes for SSH directives * mongodb: allow unauthenticated packages for Jessie * mongodb: configuration is forced by default but it's configurable (default: `false`) * mongodb: rename logrotate script diff --git a/evolinux-base/tasks/ssh.yml b/evolinux-base/tasks/ssh.yml index 773de28f..40970ca6 100644 --- a/evolinux-base/tasks/ssh.yml +++ b/evolinux-base/tasks/ssh.yml @@ -63,16 +63,16 @@ - name: "Get current user" command: logname + changed_when: False register: logname check_mode: no - changed_when: False when: evolinux_ssh_allow_current_user # we must double-escape caracters, because python - name: verify AllowUsers directive command: "grep -E '^AllowUsers' /etc/ssh/sshd_config" - changed_when: False failed_when: False + changed_when: False register: grep_allowusers_ssh check_mode: no when: evolinux_ssh_allow_current_user diff --git a/evolinux-users/defaults/main.yml b/evolinux-users/defaults/main.yml index d7d6f958..fe97185c 100644 --- a/evolinux-users/defaults/main.yml +++ b/evolinux-users/defaults/main.yml @@ -1,4 +1,7 @@ --- evolinux_users: {} + evolinux_sudo_group: "evolinux-sudo" +evolinux_ssh_group: "evolinux-ssh" + evolinux_root_disable_ssh: True diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 75b47ce2..6456bc24 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -1,6 +1,5 @@ --- - - name: "Create .ssh directory for '{{ user.name }}'" file: dest: '/home/{{ user.name }}/.ssh/' @@ -30,68 +29,13 @@ command: "grep -E '^AllowGroups' /etc/ssh/sshd_config" changed_when: False failed_when: False - register: grep_allowgroups_ssh check_mode: no + register: grep_allowgroups_ssh - # If AllowGroups is present, we don't change -- debug: - msg: "AllowGroups detected : You have to configure SSH manually" - when: grep_allowgroups_ssh.rc == 0 - -- block: - # If AllowGroups is not present, we proceed as usual - - name: verify AllowUsers directive - command: "grep -E '^AllowUsers' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - register: grep_allowusers_ssh - check_mode: no - - - name: "Add AllowUsers sshd directive for '{{ user.name }}'" - lineinfile: - dest: /etc/ssh/sshd_config - line: "\nAllowUsers {{ user.name }}" - insertafter: 'Subsystem' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_allowusers_ssh.rc != 0 - - - name: "Modify AllowUsers sshd directive for '{{ user.name }}'" - replace: - dest: /etc/ssh/sshd_config - regexp: '^(AllowUsers ((?!\b{{ user.name }}\b).)*)$' - replace: '\1 {{ user.name }}' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: grep_allowusers_ssh.rc == 0 - - - name: "verify Match User directive" - command: "grep 'Match User' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - register: grep_matchuser_ssh - check_mode: no - - - name: "Add Match User sshd directive for '{{ user.name }}' (Jessie)" - lineinfile: - dest: /etc/ssh/sshd_config - line: "\nMatch User {{ user.name }}\n PasswordAuthentication no" - insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS" - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: - - ansible_distribution_release == "jessie" - - grep_matchuser_ssh.rc != 0 - - - name: "Modify Match User's sshd directive for '{{ user.name }}' (Jessie)" - replace: - dest: /etc/ssh/sshd_config - regexp: '^(Match User ((?!{{ user.name }}).)*)$' - replace: '\1,{{ user.name }}' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: - - ansible_distribution_release == "jessie" - - grep_matchuser_ssh.rc == 0 +# If AllowGroups is present or Debian 9+, use AllowGroups mode +- include: ssh_groups.yml + when: grep_allowgroups_ssh.rc == 0 or ansible_distribution_major_version | version_compare('9', '>=') +# If AllowGroups is absent, use AllowUsers mode +- include: ssh_users.yml when: grep_allowgroups_ssh.rc != 0 diff --git a/evolinux-users/tasks/ssh_groups.yml b/evolinux-users/tasks/ssh_groups.yml new file mode 100644 index 00000000..66759ac8 --- /dev/null +++ b/evolinux-users/tasks/ssh_groups.yml @@ -0,0 +1,65 @@ +--- + +- name: "Unix group '{{ evolinux_ssh_group }}' is present" + group: + name: "{{ evolinux_ssh_group }}" + state: present + +- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_ssh_group }}'" + user: + name: '{{ user.name }}' + groups: "{{ evolinux_ssh_group }}" + append: yes + +- name: "Add AllowGroups sshd directive with '{{ evolinux_ssh_group }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nAllowGroups {{ evolinux_ssh_group }}" + insertafter: 'Subsystem' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowgroups_ssh.rc != 0 + +- name: "Append '{{ evolinux_ssh_group }}' to AllowGroups sshd directive" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(AllowGroups ((?!\b{{ evolinux_ssh_group }}\b).)*)$' + replace: '\1 {{ user.name }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowgroups_ssh.rc == 0 + +- name: disable AllowUsers directive if present + replace: + dest: /etc/ssh/sshd_config + regexp: '^(AllowUsers)' + replace: '# \1' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + +- name: "verify Match Group directive" + command: "grep 'Match Group' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_matchgroup_ssh + +- name: "Add Match Group sshd directive with '{{ evolinux_ssh_group }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nMatch Group {{ evolinux_ssh_group }}\n PasswordAuthentication no" + insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS" + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: + - grep_matchgroup_ssh.rc != 0 + +- name: "Append '{{ evolinux_ssh_group }}' to Match Group's sshd directive" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(Match Group ((?!{{ evolinux_ssh_group }}).)*)$' + replace: '\1,{{ evolinux_ssh_group }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: + - grep_matchgroup_ssh.rc == 0 diff --git a/evolinux-users/tasks/ssh_users.yml b/evolinux-users/tasks/ssh_users.yml new file mode 100644 index 00000000..a5bc3325 --- /dev/null +++ b/evolinux-users/tasks/ssh_users.yml @@ -0,0 +1,53 @@ +--- + +- name: verify AllowUsers directive + shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_allowusers_ssh + +- name: "Add AllowUsers sshd directive with '{{ user.name }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nAllowUsers {{ user.name }}" + insertafter: 'Subsystem' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowusers_ssh.rc != 0 + +- name: "Append '{{ user.name }}' to AllowUsers sshd directive" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(AllowUsers ((?!\b{{ user.name }}\b).)*)$' + replace: '\1 {{ user.name }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: grep_allowusers_ssh.rc == 0 + +- name: "verify Match User directive" + command: "grep 'Match User' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_matchuser_ssh + +- name: "Add Match User sshd directive with '{{ user.name }}'" + lineinfile: + dest: /etc/ssh/sshd_config + line: "\nMatch User {{ user.name }}\n PasswordAuthentication no" + insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS" + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: + - grep_matchuser_ssh.rc != 0 + +- name: "Append '{{ user.name }}' to Match User's sshd directive" + replace: + dest: /etc/ssh/sshd_config + regexp: '^(Match User ((?!{{ user.name }}).)*)$' + replace: '\1,{{ user.name }}' + validate: '/usr/sbin/sshd -T -f %s' + notify: reload sshd + when: + - grep_matchuser_ssh.rc == 0 From 4fc58e4b1e0074bf5466c28bab0a3f3384f14c78 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 1 Mar 2018 11:59:36 +0100 Subject: [PATCH 02/14] evolinux-users: rename included files --- evolinux-users/tasks/ssh.yml | 4 ++-- evolinux-users/tasks/{ssh_groups.yml => ssh_allowgroups.yml} | 0 evolinux-users/tasks/{ssh_users.yml => ssh_allowusers.yml} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename evolinux-users/tasks/{ssh_groups.yml => ssh_allowgroups.yml} (100%) rename evolinux-users/tasks/{ssh_users.yml => ssh_allowusers.yml} (100%) diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 6456bc24..960345cf 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -33,9 +33,9 @@ register: grep_allowgroups_ssh # If AllowGroups is present or Debian 9+, use AllowGroups mode -- include: ssh_groups.yml +- include: ssh_allowgroups.yml when: grep_allowgroups_ssh.rc == 0 or ansible_distribution_major_version | version_compare('9', '>=') # If AllowGroups is absent, use AllowUsers mode -- include: ssh_users.yml +- include: ssh_allowusers.yml when: grep_allowgroups_ssh.rc != 0 diff --git a/evolinux-users/tasks/ssh_groups.yml b/evolinux-users/tasks/ssh_allowgroups.yml similarity index 100% rename from evolinux-users/tasks/ssh_groups.yml rename to evolinux-users/tasks/ssh_allowgroups.yml diff --git a/evolinux-users/tasks/ssh_users.yml b/evolinux-users/tasks/ssh_allowusers.yml similarity index 100% rename from evolinux-users/tasks/ssh_users.yml rename to evolinux-users/tasks/ssh_allowusers.yml From e0ac7760f0a0622452a3cd8fd971ef2e47c9daae Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 1 Mar 2018 15:57:17 +0100 Subject: [PATCH 03/14] Use AllowGroups mode also if no AllowUsers is present at all --- evolinux-users/tasks/ssh.yml | 12 ++++++++++-- evolinux-users/tasks/ssh_allowgroups.yml | 14 +++++++------- evolinux-users/tasks/ssh_allowusers.yml | 7 ------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 960345cf..aeaeb8de 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -32,9 +32,17 @@ check_mode: no register: grep_allowgroups_ssh -# If AllowGroups is present or Debian 9+, use AllowGroups mode +- name: verify AllowUsers directive + shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_allowusers_ssh + +# If AllowGroups is present or +# if AllowUsers is absent and Debian 9+, use AllowGroups mode - include: ssh_allowgroups.yml - when: grep_allowgroups_ssh.rc == 0 or ansible_distribution_major_version | version_compare('9', '>=') + when: grep_allowgroups_ssh.rc == 0 or (grep_allowusers_ssh.rc != 0 and ansible_distribution_major_version | version_compare('9', '>=')) # If AllowGroups is absent, use AllowUsers mode - include: ssh_allowusers.yml diff --git a/evolinux-users/tasks/ssh_allowgroups.yml b/evolinux-users/tasks/ssh_allowgroups.yml index 66759ac8..7e8f8211 100644 --- a/evolinux-users/tasks/ssh_allowgroups.yml +++ b/evolinux-users/tasks/ssh_allowgroups.yml @@ -29,13 +29,13 @@ notify: reload sshd when: grep_allowgroups_ssh.rc == 0 -- name: disable AllowUsers directive if present - replace: - dest: /etc/ssh/sshd_config - regexp: '^(AllowUsers)' - replace: '# \1' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd +# - name: disable AllowUsers directive if present +# replace: +# dest: /etc/ssh/sshd_config +# regexp: '^(AllowUsers)' +# replace: '# \1' +# validate: '/usr/sbin/sshd -T -f %s' +# notify: reload sshd - name: "verify Match Group directive" command: "grep 'Match Group' /etc/ssh/sshd_config" diff --git a/evolinux-users/tasks/ssh_allowusers.yml b/evolinux-users/tasks/ssh_allowusers.yml index a5bc3325..3676c418 100644 --- a/evolinux-users/tasks/ssh_allowusers.yml +++ b/evolinux-users/tasks/ssh_allowusers.yml @@ -1,12 +1,5 @@ --- -- name: verify AllowUsers directive - shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - check_mode: no - register: grep_allowusers_ssh - - name: "Add AllowUsers sshd directive with '{{ user.name }}'" lineinfile: dest: /etc/ssh/sshd_config From f152ba66cdee44802c58e6470081f9ffc9cbc840 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 1 Mar 2018 18:26:18 +0100 Subject: [PATCH 04/14] evolinux-users: regroup tasks 1. create all accounts 2. configure sudo for everyone 3. configure ssh for everyone --- evolinux-users/tasks/account.yml | 57 ----------- evolinux-users/tasks/main.yml | 12 ++- evolinux-users/tasks/profile.yml | 18 ---- evolinux-users/tasks/root_disable_ssh.yml | 17 ---- evolinux-users/tasks/ssh.yml | 76 ++++++++------ evolinux-users/tasks/ssh_allowgroups.yml | 55 ++-------- evolinux-users/tasks/ssh_allowusers.yml | 9 ++ evolinux-users/tasks/sudo.yml | 9 ++ evolinux-users/tasks/user.yml | 118 ++++++++++++++++++++-- 9 files changed, 192 insertions(+), 179 deletions(-) delete mode 100644 evolinux-users/tasks/account.yml delete mode 100644 evolinux-users/tasks/profile.yml delete mode 100644 evolinux-users/tasks/root_disable_ssh.yml create mode 100644 evolinux-users/tasks/sudo.yml diff --git a/evolinux-users/tasks/account.yml b/evolinux-users/tasks/account.yml deleted file mode 100644 index 1ed142f9..00000000 --- a/evolinux-users/tasks/account.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - -- name: "Test if '{{ user.name }}' exists" - command: 'getent passwd {{ user.name }}' - register: loginisbusy - failed_when: False - changed_when: False - check_mode: no - -- name: "Test if uid exists for '{{ user.name }}'" - command: 'getent passwd {{ user.uid }}' - register: uidisbusy - failed_when: False - changed_when: False - check_mode: no - -- name: "Add Unix account with classical uid for '{{ user.name }}'" - user: - state: present - uid: '{{ user.uid }}' - name: '{{ user.name }}' - comment: '{{ user.fullname }}' - shell: /bin/bash - password: '{{ user.password_hash }}' - update_password: on_create - when: loginisbusy.rc != 0 and uidisbusy.rc != 0 - -- name: "Add Unix account with random uid for '{{ user.name }}'" - user: - state: present - name: '{{ user.name }}' - comment: '{{ user.fullname }}' - shell: /bin/bash - password: '{{ user.password_hash }}' - update_password: on_create - when: loginisbusy.rc != 0 and uidisbusy.rc == 0 - -- name: "Create secondary groups" - group: - name: "{{ group }}" - with_items: "{{ user.groups }}" - loop_control: - loop_var: group - when: user.groups is defined - -- name: "Add user '{{ user.name }}' to secondary groups" - user: - name: '{{ user.name }}' - groups: "{{ user.groups }}" - append: yes - when: user.groups is defined - -- name: "Fix perms on home directory for '{{ user.name }}'" - file: - name: '/home/{{ user.name }}' - mode: "0700" - state: directory diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml index ec1400bd..bf9033bc 100644 --- a/evolinux-users/tasks/main.yml +++ b/evolinux-users/tasks/main.yml @@ -16,5 +16,13 @@ with_dict: "{{ evolinux_users }}" when: evolinux_users != {} -- include: root_disable_ssh.yml - when: evolinux_root_disable_ssh +- name: Configure sudo + include: sudo.yml + vars: + user: "{{ item.value }}" + with_dict: "{{ evolinux_users }}" + when: evolinux_users != {} + +- name: Configure SSH + include: ssh.yml + when: evolinux_users != {} diff --git a/evolinux-users/tasks/profile.yml b/evolinux-users/tasks/profile.yml deleted file mode 100644 index 6a046e52..00000000 --- a/evolinux-users/tasks/profile.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- - -- name: search profile for presence of evomaintenance - command: 'grep -q "trap.*sudo.*evomaintenance.sh"' - changed_when: False - failed_when: False - check_mode: no - register: grep_profile_evomaintenance - -# Don't add the trap if it is present or commented -- name: "Add evomaintenance trap for '{{ user.name }}'" - lineinfile: - state: present - dest: '/home/{{ user.name }}/.profile' - insertafter: EOF - line: 'trap "sudo /usr/share/scripts/evomaintenance.sh" 0' - create: yes - when: grep_profile_evomaintenance.rc != 0 diff --git a/evolinux-users/tasks/root_disable_ssh.yml b/evolinux-users/tasks/root_disable_ssh.yml deleted file mode 100644 index 7906307f..00000000 --- a/evolinux-users/tasks/root_disable_ssh.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- - -- name: disable root login - replace: - dest: /etc/ssh/sshd_config - regexp: '^PermitRootLogin (yes|without-password|prohibit-password)' - replace: "PermitRootLogin no" - notify: reload sshd - -### Disabled : it seems useless and too dangerous for now -# - name: remove root from AllowUsers directive -# replace: -# dest: /etc/ssh/sshd_config -# regexp: '^(AllowUsers ((?!root(?:@\S+)?).)*)(\sroot(?:@\S+)?|root(?:@\S+)?\s)(.*)$' -# replace: '\1\4' -# validate: '/usr/sbin/sshd -T -f %s' -# notify: reload sshd diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index aeaeb8de..bf316ab8 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -1,30 +1,5 @@ --- -- name: "Create .ssh directory for '{{ user.name }}'" - file: - dest: '/home/{{ user.name }}/.ssh/' - state: directory - mode: "0700" - owner: '{{ user.name }}' - group: '{{ user.name }}' - -- name: "Add user's SSH public key for '{{ user.name }}'" - authorized_key: - user: "{{ user.name }}" - key: "{{ user.ssh_key }}" - state: present - when: user.ssh_key is defined - -- name: "Add user's SSH public keys for '{{ user.name }}'" - authorized_key: - user: "{{ user.name }}" - key: "{{ ssk_key }}" - state: present - with_items: "{{ user.ssh_keys }}" - loop_control: - loop_var: ssk_key - when: user.ssh_keys is defined - - name: verify AllowGroups directive command: "grep -E '^AllowGroups' /etc/ssh/sshd_config" changed_when: False @@ -32,18 +7,55 @@ check_mode: no register: grep_allowgroups_ssh +- debug: + var: grep_allowgroups_ssh + verbosity: 1 + - name: verify AllowUsers directive - shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" + command: "grep -E '^AllowUsers' /etc/ssh/sshd_config" changed_when: False failed_when: False check_mode: no register: grep_allowusers_ssh -# If AllowGroups is present or -# if AllowUsers is absent and Debian 9+, use AllowGroups mode -- include: ssh_allowgroups.yml - when: grep_allowgroups_ssh.rc == 0 or (grep_allowusers_ssh.rc != 0 and ansible_distribution_major_version | version_compare('9', '>=')) +- debug: + var: grep_allowusers_ssh + verbosity: 1 + +- set_fact: + # If "AllowGroups is present" or "AllowUsers is absent and Debian 9+", + ssh_allowgroups: "{{ grep_allowgroups_ssh.rc == 0 or (grep_allowusers_ssh.rc != 0 and (ansible_distribution_major_version | version_compare('9', '>='))) }}" + # If "AllowGroups is absent" + ssh_allowusers: "{{ grep_allowgroups_ssh.rc != 0 }}" + +- debug: + var: ssh_allowgroups + verbosity: 1 + +- debug: + var: ssh_allowusers + verbosity: 1 + +- include: ssh_allowgroups.yml + when: + - ssh_allowgroups + - not ssh_allowusers -# If AllowGroups is absent, use AllowUsers mode - include: ssh_allowusers.yml - when: grep_allowgroups_ssh.rc != 0 + vars: + user: "{{ item.value }}" + with_dict: "{{ evolinux_users }}" + when: + - ssh_allowusers + - not ssh_allowgroups + + +- name: disable root login + replace: + dest: /etc/ssh/sshd_config + regexp: '^PermitRootLogin (yes|without-password|prohibit-password)' + replace: "PermitRootLogin no" + notify: reload sshd + when: evolinux_root_disable_ssh + +- meta: flush_handlers diff --git a/evolinux-users/tasks/ssh_allowgroups.yml b/evolinux-users/tasks/ssh_allowgroups.yml index 7e8f8211..c4d946a2 100644 --- a/evolinux-users/tasks/ssh_allowgroups.yml +++ b/evolinux-users/tasks/ssh_allowgroups.yml @@ -1,15 +1,13 @@ --- -- name: "Unix group '{{ evolinux_ssh_group }}' is present" - group: - name: "{{ evolinux_ssh_group }}" - state: present - -- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_ssh_group }}'" - user: - name: '{{ user.name }}' - groups: "{{ evolinux_ssh_group }}" - append: yes +# this check must be repeated for each user +# even if it's been done before +- name: verify AllowGroups directive + shell: "grep -E '^AllowGroups' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_allowgroups_ssh - name: "Add AllowGroups sshd directive with '{{ evolinux_ssh_group }}'" lineinfile: @@ -24,42 +22,7 @@ replace: dest: /etc/ssh/sshd_config regexp: '^(AllowGroups ((?!\b{{ evolinux_ssh_group }}\b).)*)$' - replace: '\1 {{ user.name }}' + replace: '\1 {{ evolinux_ssh_group }}' validate: '/usr/sbin/sshd -T -f %s' notify: reload sshd when: grep_allowgroups_ssh.rc == 0 - -# - name: disable AllowUsers directive if present -# replace: -# dest: /etc/ssh/sshd_config -# regexp: '^(AllowUsers)' -# replace: '# \1' -# validate: '/usr/sbin/sshd -T -f %s' -# notify: reload sshd - -- name: "verify Match Group directive" - command: "grep 'Match Group' /etc/ssh/sshd_config" - changed_when: False - failed_when: False - check_mode: no - register: grep_matchgroup_ssh - -- name: "Add Match Group sshd directive with '{{ evolinux_ssh_group }}'" - lineinfile: - dest: /etc/ssh/sshd_config - line: "\nMatch Group {{ evolinux_ssh_group }}\n PasswordAuthentication no" - insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS" - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: - - grep_matchgroup_ssh.rc != 0 - -- name: "Append '{{ evolinux_ssh_group }}' to Match Group's sshd directive" - replace: - dest: /etc/ssh/sshd_config - regexp: '^(Match Group ((?!{{ evolinux_ssh_group }}).)*)$' - replace: '\1,{{ evolinux_ssh_group }}' - validate: '/usr/sbin/sshd -T -f %s' - notify: reload sshd - when: - - grep_matchgroup_ssh.rc == 0 diff --git a/evolinux-users/tasks/ssh_allowusers.yml b/evolinux-users/tasks/ssh_allowusers.yml index 3676c418..1e561415 100644 --- a/evolinux-users/tasks/ssh_allowusers.yml +++ b/evolinux-users/tasks/ssh_allowusers.yml @@ -1,5 +1,14 @@ --- +# this check must be repeated for each user +# even if it's been done before +- name: verify AllowUsers directive + shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" + changed_when: False + failed_when: False + check_mode: no + register: grep_allowusers_ssh + - name: "Add AllowUsers sshd directive with '{{ user.name }}'" lineinfile: dest: /etc/ssh/sshd_config diff --git a/evolinux-users/tasks/sudo.yml b/evolinux-users/tasks/sudo.yml new file mode 100644 index 00000000..ed696b43 --- /dev/null +++ b/evolinux-users/tasks/sudo.yml @@ -0,0 +1,9 @@ +--- + +- include: sudo_jessie.yml + when: ansible_distribution_release == "jessie" + +- include: sudo_stretch.yml + when: ansible_distribution_major_version | version_compare('9', '>=') + +- meta: flush_handlers diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index 73fea728..bad260f5 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -1,15 +1,119 @@ --- -- include: account.yml +# Unix account -- include: profile.yml +- name: "Test if '{{ user.name }}' exists" + command: 'getent passwd {{ user.name }}' + register: loginisbusy + failed_when: False + changed_when: False + check_mode: no -- include: ssh.yml +- name: "Test if uid exists for '{{ user.name }}'" + command: 'getent passwd {{ user.uid }}' + register: uidisbusy + failed_when: False + changed_when: False + check_mode: no -- include: sudo_jessie.yml - when: ansible_distribution_release == "jessie" +- name: "Add Unix account with classical uid for '{{ user.name }}'" + user: + state: present + uid: '{{ user.uid }}' + name: '{{ user.name }}' + comment: '{{ user.fullname }}' + shell: /bin/bash + password: '{{ user.password_hash }}' + update_password: on_create + when: loginisbusy.rc != 0 and uidisbusy.rc != 0 -- include: sudo_stretch.yml - when: ansible_distribution_major_version | version_compare('9', '>=') +- name: "Add Unix account with random uid for '{{ user.name }}'" + user: + state: present + name: '{{ user.name }}' + comment: '{{ user.fullname }}' + shell: /bin/bash + password: '{{ user.password_hash }}' + update_password: on_create + when: loginisbusy.rc != 0 and uidisbusy.rc == 0 + +# Unix groups + +- name: "Unix group '{{ evolinux_ssh_group }}' is present" + group: + name: "{{ evolinux_ssh_group }}" + state: present + +- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_ssh_group }}'" + user: + name: '{{ user.name }}' + groups: "{{ evolinux_ssh_group }}" + append: yes + +- name: "Create secondary groups" + group: + name: "{{ group }}" + with_items: "{{ user.groups }}" + loop_control: + loop_var: group + when: user.groups is defined + +- name: "Add user '{{ user.name }}' to secondary groups" + user: + name: '{{ user.name }}' + groups: "{{ user.groups }}" + append: yes + when: user.groups is defined + +- name: "Fix perms on home directory for '{{ user.name }}'" + file: + name: '/home/{{ user.name }}' + mode: "0700" + state: directory + + # Evomaintenance + +- name: search profile for presence of evomaintenance + command: 'grep -q "trap.*sudo.*evomaintenance.sh"' + changed_when: False + failed_when: False + check_mode: no + register: grep_profile_evomaintenance + +# Don't add the trap if it is present or commented +- name: "Add evomaintenance trap for '{{ user.name }}'" + lineinfile: + state: present + dest: '/home/{{ user.name }}/.profile' + insertafter: EOF + line: 'trap "sudo /usr/share/scripts/evomaintenance.sh" 0' + when: grep_profile_evomaintenance.rc != 0 + +# SSH keys + +- name: "Create .ssh directory for '{{ user.name }}'" + file: + dest: '/home/{{ user.name }}/.ssh/' + state: directory + mode: "0700" + owner: '{{ user.name }}' + group: '{{ user.name }}' + +- name: "Add user's SSH public key for '{{ user.name }}'" + authorized_key: + user: "{{ user.name }}" + key: "{{ user.ssh_key }}" + state: present + when: user.ssh_key is defined + +- name: "Add user's SSH public keys for '{{ user.name }}'" + authorized_key: + user: "{{ user.name }}" + key: "{{ ssk_key }}" + state: present + with_items: "{{ user.ssh_keys }}" + loop_control: + loop_var: ssk_key + when: user.ssh_keys is defined - meta: flush_handlers From 13abc4499242317302a028f665c7232879e9d3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 16:58:33 +0200 Subject: [PATCH 05/14] evolinux-users: use assert instead of fail --- evolinux-users/tasks/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml index bf9033bc..a32bbd13 100644 --- a/evolinux-users/tasks/main.yml +++ b/evolinux-users/tasks/main.yml @@ -1,9 +1,10 @@ --- -- fail: +- assert: + that: + - ansible_distribution == "Debian" + - ansible_distribution_major_version | version_compare('8', '>=') msg: only compatible with Debian >= 8 - when: - - ansible_distribution != "Debian" or ansible_distribution_major_version | version_compare('8', '<') - debug: msg: "Warning: empty 'evolinux_users' variable, tasks will be skipped!" From 2027420877151cccc3e0b906e474852a1625e7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 16:59:00 +0200 Subject: [PATCH 06/14] whitespaces --- evolinux-users/tasks/ssh.yml | 9 ++++----- evolinux-users/tasks/ssh_allowusers.yml | 6 ++---- evolinux-users/tasks/user.yml | 10 +++++++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index bf316ab8..20eac23a 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -38,17 +38,16 @@ - include: ssh_allowgroups.yml when: - - ssh_allowgroups - - not ssh_allowusers + - ssh_allowgroups + - not ssh_allowusers - include: ssh_allowusers.yml vars: user: "{{ item.value }}" with_dict: "{{ evolinux_users }}" when: - - ssh_allowusers - - not ssh_allowgroups - + - ssh_allowusers + - not ssh_allowgroups - name: disable root login replace: diff --git a/evolinux-users/tasks/ssh_allowusers.yml b/evolinux-users/tasks/ssh_allowusers.yml index 1e561415..db113494 100644 --- a/evolinux-users/tasks/ssh_allowusers.yml +++ b/evolinux-users/tasks/ssh_allowusers.yml @@ -41,8 +41,7 @@ insertafter: "# END EVOLINUX PASSWORD RESTRICTIONS BY ADDRESS" validate: '/usr/sbin/sshd -T -f %s' notify: reload sshd - when: - - grep_matchuser_ssh.rc != 0 + when: grep_matchuser_ssh.rc != 0 - name: "Append '{{ user.name }}' to Match User's sshd directive" replace: @@ -51,5 +50,4 @@ replace: '\1,{{ user.name }}' validate: '/usr/sbin/sshd -T -f %s' notify: reload sshd - when: - - grep_matchuser_ssh.rc == 0 + when: grep_matchuser_ssh.rc == 0 diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index bad260f5..49e88cbc 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -25,9 +25,11 @@ shell: /bin/bash password: '{{ user.password_hash }}' update_password: on_create - when: loginisbusy.rc != 0 and uidisbusy.rc != 0 + when: + - loginisbusy.rc != 0 + - uidisbusy.rc != 0 -- name: "Add Unix account with random uid for '{{ user.name }}'" +- name: "Unix account for '{{ user.name }}' is present (with random uid)" user: state: present name: '{{ user.name }}' @@ -35,7 +37,9 @@ shell: /bin/bash password: '{{ user.password_hash }}' update_password: on_create - when: loginisbusy.rc != 0 and uidisbusy.rc == 0 + when: + - loginisbusy.rc != 0 + - uidisbusy.rc == 0 # Unix groups From f065310ca691845a12a28d7e04b19768961abf44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 16:59:24 +0200 Subject: [PATCH 07/14] evolinux-users: use command instead of shell when possible --- evolinux-users/tasks/ssh_allowgroups.yml | 2 +- evolinux-users/tasks/ssh_allowusers.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/evolinux-users/tasks/ssh_allowgroups.yml b/evolinux-users/tasks/ssh_allowgroups.yml index c4d946a2..68635548 100644 --- a/evolinux-users/tasks/ssh_allowgroups.yml +++ b/evolinux-users/tasks/ssh_allowgroups.yml @@ -3,7 +3,7 @@ # this check must be repeated for each user # even if it's been done before - name: verify AllowGroups directive - shell: "grep -E '^AllowGroups' /etc/ssh/sshd_config" + command: "grep -E '^AllowGroups' /etc/ssh/sshd_config" changed_when: False failed_when: False check_mode: no diff --git a/evolinux-users/tasks/ssh_allowusers.yml b/evolinux-users/tasks/ssh_allowusers.yml index db113494..fff04f8c 100644 --- a/evolinux-users/tasks/ssh_allowusers.yml +++ b/evolinux-users/tasks/ssh_allowusers.yml @@ -3,7 +3,7 @@ # this check must be repeated for each user # even if it's been done before - name: verify AllowUsers directive - shell: "grep -E '^AllowUsers' /etc/ssh/sshd_config" + command: "grep -E '^AllowUsers' /etc/ssh/sshd_config" changed_when: False failed_when: False check_mode: no @@ -28,7 +28,7 @@ when: grep_allowusers_ssh.rc == 0 - name: "verify Match User directive" - command: "grep 'Match User' /etc/ssh/sshd_config" + command: "grep -E '^Match User' /etc/ssh/sshd_config" changed_when: False failed_when: False check_mode: no From dba26fbbafe0725f730ed8315286a354f961e446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 16:59:57 +0200 Subject: [PATCH 08/14] evolinux-users: sudoers file should be 0440 also in Stretch --- evolinux-users/tasks/sudo_stretch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/evolinux-users/tasks/sudo_stretch.yml b/evolinux-users/tasks/sudo_stretch.yml index 3aa89e63..dc744c56 100644 --- a/evolinux-users/tasks/sudo_stretch.yml +++ b/evolinux-users/tasks/sudo_stretch.yml @@ -5,6 +5,7 @@ src: sudoers_stretch.j2 dest: /etc/sudoers.d/evolinux force: no + mode: "0440" validate: '/usr/sbin/visudo -cf %s' register: copy_sudoers_evolinux From a782ef3180c9fd71c18aba646d7daa9e26bdd9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 17:00:18 +0200 Subject: [PATCH 09/14] evolinux-users: better names for a fewtasks --- evolinux-users/tasks/user.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index 49e88cbc..d2c57960 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -16,7 +16,7 @@ changed_when: False check_mode: no -- name: "Add Unix account with classical uid for '{{ user.name }}'" +- name: "Unix account for '{{ user.name }}' is present (with uid '{{ user.uid }}')" user: state: present uid: '{{ user.uid }}' @@ -54,7 +54,7 @@ groups: "{{ evolinux_ssh_group }}" append: yes -- name: "Create secondary groups" +- name: "Secondary Unix groups are present" group: name: "{{ group }}" with_items: "{{ user.groups }}" @@ -62,14 +62,14 @@ loop_var: group when: user.groups is defined -- name: "Add user '{{ user.name }}' to secondary groups" +- name: "Unix user '{{ user.name }}' belongs to secondary groups" user: name: '{{ user.name }}' groups: "{{ user.groups }}" append: yes when: user.groups is defined -- name: "Fix perms on home directory for '{{ user.name }}'" +- name: "Home directory for '{{ user.name }}' is not accessible by group and other users" file: name: '/home/{{ user.name }}' mode: "0700" @@ -77,7 +77,7 @@ # Evomaintenance -- name: search profile for presence of evomaintenance +- name: Search profile for presence of evomaintenance command: 'grep -q "trap.*sudo.*evomaintenance.sh"' changed_when: False failed_when: False @@ -85,7 +85,7 @@ register: grep_profile_evomaintenance # Don't add the trap if it is present or commented -- name: "Add evomaintenance trap for '{{ user.name }}'" +- name: "User '{{ user.name }}' has its shell trap for evomaintenance" lineinfile: state: present dest: '/home/{{ user.name }}/.profile' @@ -95,7 +95,7 @@ # SSH keys -- name: "Create .ssh directory for '{{ user.name }}'" +- name: "SSH directory for '{{ user.name }}' is present" file: dest: '/home/{{ user.name }}/.ssh/' state: directory @@ -103,14 +103,14 @@ owner: '{{ user.name }}' group: '{{ user.name }}' -- name: "Add user's SSH public key for '{{ user.name }}'" +- name: "SSH public key for '{{ user.name }}' is present" authorized_key: user: "{{ user.name }}" key: "{{ user.ssh_key }}" state: present when: user.ssh_key is defined -- name: "Add user's SSH public keys for '{{ user.name }}'" +- name: "SSH public keys for '{{ user.name }}' are present" authorized_key: user: "{{ user.name }}" key: "{{ ssk_key }}" From 5bcd7e44cff189b5e06d71785a7f96cf2f83be71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 22:22:08 +0200 Subject: [PATCH 10/14] evolinux-users: really look for evomaintenance The file was missing in the grep command :/ --- evolinux-users/tasks/user.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index d2c57960..af1a920a 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -75,10 +75,10 @@ mode: "0700" state: directory - # Evomaintenance +# Evomaintenance - name: Search profile for presence of evomaintenance - command: 'grep -q "trap.*sudo.*evomaintenance.sh"' + command: 'grep -q "trap.*sudo.*evomaintenance.sh" /home/{{ user.name }}/.profile' changed_when: False failed_when: False check_mode: no From 32c289d915212e06ebe8733c3ec1644a600986a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 22:24:13 +0200 Subject: [PATCH 11/14] evolinux: improve case switching A case was missing : no AllowUsers/AllowGroups, on Debian 9 --- evolinux-users/tasks/ssh.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 20eac23a..699c0686 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -24,9 +24,9 @@ - set_fact: # If "AllowGroups is present" or "AllowUsers is absent and Debian 9+", - ssh_allowgroups: "{{ grep_allowgroups_ssh.rc == 0 or (grep_allowusers_ssh.rc != 0 and (ansible_distribution_major_version | version_compare('9', '>='))) }}" - # If "AllowGroups is absent" - ssh_allowusers: "{{ grep_allowgroups_ssh.rc != 0 }}" + ssh_allowgroups: "{{ (grep_allowgroups_ssh.rc == 0) or (grep_allowusers_ssh.rc != 0 and (ansible_distribution_major_version | version_compare('9', '>='))) }}" + # If "AllowGroups is absent" and "Debian <9" + ssh_allowusers: "{{ (grep_allowgroups_ssh.rc != 0) and (ansible_distribution_major_version | version_compare('9', '<')) }}" - debug: var: ssh_allowgroups From b0b4e13130a805fb610feb4dbae45603b2cda87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Sun, 15 Apr 2018 22:32:32 +0200 Subject: [PATCH 12/14] evolinux-users: Add users to group for SSH on Debian 9+ --- evolinux-users/tasks/user.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index af1a920a..ff2b7390 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -43,16 +43,18 @@ # Unix groups -- name: "Unix group '{{ evolinux_ssh_group }}' is present" +- name: "Unix group '{{ evolinux_ssh_group }}' is present (Debian 9 or later)" group: name: "{{ evolinux_ssh_group }}" state: present + when: ansible_distribution_major_version | version_compare('9', '>=') -- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_ssh_group }}'" +- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_ssh_group }}' (Debian 9 or later)" user: name: '{{ user.name }}' groups: "{{ evolinux_ssh_group }}" append: yes + when: ansible_distribution_major_version | version_compare('9', '>=') - name: "Secondary Unix groups are present" group: From 2f631f1ae701cda1593b4e639bbd7e6cec50be83 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 18 Apr 2018 12:01:03 +0200 Subject: [PATCH 13/14] update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 169554c5..f545fd9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes incrementally at each release. ### Changed * evolinux-base: fail2ban is not enabled by default +* evolinux-users: refactoring of the SSH configuration * mysql-oracle: copy evolinux config files in mysql.cond.d ### Fixed From 43d86f55412c36ce7b80dff8034f03c172d6b8ac Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 18 Apr 2018 18:20:23 +0200 Subject: [PATCH 14/14] evolinux-users: cover more cases for AllowUsers/Groups in sshd config --- evolinux-users/tasks/ssh.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 699c0686..ff7cf85a 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -22,11 +22,15 @@ var: grep_allowusers_ssh verbosity: 1 +- assert: + that: "not (grep_allowusers_ssh.rc == 0 and grep_allowgroups_ssh.rc == 0)" + msg: "We can't deal with AllowUsers and AllowGroups at the same time" + - set_fact: # If "AllowGroups is present" or "AllowUsers is absent and Debian 9+", ssh_allowgroups: "{{ (grep_allowgroups_ssh.rc == 0) or (grep_allowusers_ssh.rc != 0 and (ansible_distribution_major_version | version_compare('9', '>='))) }}" - # If "AllowGroups is absent" and "Debian <9" - ssh_allowusers: "{{ (grep_allowgroups_ssh.rc != 0) and (ansible_distribution_major_version | version_compare('9', '<')) }}" + # If "AllowGroups is absent" and "AllowUsers is absent or Debian <9" + ssh_allowusers: "{{ (grep_allowusers_ssh.rc == 0) or (grep_allowgroups_ssh.rc != 0 and (ansible_distribution_major_version | version_compare('9', '<'))) }}" - debug: var: ssh_allowgroups