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


11

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

Мені потрібно вдатися до 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

вихід

$ 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  

Відповіді:


14

Наскільки я знаю, єдина причина, чому вам потрібно буде передати «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умов для вибіркового видалення їх, якщо вони були старшими за певну дату чи щось таке.


Прекрасний приклад і подяка за думки про збереження самопочуття. Для мого використання я надаю клоновані віртуальні машини, тому завжди будуть ключі для перезапису. Мені якось потрібен ядерний варіант просто зняти та замінити.
Помилка сервера

Якщо ви завжди хочете, щоб його видалили, я, мабуть, зробив би file: state:absent ...підхід щодо передачі матеріалів до ssh-keygen. Хоча, мабуть, не така велика різниця.
Зоредаче

А, добре. це має більше сенсу. Я не знав про absentце пару днів тому. Ефективно, це видалить файл до повторного генерування ключа. Це набагато чіткіший підхід. Дякую.
Помилка сервера

6

Анзібль commandмодуль не передавати команди через оболонку . Це означає, що ви не можете використовувати оператори оболонки, такі як труба, і саме тому ви бачите символ труби на виході. Що стосується ansible, воно виконало команду echoз усіма рештою рядка як аргументи до echo.

Якщо вам потрібен командний рядок, оброблений оболонкою, використовуйтеshell замість command.

І, мабуть, є кращий спосіб відновити ключі хоста ssh, але я не можу знайти його зараз ...


Дякую за команду shell - команда (працює нормально). Я не знав - все ще досить новинка для ansible
Помилка сервера

Щодо останнього твердження (принаймні, про CentOS / RHEL), якщо ви вилучите старі ключі та перезапустите ключі хоста демона, для вас відновлять. Вам все одно доведеться перезапустити послугу, так що це, безумовно, здається дещо кращим.
Аарон Коплі

@AaronCopley Я більше посилався на роль Ansible, ніж на дистрибуцію. Я знаю, що в більшості основних дистрибутивів є системна служба, яка генерує хости ключі ssh. На жаль, сервіс має тонкі відмінності, пов'язані з дистрофією (він навіть різний між CentOS та Fedora). Роль була б приємним способом інкапсулювати все це, але я не можу знайти її назовні.
Майкл Хемптон

Не хвилюйтесь, просто думав, що це згадаю. (Ви можете знати, але ОП може не зробити.)
Аарон Коплі

@AaronCopley - до речі, саме це я і закінчила. echo ...трохи не зробили роботу після другого запуску (я тестував в /tmp/якій ключі не були в перший раз). Я вдався спочатку видалити хост-ключі, як ви вже згадували, та створити нові. Що стосується автоматичного відновлення ключів, це залежить від вашого розповсюдження, правда? Не всі дистрибутиви Linux використовують systemd.
Помилка сервера

2

Використовуйте для цього завдання спеціальний модуль:

- 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

Це не ssh хост-ключі
KumZ

1

Вибачте, але я не міг використовувати "створює" у завданні. я отримав таку помилку:

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

2
Використовуйте поточну версію Ansible.
Майкл Хемптон

Ви маєте рацію, моя версія Ansible трохи стара: 2.0.0.2 ... (На Ubuntu 16.04). Я мушу змінитись!
MaxiReglisse

1

@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

1

Іншим варіантом є використання модуля користувача . Позитивною стороною цього є те, що ви отримаєте самовпевнене завдання. Ось приклад, як генерувати ключі 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 }}"

1
Це не для ключів користувача, а не ключів хоста?
MadHatter

Ви можете використовувати його і для ключів хоста, оскільки це фактично те саме. Просто не забудьте відновити контекст selinux, якщо ви використовуєте SELinux в режимі примусового виконання
HeroFromEarth

З документації мені незрозуміло, що ви можете. Якщо ви перезаписуєте свою відповідь, щоб вона явно показувала створені ключі хоста, я б видалив свій звуковий сигнал
MadHatter

Гаразд, може, це було незрозуміло. Я додав ще одне завдання пояснити, як скопіювати ці клавіші на віддаленій машині. І звичайно, це лише мій випадок (мені потрібні однакові ключі на кількох машинах для кластеру, тому мені потрібно генерувати їх на localhost), і я впевнений, що ви можете використовувати модуль 'user' для генерації ключів для ssh-сервера на віддалена машина (дивіться на 'ssh_key_file')
HeroFromEarth

Я все ще не впевнений, що це щось інше, ніж хак (не в останню чергу тому, що він залишає одному користувачеві копію приватного ключа хоста!), Але принаймні це щось, що тепер відповість на запитання, тому я видалив downvote.
MadHatter

0

Використовуйте модуль openssh_keypair та авторизований ключ для створення та розгортання ключів одночасно, не зберігаючи їх у своєму відповідальному хості.

- 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.