Управление SSH-ключами через Ansible: authorized_key

Рейтинг: 71.7% · 16 голосов
Подробный курс по Ansible с прицелом на экзамен RHCE EX294: установка и инвентарь, плейбуки, переменные и факты, Vault, циклы и условия, шаблоны Jinja2, роли и коллекции, Execution Environments и ansible-navigator, управление системами (диски, LVM, cron, SELinux, firewalld). Примеры на RHEL/Fedora. Актуально на 2026.
Ответить
Аватара пользователя
Maksim_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Управление SSH-ключами через Ansible: authorized_key

Сообщение Maksim_DevOps »

Оглавление курса (47)
  1. Что такое Ansible и зачем он нужен: автоматизация без агентов
  2. Сертификация RHCE и экзамен EX294: что внутри и как готовиться
  3. Архитектура Ansible: control node, узлы, модули и плагины
  4. Установка Ansible на control node: dnf, pip и версии ansible-core
  5. Подготовка управляемых узлов: SSH, пользователь и sudo
  6. Инвентарь Ansible: hosts, группы и переменные
  7. Настройка Ansible: файл ansible.cfg и приоритеты конфигурации
  8. Host patterns и инструменты командной строки Ansible
  9. Ad hoc команды Ansible: быстрые задачи без плейбука
  10. Ansible playbook: что это такое и как устроен
  11. Структура плейбука: play, task, модули и переменные
  12. Запуск плейбуков: проверка, теги, ограничения и отладка
  13. Параллелизм и порядок выполнения: forks, serial, strategy
  14. Факты Ansible: сбор информации об узлах
  15. Переменные Ansible: типы, объявление и приоритет
  16. Регистрация результатов и специальные переменные
  17. Ansible Vault: шифрование паролей и секретов
  18. Организация инвентаря: group_vars, host_vars и вложенные группы
  19. Динамический инвентарь и инвентарные плагины
  20. Циклы в Ansible: loop, списки и словари
  21. Повтор задачи до условия: until, retries и delay
  22. Условия в Ansible: директива when и логика
  23. Jinja2 в Ansible: выражения, фильтры и подстановки
  24. Обработчики Ansible: handlers, notify и flush_handlers
  25. Обработка ошибок: failed_when, changed_when и ignore_errors
  26. Блоки в Ansible: block, rescue и always
  27. Управление файлами: модули file, copy, fetch и stat
  28. Архивы и сборка файлов: archive, unarchive, assemble
  29. Точечное редактирование файлов: lineinfile и blockinfile
  30. Шаблоны Jinja2: модуль template и динамические конфиги
  31. Jinja2 продвинуто: фильтры, циклы, макросы и lookup
  32. Модули Ansible: ansible-doc и поиск нужного модуля
  33. Разработка собственного модуля Ansible на Python
  34. Роли Ansible и Ansible Galaxy: переиспользование
  35. Разработка роли Ansible: создание с нуля
  36. Зависимости ролей и requirements.yml
  37. Коллекции Ansible: ansible.posix, community и своя коллекция
  38. Execution Environments: контейнеры для запуска Ansible
  39. Сборка Execution Environment с ansible-builder
  40. ansible-navigator: запуск плейбуков в Execution Environment
  41. Управление SSH-ключами через Ansible: authorized_key (вы здесь)
  42. Управление дисками: filesystem, mount и parted
  43. LVM через Ansible: тома, группы и расширение
  44. Планировщик задач: cron и systemd timers через Ansible
  45. Безопасность: hardening SSH и репозитории dnf/yum
  46. SELinux через Ansible: булевы, контексты и порты
  47. Сквозной проект и подготовка к экзамену EX294
Представь парк из сорока серверов. Тебе нужно завести там нового админа, раскатать его публичный ключ, а заодно выкинуть ключ уволенного коллеги, который полгода висит в authorized_keys и про который все забыли. Руками через ssh-copy-id на каждую машину - это полдня и гарантированный дрейф конфигов: где-то ключ забыли, где-то добавили лишний. Ansible решает это одной таской, и сегодня разберём, как раздать ssh ключ через ansible так, чтобы состояние было воспроизводимым и идемпотентным, а не "вроде раскатал, надо проверить".

Тема не учебная для галочки: на экзамене RHCE (EX294) раздача SSH-ключей через authorized_key - прямая задача из главы про управление пользователями. Там реально просят: создай пользователя на всех узлах и положи ему публичный ключ. Кто путает, чей ключ кладёт и куда, теряет баллы на ровном месте.

Зачем вообще ansible authorized_key, а не shell

Можно ведь просто скопировать файл в ~/.ssh/authorized_keys через ansible.builtin.copy. Можно. Но тогда ты управляешь файлом целиком: либо затираешь всё, что там было, либо не трогаешь чужие ключи вообще. А жизнь между этими крайностями. Модуль ansible.posix.authorized_key понимает структуру файла: он добавляет конкретный ключ, не ломая остальные, проверяет, есть ли он уже (идемпотентность), и умеет режим "только эти ключи и никаких других". Плюс сам создаёт каталог .ssh с правильными правами 0700 и сам файл с 0600 - а на эти права болезненно реагирует sshd и SELinux в RHEL/Fedora.

Модуль живёт в коллекции ansible.posix, поэтому полное имя (FQCN) - ansible.posix.authorized_key. Если коллекции нет, ставится так:

Код: Выделить всё

ansible-galaxy collection install ansible.posix
Ключевые параметры, которые надо знать наизусть для работы с ansible ssh key:
  • user - чьи authorized_keys правим (обязательный). Это пользователь НА УЗЛЕ, не тот, под кем подключаешься.
  • key - сам публичный ключ строкой, или несколько ключей, или даже URL вида https://github.com/username.keys.
  • state - present (добавить) или absent (убрать). По умолчанию present.
  • exclusive - если true, в файле останутся ТОЛЬКО ключи из этой таски, всё остальное вычищается. Мощно и опасно.
  • path - нестандартный путь к файлу ключей, если authorized_keys лежит не в дефолтном месте.
  • key_options - опции ограничения: from="10.0.0.0/24", command="...", no-agent-forwarding и прочее.
Изображение

Практика: раздаём ключ админа на парк серверов

Сначала ключ нужно иметь. Сгенерировать пару на своей машине - обычный ssh-keygen, ничего ansible-специфичного:

Код: Выделить всё

ssh-keygen -t ed25519 -C "admin@cyberlake" -f ~/.ssh/id_admin
Ed25519 короче и быстрее RSA, для новых ключей бери его. Если по требованиям нужен RSA - только 4096 бит, не меньше.

Теперь типовой плейбук. Сначала заводим пользователя автоматизации через ansible.builtin.user, потом кладём ему ключ. Связка ansible user ssh - именно про это: пользователь и его ключ управляются вместе, в одном плейбуке, иначе получится таска, которая падает на несуществующем юзере.

Код: Выделить всё

---
- name: Раскатка админского SSH-доступа на парк серверов
  hosts: all
  become: true
  vars:
    admin_user: deploy
  tasks:
    - name: Создаём пользователя автоматизации
      ansible.builtin.user:
        name: "{{ admin_user }}"
        shell: /bin/bash
        state: present

    - name: Кладём публичный ключ админа
      ansible.posix.authorized_key:
        user: "{{ admin_user }}"
        state: present
        key: "{{ lookup('ansible.builtin.file', '~/.ssh/id_admin.pub') }}"
Обрати внимание на lookup: он читает файл с публичным ключом на управляющей машине во время сборки, а не на узле. Это частая ошибка - думать, что ansible сам где-то найдёт ключ. Нет, ты явно говоришь, откуда его взять.

Запускаем по всему инвентарю:

Код: Выделить всё

ansible-playbook -i inventory site.yml
Прогони второй раз - таска authorized_key покажет ok, а не changed. Это и есть идемпотентность: ключ уже на месте, модуль ничего не трогает.

exclusive: наводим жёсткий порядок в ключах

Самое интересное в задаче "ansible ssh ключи на парке" - это уборка. Допустим, политика такая: на сервере должны лежать ровно два ключа, админский и CI-раннера, и больше ничего. Любой ключ, который кто-то добавил руками, должен исчезнуть при следующем прогоне. Для этого exclusive: true, причём оба ключа передаются ОДНОЙ строкой через перевод строки:

Код: Выделить всё

- name: Только разрешённые ключи, остальное вычистить
  ansible.posix.authorized_key:
    user: deploy
    state: present
    exclusive: true
    key: |
      {{ lookup('ansible.builtin.file', '~/.ssh/id_admin.pub') }}
      {{ lookup('ansible.builtin.file', '~/.ssh/id_ci.pub') }}
Важнейший момент про exclusive: он работает в рамках ОДНОЙ таски. Если ты сделаешь две отдельные таски с exclusive: true для одного пользователя, вторая затрёт результат первой. Поэтому при exclusive все нужные ключи перечисляй разом. На этом срезаются и в проде, и на тренировках к экзамену: положили админский ключ exclusive, потом отдельной таской CI-ключ exclusive - и админский улетел.

Убрать конкретный ключ уволенного без exclusive - чисто state: absent:

Код: Выделить всё

- name: Отозвать ключ бывшего сотрудника
  ansible.posix.authorized_key:
    user: deploy
    state: absent
    key: "ssh-ed25519 AAAA...старый_ключ... ivan@old"
Безопасность: отключаем вход по паролю

Раскатать ключи - половина дела. Пока на сервере разрешён вход по паролю, ключи дают удобство, но не защиту: брутфорс пароля root по ssh никуда не делся. После того как ключевой доступ проверен и работает (проверь обязательно, иначе закроешь себе вход), выключаем парольную аутентификацию через sshd. На RHEL/Fedora правим конфиг и перезапускаем демон:

Код: Выделить всё

- name: Запретить вход по паролю
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PasswordAuthentication'
    line: 'PasswordAuthentication no'
    validate: 'sshd -t -f %s'
  notify: restart sshd

handlers:
  - name: restart sshd
    ansible.builtin.service:
      name: sshd
      state: restarted
Параметр validate здесь спасает от катастрофы: ansible не применит файл, если sshd -t нашёл синтаксическую ошибку. Без него одна опечатка в sshd_config валит демон на всём парке разом. На современных RHEL 9 учти, что конфиг может подтягивать /etc/ssh/sshd_config.d/*.conf, и drop-in файл способен переопределить твою строку - проверяй итоговый эффект через sshd -T.

Маленькая заметка про другие дистрибутивы: на Ubuntu/Debian модуль authorized_key работает ровно так же, отличается только установка пакетов (apt вместо dnf) и иногда имя сервиса (ssh вместо sshd). На RED OS и Astra Linux всё ближе к RHEL-семейству, sshd и systemd на месте.

Типичные грабли
  • Путают user в таске. user - это владелец authorized_keys НА УЗЛЕ, а не аккаунт подключения Ansible. Хочешь ключ для deploy - пиши user: deploy.
  • Передают приватный ключ вместо публичного. В authorized_keys идёт ТОЛЬКО .pub. Приватный там - дыра размером с сервер.
  • Забывают про exclusive scope. Несколько exclusive-тасок на одного юзера затирают друг друга. Все ключи - в одну таску.
  • SELinux и контекст. Если создавал .ssh нестандартно, контекст ssh_home_t может слететь, и вход не пойдёт. Модуль сам ставит права, но при ручных манипуляциях спасает restorecon -Rv ~/.ssh.
  • become забыли. Чтобы писать в чужой ~/.ssh, нужен become: true, иначе таска упрётся в права.
Мини-лаба

Повтори руками на двух тестовых узлах:
  • Сгенерируй пару ed25519 через ssh-keygen, не задавая passphrase.
  • Напиши плейбук: ansible.builtin.user создаёт юзера automation, ansible.posix.authorized_key кладёт ему публичный ключ.
  • Прогони дважды, убедись что второй раз - ok, а не changed.
  • Добавь второй ключ с exclusive: true одной строкой, проверь cat ~automation/.ssh/authorized_keys - лишнего нет.
  • Отзови один ключ через state: absent.
  • Отключи PasswordAuthentication с validate, перезайди по ключу и убедись, что пароль больше не спрашивают.
Контрольные вопросы
  • Чем ansible.posix.authorized_key лучше копирования файла authorized_keys целиком?
  • Что делает exclusive: true и почему опасно ставить его в нескольких тасках для одного пользователя?
  • Какой ключ - публичный или приватный - идёт в параметр key и почему?
  • Зачем нужен validate в таске правки sshd_config и что будет без него?
Итог

ansible.posix.authorized_key превращает раздачу SSH-доступа из ручной рутины в воспроизводимое состояние: один плейбук - и весь парк синхронизирован. Связка с ansible.builtin.user даёт полный цикл "завести пользователя и выдать ему ключ", exclusive держит файл в чистоте, а отключение парольной аутентификации закрывает дыру. Для EX294 это базовый навык, который должен отскакивать от зубов: создать юзера, положить ключ, проверить идемпотентность. Отработай мини-лабу - и эта задача на экзамене станет одной из самых быстрых.
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
lolka2
Сообщения: 1
Зарегистрирован: 16 май 2026, 23:24

Re: Управление SSH-ключами через Ansible: authorized_key

Сообщение lolka2 »

Долго копировал ключи через ssh-copy-id по машинам, теперь дошло почему все хвалят authorized_key. Вопрос: если exclusive true стоит, а кто-то добавит ключ руками между прогонами - он же при следующем плейбуке улетит, верно?
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
soliditynerd
Сообщения: 1
Зарегистрирован: 15 май 2026, 07:02

Re: Управление SSH-ключами через Ansible: authorized_key

Сообщение soliditynerd »

Спасибо за акцент на validate в sshd_config. Один раз положил весь парк опечаткой в этом файле, теперь без sshd -t вообще ничего не трогаю.
👍 ❤️1 🔥 😄 🤔2
Ответить
← Предыдущая глава
ansible-navigator: запуск плейбуков в Execution Environment
Следующая глава →
Управление дисками: filesystem, mount и parted

Все главы курса «Ansible: автоматизация и подготовка к RHCE (EX294)»

Поделиться темой: ✈ Telegram VK
Похожие запросы: что такое ansible простыми словамиansible для начинающих с чего начатьустановка ansible на linuxпеременные ansible приоритет какая важнеециклы ansible loop по списку и словарюколлекции ansible posix и community установка через galaxy и fqcn модулей

Вернуться в «Ansible: автоматизация и подготовка к RHCE (EX294)»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость