Представьте ситуацию: вам нужно дать пользователю права на выполнение команды find через sudo, но при этом запретить потенциально опасные варианты вроде -exec rm или -delete. Казалось бы, всё просто – добавил разрешение и исключения в sudoers. Но на практике правила срабатывают не так, как ожидается. Почему? Давайте разберёмся с нюансами работы sudoers и тонкостями настройки.
Основная проблема кроется в порядке записи правил. Sudo обрабатывает их сверху вниз, и последнее совпавшее правило становится приоритетным. Если сначала запретить -exec, а потом разрешить find *, то разрешение «перекроет» запрет. Вот типичная ошибка:
myUser ALL=!/usr/bin/find * -exec * # Запрет
myUser ALL=!/usr/bin/find * -delete * # Запрет
myUser ALL=/usr/bin/find * # Разрешение
Здесь команда sudo find … -exec … всё равно выполнится, потому что последнее правило (/usr/bin/find *) разрешает всё, что начинается с find.
Как правильно настроить порядок правил
Решение – поменять последовательность. Сначала разрешите общий вызов find, а затем добавьте запреты для конкретных опций:
myUser ALL=/usr/bin/find * # Разрешаем базовый find
myUser ALL=!/usr/bin/find * -exec * # Запрещаем -exec с аргументами
myUser ALL=!/usr/bin/find * -delete * # Запрещаем -delete с аргументами
Почему это работает:
- Когда пользователь вводит sudo find /path -exec ls {} ;, sudo проверяет правила по порядку.
- Первое правило (/usr/bin/find *) разрешает команду, но следующие строки добавляют исключения для -exec и -delete.
- Поскольку запреты идут после разрешения, они имеют приоритет.
Кстати, именно так работает «белый список» в sudoers: общее разрешение + точечные запреты.
Тонкости, о которых часто забывают
Даже после настройки могут остаться лазейки. Например:
1. Короткие варианты команд:
Если пользователь запустит sudo find -exec … (без указания пути), правило find * -exec *` не сработает. Для этого случая нужна отдельная строка:
myUser ALL=!/usr/bin/find -exec * # Без путей перед -exec
2. Другие опасные опции:
Помимо -exec и -delete, стоит запретить:
- -ok # Интерактивный аналог -exec
- -execdir # Выполняет команды в каталоге найденного файла
- -fprint # Сохранение результатов в файл (может перезаписать системные файлы)
Полный список зависит от версии find (проверьте через man find).
3. Специфика аргументов:
Для -delete иногда требуется отдельное правило без `*` в конце, если опция стоит в самом конце команды:
myUser ALL=!/usr/bin/find * -delete # Без звёздочки
Пример полной конфигурации
Вот как может выглядеть итоговый файл в /etc/sudoers.d/myUser:
# Разрешаем базовый find
myUser ALL=/usr/bin/find *
# Запрещаем опасные опции
myUser ALL=!/usr/bin/find * -exec *
myUser ALL=!/usr/bin/find * -delete *
myUser ALL=!/usr/bin/find * -execdir *
myUser ALL=!/usr/bin/find * -ok *
myUser ALL=!/usr/bin/find * -fprint *
# Запреты для случаев без указания пути
myUser ALL=!/usr/bin/find -exec *
myUser ALL=!/usr/bin/find -delete
Как проверить настройку:
1. Попробуйте выполнить запрещённую команду:
sudo find /var/log -name "*.log" -exec rm {} ;
Если всё настроено верно, вы увидите: Sorry, user myUser is not allowed to execute…
2. Убедитесь, что обычный find работает:
sudo find /home -name "*.txt" # Должно выполняться без ошибок
Важно: Никогда не редактируйте sudoers через обычный текстовый редактор. Используйте
visudo
– эта команда проверяет синтаксис перед сохранением и предотвращает ошибки, которые могут заблокировать доступ к sudo.
Если после настройки что-то пошло не так (например, все команды find запрещены), проверьте:
– Нет ли опечаток в путях (/usr/bin/find vs /bin/find);
– Корректно ли указаны аргументы (пробелы, звёздочки);
– Не перекрывают ли другие файлы в /etc/sudoers.d ваши правила.
Итог: Правильная настройка sudoers для find требует не только знания синтаксиса, но и понимания, как sudo применяет правила. Главное – расположить запреты после общего разрешения и учесть все возможные варианты использования опасных опций. Не поленитесь потратить 10 минут на тестирование: это избавит от головной боли в будущем.