在Ansible中处理带有特殊字符的密码

6

我正在尝试运行一个带有ansible_ssh_pass选项的ansible playbook,以连接到目标服务器。

ansible-playbook test-playbook.yml -i hosts -u daniel --extra-vars "{"ansible_ssh_pass":"u5!vuL!<35Lf?<>n'x"}"

问题在于密码中包含特殊字符。 我尝试使用以下方式保存:
"password\'s"
"password"
"\"password\""

我该如何保存密码?


你尝试过将它编码为JSON吗? - Ignacio Vazquez-Abrams
使用 JSON 编码时出现相同的错误。 - radicaled
'{"ansible_ssh_pass":"u5!vuL!<35Lf?<>n'x"}'?(在整个JSON值中使用单引号,在JSON字符串内部使用双引号并转义JSON中的单引号) - zigarn
5个回答

5

最终为一个无法使用vars_prompts的密码更改脚本找到了解决方法。

对于我运行ansiblebash程序,我需要先通过read从用户那里获取密码,然后执行以下操作:

  1. 将错误的字符串转换为base64并保存到b64_pass
  2. b64_pass作为b64_ansible_ssh_pass额外参数传递
  3. 使用set_fact设置ansible_ssh_pass并在额外参数b64_ansible_ssh_pass上使用b64decode过滤器

简短的示例testba.sh:

#!/bin/bash
read -p -s "Enter ssh password: " ssh_pass

# Convert input or var to base64
b64_pass=$(printf '%s' "$ssh_pass" | base64)

# Run ansible command
ansible-playbook test.yml -m shell -a "echo OK" -e "b64_ansible_ssh_pass='$b64_pass'" -v

Playbook测试.yml:

- hosts: all

  # Assign ansible_ssh_pass in vars OR below in task with set_fact
  vars:
    ansible_ssh_pass: "{{ b64_ansible_ssh_pass | b64decode }}"

  tasks:
    # Assign ansible_ssh_pass in task with set_fact
    - name: Set ssh pass
      set_fact:
        ansible_ssh_pass: "{{ b64_ansible_ssh_pass | b64decode }}"
      no_log: true

    - shell: echo hi

如果您需要将密码变量传递到用户模块中,请使用以下方法。
#!/bin/bash
read -p -s "Enter ssh password: " ssh_pass

# Convert input or var to base64
b64_pass=$(printf '%s' "$ssh_pass" | base64)

# Run ansible command
ansible <hosts_to_run_on> -m shell -a "echo OK" -e "new_pass=$b64_pass"

然后在你的playbook中

- hosts: all
  vars:
    my_new_pass: "{{ new_pass | b64decode }}" 
  tasks:
    user:
      name: "NewUser"
      password: "{{ my_new_pass }}"

4

可能有点晚了,但是你特定问题的确切解决方案是:

ansible-playbook test-playbook.yml -i hosts -u daniel --extra-vars ansible_ssh_pass=$'"u5!vuL!<35Lf?<>n\'x"'

Shell 对 $'<string>' 进行特殊处理,内部转义单引号(参见反斜杠)。

最外层双引号是必要的,这样 jinja2 模板引擎就不会在 ansible 中混淆。

话虽如此,这种方法至少有两个问题:

  • 不安全。任何能够访问机器上进程列表或您的 shell 历史记录的人都可以看到密码。
  • 不灵活。在命令行上提供的 Ansible 额外变量具有最高优先级。如果您在清单中添加了一个带有不同 ssh 密码的主机,您将无法区分两个密码。

对于第一个问题,如果您确定只有一台机器(或密码在所有位置相同),您可以使用 vars_prompt 交互式地询问密码,例如(http://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html

解决这两个问题的最佳方法是将密码使用 vault 加密添加到特定主机的清单中。然后,您可以在调用播放时通过交互方式提供整体保险库密码(--ask-vault-pass)或通过安全保护的 vault 密码文件(--vault-password-file=)提供。


0

1、如果ansible_ssh_pass中有特殊字符

[test]
192.168.1.1 ansible_ssh_user=network ansible_ssh_pass="'6j#@D@vcsA4'"

0

如果您删除单引号特殊字符,您可以在其余部分周围使用单引号,这样它应该可以工作:

ansible-playbook test-playbook.yml -i hosts -u daniel -e ansible_ssh_pass='u5!vuL!<35Lf?<>nx'

0

我知道对于ansible-vault,您可以在文件中指定密码,我认为在这种情况下也可以使用,但我不确定。

ansible-playbook test-playbook.yml -i hosts -u daniel --extra-vars ansible_ssh_pass=/path/to/file.txt

如果您使用Linux,可以为所需用户设置SSH密钥,从而完全绕过密码。 - tweeks200
我们不允许在服务器之间共享密钥。想法是使用用户名/密码进行连接。 - radicaled

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接