--- title: Sudoers status: seed type: guide tags: - linux - sudo - security created: 2026-06-15 updated: 2026-06-15 aliases: - sudoers - Настройка sudo --- # Sudoers `sudo` запускает команду с полномочиями другого пользователя, обычно `root`. Политика доступа задаётся в `/etc/sudoers` и дополнительных файлах из `/etc/sudoers.d/`. `sudo` не является заменой файловых прав. Он выдаёт полномочия на конкретное действие после проверки пользователя, хоста, целевого пользователя, команды и параметров политики. ## Где хранится конфигурация - `/etc/sudoers` — основной файл. - `/etc/sudoers.d/` — каталог для отдельных правил. - `/var/log/` или журнал systemd — записи о вызовах `sudo`, в зависимости от конфигурации системы. Основной файл обычно содержит: ```sudoers @includedir /etc/sudoers.d ``` Для локальных правил удобнее создавать отдельный файл: ```bash sudo visudo -f /etc/sudoers.d/backup ``` Имена файлов в `sudoers.d` лучше делать без точки и символа `~`: некоторые реализации игнорируют такие файлы. Права должны исключать запись обычными пользователями: ```bash sudo chown root:root /etc/sudoers.d/backup sudo chmod 0440 /etc/sudoers.d/backup ``` ## Редактирование через visudo Не следует редактировать `/etc/sudoers` обычным редактором. `visudo` блокирует файл от одновременного изменения и проверяет синтаксис перед сохранением. ```bash sudo visudo sudo visudo -f /etc/sudoers.d/backup sudo visudo -c ``` Если ошибка уже внесена, исправление потребует действующей root-сессии, загрузки в recovery mode или другого способа получить root-доступ. Редактор можно выбрать переменными окружения: ```bash sudo EDITOR=nvim visudo ``` Возможность выбора редактора зависит от настроек `sudo`; небезопасные переменные окружения могут быть отброшены. ## Формат правила Базовая форма: ```sudoers пользователь хост=(целевой_пользователь:целевая_группа) теги: команды ``` Пример: ```sudoers ada ALL=(root) /usr/bin/systemctl restart nginx ``` Значение полей: | Поле | Смысл | |---|---| | `ada` | кому разрешено использовать правило | | `ALL` | на каких хостах действует правило | | `(root)` | от имени какого пользователя разрешён запуск | | `/usr/bin/systemctl restart nginx` | разрешённая команда и аргументы | Группа указывается с `%`: ```sudoers %wheel ALL=(ALL:ALL) ALL ``` Это разрешает членам группы `wheel` запускать любые команды от имени любого пользователя и группы. Такое правило выдаёт полный административный доступ. ## Команды и аргументы В правилах следует использовать абсолютный путь: ```sudoers ada ALL=(root) /usr/bin/systemctl status nginx ``` Путь можно узнать командой: ```bash command -v systemctl ``` Аргументы являются частью разрешения. Эти правила различаются: ```sudoers ada ALL=(root) /usr/bin/systemctl restart nginx ada ALL=(root) /usr/bin/systemctl restart * ``` Первое разрешает перезапустить только `nginx`. Второе намного шире и может разрешить перезапуск произвольного юнита. Правило без аргументов в современных версиях `sudo` может разрешать команду с любыми аргументами. Для явного запрета аргументов используется пустая строка: ```sudoers ada ALL=(root) /usr/bin/id "" ``` Поведение сопоставления аргументов и специальных символов зависит от версии `sudo`. После изменения правило нужно проверять на целевой системе. ## Псевдонимы Псевдонимы уменьшают повторение в больших конфигурациях. ### User_Alias ```sudoers User_Alias OPERATORS = ada, alice, %ops ``` ### Runas_Alias ```sudoers Runas_Alias SERVICE_USERS = nginx, postgres ``` ### Host_Alias ```sudoers Host_Alias WEB_SERVERS = web01, web02 ``` ### Cmnd_Alias ```sudoers Cmnd_Alias NGINX_CONTROL = \ /usr/bin/systemctl status nginx, \ /usr/bin/systemctl reload nginx, \ /usr/bin/systemctl restart nginx %ops WEB_SERVERS=(root) NGINX_CONTROL ``` Имена псевдонимов принято писать в верхнем регистре. ## Теги ### PASSWD и NOPASSWD По умолчанию `sudo` запрашивает пароль вызывающего пользователя: ```sudoers ada ALL=(root) /usr/bin/systemctl restart nginx ``` Без пароля: ```sudoers ada ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx ``` `NOPASSWD` удобно для автоматизации, но увеличивает последствия компрометации учётной записи. Его следует ограничивать минимальным набором команд. Теги действуют на следующие команды в списке, пока не будут переопределены: ```sudoers ada ALL=(root) NOPASSWD: /usr/bin/systemctl status nginx, \ PASSWD: /usr/bin/systemctl restart nginx ``` ### NOEXEC ```sudoers ada ALL=(root) NOEXEC: /usr/bin/less /var/log/nginx/error.log ``` `NOEXEC` пытается запретить программе запускать другие процессы. Это дополнительная мера, а не надёжная граница безопасности: поддержка зависит от платформы и типа бинарника. ### SETENV ```sudoers ada ALL=(root) SETENV: /usr/local/sbin/deploy ``` `SETENV` позволяет передавать переменные окружения с меньшим числом ограничений. Это опасно для команд, поведение которых зависит от `PATH`, загрузчиков библиотек, интерпретаторов и конфигурационных переменных. ## Defaults Директивы `Defaults` управляют поведением `sudo`. ```sudoers Defaults env_reset Defaults use_pty Defaults timestamp_timeout=5 Defaults passwd_tries=3 ``` Часто используемые параметры: | Параметр | Назначение | |---|---| | `env_reset` | оставляет ограниченный набор переменных окружения | | `secure_path` | задаёт доверенный `PATH` для команд через `sudo` | | `use_pty` | запускает команду в псевдотерминале | | `timestamp_timeout` | срок действия успешной аутентификации в минутах | | `passwd_tries` | число попыток ввода пароля | | `log_input`, `log_output` | запись ввода и вывода поддерживаемых сессий | Пример `secure_path`: ```sudoers Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/bin" ``` Настройки можно ограничить пользователем, группой, хостом или командой: ```sudoers Defaults:ada timestamp_timeout=0 Defaults:%ops use_pty Defaults!/usr/bin/systemctl !log_output ``` `timestamp_timeout=0` требует пароль для каждого отдельного запуска. Отрицательное значение создаёт сессию без ограничения по времени и обычно нежелательно. ## Запуск от имени другого пользователя ```sudoers ada ALL=(postgres) /usr/bin/psql ``` Использование: ```bash sudo -u postgres /usr/bin/psql ``` С указанием группы: ```sudoers ada ALL=(deploy:deploy) /usr/local/bin/release ``` ## Запреты Команду можно исключить через `!`: ```sudoers ada ALL=(root) ALL, !/usr/bin/su, !/usr/bin/bash ``` Такой список не создаёт безопасное ограничение полного административного доступа. Пользователь с разрешением `ALL` часто может получить оболочку другим способом: через редактор, интерпретатор, отладчик, файловый менеджер, загрузку модуля, изменение исполняемого файла или сервисной конфигурации. Отрицания полезны для уточнения узкого списка, но не должны использоваться как sandbox. ## Опасные категории команд Нельзя считать ограниченными команды, которые позволяют: - запустить оболочку или произвольный процесс; - выполнять код или загружать модули; - редактировать произвольные файлы; - менять владельца, права или ACL; - записывать в исполняемые файлы и каталоги из `PATH`; - менять unit-файлы, cron-задачи, PAM, загрузчик или конфигурацию сервисов; - читать секреты и закрытые ключи; - управлять контейнерами или виртуальными машинами с доступом к хосту. Примеры команд, которые часто позволяют выйти к root: ```text sh, bash, zsh, python, ruby, perl, vim, nvim, less, find, tar, rsync, awk, sed, env, systemctl, docker, podman ``` Риск зависит от разрешённых аргументов, файловой системы и окружения. Само имя команды недостаточно для оценки безопасности. ## Безопасная автоматизация Предпочтительный подход — разрешить один root-owned wrapper с фиксированным поведением: ```sudoers deploy ALL=(root) NOPASSWD: /usr/local/sbin/restart-myapp ``` Требования к wrapper: - файл и родительские каталоги не доступны на запись вызывающему пользователю; - используются абсолютные пути; - входные параметры проверяются по allowlist; - не выполняются строки через shell без необходимости; - окружение очищается или задаётся явно; - временные файлы создаются безопасно; - логируются значимые действия. Если пользователь может изменить разрешённый скрипт, библиотеку, конфигурацию или исполняемый файл, правило фактически разрешает выполнение произвольного кода с повышенными правами. ## Проверка правил Показать доступные текущему пользователю команды: ```bash sudo -l ``` Проверить другого пользователя от root: ```bash sudo -l -U ada ``` Сбросить сохранённую аутентификацию: ```bash sudo -k ``` Удалить timestamp полностью: ```bash sudo -K ``` Проверить конфигурацию: ```bash sudo visudo -c ``` Проверять нужно не только синтаксис, но и фактический результат `sudo -l`: правила могут объединяться, а более широкое разрешение в другом файле отменяет ожидаемое ограничение. ## Приоритет и объединение правил `sudoers` не работает как обычный firewall с простым правилом «первое совпадение победило». Для пользователя могут совпасть несколько записей; разрешения и теги вычисляются по правилам sudoers и могут объединяться. Практические следствия: - узкое правило не отменяет широкое разрешение из другого файла; - порядок важен для некоторых тегов и параметров; - членство пользователя в нескольких административных группах нужно учитывать; - проверять итог следует через `visudo -c` и `sudo -l`. ## Минимальный пример Задача: разрешить группе `webops` проверять и перезапускать только `nginx`. ```sudoers Cmnd_Alias NGINX_READ = \ /usr/bin/systemctl status nginx Cmnd_Alias NGINX_WRITE = \ /usr/bin/systemctl reload nginx, \ /usr/bin/systemctl restart nginx %webops ALL=(root) NGINX_READ %webops ALL=(root) PASSWD: NGINX_WRITE ``` Проверка: ```bash sudo visudo -c sudo -l sudo /usr/bin/systemctl status nginx ``` ## Чек-лист - Правило хранится в отдельном файле `/etc/sudoers.d/`. - Файл проверен через `visudo`. - Использованы абсолютные пути. - Разрешены конкретные команды и аргументы. - Нет лишнего `ALL`. - `NOPASSWD` используется только при необходимости. - Пользователь не может изменить разрешённую команду или её зависимости. - Не разрешены оболочки, редакторы и интерпретаторы без осознанной причины. - Учтены переменные окружения и `secure_path`. - Итоговые права проверены через `sudo -l`. - Есть журналирование и способ аварийного получения root-доступа. ## Связанные заметки - [[Super-user]] - [[File Permissions]] - [[Linux - MOC]]