
Команды su и sudo решают похожую задачу — запускают процессы с другой идентичностью, — но делают это через разные механизмы допуска. Разница становится важной, когда нужно дать инженеру право перезапускать один сервис, отредактировать системный файл, разобрать ошибку Permission denied или настроить автоматизацию без общего пароля root. Здесь разобраны и повседневные команды, и границы их безопасности: запуск редактора, перенаправление вывода, окружение, делегирование и аудит.
Примеры рассчитаны на Linux с Bash, util-linux su и классическим sudo с политикой sudoers. Названия групп, пути к программам и реализация sudo зависят от системы. Команды изменения конфигурации выполняйте сначала на тестовой машине, имея отдельный рабочий административный вход. Демонстрационный сервис demo.service нужно заменить на проверенный сервис своей инфраструктуры; его существование не предполагается.

1. Что действительно меняется при получении root
Linux проверяет числовые идентификаторы, а не слово root в приглашении. UID (User ID) — числовой идентификатор пользователя; UID 0 — административная учётная запись. Обычный пользователь может называться admin и не иметь особых прав. Для процесса важны реальный UID, эффективный UID и группы. Реальный UID отражает идентичность процесса в соответствующем механизме, эффективный участвует в проверках доступа; их значения могут различаться. После запуска целевой команды через sudo её идентификаторы обычно уже соответствуют целевому пользователю. Для установления инициатора нужны события sudo и данные аудита, а не только ps.
id
id -u
id -ru
ps -o pid,ppid,ruid,euid,rgid,egid,comm -p "$$"
id показывает UID, основную и дополнительные группы текущего пользователя. id -u выводит эффективный UID, id -ru — реальный. В Bash $$ обозначает PID текущей оболочки; ps показывает её идентификаторы. Если id -u вернул 0, текущая команда работает с идентичностью root. Значок # в приглашении — только соглашение, которое можно настроить произвольно.
Не каждое Permission denied исправляется sudo. Запись может блокировать read-only mount, SELinux, AppArmor, immutable-атрибут или ограничения контейнера. Root внутри user namespace не равнозначен root на хосте. Capabilities распределяют отдельные привилегии между процессами; сервис может слушать привилегированный порт без полноценного root. Поэтому сначала определите ресурс и ограничение, затем выбирайте способ доступа.
findmnt -T /etc -o TARGET,FSTYPE,OPTIONS
ls -ld /etc
command -v getenforce
command -v aa-status
findmnt показывает файловую систему, содержащую путь, и её параметры. ro означает монтирование только для чтения. Последние две команды лишь ищут диагностические утилиты SELinux и AppArmor; отсутствие программы не является доказательством отсутствия всех ограничений. Для действующей системы сверяйте сообщения отказа с журналом и её политикой доступа.
2. su, su -, sudo -i и sudo -s: какую команду выбрать
PAM (Pluggable Authentication Modules) — механизм подключаемых проверок аутентификации, состояния учётной записи и сессии. Он может учитывать пароль, ограничения входа или дополнительные факторы. su обычно допускает пользователя через пароль целевой учётной записи и PAM. Если имя не указано, целью является root. В sudo доступ определяется политикой; при обычной настройке запрашивается пароль инициатора, затем выполняется разрешённая команда. Возможны исключения: NOPASSWD, параметры rootpw/targetpw/runaspw, другая PAM-аутентификация или внешняя политика. По виду приглашения нельзя достоверно определить все условия допуска.
| Задача | Команда | Идентичность и окружение | Условие применения |
|---|---|---|---|
| Одна административная команда | sudo -- /usr/bin/id | Целевой пользователь по политике, обычно root | Разрешение sudoers; путь id проверить локально |
| Команда от имени postgres | sudo -u postgres -- /usr/bin/id | UID и группы postgres, без требования интерактивной оболочки | Учётная запись существует, выполнение разрешено |
| Административная login shell | sudo -i | Оболочка и домашний каталог целевого пользователя; окружение формирует политика | Нужны полные административные полномочия |
| Оболочка через sudo без режима login | sudo -s | Выбор оболочки и переменных зависит от sudoers и среды | Нужна оболочка, но различия окружения осознанны |
| Login shell другого пользователя через su | su - root | Перестраивает окружение и переходит в домашний каталог | Доступ к целевой учётной записи разрешён PAM |
| su без login | su root | Часть текущего окружения и каталог сохраняются | Совместимость среды нужна намеренно |
| Редактирование системного файла | sudoedit /etc/demo-app.conf | Редактор работает от имени инициатора | Сам файл разрешён политикой и его изменение не даёт обходных привилегий |
su - — полноценный рабочий вариант, а не неправильная команда. Для util-linux режим login предпочтителен, когда требуется среда целевого пользователя: он уменьшает смешение пользовательских переменных и root-окружения. Однако login shell не равна полноценному входу в новую системную сессию; PAM может дополнительно изменить переменные. Порядок и детали описаны в руководстве util-linux su.
В Bash login shell читает login-профили: /etc/profile, затем первый доступный из ~/.bash_profile, ~/.bash_login, ~/.profile. Интерактивная shell без login обычно читает ~/.bashrc; login-профиль может подключать его явно. Поэтому одинаковые UID и HOME ещё не означают одинаковые aliases, PATH и переменные. Это поведение Bash; для другой shell смотрите её документацию. Ошибку «команда находится в одном входе, но не находится в другом» начинайте с проверки command -v, PATH и файлов запуска, а не с выдачи дополнительных прав.
sudo su - создаёт два перехода: сначала sudo запускает su, затем su запускает оболочку. Для обычного административного входа sudo -i проще интерпретировать и сопровождать. Наличие sudo не делает su устаревшим: su остаётся полезен там, где доступ действительно организован через целевую учётную запись.
Посмотрите различие окружений на тестовой машине. Одиночные кавычки вокруг команды сохраняют переменные для раскрытия целевой оболочкой, а не исходной.
printf 'caller: HOME=%s USER=%s PWD=%s\n' "$HOME" "$USER" "$PWD"
sudo -i -- /bin/sh -c 'id; printf "HOME=%s USER=%s PWD=%s\n" "$HOME" "$USER" "$PWD"'
В обычной конфигурации второй вызов показывает UID 0 и HOME/PWD /root. Это пример ожидаемого результата, не универсальное обещание: домашний каталог, shell, PATH и политика могут быть другими. Если задача зависит от конкретной переменной, задавайте её явно в разрешённой конфигурации сервиса, а не переносите всё окружение через sudo -E.
3. Дистрибутив, версия и группы: сначала проверьте свою систему
Одинаковая строка sudo может запускать разные реализации. Помимо классического sudo существуют sudo-rs и альтернативы вроде doas. BusyBox su отличается от util-linux su. Нельзя переносить все ключи и параметры политики между ними без проверки локального руководства.
cat /etc/os-release
command -v sudo su visudo sudoedit
sudo --version
su --help
getent passwd root
id -nG
command -v показывает фактически вызываемые программы. sudo --version помогает определить реализацию, сборку и поддерживаемые плагины; вывод util-linux можно дополнительно проверить через su --version, если такой ключ есть в su --help. getent использует настроенные источники учётных записей, поэтому полезнее прямого чтения только /etc/passwd в среде LDAP/SSSD. Строка root показывает UID, каталог и shell, но не сообщает, можно ли войти по паролю.
| Семейство системы | Что обычно встретится | Что нужно проверить до инструкции |
|---|---|---|
| Ubuntu | Администрирование через sudo; состав реализации зависит от выпуска | Версию sudo, членство пользователя в sudo, действующую политику |
| Debian | Пароль root и установка sudo зависят от выбора при установке | Настроен ли root, установлен ли sudo, кому разрешены команды |
| Fedora, RHEL и совместимые | Часто используется административная группа wheel | Активное правило wheel, PAM/SSSD, локальные ограничения |
| openSUSE/SUSE | Поведение аутентификации определяется настройкой sudoers | Требуется пароль инициатора или root, правила групп |
| Arch Linux | Программы и правила задаёт администратор | Установлен ли sudo, включено ли нужное правило |
| Alpine и минимальные образы | Возможны BusyBox su, doas, отсутствие sudo | Реальные программы, формат политики, доступные опции |
| Контейнеры и appliances | UID 0 может быть ограничен namespace и политикой среды | Нужен ли вообще sudo внутри образа, какие ограничения задаёт хост |
Членство в wheel само по себе не даёт право на su или sudo. Его должна использовать конкретная конфигурация. Утверждение, что во всех Debian-подобных системах root не имеет пароля, неверно. Выбор при установке описан в руководстве Debian. Старые инструкции с gksudo также нельзя считать универсальным способом запуска графических приложений. Для административной задачи выбирайте механизм, который поддерживается конкретным выпуском и интерфейсом приложения.
4. Повседневная работа: одна команда, другой пользователь, временная оболочка
Начните с проверки собственных разрешений:
sudo -l
command -v systemctl
sudo -- /usr/bin/systemctl --no-pager status demo.service
sudo -l перечисляет действующие права. Он может запросить аутентификацию. Путь /usr/bin/systemctl — пример распространённого расположения; используйте фактический путь своей системы. status читает состояние, а --no-pager отключает интерактивный pager. Это важно при делегировании: разрешённый просмотр не должен незаметно превращаться в запуск интерактивной программы с широкими возможностями.
В выводе systemctl смотрите Loaded, Active, результат завершения и сообщения сервиса. active (running) означает, что процесс работает, но не доказывает работоспособность API. failed требует разбора причины. Ненулевой exit status у status может означать остановленный сервис; это не обязательно отказ sudo. Проверяйте текст и код возврата вместе.
sudo -- /usr/bin/systemctl --no-pager status demo.service
result=$?
printf 'exit status=%s\n' "$result"
Для служебной учётной записи не требуется выдавать ей пароль ради одного процесса. Если политика допускает нужный запуск, sudo -u postgres -- /usr/bin/id покажет идентичность postgres без интерактивного входа. Имя postgres приведено как пример установленной службы. Отказ пользователя с /usr/sbin/nologin при su - ожидаем для запрета login shell; это не причина менять shell сервисной учётной записи на Bash.
Полная оболочка sudo -i нужна для связанного набора административных действий, когда это разрешено. Перед изменениями выполните id и pwd; после работы — exit. Не держите root-shell открытой как обычное рабочее окно: легко выполнить команду в неверном каталоге и потерять разделение между пользовательской и административной работой.
5. Почему sudo echo не может записать файл: shell, pipe и tee
В строке sudo echo value > /etc/file перенаправление открывает исходная оболочка до запуска echo. Sudo повышает права запускаемой программы, но не меняет права уже работающей оболочки. Поэтому ошибка записи может возникнуть до проверки самой команды sudo. Аналогично sudo command1 | command2 повышает права только первой программы конвейера.
Следующий опыт создаёт отдельный временный каталог. Он требует уже имеющегося полного sudo-доступа и не относится к ограниченной политике из следующего раздела.
demo_dir=$(mktemp -d /tmp/avg-sudo-demo.XXXXXX)
sudo chown root:root -- "$demo_dir"
sudo chmod 0755 -- "$demo_dir"
sudo touch -- "$demo_dir/example.conf"
sudo chmod 0644 -- "$demo_dir/example.conf"
sudo /usr/bin/printf '%s\n' 'mode=demo' > "$demo_dir/example.conf"
Последняя строка у обычного пользователя должна завершиться Permission denied: файл принадлежит root и доступен другим только для чтения. Каталог создан специально для опыта; не подставляйте сюда боевые конфигурации. Введите следующую строку отдельно после ожидаемого отказа:
printf '%s\n' 'mode=demo' | sudo tee -- "$demo_dir/example.conf" >/dev/null
cat -- "$demo_dir/example.conf"
printf '%s\n' 'enabled=true' | sudo tee -a -- "$demo_dir/example.conf" >/dev/null
cat -- "$demo_dir/example.conf"
tee получает повышенные права и открывает файл сам. Без -a он перезаписывает содержимое; с -a добавляет строку. Здесь >/dev/null выполняется обычной оболочкой и только убирает дублирование текста на экран. После двух операций ожидаются строки mode=demo и enabled=true. Tee не делает запись атомарной, не проверяет формат и не сохраняет автоматически резервную версию.
Альтернатива — sudo /bin/sh -c '...': тогда и команда, и перенаправление выполняются внутри привилегированной shell. Это выдаёт существенно более широкую возможность исполнения. Для постоянной автоматизации предпочтительнее узкий административный интерфейс или проверенный helper. После опыта удалите только два точно известных объекта, без рекурсивной очистки:
sudo rm -- "$demo_dir/example.conf"
sudo rmdir -- "$demo_dir"
unset demo_dir
6. sudoedit: редактор без root и привилегированное сохранение
Редактор — сложная программа: плагины, дополнительные файлы, команды, внешние инструменты. Запуск sudo vim или sudo nano даёт самому редактору повышенную идентичность. Для пользователя с ограниченными правами это плохая граница делегирования. Проблема шире одной функции конкретного редактора: любой доступный путь выполнения и записи становится частью модели безопасности.
sudoedit проверяет разрешение на редактирование, подготавливает временную копию, запускает редактор от имени инициатора и сохраняет изменения в разрешённый файл привилегированным механизмом. Переменные SUDO_EDITOR, VISUAL и EDITOR могут участвовать в выборе редактора; конкретные ограничения определяются реализацией и политикой. См. руководство sudoedit.
SUDO_EDITOR=/usr/bin/nano sudoedit /etc/demo-app.conf
Это пример для заранее существующего разрешённого файла. Проверьте путь nano локально. Сообщения о символической ссылке или writable directory нельзя лечить отключением защит: они могут означать, что пользователь способен подменить путь между проверкой и сохранением.
namei -l /etc/demo-app.conf
ls -l /etc/demo-app.conf
namei -l показывает права каждого компонента пути. Недостаточно, чтобы файл принадлежал root: его родительский каталог тоже не должен давать делегированному пользователю возможность подмены. Дополнительно учитывайте ACL, если они используются.
Sudoedit защищает процесс редактирования, но не превращает любую конфигурацию в безопасный объект. Если файл позволяет указать исполняемый скрипт, плагин или команду запуска сервиса от root, право его изменения эквивалентно более широким полномочиям. Перед выдачей доступа изучите семантику файла. После сохранения запустите штатную проверку формата приложения, затем согласованную перезагрузку конфигурации и проверку сервиса. Наличие строки в файле ещё не доказывает, что программа её приняла.
7. Как написать узкое правило sudoers без скрытого полного доступа
Пример: группе demo-operators разрешены только просмотр состояния и перезапуск demo.service. Административные файлы, executable, unit и drop-in должны принадлежать root и не быть доступны группе для записи. Если оператор может изменить ExecStart или запускаемый скрипт, ограничение на restart перестаёт защищать систему.
Перед настройкой получите текущие пути и зависимости. Эти команды выполняет администратор, а не пользователь с будущим ограниченным доступом:
getent group demo-operators
command -v systemctl
sudo systemctl cat demo.service
sudo systemctl show demo.service -p FragmentPath -p DropInPaths -p ExecStart
sudo visudo -c
Если группа отсутствует, её создание и членство оформляйте по принятому в компании процессу; добавление пользователя в wheel вместо специальной группы меняет объём доступа. systemctl cat показывает unit и drop-in, show помогает найти путь и команду запуска. Проверьте также права всех родительских каталогов и конфигураций, которые исполняемый процесс читает с возможностью запуска кода.
Убедитесь, что основной sudoers включает /etc/sudoers.d. Обычно используется @includedir, в некоторых конфигурациях — совместимая форма #includedir. Не добавляйте второй include без проверки. Затем создайте правило через visudo:
sudo visudo -f /etc/sudoers.d/demo-operators
Содержимое для системы, где systemctl находится по указанному пути:
Cmnd_Alias DEMO_SERVICE = /usr/bin/systemctl --no-pager status demo.service, /usr/bin/systemctl restart demo.service
%demo-operators ALL=(root) DEMO_SERVICE
Здесь зафиксированы программа и аргументы. Нет *, ALL в списке команд, оболочки или редактора. Host-поле ALL не означает все команды: оно задаёт применимость правила к хостам. На многосерверной конфигурации дополнительно ограничьте применимость по принятой схеме. Имя файла не содержит точки: для includedir есть правила отбора имён, поэтому не используйте случайное policy.conf, не сверив руководство.
sudo chown root:root /etc/sudoers.d/demo-operators
sudo chmod 0440 /etc/sudoers.d/demo-operators
sudo visudo -c
0440 разрешает чтение владельцу и группе без записи. Полная проверка visudo -c нужна после локальной проверки файла: ошибки могут находиться в другом include или в общей композиции. Правила имеют смысл только при защищённых путях и корректной сервисной конфигурации. Не считайте NOEXEC универсальной песочницей; механизмы ограничения подпроцессов имеют условия и ограничения, а сам разрешённый бинарник может обладать достаточными опасными функциями. Детали сопоставления команд описаны в sudoers.
8. Приёмка: разрешённая операция, запрет, журнал и диагностика
Проверяйте из нового входа оператора, чтобы получить актуальные дополнительные группы. Сначала id -nG и sudo -l. Если пользователь уже имеет полное административное правило через другую группу, тест запрета бессмыслен: узкая запись не отменяет остальные разрешения.
id -nG
sudo -l
sudo -l /usr/bin/systemctl --no-pager status demo.service
sudo -l /usr/bin/bash
sudo -- /usr/bin/systemctl --no-pager status demo.service
С формой sudo -l command проверяется разрешение на команду без её запуска. Для Bash в изолированном примере ожидается отказ политики; фактический путь Bash предварительно уточните. Для status ожидается разрешение, затем вывод сервиса. Restart выполняйте отдельно в согласованное окно и проверяйте прикладной endpoint, а не только Active. Не проверяйте запрет реальным запуском разрушительной команды.
| Симптом | Возможная причина | Следующая проверка |
|---|---|---|
| User is not in sudoers / not allowed | Нет правила или несовпадение пути/аргументов | sudo -l, членство, точная команда |
| Authentication failure | Пароль, PAM, MFA, состояние учётной записи | Сообщение и журнал аутентификации; не расширять политику |
Password is required при sudo -n | Нет подходящей сохранённой аутентификации или NOPASSWD | Интерактивно проверить разрешение; -n не обходит пароль |
| Правило добавлено, группового доступа нет | Сессия хранит старые группы | Новый login, id, источник NSS/SSSD |
| Sudo работает, сервис возвращает ошибку | Отказ целевой программы | Exit status, unit, журнал приложения |
| Sudoedit отказывается открыть путь | Symlink, доступный для записи каталог, политика | namei, ACL, владельцы пути |
Для классического sudo sudo -k без команды инвалидирует текущую сохранённую аутентификацию; sudo -K удаляет записи timestamp пользователя. Повторный запрос зависит от вида timestamp и политики. Не путайте это с закрытием уже запущенной root-shell: она продолжает работать.
На systemd-системе администратор может посмотреть события:
sudo journalctl --since '30 minutes ago' _COMM=sudo --no-pager
Маршрутизация логов зависит от сборки, rsyslog и journald. Если ожидаемых записей нет, проверьте настройки хранения; на части систем события также доступны в /var/log/auth.log или /var/log/secure. Обычно sudo регистрирует запрос и запуск команды. Внутренние команды после sudo -i не становятся автоматически отдельными событиями sudo. Полный аудит действий требует отдельно настроенных средств, а I/O logging может записывать чувствительные данные. Политику хранения и доступа к таким журналам определяйте заранее.
9. Автоматизация: NOPASSWD для действия, а не для shell
Задание по расписанию не должно передавать пароль через echo password | sudo -S. Пароль окажется в конфигурации, выводе или других доступных местах. Используйте сервисную идентичность, systemd-настройку процесса или узкое правило на единственное необходимое административное действие.
Если для выделенной группы автоматизации действительно нужен restart демо-сервиса, пример отдельного правила:
%demo-automation ALL=(root) NOPASSWD: /usr/bin/systemctl restart demo.service
Группа должна существовать и содержать только нужную сервисную учётную запись. Не добавляйте NOPASSWD: ALL; иначе компрометация одного job становится компрометацией хоста. Вызов из Bash с явной обработкой отказа:
if sudo -n -- /usr/bin/systemctl restart demo.service; then
printf '%s\n' 'restart command completed'
else
result=$?
printf 'restart failed: exit=%s\n' "$result" >&2
exit "$result"
fi
-n запрещает интерактивный запрос: job завершится с ошибкой, а не зависнет в ожидании ввода. Успешное выполнение restart означает завершение этой операции systemctl, а не готовность бизнес-функции. Добавьте проверку локального health endpoint и контроль времени запуска, соответствующие приложению.
Если нужен helper, фиксируйте входные аргументы, используйте абсолютные пути, защищайте файл и родителей от записи пользователем, не читайте управляемые им команды из конфигурации и не применяйте eval. Для штатного демона часто лучше сразу корректно задать User= и права на его ресурсы в unit, чем многократно повышать привилегии внутри приложения. Возможность редактировать root-unit опять же является административной привилегией.
10. Как внедрить и отозвать доступ, не потеряв управление
Перед изменениями оставьте отдельную проверенную административную сессию или консоль. Сохраните резервную копию существующего правила в каталог root вне /etc/sudoers.d, чтобы backup случайно не включился в политику. Если файла ещё не было, зафиксируйте это: возврат означает его удаление, а не восстановление вымышленной предыдущей версии.
Для существующего файла пример резервирования под уникальным именем:
sudo install -d -m 0700 /root/sudoers-backups
sudo cp -a /etc/sudoers.d/demo-operators /root/sudoers-backups/demo-operators.before-change
sudo visudo -c
Не перезаписывайте единственную предыдущую копию при последующих изменениях; добавляйте дату или номер изменения. После редактирования проверяйте syntax, эффективные разрешения и реальную разрешённую операцию в отдельной сессии. Только после успешной приёмки закрывайте резервный административный вход.
При возврате восстановите сохранённый файл, владельца и mode, затем снова выполните visudo -c. Если добавлялся новый include-файл, администратор удаляет именно его и проверяет всю политику. При отзыве группового доступа дополнительно учитывайте действующие сессии, кэш каталогов и ранее запущенные процессы. Удаление строки из sudoers предотвращает новые разрешённые запуски, но не отбирает полномочия у уже работающей root-shell.
Практический критерий качества настройки: оператор может выполнить свою конкретную задачу, не может запросить лишние команды через другие правила, а администратор способен объяснить, кто инициировал действие, какой файл или сервис оно затронуло и как вернуть предыдущую конфигурацию. Sudo помогает реализовать это разделение; широкие права на редактор, shell или исполняемую конфигурацию могут его полностью разрушить.
Дополнительное руководство по ключам запуска, выбору целевой идентичности и окружению: sudo(8). Локальные man su, man sudo, man sudoers остаются главным ориентиром для установленной версии.
Для проверки механизма перенаправлений: Bash — Redirections; для проверки sudoers: visudo(8).
Механизм файлов запуска оболочки: Bash — Startup Files.
