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


14

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

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

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

我该怎么做?

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


好问题,您到目前为止尝试了什么?
dawud

1
我将ssh配置带到一个单独的剧本中,并使用-k选项运行它,然后运行不带-k的主剧本(使用代理的密钥)。我希望它可以包装在一个单一的剧本中……
petr0

@ petr0当询问密码与密钥使用的用户不同时(例如,禁用密码ssh后切换远程用户),这对我有用。不确定是否有帮助。
DylanYoung '18

Answers:


6

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

您可能可以使用包装器脚本。例如,在其中输入key_or_password.shpass.sh提供密码时,运行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' "$@"

日志指示成功的方法,例如

debug1: Authentication succeeded (publickey).

7

如果ansible_user该剧本的“首次运行”方式有所不同,这就是我要做的事情(例如,如果您只有一个root用户,并且打算使用SSH密钥设置一个新用户):

  • ansible_pass使用密码登录名时(请记住要使用Vault)一样存储密码,这应该是您用于剧本“首次运行”的用户的密码。
  • ansible_user当您在服务器上正确设置用户时,设置为您希望在首次运行后使用的用户的用户名。
  • 例如,将变量设置为ansible_user_first_run要用于剧本“首次运行”的用户root
  • 使用本地命令尝试使用正确的SSH密钥连接服务器,ignore_errors并使用和changed_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

注意:值得进行设置,transport = ssh因为在某些配置中paramiko可能意外地无法登录到服务器(例如,当服务器设置为不接受密码,并且您首先尝试输入密钥然后输入密码...很奇怪!) ssh传输也更快,因此还是值得的。

进一步说明:如果使用此方法,则需要gather_facts: false在剧本定义文件中进行指定,以便在进入测试密码阶段之前不会自动运行设置/事实收集任务。如果您需要任何有关事实的信息,则需要setup在访问诸如等位置通常可用的任何数据之前显式调用您的角色ansible_devices。执行此操作的一种好方法是调用setup一个when子句来检查是否在您将其称为角色之前,使用的事实是否为空。


您的解决方案很好,但是您必须gather_facts: no在启动剧本时添加a 来停止ansible尝试连接:)
k4cy

你是对的。我为所有剧本设置了collect_facts,因此我必须显式调用“ setup”。我忘了在答案中提及这一点,现在我将对其进行更新。
汤姆·布尔

5

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

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


--ask-pass(与-k相同)是我正在做的事情,我在上面的评论中对此进行了写道
petr0 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.