Назад | Перейти на главную страницу

Как сгенерировать SSH-ключи хоста через ansible?

Я пытаюсь повторно сгенерировать ключи хоста ssh на нескольких удаленных серверах через ansible (и ssh-keygen), но файлы, похоже, не отображаются. Playbook работает нормально, но файлы на пульте дистанционного управления не изменяются.

Мне нужно прибегнуть к echo -e хакерство, поскольку эти пульты работают под управлением Ubuntu 14.04 и не имеют правильной версии python-pexpect в наличии (согласно ансиблю).

Что мне не хватает? Мои пьесы и результаты приведены ниже:

учебник

---
- 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

вывод

$ 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  

Насколько мне известно, единственная причина, по которой вам нужно направить '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

Если по какой-то причине вы хотели заменить эти ключи, например, если они были слишком старыми или что-то еще, вы можете добавить еще одну задачу для их удаления. Вот простое удаление

- file:
    state: absent:
    path: "{{item}}"
  loop:
  - /etc/ssh/ssh_host_rsa_key
  - /etc/ssh/ssh_host_dsa_key
  - /etc/ssh/ssh_host_ecdsa_key

Если вы хотите удалить файлы, созданные до определенного времени, вы можете использовать модуль stat для получения сведений об этих файлах и настройки when условия для выборочного удаления их, если они старше определенной даты или чего-то в этом роде.

Анзибль command модуль не передает команды через оболочку. Это означает, что вы не можете использовать операторы оболочки, такие как конвейер, и именно поэтому вы видите символ конвейера в выводе. Что касается ansible, он выполнил команду echo со всей остальной частью строки в качестве аргументов для echo.

Если вам нужна командная строка, обрабатываемая оболочкой, использовать shell вместо того command.

И должен быть лучший способ восстановить ключи хоста ssh, но я не могу найти его прямо сейчас ...

Используйте специальный модуль для этой задачи:

- 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

извините, но я не мог использовать «создает» в задаче. я получил следующую ошибку:

ERROR! 'creates' is not a valid attribute for a Task

поэтому я использую следующие задачи:

- name: remove existing ssh_host keys
  file: path={{ item }} state=absent
  with_items:
    - "/etc/ssh/ssh_host_rsa_key"
    - "/etc/ssh/ssh_host_dsa_key"
    - "/etc/ssh/ssh_host_ecdsa_key"

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

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

- name: Generate /etc/ssh/ ECDSA host key
  command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""

@Zoredache дает правильный ответ, но не работает (отмечен @MaxiReglisse) для последних версий Ansible. Вместо этого используйте следующий код:

---
- 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

Другой вариант - использовать пользователь модуль. Положительной стороной этого является то, что вы получите идемпотентную задачу. Вот пример того, как сгенерировать ключи ssh на localhost:

- name: Generate ssh keys
  local_action:
    module: "user"
    name: "{{ lookup('env','USER') }}"
    generate_ssh_key: true
    ssh_key_type: "{{ item.0 }}"
    ssh_key_bits: "{{ item.1 }}"
    ssh_key_file: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
  with_together:
  - [ 'rsa', 'dsa' ]
  - [ 2048, 1024 ]
  loop_control:
    label: "{{ item.0 }}_{{ item.1 }}_key"

- name: Copy generated ssh keys to remote machine
  copy:
    src: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
    dest: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"
  with_nested:
  - [ 'rsa', 'dsa' ]
  - [ '', '.pub' ]
  notify:
  - Restart sshd
  loop_control:
    label: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"

Используйте модули openssh_keypair и authorized_key для одновременного создания и развертывания ключей, не сохраняя их на своем доступном хосте.

- openssh_keypair:
    group: root
    owner: root
    path: /some/path/in/your/server
    register: ssh_key

- name: Store public key into origin
  delegate_to: central_server_name
  authorized_key:
     key: "{{ssh_key.public_key}}"
     comment: "{{ansible_hostname}}"
     user: any_user_on_central