SELinux через Ansible: булевы, контексты и порты

Рейтинг: 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

SELinux через Ansible: булевы, контексты и порты

Сообщение 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
Зачем вообще трогать SELinux из Ansible

Знакомая боль: накатил веб-сервер плейбуком, поменял DocumentRoot на /srv/web, открыл порт 8080, перезапустил httpd - а в браузере 403 или вообще "Permission denied" в логах. Руки тянутся к setenforce 0, и проблема "решается". А потом этот хост приезжает в прод с выключенным SELinux, и безопасник смотрит на тебя как на врага народа.

SELinux - это не лишний слой, который надо отключать. Это мандатный контроль доступа, и на RHEL/Fedora он включён по умолчанию в режиме enforcing. Правильный путь - не глушить его, а научить пускать твоё приложение туда, куда нужно. И делать это декларативно, через Ansible, чтобы конфигурация была воспроизводимой на сотне машин, а не набором ручных команд, которые ты забудешь через неделю.

Связка ansible selinux - это три кита: булевы переключатели (seboolean), контексты файлов (sefcontext) и метки портов (seport). Плюс управление самим режимом. Разберём каждый, и сразу скажу: setype и sefcontext почти гарантированно встретятся на экзамене RHCE (EX294), потому что без них реальную задачу "разверни сервис" в enforcing-режиме не закрыть.

Маленькая оговорка по дистрибутивам. SELinux - это мир RHEL-семейства (RHEL 9, Fedora, RED OS, AlmaLinux, Rocky). В Debian/Ubuntu по умолчанию AppArmor, и эти модули там просто не применимы. Все примеры ниже - для RHEL 9 с ansible-core 2.14, как на актуальном EX294.

Изображение

Режим и состояние: модуль ansible.posix.selinux

Сначала база. Узнать текущее состояние руками - getenforce и sestatus. Из Ansible режимом управляет модуль ansible.posix.selinux. Он умеет ставить enforcing, permissive или disabled и менять политику (обычно targeted).

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

- name: SELinux в enforcing, политика targeted
  ansible.posix.selinux:
    policy: targeted
    state: enforcing
Важный нюанс: переключение между enforcing/permissive применяется на лету, а вот переход в disabled или из disabled требует перезагрузки. Модуль честно вернёт в результате поле reboot_required: true. Поэтому грамотный плейбук связывает это с перезагрузкой:

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

- name: Настроить SELinux
  ansible.posix.selinux:
    state: enforcing
  register: selinux_state

- name: Перезагрузить, если SELinux этого требует
  ansible.builtin.reboot:
  when: selinux_state.reboot_required
Совет из жизни: на экзамене и в проде не выставляй disabled. Если что-то не работает - временно permissive (он не блокирует, но пишет в лог, что заблокировал бы), чините метки, возвращаете enforcing. permissive - это диагностический режим, а не "выключатель".

Булевы переключатели: ansible seboolean

Булевы (booleans) - это готовые тумблеры в политике SELinux, которыми Red Hat заранее предусмотрел частые сценарии. Не надо писать свою политику - надо просто включить нужный флаг. Посмотреть все: getsebool -a, найти описание: semanage boolean -l.

Классика: твой PHP/веб хочет ходить в сеть (коннект к БД, внешний API) - блокируется, пока не включён httpd_can_network_connect. Или NFS-домашние каталоги - use_nfs_home_dirs. Модуль ansible seboolean делает это идемпотентно:

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

- name: Разрешить httpd сетевые подключения (persistent)
  ansible.posix.seboolean:
    name: httpd_can_network_connect
    state: true
    persistent: true
Ключевой параметр - persistent: true. Без него флаг включится только до перезагрузки (эквивалент setsebool без -P), и после ребута сервис снова отвалится. Это самая частая ошибка новичков. На EX294, если в задаче сказано "настройте так, чтобы работало после перезагрузки" - persistent обязателен, иначе балл не зачтут.

Параметр state здесь булев (true/false), не путай с состоянием present/absent из других модулей. Есть ещё ignore_selinux_state на случай, когда SELinux выключен и модуль иначе упал бы с ошибкой, но в норме он не нужен.

Контексты файлов: selinux ansible через sefcontext и restorecon

Вот где срезается большинство. Каждый файл в RHEL имеет SELinux-метку (контекст), и тип в ней (setype) определяет, что с файлом можно делать. httpd читает только файлы с типом httpd_sys_content_t. Положил сайт в нестандартный /srv/web - там тип default_t или var_t, и httpd получает отказ.

Тут важно понять механику, иначе будешь биться головой. Контекст файла живёт в двух местах:
  • на самом файле (xattr на диске) - его показывает ls -Z;
  • в правилах политики - "файлам по такому-то пути назначать такой-то тип". Это база fcontext.
Модуль community.general.sefcontext правит только правило в политике. Он НЕ перемечает уже существующие файлы. Поэтому связка всегда из двух шагов: сначала sefcontext добавляет правило, потом restorecon применяет его к реальным файлам на диске. Забыл restorecon - метки на файлах остались старыми, httpd по-прежнему упирается в 403. Это грабли номер один и в проде, и на экзамене.

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

- name: Правило контекста для каталога веб-сервера
  community.general.sefcontext:
    target: '/srv/web(/.*)?'
    setype: httpd_sys_content_t
    state: present
  notify: restore web context

# в handlers:
- name: restore web context
  ansible.builtin.command: restorecon -Rv /srv/web
Разберём по косточкам. target - это регулярка пути в формате semanage, не glob. Запись (/.*)? значит "сам каталог и всё внутри рекурсивно". setype - целевой тип; для статики httpd это httpd_sys_content_t, для каталогов, куда веб пишет (загрузки) - httpd_sys_rw_content_t. Параметр state: present создаёт правило (под капотом semanage fcontext -a), absent - удаляет.

Почему restorecon вынесен в handler, а не отдельной задачей? Чтобы перемечать только когда правило реально изменилось. Сам по себе ansible.builtin.command неидемпотентен (Ansible не знает, надо ли перемечать), а notify запускает его лишь при changed от sefcontext. restorecon же по своей природе идемпотентен: если метки уже правильные - он ничего не трогает. Альтернатива restorecon - ansible.builtin.command с chcon, но chcon меняет метку только на файле и не переживёт общего restorecon, так что для постоянной настройки всегда sefcontext + restorecon.

Цельный фрагмент роли, который реально разворачивает сайт в нестандартном каталоге в enforcing-режиме:

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

- name: Каталог сайта
  ansible.builtin.file:
    path: /srv/web
    state: directory
    mode: '0755'

- name: Правило SELinux-контекста
  community.general.sefcontext:
    target: '/srv/web(/.*)?'
    setype: httpd_sys_content_t
    state: present
  notify: restore web context

- name: Индексная страница
  ansible.builtin.copy:
    content: "Cyberlake works\n"
    dest: /srv/web/index.html
    mode: '0644'
  notify: restore web context

- name: Открыть порт во firewalld
  ansible.posix.firewalld:
    service: http
    permanent: true
    immediate: true
    state: enabled
Порты: ansible setype для нестандартного порта через seport

SELinux метит не только файлы, но и сетевые порты. По умолчанию httpd разрешено слушать 80, 443, 8080 и ещё несколько (тип http_port_t). Решил повесить веб на 8000 - SELinux заблокирует bind, и сервис не стартанёт. Посмотреть, какие порты к какому типу привязаны: semanage port -l. Из Ansible это лечит модуль ansible.posix.seport:

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

- name: Разрешить httpd слушать порт 8000
  ansible.posix.seport:
    ports: 8000
    proto: tcp
    setype: http_port_t
    state: present
Логика та же, что у файлов: ты приписываешь порту 8000 тип http_port_t (тот же setype, только для порта), и теперь демоны, которым разрешён этот тип, могут на нём слушать. ports принимает и диапазон ("9000-9005"), proto - tcp или udp. И снова не забывай: открыть порт в firewalld - это отдельная задача (ansible.posix.firewalld), SELinux и файрвол - разные подсистемы, нужны обе.

Типичные грабли
  • Забыл restorecon после sefcontext. Правило есть, метки на файлах старые - сервис всё равно в отказе. Лечится handler-ом, как выше.
  • Забыл persistent: true в seboolean - после ребута всё разваливается.
  • Перепутал target в sefcontext: написал glob /srv/web/* вместо регулярки /srv/web(/.*)? - часть путей не покрылась.
  • Поставил setenforce 0 "на попробовать" и забыл вернуть. На EX294 это провал автоматом: проверка идёт в enforcing.
  • Лечил chcon вместо sefcontext - метка слетит при следующем restorecon -R или релейбле ФС.
  • Диагностика вслепую. Смотри причину: ausearch -m AVC -ts recent или sealert -a /var/log/audit/audit.log из пакета setroubleshoot-server. AVC-запись прямо подскажет нужный тип или булев.
Мини-лаба

Подними тестовую RHEL 9 (или RED OS) и руками-через-Ansible проведи путь целиком:
  • Установи httpd, переопредели DocumentRoot на /srv/web, положи туда index.html.
  • Напиши плейбук: ansible.posix.selinux (enforcing), community.general.sefcontext на /srv/web с httpd_sys_content_t + handler restorecon, ansible.posix.seport на нестандартный порт, ansible.posix.firewalld.
  • Включи нужный булев через ansible.posix.seboolean с persistent: true (например httpd_can_network_connect, если сайт стучится наружу).
  • Запусти, проверь ls -Z /srv/web и getsebool -a, дёрни curl. Затем удали из плейбука restorecon, накати на чистую машину - убедись, что ловишь 403. Это закрепит, зачем он нужен.
Контрольные вопросы
  • Почему один модуль community.general.sefcontext не чинит доступ к файлам и какой второй шаг обязателен?
  • Что делает persistent: true в ansible.posix.seboolean и что будет без него после перезагрузки?
  • Чем отличается permissive от disabled и почему на EX294 нельзя ставить disabled?
  • Тебе надо повесить веб-сервер на TCP-порт 8000 - какой модуль и какой setype используешь, и что ещё открыть, чтобы соединение дошло?
Итог

SELinux из Ansible - это четыре инструмента под одну задачу: ansible.posix.selinux держит режим enforcing, ansible.posix.seboolean щёлкает готовые тумблеры (с persistent), community.general.sefcontext плюс restorecon правят метки файлов, ansible.posix.seport - метки портов. Запомни главную связку "sefcontext + restorecon" и параметр persistent - на этом сыпется большинство и в проде, и на экзамене. Не выключай SELinux. Научи его пускать твой сервис - это ровно то, что проверяет RHCE.
👍5 ❤️4 🔥1 😄 🤔
Аватара пользователя
jjonclo
Сообщения: 1
Зарегистрирован: 26 май 2026, 07:38

Re: SELinux через Ansible: булевы, контексты и порты

Сообщение jjonclo »

Вопрос по экзамену: на EX294 нормально решать через handler с restorecon или они хотят чтобы это была обычная задача? Боюсь что handler не отработает если sefcontext не changed на повторном прогоне.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
sleonard
Сообщения: 1
Зарегистрирован: 04 июн 2026, 06:17

Re: SELinux через Ansible: булевы, контексты и порты

Сообщение sleonard »

Вот про restorecon прям в точку, я неделю назад на этом и попался: правило semanage добавил, ls -Z показывает старый тип, httpd 403. Думал политика битая, а оказалось просто перемечать забыл. Спасибо что разжевали механику с двумя местами хранения контекста.
👍 ❤️1 🔥 😄 🤔1
Ответить
← Предыдущая глава
Безопасность: hardening SSH и репозитории dnf/yum
Следующая глава →
Сквозной проект и подготовка к экзамену EX294

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

Поделиться темой: ✈ Telegram VK
Похожие запросы: управление selinux через ansible булевы контексты и портыкак готовиться к экзамену rhce ex294 с нуля

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

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

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