如何忽略ansible SSH真实性检查?

Joh*_*han 141 ssh ansible

有没有办法忽略Ansible的SSH真实性检查?例如,当我刚刚设置一个新服务器时,我必须对这个问题回答"是":

GATHERING FACTS ***************************************************************
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
RSA key fingerprint is xx:yy:zz:....
Are you sure you want to continue connecting (yes/no)?
Run Code Online (Sandbox Code Playgroud)

我知道这通常是一个坏主意,但我将其合并到一个脚本中,该脚本首先在我的云提供商处创建一个新的虚拟服务器,然后自动调用我的ansible playbook来配置它.我想在脚本执行过程中避免任何人为干预.

nik*_*lia 211

两个选项 - 第一个,正如您在自己的答案中所说,将环境变量设置ANSIBLE_HOST_KEY_CHECKING为False.

设置它的第二种方法是将它放在一个ansible.cfg文件中,这是一个非常有用的选项,因为您可以全局设置(在系统或用户级别,在/etc/ansible/ansible.cfg或中~/.ansible.cfg),或在同一目录中的配置文件中作为你正在运行的剧本.

为此,请ansible.cfg在其中一个位置创建一个文件,并包含以下内容:

[defaults]
host_key_checking = False
Run Code Online (Sandbox Code Playgroud)

您还可以在那里设置许多其他方便的默认值,例如是否在播放开始时收集事实,是否合并在多个位置声明的哈希值或将其替换为另一个,等等.有一个选项整个大名单这里的Ansible文档.


编辑:关于安全性的说明.

SSH主机密钥验证对于持久主机来说是一个有意义的安全层- 如果您多次连接到同一台机器,那么在本地接受主机密钥是很有价值的.

对于寿命较长的EC2实例,接受主机密钥并在初始创建实例时运行一次任务是有意义的:

  - name: Write the new ec2 instance host key to known hosts
    connection: local
    shell: "ssh-keyscan -H {{ inventory_hostname }} >> ~/.ssh/known_hosts"
Run Code Online (Sandbox Code Playgroud)

在动态站起来的实例上检查主机密钥并在Playbook执行后立即删除没有安全价值,但检查持久性机器的主机密钥有安全价值.因此,您应该按逻辑环境不同地管理主机密钥检查.

  • 默认情况下启用保留检查(in ~/.ansible.cfg)
  • 禁用工作目录中的主机密钥检查,以查看针对短暂实例运行./ansible.cfg的剧本(以及针对流浪虚拟机的单元测试的剧本,以及短期ec2实例的自动化)

  • 谁知道这里的最佳做法是什么?例如,您可以定期运行脚本来重置已知主机,这样会更安全(除非在该窗口中受到MITM攻击).默认情况下忽略真实性会消除SSH主要安全机制之一 (5认同)
  • 我喜欢我的团队使用的模式:我们放置了ansible.cfg文件,这些文件禁用了工作目录中的主机密钥检查,以便我们针对短暂的实例(在流浪的虚拟机上运行的单元测试,AWS ec2实例等)运行,并在系统级别. (3认同)
  • 如果使用某种机制来配置永久或临时的新机器,该机制应该为您提供此机器的SSH公钥.然后,您可以将其存储在各种本地`known_hosts`文件中,以便SSH和Ansible识别机器.如果不这样做,特别是通过禁用主机密钥检查,会将SSH的安全性降低到几乎为零,并允许MITM攻击.许多被认为属于"内部网络"的机器实际上连接到互联网,其中一个更快的DNS响应可让您与攻击者而不是目标进行对话. (2认同)
  • @TonyH在通过AWS Cloudformation和Ansible设置多个主机时,我在同一个网络中的受信任机器(对我来说,它是一个堡垒/跳转主机)上运行`ssh-keyscan <ip list>`,并将结果放入` known_hosts`为了设置该可信主机,AWS在实例的启动日志中公开了主机密钥,因此,如果我正在完全重新创建我的环境,那么搜索该密钥是一个手动步骤,我从未删除过.但该主机通常不需要删除.[这](https://unix.stackexchange.com/a/276007)可能有所帮助. (2认同)

Joh*_*han 27

我找到了答案,你需要将环境变量设置ANSIBLE_HOST_KEY_CHECKINGFalse.例如:

ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook ...
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是您说您正在将其用于刚刚设置的新服务器。这样可以避免这次必须处理主机密钥,但是后续的SSH连接又如何呢?您的安装脚本将运行,配置服务器并完成。现在,您拥有运行的其他剧本,或者说拥有使用SSH的脚本。现在,因为主机密钥仍不在known_hosts中,所以它们已损坏。您只是推迟了问题。简而言之,您在这里写的内容听起来并不能很好地回答您提出的问题。 (2认同)

dav*_*rik 12

更改host_key_checkingfalse所有主机是一个非常糟糕的主意。

您唯一想忽略它的时间是“第一次接触”,这两个任务将完成:

    - name: Check SSH known_hosts for {{ inventory_hostname }}
      local_action: shell ssh-keygen -F {{ inventory_hostname }}
      register: checkForKnownHostsEntry
      failed_when: false
      changed_when: false
      ignore_errors: yes
    - name: Add {{ inventory_hostname }} to SSH known hosts automatically
      when: checkForKnownHostsEntry.rc == 1
      changed_when: checkForKnownHostsEntry.rc == 1
      set_fact:
        ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
Run Code Online (Sandbox Code Playgroud)

因此,如果我们的known_hosts文件中没有主机密钥,我们只会关闭主机密钥检查。


ane*_*yte 9

您可以简单地告诉 SSH 自动接受新主机的指纹。只需添加

StrictHostKeyChecking=accept-new
Run Code Online (Sandbox Code Playgroud)

给你的~/.ssh/config. 它不会完全禁用主机密钥检查,它只是禁用这个恼人的问题是否要向已知主机列表添加新指纹。如果已知机器的指纹发生变化,您仍然会收到错误消息。

此策略还适用于ANSIBLE_HOST_KEY_CHECKING将此参数传递给 SSH 的其他方式。


小智 8

您可以在运行剧本时将其作为命令行参数传递:

ansible-playbook play.yml --ssh-common-args='-o StrictHostKeyChecking=no'


xjc*_*jcl 7

忽略检查是一个坏主意,因为它使您容易受到中间人攻击。

我通过只添加每台机器的密钥一次并在 Ansible 中实际设置 ok/changed 状态来自由地改进nikobelia 的答案:

- name: Accept EC2 SSH host keys
  connection: local
  become: false
  shell: |
    ssh-keygen -F {{ inventory_hostname }} || 
      ssh-keyscan -H {{ inventory_hostname }} >> ~/.ssh/known_hosts
  register: known_hosts_script
  changed_when: "'found' not in known_hosts_script.stdout"
Run Code Online (Sandbox Code Playgroud)

然而,Ansible 在脚本运行之前开始收集事实,这需要 SSH 连接,因此我们必须禁用此任务或手动将其移至稍后:

- name: Example play
  hosts: all
  gather_facts: no  # gather facts AFTER the host key has been accepted instead

  tasks:

  # https://stackoverflow.com/questions/32297456/
  - name: Accept EC2 SSH host keys
    connection: local
    become: false
    shell: |
      ssh-keygen -F {{ inventory_hostname }} ||
        ssh-keyscan -H {{ inventory_hostname }} >> ~/.ssh/known_hosts
    register: known_hosts_script
    changed_when: "'found' not in known_hosts_script.stdout"
  
  - name: Gathering Facts
    setup:
Run Code Online (Sandbox Code Playgroud)

我无法解决的一个问题是,即使它只添加一个键,它也会将所有内容标记为已更改。如果有人可以贡献一个修复程序,那就太好了!


dsa*_*don 6

转发到nikobelia

对于那些使用jenkins来运行剧本的人,我只是在运行ansible-playbook之前将其添加到我的jenkins作业中,他的环境变量ANSIBLE_HOST_KEY_CHECKING = False例如:

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook 'playbook.yml' \
--extra-vars="some vars..." \
--tags="tags_name..." -vv
Run Code Online (Sandbox Code Playgroud)


Ren*_* B. 6

如果你不想修改ansible.cfg或者,playbook.yml那么你可以设置一个环境变量:

export ANSIBLE_HOST_KEY_CHECKING=False
Run Code Online (Sandbox Code Playgroud)