如果密钥被拒绝,如何让 Ansible 使用密码?

pet*_*tr0 16 ssh authentication ansible

我的新服务器实例配置为使用密码通过 ssh 登录 root。我希望我的 Ansible playbook 将其重新配置为使用密钥,并在第一次运行时禁用使用密码的 root 登录,所以我需要这样的东西:

  • 尝试使用密钥登录
  • 如果无法使用密钥登录:

    • 使用密码登录
    • 将密钥添加到authorized_keys
    • 使用密码禁用 root 登录
    • 可选地使用密钥重新连接
  • 做其他任务

我怎样才能做到这一点?

编辑:要清楚,我不是在问如何添加密钥或禁用 root,这只是为了上下文。我问的是如果无法使用密钥进行身份验证,如何回退到密码。使用--ask-passansible_ssh_pass设置,Ansible 甚至不会尝试使用公钥身份验证

Tom*_*ull 7

如果ansible_user剧本的“第一次运行”不同,我会这样做(例如,如果您只有一个root用户并且您将使用 SSH 密钥设置一个新用户):

  • ansible_pass像使用密码登录一样存储密码(记住使用 Vault),这应该是您用于“第一次运行”剧本的用户的密码。
  • ansible_user当您在服务器上正确设置用户时,设置为您希望在第一次运行后使用的用户的用户名。
  • ansible_user_first_run为您将用于剧本“第一次运行”的用户设置一个变量,例如root
  • 使用本地命令尝试使用正确的 SSH 密钥连接到服务器,使用ignore_errorschanged_when: False
  • 如果失败,请更新ansible_useransible_user_first_run

这是代码:

---
- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
  set_fact:
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed
Run Code Online (Sandbox Code Playgroud)

注意:值得设置,transport = ssh因为 paramiko 在某些配置中可能会意外地无法登录服务器(例如,当服务器设置为不接受密码时,您首先尝试使用密钥然后输入密码......很奇怪!)此外,ssh 传输速度更快,因此无论如何都是值得的。

进一步注意:如果您使用此方法,则需要gather_facts: false在剧本定义文件中指定,以便在进入测试密码阶段之前不会自动运行设置/事实收集任务。如果您需要任何 ansible 事实,则需要setup在访问任何通常在 等地方可用的数据之前显式调用您的角色ansible_devices。这样做的一个好方法是调用setup一个when子句来检查是否在您将其用于您的角色之前,您正在使用的事实是否为空。


tit*_*tus 6

您可以--ask-pass在运行 ansible-playbook 时使用。

对于您要求的其他任务,可以通过各种方式实现,例如复制模块。
也可以禁用 root 登录,例如。通过模板化sshd_conf或在 conf 文件中插入行。


小智 6

您可以尝试该PreferredAuthentications选项,将其设置为publickey,password. 默认值按此顺序包括这些以及其他选项,因此 ansible 可能正在设置它。通过-o或客户端添加它ssh_config可能会阻止这种情况。

您也许可以使用包装器脚本。例如,使用这个 inkey_or_password.shpass.sh给出密码的 a ,运行bash key_or_password.sh root@host将尝试一个公钥,然后是一个非交互式密码登录。

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"
Run Code Online (Sandbox Code Playgroud)

日志指示哪种方法成功,例如

debug1: Authentication succeeded (publickey).
Run Code Online (Sandbox Code Playgroud)