Вы запускаете скрипт up от имени root, он завершается, а тот же скрипт терпит неудачу, когда его вызывает служба. Права файла не изменились, поэтому естественный следующий шаг — снова их ослабить, что ничего не исправляет. На хосте с SELinux решающим фактором часто оказывается не то, кто такой процесс, а то, в каком домене он работает, а root внутри ограниченного домена остаётся ограниченным.

Та же команда, два разных домена безопасности

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

Именно поэтому сравнивать два запуска полезно, только если сравнивать их контексты. Запустите ту же команду из оболочки и из hook: версия из оболочки доказывает, что бинарный файл существует и аргументы верны, но ничего не доказывает о том, разрешено ли службе его выполнять. Запустите её обоими способами и сравните домены, а не только коды выхода. Именно это сравнение превращает расплывчатую жалобу на разрешения в конкретный вопрос об одном домене и одной метке.

Классическая форма этой неисправности — помощник, который вызывает внешний инструмент. Сам hook может быть разрешён, тогда как у вызываемого инструмента есть метка, которую домен службы не может выполнить, или он пишет в каталог, метка которого это запрещает.

Прочитайте запись AVC рядом с ошибкой hook

Отказ AVC называет поля, которые решают дело: контекст источника процесса, контекст цели объекта, класс объекта и конкретное отклонённое разрешение. Прочитайте все четыре, прежде чем строить теорию, потому что отказ на execute и отказ на write требуют совершенно разных исправлений.

ausearch -m AVC,USER_AVC -ts recent
ls -Z /usr/local/sbin/vpn-up.sh
ps -eZ | grep openvpn

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

Отметьте рядом с записью версию политики и точный путь исполняемого файла. Имя домена, встречающееся в политике одного дистрибутива, — это свидетельство об этой установке, а не гарантия, что другая сборка поставляет те же правила. Именно этот контекст позволяет другому человеку воспроизвести ваш вывод на своём хосте. Без него запись читается как анекдот, а не как доказательство.

Метка, конфигурация или политика: три исправления

Первое исправление — метка, не соответствующая установленному расположению файла. Скрипт, скопированный на место с помощью cp или написанный редактором, может нести метку по умолчанию, которую домен службы не может использовать, и восстановление ожидаемого контекста исправляет это, вообще не трогая политику.

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

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

Почему старый модуль allow не является ответом

Результаты поиска по этой неисправности полны готовых модулей, часто для инструмента, который hook больше не вызывает. Установка одного даёт разрешения, которые могут не иметь никакого отношения к вашему отказу, и оставляет реальное несоответствие на месте, добавляя постоянную дыру.

Он также скрывает следующий сбой. Модуль, разрешающий широкий класс операций, заставит эту ошибку исчезнуть и превратит следующую в нечто гораздо более трудное для привязки. Удаление модуля позже — тоже изменение, которое никто не хочет планировать, поэтому короткий путь имеет свойство становиться постоянным.

Дисциплинированное сравнение — это сравнение между отказом, который вы можете прочитать, и изменением, которое вы предлагаете. Руководство Red Hat по устранению неполадок SELinux ставит проверки меток и конфигурации перед сгенерированной политикой именно по этой причине. Если в записи нет соответствующего отказа, SELinux, вероятно, не ваша проблема, и вопросы пути, sandbox или разрешений остаются открытыми.

Похожие статьи