Привет, Хабр! Меня зовут Ольга, я инженер по автоматизации в компании РЕД СОФТ. Моя работа – превращать сложные и рутинные задачи системных администраторов в простые и понятные конфигурации в РЕД АДМ. Сегодня поговорим о системе, которая у многих администраторов вызывает легкую (или не очень) дрожь – о SELinux.

Уверена, что у каждого сисадмина есть своя история, когда какая-то служба упорно не хотела работать, а в логах было сообщение avc: denied. Классикой жанра является моментальный переход в режим Permissive (или даже Disabled), после чего всё волшебным образом начинало работать. Знакомо?

Когда мы с командой начинали разрабатывать блок конфигураций для РЕД АДМ, мы видели, как администраторы борются с SELinux. Мы тоже решили побороться, но уже на новых условиях: создали инструмент, который превращает SELinux из источника проблем в помощника. Ниже в статье рассмотрим несколько вариантов наиболее распространённых сценариев из жизни ИТ-инфраструктуры и решения, которые заставят SELinux играть на вашей стороне.

Одна вещь, делающая SELinux невыносимым (и как это исправить)

Обычно знакомство с SELinux происходит по одному сценарию:

1. Что-то не работает.
 2. В логах видим SELinux is preventing.
 3. Быстро гуглим решение и выполняем команды типа setsebool или chcon.
 4. На следующий день после перезагрузки сист��мы всё ломается снова, потому что изменения не были постоянными.

Как мы это «починили»: а) сделали изменения постоянными; б) упаковали команды в наборы конфигураций.

Итак, как это работает

Сценарий №1: Доступ к базе запрещен

Проблема: Ваш веб-сервер перестал соединяться с базой данных на другом хосте. В логах предательское avc: denied. Стандартный совет на форумах – отключить SELinux для веб-сервера.

Решение: Конфигурация «Булевые параметры SELinux»

Указываете параметр (в данном случае httpd_can_network_connect_db), выбираете его состояние «Включить» или «Выключить» и нажимаете кнопку «Применить».

Под капотом:

- name: Set SELinux boolean parameter

shell: setsebool -P {{ sebool }} {{ state }}

Всё. Просто, эффективно и надолго. Больше не нужно лезть в мануалы, чтобы вспомнить этот злосчастный ключ.

Сценарий №2: А я тут для тебя новый порт приготовил

Проблема: Вы решили запустить свой RabbitMQ на порту 9000 вместо стандартного 5672. SELinux, верный страж, блокирует все попытки подключения. Руки так и тянутся отключить его.

Решение: Конфигурация «Типы контекстов SELinux для сетевых портов»

Указываете порт, протокол и нужный тип контекста (в данном случае rabbitmq_port_t), а затем нажимаете кнопку «Применить».

Самое интересное – внутренняя логика. Наша конфигурация не слепо добавляет правило, а сначала проверяет, не занят ли порт другим контекстом.

Под капотом:

- name: Check SELinux port context

shell: |

semanage port -l | grep "{{ protocol }}" | grep -E "(^|, | +){{ seport }}(,|$)"

register: port_exists

failed_when: false

- name: Display current port contexts

debug:

msg: |

Current contexts for port(-s) {{ seport }}: {{ port_exists.stdout | regex_findall('\w+_port_t') | join(', ') }}

when: port_exists.rc == 0

- name: Determine SELinux action

set_fact:

action_type: "{{ '-a' if port_exists.rc != 0 else '-m' }}"

Если порт свободен – добавляем (-a), если уже привязан к другому типу – выводим текущие привязки в журнал, а затем модифицируем (-m).

Теперь сразу видно, какой контекст был у порта до изменения, и что затем меняется. Никаких конфликтов и случайных ошибок.

Сценарий №3: Я тут, но меня не видно!

Проблема: Вы разместили файлы для Samba-шары в /srv/share, но пользователи не могут к ним подключиться. Причина – у файлов неправильный SELinux-контекст, из-за чего служба не распознает их как разрешенные для доступа.

Решение: Конфигурация «Типы контекстов SELinux для файловых объектов»

Правильный контекст – ключ к доступу. Указываете путь к файлу или каталогу и нужный тип контекста (в данном случае samba_share_t). Система автоматически определяет тип объекта и применяет соответствующие правила.

Под капотом:

- name: SELinux context rule  

shell: |

semanage fcontext -d "{{ reg_path }}"

semanage fcontext -a -t {{ context }} "{{ reg_path }}"

restorecon -v{{ recursive }} {{ path }}

Мы не просто временно меняем контекст через chcon, а добавляем постоянное правило в политику через semanage fcontext и сразу же применяем его через restorecon.

Сценарий №4: Кто есть кто

Проблема: В системе работает несколько администраторов, и необходимо разграничить их права через SELinux. Например, пользователь admin должен работать в контексте staff_u, а auditor – в контексте user_u.

Решение: Конфигурация «Маппинг пользователей SELinux»

Указываете имя локального пользователя и соответствующего пользователя SELinux.

Под капотом:

- name: Check current SELinux user mapping

shell: |

semanage login -l | grep -w "{{ localuser }}"

register: current_mapping

failed_when: false

- name: Extract current SELinux user

set_fact:

current_seuser: "{{ current_mapping.stdout.split()[1] }}"

when: current_mapping.rc == 0

- name: Determine action type

set_fact:

action_type: "{{ '-a' if current_mapping.rc != 0 else ( '-m' if seuser != current_seuser else 'none' ) }}"

Система анализирует текущее состояние: если маппинга для пользователя нет – добавляет новый; если есть – изменяет; если уже соответствует желаемому состоянию – ничего не делает.

Сценарий №5: Кардинальные меры

Проблема: Иногда действительно нужно изменить режим работы SELinux – например, для отладки перевести в режим Permissive, где правила проверяются, но не блокируют действия.

Решение: Конфигурация «Режим SELinux»

Мы предусмотрели не только смену текущего режима, но и автоматическую пометку системы для полного пересмотра контекстов при следующей загрузке, если вы переходите из режима Disabled.

- name: Create /.autorelabel

file:

path: /.autorelabel

state: touch

when:

- mode != "disabled"

- current_mode.stdout | lower == "disabled"

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

Резюмируем

Вот такое SELinux-айкидо: не боремся, а направляем в нужное админу русло. Конфигурации в РЕД АДМ не скрывают SELinux, а, наоборот, показывают его логику и дают инструменты для осознанного управления. Вы по-прежнему должны понимать, что такое контекст, булевый параметр или тип порта. Однако больше не нужно запоминать синтаксис десятка консольных команд.

Как говорится, любой достаточно продвинутый интерфейс неотличим от магии. Мы же предпочитаем, чтобы ��то была магия, которую можно понять и контролировать.

Пишите комментарии, делитесь своим мнением и опытом работы с SELinux. Возможно, вам хотелось бы увидеть больше материалов тему конфигураций и автоматизации процессов администрирования?