From 17856832625efbf103cc744447984311b898cd74 Mon Sep 17 00:00:00 2001 From: Gaudenz Steinlin Date: Wed, 27 Mar 2024 23:20:03 +0100 Subject: [PATCH 1/2] Don't skip authorized SSH keys if empty Without this bugfix it's impossible to remove all authorized SSH keys without also removing the file. (cherry picked from commit dc8b46063aebc7022c6db55ffe1c1197a9395638) --- ansible/roles/root_account/tasks/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ansible/roles/root_account/tasks/main.yml b/ansible/roles/root_account/tasks/main.yml index 2192fbff9d..b92f716525 100644 --- a/ansible/roles/root_account/tasks/main.yml +++ b/ansible/roles/root_account/tasks/main.yml @@ -84,8 +84,7 @@ exclusive: '{{ root_account__authorized_keys_exclusive|bool }}' state: 'present' user: 'root' - when: root_account__enabled|bool and root_account__combined_authorized_keys|d() and - root_account__authorized_keys_state != 'absent' + when: root_account__enabled|bool and root_account__authorized_keys_state != 'absent' - name: Remove /root/.ssh/authorized_keys file if requested file: From 749adc532ec4737be1accb0c59d0e133f411dac4 Mon Sep 17 00:00:00 2001 From: Gaudenz Steinlin Date: Wed, 27 Mar 2024 23:21:16 +0100 Subject: [PATCH 2/2] Support follow parameter for authorized_keys Support the `follow` parameter for the authorized_keys module where it makes sense. This allows having the `authorized_keys` file symlinked. The default behaviour remains unchanged. (cherry picked from commit d40f8922277a9a36dd902a26438473a0ffd805ec) --- ansible/roles/authorized_keys/tasks/main.yml | 1 + ansible/roles/root_account/defaults/main.yml | 6 ++++++ ansible/roles/root_account/tasks/main.yml | 1 + ansible/roles/system_users/tasks/main.yml | 1 + ansible/roles/users/tasks/main.yml | 1 + docs/ansible/roles/authorized_keys/defaults-detailed.rst | 4 ++++ docs/ansible/roles/system_users/defaults-detailed.rst | 4 ++++ docs/ansible/roles/users/defaults-detailed.rst | 4 ++++ 8 files changed, 22 insertions(+) diff --git a/ansible/roles/authorized_keys/tasks/main.yml b/ansible/roles/authorized_keys/tasks/main.yml index 0f58fc4b77..1924cdbb94 100644 --- a/ansible/roles/authorized_keys/tasks/main.yml +++ b/ansible/roles/authorized_keys/tasks/main.yml @@ -59,6 +59,7 @@ comment: '{{ item.comment | d(omit) }}' path: '{{ item.path | d(omit) }}' exclusive: '{{ item.exclusive | d(omit) }}' + follow: '{{ item.follow | d(omit) }}' loop: '{{ lookup("template", "lookup/authorized_keys__identities.j2") | from_yaml }}' loop_control: label: '{{ {"identity": item.identity, diff --git a/ansible/roles/root_account/defaults/main.yml b/ansible/roles/root_account/defaults/main.yml index 7f8efb6830..be367cd26d 100644 --- a/ansible/roles/root_account/defaults/main.yml +++ b/ansible/roles/root_account/defaults/main.yml @@ -201,6 +201,12 @@ root_account__combined_authorized_keys: '{{ root_account__authorized_keys # to the existing keys on the ``root`` account. root_account__authorized_keys_exclusive: False + # ]]] +# .. envvar:: root_account__authorized_keys_follow [[[ +# +# If ``True``, follow symlinks instead of replacing the file. +root_account__authorized_keys_follow: False + # ]]] # .. envvar:: root_account__authorized_keys_state [[[ # diff --git a/ansible/roles/root_account/tasks/main.yml b/ansible/roles/root_account/tasks/main.yml index b92f716525..410a265abb 100644 --- a/ansible/roles/root_account/tasks/main.yml +++ b/ansible/roles/root_account/tasks/main.yml @@ -84,6 +84,7 @@ exclusive: '{{ root_account__authorized_keys_exclusive|bool }}' state: 'present' user: 'root' + follow: '{{ root_account__authorized_keys_follow | bool }}' when: root_account__enabled|bool and root_account__authorized_keys_state != 'absent' - name: Remove /root/.ssh/authorized_keys file if requested diff --git a/ansible/roles/system_users/tasks/main.yml b/ansible/roles/system_users/tasks/main.yml index 6cfdeba3f4..085adb4c76 100644 --- a/ansible/roles/system_users/tasks/main.yml +++ b/ansible/roles/system_users/tasks/main.yml @@ -226,6 +226,7 @@ state: 'present' user: '{{ (item.prefix | d(system_users__prefix)) + item.name }}' exclusive: '{{ item.sshkeys_exclusive | d(omit) }}' + follow: '{{ item.sshkeys_follow | d(omit) }}' loop: '{{ system_users__combined_accounts | debops.debops.parse_kv_items }}' loop_control: label: '{{ {"name": (item.prefix | d(system_users__prefix)) + item.name, diff --git a/ansible/roles/users/tasks/main.yml b/ansible/roles/users/tasks/main.yml index 94e0a56163..8257d6d9cf 100644 --- a/ansible/roles/users/tasks/main.yml +++ b/ansible/roles/users/tasks/main.yml @@ -212,6 +212,7 @@ state: 'present' user: '{{ item.name }}' exclusive: '{{ item.sshkeys_exclusive | d(omit) }}' + follow: '{{ item.sshkeys_follow | d(omit) }}' loop: '{{ users__combined_accounts | debops.debops.parse_kv_items }}' loop_control: label: '{{ {"name": item.name, diff --git a/docs/ansible/roles/authorized_keys/defaults-detailed.rst b/docs/ansible/roles/authorized_keys/defaults-detailed.rst index a9201033d7..39b7368224 100644 --- a/docs/ansible/roles/authorized_keys/defaults-detailed.rst +++ b/docs/ansible/roles/authorized_keys/defaults-detailed.rst @@ -317,6 +317,10 @@ Each list entry is a YAML dictionary with specific parameters: this option can break idempotency if multiple entries with the same ``name`` parameter are used. + ``follow`` + Optional, boolean. If defined and ``True``, the role will follow symlinks to + the :file:`authorized_keys` file instead of replacing them. + ``home`` Optional, boolean. If not specified or ``False``, the SSH keys will be managed in the :file:`/etc/ssh/authorized_keys/` directory, with custom diff --git a/docs/ansible/roles/system_users/defaults-detailed.rst b/docs/ansible/roles/system_users/defaults-detailed.rst index af23f136e7..8c7303e134 100644 --- a/docs/ansible/roles/system_users/defaults-detailed.rst +++ b/docs/ansible/roles/system_users/defaults-detailed.rst @@ -284,6 +284,10 @@ Parameters related to public SSH keys ``~/.ssh/authorized_keys`` file that are not specified in the ``sshkeys`` parameter. +``sshkeys_follow`` + Optional, boolean. If ``True``, the role will follow symlinks to the user's + ``~/.ssh/authorized_keys`` file instead of replacing them. + ``sshkeys_state`` Optional. If not specified or ``present``, the SSH keys will be set on the user's account. If ``absent``, the ``~/.ssh/authorized_keys`` file will be diff --git a/docs/ansible/roles/users/defaults-detailed.rst b/docs/ansible/roles/users/defaults-detailed.rst index 694d3bc11f..79ea90b205 100644 --- a/docs/ansible/roles/users/defaults-detailed.rst +++ b/docs/ansible/roles/users/defaults-detailed.rst @@ -298,6 +298,10 @@ Parameters related to public SSH keys ``~/.ssh/authorized_keys`` file that are not specified in the ``sshkeys`` parameter. +``sshkeys_follow`` + Optional, boolean. If ``True``, the role will follow symlinks to the user's + ``~/.ssh/authorized_keys`` file instead of replacing them. + ``sshkeys_state`` Optional. If not specified or ``present``, the SSH keys will be set on the user's account. If ``absent``, the ``~/.ssh/authorized_keys`` file will be