是否可以使用ansible在带内更改当前用户的密码?

Tal*_*Tal 5 linux ansible yaml

我有一个新安装的 Linux 发行版。它有一个具有默认密码的普通用户和一个锁定的 root 帐户(root 上没有密码 - 不能直接通过 SSH 连接)。我希望能够运行 ansible playbook 来配置此服务器,并通过更改其密码锁定此默认帐户,而无需执行额外的带外步骤。

我的剧本所做的大部分设置都需要 root,所以它被配置为作为默认用户 ssh 进入,成为 root,并运行所有命令。这很好用。问题是更改密码。

如果我尝试使用用户模块更改用户的密码,它会成功,但之后的所有任务都会失败。即使我将更改作为剧本中的最后一步进行,所有应该在最后运行的处理程序都会失败。

对于类似的问题,我在网上遇到了 2 个建议:

  • 使用 RSA 密钥
  • 使用初始播放以某种方式测试并更改密码

使用 RSA 密钥需要您提前设置 RSA,因此不是带内的。

我一直在尝试使用初始播放以某种方式执行此操作,但到目前为止,第二个初始播放无法使用默认密码登录,ansible 退出并出现错误,并忽略其他任务,以及下一个播放。

还有一个办法做到这一点使用ssh通,这表现在这里,它应该工作,但似乎更多的是黑客攻击,和ssh通并不总是容易获得,就像上运行MacOS的ansible机器。

十多年前这里讨论过一个类似的主题,但看起来 Dave 通过将 Linux 设置为在您尝试以默认用户身份登录时显示“帐户已禁用”消息并改为更改用户来解决此问题,这听起来也像它应该可以工作,但与简单地更改默认用户的密码不同。

ansible 是否可以在不断开连接的情况下更改其运行用户的密码?

Zor*_*che 3

有没有办法让 Ansible 尝试默认密码,并在失败时继续运行剧本?

这是一个示例,它与您提到的不完全匹配,但可能是一个起点。

---
# SYNOPSIS
# try authentication using keys, if that fails, fall back to default credentials

- import_playbook: ../bootstrap.yml

- hosts: linux_systems
  gather_facts: no
  become: yes
  any_errors_fatal: true
  vars: 
    ansible_user_first_run: vagrant
    ansible_pass_first_run: vagrant
  tasks:

  - block:
    - name: Check if connection is possible using keys
      command: ssh -F {{project_dir}}/.ssh/ansible_ssh_config -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ ansible_host }} /bin/true
      register: result
      connection: local
      ignore_errors: yes
      changed_when: False

    - name: If using user_first_run
      connection: local
      set_fact:
        using_first_run: true
      when: result is failed

    - name: If no connection, change ansible_user
      connection: local
      set_fact:
        ansible_user: "{{ ansible_user_first_run }}"
      when: result is failed

    - name: If no connection, change ansible_ssh_pass
      connection: local
      set_fact:
        ansible_ssh_pass: "{{ ansible_pass_first_run }}"
      when: result is failed

    - name: If no connection, change ansible_become_pass
      connection: local
      set_fact:
        ansible_become_pass: "{{ ansible_pass_first_run }}"
      when: result is failed

    # since any_errors_fatal this should fail the play
    # if we still cannot reach all hosts.
    - name: Check if connection is possible
      raw: /bin/true
      changed_when: False

    tags:
    - always

  - name: Perform a ansible ping
    ping: {}
Run Code Online (Sandbox Code Playgroud)