Ansible:在 sshd_config 中添加用户

Ansible:在 sshd_config 中添加用户

一名新员工加入,我需要允许他访问测试服务器。通常我使用模板并根据环境类型将此模板上传到服务器上。但这次我想使用不同的方法:我只想在sshd_configAllowUsers且仅当用户不可用时添加这个新用户。

尝试过lineinfile模块但到目前为止没有成功。

答案1

使用过滤器社区.general.jc解析/etc/ssh/sshd_config

声明变量

  sshd_conf: "{{ sshd_out.stdout|community.general.jc('sshd_conf') }}"

并读取文件

    - command: cat /etc/ssh/sshd_config
      register: sshd_out

获取已配置的列表允许用户

  sshd_allow_users: "{{ sshd_conf.allowusers|d('')|split }}"

您还可以使用其他模块来读取文件(slurp、fetch 等)。要使用过滤器,您必须安装杰西在控制器上。如果您不能或不想安装它,请自行解析配置。使用命令

    - command: sshd -T
      register: sshd_out

并声明变量

  sshd_allow_users: "{{ sshd_out.stdout_lines|
                        select('match', 'allowusers')|
                        map('split')|map('last') }}"

声明要添加的用户列表并连接列表

  sshd_allow_users_add: [alice, bob]
  sshd_conf_update:
    AllowUsers: "{{ (sshd_allow_users + sshd_allow_users_add)|flatten|unique|sort }}"

例如,给定文件

shell> grep AllowUsers /etc/ssh/sshd_config
AllowUsers cloe

更新它

    - lineinfile:
        path: /etc/ssh/sshd_config
        firstmatch: true
        regexp: '^\s*{{ item.key }}\s+(.*)$'
        line: "{{ item.key }} {{ item.value|join(' ') }}"
        validate: sshd -t -f %s
      loop: "{{ sshd_conf_update|dict2items }}"

让步--检查--差异模式

TASK [lineinfile] ********************************************************************
--- before: /etc/ssh/sshd_config (content)
+++ after: /etc/ssh/sshd_config (content)
@@ -127,4 +127,4 @@
 #  AllowTcpForwarding no
 #  PermitTTY no
 #  ForceCommand cvs server
-AllowUsers cloe
+AllowUsers alice bob cloe

changed: [localhost] => (item={'key': 'AllowUsers', 'value': ['alice', 'bob', 'cloe']})

用于测试的完整剧本示例

- hosts: all
  become: true

  vars:

    sshd_allow_users_add: [alice, bob]
    sshd_conf_update:
      AllowUsers: "{{ (sshd_allow_users + sshd_allow_users_add)|flatten|unique|sort }}"

    sshd_conf: "{{ sshd_out.stdout|community.general.jc('sshd_conf') }}"
    sshd_allow_users: "{{ sshd_conf.allowusers|d('')|split }}"

  tasks:

    - command: cat /etc/ssh/sshd_config
      register: sshd_out
      check_mode: false
      changed_when: false

    - debug:
        msg: |
          sshd_conf:
           {{ sshd_conf|to_yaml|indent(2) }}
          sshd_allow_users_add: {{ sshd_allow_users_add }}
          sshd_conf_update:
            {{ sshd_conf_update|to_yaml|indent(2) }}
      when: debug|d(false)|bool
 
    - lineinfile:
        path: /etc/ssh/sshd_config
        firstmatch: true
        regexp: '^\s*{{ item.key }}\s+(.*)$'
        line: "{{ item.key }} {{ item.value|join(' ') }}"
        validate: sshd -t -f %s
      loop: "{{ sshd_conf_update|dict2items }}"

问:没有名为“split”的过滤器

答:过滤器分裂自 2.11 起可用。如果此过滤器不可用,请使用该方法分裂()在第一种情况下

  sshd_allow_users: "{{ (sshd_conf.allowusers|d('')).split() }}"

并使用过滤器正则表达式_替换在第二种情况下

  sshd_allow_users: "{{ sshd_out.stdout_lines|
                        select('match', 'allowusers')|
                        map('regex_replace', '^(.*) (.*)$', '\\2') }}"

答案2

坦白说,这感觉就像是XY问题-- 您询问如何针对您的问题实施特定的解决方案,但该解决方案......充其量只是次优。

让我们来解压一下。您希望能够确保应被授权连接到测试服务器的新员工能够通过 SSH 进行连接,并且您尝试通过维护文件AllowUsers中的列表来实现这一点sshd_config。这样做你会遇到一个问题,即通过 ansible 修改随机配置文件可能很棘手,并且lineinfile可能会出现偶然情况。

根据您对这种特定方法的喜爱程度,我看到了一些可能的选择。

一,就像 Sotto Voce 已经指出的那样,您不是在文件中显式指定用户,而是sshd_config创建一个系统级组,以通常的方式ssh_allowed通过ansible.builtin.user模块的 ansible 将所述用户添加到该组中,并确保sshd_config有一个AllowGroup ssh_allowed与该组匹配的条目。

两个现代版本的 sshd 支持该Include声明。如果你的 - 你可能需要手动检查 - 那么会有一个更简单的解决方案:

首先,添加行

Include /etc/ssh/sshd_config.d/*.conf

对于主sshd_config配置文件,然后创建一个可以通过内置模板生成的文件,/etc/ssh/sshd_config.d/01-authusers.conf因为它完全独立于服务器级 sshd 配置的其余部分。

答案3

(这本来是评论,但我已将其移至答案)

AllowGroups当我做类似的事情时,我在文件的一行中使用了组的静态列表sshd_config,并通过普通的 Unix/Linux 组成员身份管理访问。 Ansible(或其他配置管理套件)中用于管理组成员资格的工具比编辑 sshd_config 文件的中间要容易得多,并且如果您遵循创建具有与用户名匹配的主要组的用户的常见做法,则AllowGroups可以允许个人用户以及团体。

请注意,AllowGroups/ 的AllowUsers工作方式是大多数人意想不到的。如果AllowGroups/线上存在任何组/用户AllowUsers,则仅允许线路上的组/用户通过 SSH 登录。 所有其他组/用户都被拒绝。 IMO 的名称AllowOnlyTheseGroupsAllowOnlyTheseUsers会更准确地描述它们的工作原理。

尝试在文件中配置多行AllowGroups或多AllowUsers行时要小心sshd_config。这两个参数与大多数其他 SSH 配置参数一样:配置文件中出现的第一个参数获胜。第二次、第三次等出现将被忽略。即使它们出现在Include.

相关内容