如何通过ansible生成主机SSH密钥?

Ser*_*ult 18 ssh-keys ansible

我正在尝试通过 ansible(和ssh-keygen)在少数远程服务器上重新生成 ssh 主机密钥,但文件似乎没有出现。剧本运行正常,但遥控器上的文件没有改变。

我需要求助于echo -e黑客,因为这些遥控器运行的是 Ubuntu 14.04 并且没有python-pexpect可用的正确版本(根据 ansible)。

我错过了什么?我的剧本和输出如下:

剧本

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
    - name: Generate /etc/ssh/ RSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ DSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ ECDSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines
Run Code Online (Sandbox Code Playgroud)

输出

$ ansible-playbook ./playbooks/ssh-hostkeys.yml -l myhost.mydom.com, 
SUDO password: 

PLAY [all] **********************************************************************************************

TASK [Generate /etc/ssh/ RSA host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ DSA host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ ECDSA host key] ****************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C  -N "
    ]
}

PLAY RECAP **********************************************************************************************
myhost.mydom.com : ok=6    changed=3    unreachable=0    failed=0  
Run Code Online (Sandbox Code Playgroud)

Zor*_*che 20

据我所知,您需要通过管道将“y”传递给 ssh-keygen 的唯一原因是您的命令是否正在替换现有文件。在我看来,这不是从配置管理工具做某事的好方法。

您应该调整您的任务以使其具有幂等性。具体来说,如果您将creates: filename加到您的命令中,那么新键只会在它们不存在时创建,而不是每次运行该剧本时都被替换。

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
  - name: Generate /etc/ssh/ RSA host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_rsa_key

  - name: Generate /etc/ssh/ DSA host key
    command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_dsa_key

  - name: Generate /etc/ssh/ ECDSA host key
    command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_ecdsa_key
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因您想要替换这些键,例如如果它们太旧或者您可能想要添加另一个任务来删除它们。这是一个简单的删除

- file:
    state: absent:
    path: "{{item}}"
  loop:
  - /etc/ssh/ssh_host_rsa_key
  - /etc/ssh/ssh_host_dsa_key
  - /etc/ssh/ssh_host_ecdsa_key
Run Code Online (Sandbox Code Playgroud)

如果您想删除在某个时间之前生成的文件,您可以使用 stat 模块来检索有关此文件的详细信息,并设置when条件以选择性地删除它们(如果它们早于某个日期或其他时间)。


小智 8

为此任务使用特殊模块:

- name: Generate an OpenSSH keypair with the default values (4096 bits, rsa)
  openssh_keypair:
    path: /home/youruser/.ssh/id_rsa
    owner: youruser
    group: youruser

- name: Fix owner of the generated pub key
  file:
    path: /home/youruser/.ssh/id_rsa.pub
    owner: youruser
    group: youruser
Run Code Online (Sandbox Code Playgroud)


Mic*_*ton 7

ansiblecommand模块 不通过 shell 传递命令。这意味着您不能使用诸如管道之类的 shell 运算符,这就是您在输出中看到管道符号的原因。就 ansible 而言,它已执行该命令echo,并将该行的所有其余部分作为 的参数echo

如果您需要由 shell 处理的命令行,请使用shell代替command

而且,应该有更好的方法来重新生成 ssh 主机密钥,但我现在找不到...