На сервере с несколькими пользователями права на выполнение команд от имени root приходится разграничивать: одному пользователю нужен полный доступ, другому – только возможность перезапускать определенный сервис, третьему – вообще ничего, кроме собственных задач. За такое разграничение прав в Linux отвечают команда sudo и файл /etc/sudoers.
В статье рассматривается, как устроен файл Sudoers, как его безопасно редактировать и как добавлять в него собственные правила доступа. Все примеры приводятся для VPS с Ubuntu 24.04 LTS.
Что такое sudo и файл /etc/sudoers
Команда sudo позволяет пользователю выполнить отдельную команду с правами другого пользователя. Чаще всего sudo используется для выполнения административных команд с правами root.
При использовании sudo пользователю не требуется знать пароль root: для подтверждения операции используется пароль самого пользователя.
Использование sudo также позволяет связать выполненную команду с конкретной учетной записью. События, связанные с использованием sudo, записываются в системный журнал. В Ubuntu информация об аутентификации и использовании привилегий обычно находится в файле /var/log/auth.log:
sudo tail -n 20 /var/log/auth.logПравила, которые определяют, какие пользователи и группы могут выполнять те или иные команды через sudo, хранятся в файле /etc/sudoers. Это обычный текстовый файл: каждая его строка – либо правило, либо параметр, либо комментарий. sudo читает файл при каждом вызове, поэтому изменения вступают в силу сразу после сохранения – перезапускать или перезагружать ничего не нужно.
Дополнительные правила размещают в отдельных файлах каталога /etc/sudoers.d/. Они подключаются к основному файлу директивой в его последней строке и обрабатываются как его продолжение. Такой способ удобнее правки основного файла: правило для конкретной задачи лежит в отдельном файле, его легко найти, изменить или удалить целиком, а обновление пакета sudo не затронет ваши настройки.
Файл /etc/sudoers принадлежит пользователю root и группе root и имеет права доступа 0440. Читать его и вносить изменения могут только root и члены группы root – всем остальным файл недоступен даже на чтение.
Как открыть файл /etc/sudoers для редактирования
Редактирование Sudoers не следует выполнять обычным текстовым редактором. Используйте для этого отдельную команду:
sudo visudovisudo блокирует файл на время редактирования, чтобы его не изменил параллельно другой администратор, и проверяет синтаксис перед сохранением: при ошибке команда сообщит о ней и предложит вернуться к правке. Ни один другой способ такой проверки не выполняет – поэтому файлы в каталоге /etc/sudoers.d/ тоже создавайте и редактируйте только через visudo, указав путь к файлу явно:
sudo visudo -f /etc/sudoers.d/имя_файлаЕсли файла еще нет, visudo создаст его.
Если отредактировать конфигурацию обычным редактором и допустить ошибку в синтаксисе, sudo будет сообщать о ней при каждом вызове. Более того, неверно составленное правило может лишить пользователей доступа — а при отсутствии активной root-сессии восстановить его будет сложнее.
Перед крупными изменениями сохраните резервную копию файла:
sudo cp /etc/sudoers /etc/sudoers.bakКаталог /etc для копии выбран не случайно. Файл, сохраненный в /etc/sudoers.d/ под именем без точки, будет подключен как еще один конфигурационный файл. А поскольку копия основного файла содержит директиву @includedir /etc/sudoers.d, каталог начнет подключать сам себя: параметры продублируются, и sudo выдаст ошибку /etc/sudoers.d: too many levels of includes.
По умолчанию на Ubuntu visudo открывает файл в редакторе nano. Чтобы выбрать другой редактор, выполните команду:
sudo update-alternatives --config editorКоманда выводит список установленных редакторов с номерами:
There are 4 choices for the alternative editor (providing /usr/bin/editor).
Selection Path Priority Status
------------------------------------------------------------
* 0 /bin/nano 40 auto mode
1 /bin/ed -100 manual mode
2 /bin/nano 40 manual mode
3 /usr/bin/vim.basic 30 manual mode
4 /usr/bin/vim.tiny 15 manual mode
Press <enter> to keep the current choice[*], or type selection number:Введите номер требуемого редактора и нажмите Enter. Учтите, что эта настройка изменит редактор по умолчанию не только для visudo, а для всех программ, которые обращаются к /usr/bin/editor.
Из чего состоит файл Sudoers
Файл /etc/sudoers содержит настройки, которые определяют поведение sudo и права пользователей. В нем могут находиться:
- комментарии;
- параметры Defaults;
- правила доступа;
- псевдонимы пользователей, хостов, команд и пользователей для запуска (Runas);
- директивы подключения дополнительных файлов.
После установки Ubuntu 24.04 LTS файл Sudoers выглядит следующим образом:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# This fixes CVE-2005-4890 and possibly breaks some versions of kdesu
# (#1011624, https://bugs.kde.org/show_bug.cgi?id=452532)
Defaults use_pty
# This preserves proxy settings from user environments of root
# equivalent users (group sudo)
#Defaults:%sudo env_keep += "http_proxy https_proxy ftp_proxy all_proxy no_proxy"
# This allows running arbitrary commands, but so does ALL, and it means
# different sudoers have their choice of editor respected.
#Defaults:%sudo env_keep += "EDITOR"
# Completely harmless preservation of a user preference.
#Defaults:%sudo env_keep += "GREP_COLOR"
# While you shouldn't normally run git as root, you need to with etckeeper
#Defaults:%sudo env_keep += "GIT_AUTHOR_* GIT_COMMITTER_*"
# Per-user preferences; root won't have sensible values for them.
#Defaults:%sudo env_keep += "EMAIL DEBEMAIL DEBFULLNAME"
# "sudo scp" or "sudo rsync" should be able to use your SSH agent.
#Defaults:%sudo env_keep += "SSH_AGENT_PID SSH_AUTH_SOCK"
# Ditto for GPG agent
#Defaults:%sudo env_keep += "GPG_AGENT_INFO"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "@include" directives:
@includedir /etc/sudoers.dСодержимое файла может немного отличаться в зависимости от версии пакета sudo.
Комментарии
Строки, начинающиеся с #, являются комментариями и не влияют на работу sudo. Например:
# User alias specificationВ стандартном файле такие строки служат заголовками разделов конфигурации, а также поясняют закомментированные настройки.
Параметры Defaults
Строки, начинающиеся с Defaults, задают параметры работы sudo. Они не предоставляют пользователям дополнительных прав.
В стандартном файле Ubuntu активны четыре параметра:
env_reset– ограничивает набор переменных окружения, которые передаются команде, запущенной черезsudo;mail_badpass– отправляет письмо (по умолчанию – пользователюroot) при вводе неверного пароля. Работает, только если на сервере настроен почтовый агент (MTA);secure_path– задает список каталогов, в которыхsudoищет исполняемые файлы;use_pty– предписываетsudoзапускать команды в отдельном псевдотерминале (PTY).
Ниже в файле находится блок закомментированных параметров env_keep. Он дополняет env_reset: env_keep перечисляет переменные окружения, которые нужно сохранить при запуске команды через sudo. Эти строки отключены по умолчанию и предлагаются как готовые решения для частых ситуаций: сохранить настройки прокси, выбранный пользователем редактор, переменные Git или переменные SSH-агента. Чтобы применить любую из них, достаточно удалить # в начале строки.
Запись вида Defaults:%sudo означает, что параметр действует не для всех, а только для пользователей группы sudo.
Еще два параметра часто добавляют вручную, хотя в стандартном файле Sudoers они отсутствуют:
timestamp_timeout– время в минутах, в течение которого sudo не запрашивает пароль повторно;passwd_tries– количество попыток ввода пароля (по умолчанию – три).
Изменять параметры Defaults без необходимости не рекомендуется.
Правила доступа
Правила доступа определяют, кому, где, от имени какого пользователя и какие команды разрешено выполнять через sudo.
Правило строится по схеме:
кто где=(от_кого:от_какой_группы) ТЕГИ: командыНапример:
%sudo ALL=(ALL:ALL) ALLДанное правило означает:
%sudo ALL=(ALL:ALL) ALL– пользователи группы sudo. Символ % перед именем означает, что указана группа;%sudo ALL=(ALL:ALL) ALL– правило действует на любом хосте;%sudo ALL=(ALL:ALL) ALL– команду можно выполнить от имени любого пользователя и любой группы;%sudo ALL=(ALL:ALL) ALL– разрешены любые команды.
Таким образом, пользователи группы sudo могут выполнять любые команды с помощью sudo. Пользователь, добавленный в эту группу командой sudo usermod -aG sudo username, получает права, определенные этим правилом. Чтобы новое членство в группе вступило в силу, пользователю нужно переподключиться по SSH.
В скобках указывается, от чьего имени разрешено выполнять команду. Это может быть любая учетная запись, существующая на сервере: (root), (www-data). Значение ALL разрешает выполнить команду от имени любого пользователя – выбрать его можно флагом sudo -u.
Через двоеточие добавляется второе значение – группа, с которой выполняется команда: например, (ALL:ALL) или (www-data:www-data). Выбрать группу можно флагом sudo -g. Если вторая часть не указана, флаг -g использовать не требуется.
Строка %admin ALL=(ALL) ALL осталась в файле от старых версий Ubuntu, где группа admin использовалась для выдачи административных прав. В современных версиях Ubuntu для этой цели используется группа sudo.
Перед списком разрешенных команд можно использовать специальные теги. Наиболее распространенный – NOPASSWD:. Он отключает запрос пароля для указанных команд:
ivan ALL=(root) NOPASSWD: /usr/bin/apt updateЕсли NOPASSWD: не указан, sudo запросит пароль самого пользователя. После успешного ввода пароль не запрашивается повторно в течение 15 минут в рамках того же терминала – это поведение задается параметром timestamp_timeout. В другом терминале пароль будет запрошен заново.
Псевдонимы
Псевдонимы позволяют объединить несколько пользователей, хостов или команд под одним именем. Это удобно, когда один и тот же набор команд или пользователей встречается в нескольких правилах:
User_Alias ADMINS = ivan, petr
Cmnd_Alias SERVICES = /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart mysql
ADMINS ALL=(root) SERVICES
%deployers ALL=(root) NOPASSWD: SERVICESДанные правила означают:
ADMINS– псевдоним пользователейivanиpetr;SERVICES– псевдоним двух разрешенных команд;- третья строка разрешает пользователям
ivanиpetrвыполнять эти команды с запросом пароля; - четвертая строка разрешает те же команды пользователям группы
deployers, но уже без запроса пароля.
Если позже потребуется добавить в список третий сервис, достаточно изменить одну строку с Cmnd_Alias.
Имя псевдонима должно начинаться с заглавной буквы и состоять из заглавных латинских букв, цифр и подчеркиваний. Имена вида Admins или admins visudo не примет.
Кроме User_Alias и Cmnd_Alias, есть еще два типа псевдонимов: Host_Alias – для объединения хостов и Runas_Alias – для объединения пользователей, от имени которых разрешено выполнять команды. Например, для пользователя www-data можно завести псевдоним:
Runas_Alias WEB = www-dataИ затем указывать в правилах (WEB) вместо (www-data).
Пока правил немного, псевдонимы только усложняют файл. Они полезны в конфигурациях с большим количеством пользователей и разрешенных команд.
Подключение каталога sudoers.d
В конце стандартного файла Ubuntu находится директива:
@includedir /etc/sudoers.dОна подключает дополнительные конфигурационные файлы из каталога /etc/sudoers.d/. Например:
/etc/sudoers.d/deploy
/etc/sudoers.d/backupВ Ubuntu 20.04 и более ранних версиях эта же строка выглядит как #includedir /etc/sudoers.d. Несмотря на символ #, это не комментарий, а та же директива в старом синтаксисе.
sudo рассматривает основной файл и подключенные файлы как единую конфигурацию. Если пользователю соответствуют несколько правил, они могут влиять на итоговые разрешения. Для совпадающих команд порядок правил имеет значение: последующее правило может изменить, например, тег NOPASSWD на PASSWD или наоборот.
Файлы из /etc/sudoers.d/ обрабатываются в лексикографическом порядке: например, /etc/sudoers.d/10-deploy будет прочитан раньше, чем /etc/sudoers.d/20-monitor. Файлы, чье имя содержит точку или заканчивается на ~, пропускаются – такие имена характерны для резервных копий и временных файлов, которые оставляют некоторые редакторы.
Как добавить собственное правило
Собственные правила рекомендуем добавлять в отдельные файлы каталога /etc/sudoers.d/, а не изменять основной файл /etc/sudoers. Так вы сможете изменить или удалить правило отдельно от основной конфигурации.
Создайте файл – назовите его по назначению правила или по имени пользователя, например, deploy, backup или nginx-restart. Точки в имени быть не должно: как сказано выше, такие файлы sudo пропускает. Например:
sudo visudo -f /etc/sudoers.d/nginx-restartПосле сохранения задайте файлу права 0440:
sudo chmod 0440 /etc/sudoers.d/nginx-restartС другими правами sudo продолжит применять правила из файла, но при проверке конфигурации будет сообщать bad permissions, should be mode 0440.
Команды в правилах указываются полным путем. Узнать путь можно командой command -v. Например:
command -v systemctl
/usr/bin/systemctlНиже разобраны четыре типовые ситуации – от простого правила к более сложному.
Одна команда для одного пользователя
Начнем с самого простого случая: разработчик ivan должен уметь перезапускать nginx после правки конфигурации сайта, но полный доступ к sudo ему не нужен.
Добавьте в файл правило:
ivan ALL=(root) /usr/bin/systemctl restart nginxДанное правило означает:
ivan– пользователь, которому предоставляется право;ALL– правило действует на любом хосте;(root)– команда выполняется только от имениroot. Перезапуск системного сервиса требует правroot, но указывать здесь(ALL)не нужно: это разрешило бы запускать команду и от имени любой другой учетной записи;/usr/bin/systemctl restart nginx– конкретная разрешенная команда с фиксированным аргументом.
Теперь ivan может выполнить sudo systemctl restart nginx, введя свой пароль. Любая другая команда через sudo ему недоступна, в том числе sudo systemctl restart mysql или sudo systemctl stop nginx.
sudo сравнивает команду с правилом посимвольно. Правило из примера выше не разрешит команду sudo systemctl restart nginx.service, хотя для systemd это то же самое действие.Несколько команд без запроса пароля
Теперь усложним задачу: тот же перезапуск nginx выполняет не человек, а скрипт автоматического деплоя, который работает от имени пользователя deploy. Кроме перезапуска, скрипту нужно перезагружать конфигурацию nginx без остановки сервиса. Пароль в этом случае вводить некому – значит, его запрос нужно отключить.
Несколько команд перечисляются в одном правиле через запятую, а за отключение пароля отвечает тег NOPASSWD::
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginxПользователю deploy становятся доступны обе команды, причем без ввода пароля. Любая другая команда через sudo останется недоступной – при условии, что deploy не состоит в группе sudo и под него не подходит другое, более широкое правило.
NOPASSWD: стоит использовать только там, где ввод пароля действительно невозможен: в скриптах, заданиях cron и системах автоматического развертывания. Если команду выполняет человек, запрос пароля лучше оставить.Правило для нескольких пользователей
Следующая ситуация: смотреть журнал nginx нужно всем разработчикам, а не одному человеку. Перечислять их поименно неудобно – при появлении нового сотрудника необходимо будет внести изменения в конфигурацию sudo. Вместо этого права выдают группе.
Создайте группу и добавьте в нее пользователей:
sudo groupadd devs
sudo usermod -aG devs имя_пользователяПосле добавления в группу пользователь должен переподключиться по SSH – новая сессия нужна, чтобы изменение членства в группе вступило в силу.
В правиле вместо имени пользователя укажите группу, поставив перед ее именем знак %:
%devs ALL=(root) /usr/bin/journalctl -u nginxПравило распространяется на всех участников группы devs. Чтобы выдать право новому сотруднику, теперь достаточно добавить его в группу – файлы в /etc/sudoers.d/ менять не нужно.
Запуск команды от имени другого пользователя
В последней ситуации меняется не список команд, а учетная запись, от имени которой они выполняются. Пользователю deploy нужно запускать скрипт очистки кеша приложения. Сам кеш принадлежит www-data – учетной записи, от имени которой работает веб-сервер и приложение. Если запустить скрипт от root, файлы, которые он создаст заново, будут принадлежать root, и приложение под www-data не сможет их перезаписать – работа сайта нарушится.
Укажите в скобках www-data вместо root:
deploy ALL=(www-data) /usr/local/bin/clear-app-cache.shТакое правило требует, чтобы пользователь deploy явно указал целевую учетную запись флагом -u:
sudo -u www-data /usr/local/bin/clear-app-cache.shБез флага -u команда выполнялась бы от имени root – а такого разрешения правило не дает, и sudo отклонит запуск.
Пользователю deploy при этом не нужно ни состоять в группе sudo, ни знать пароль учетной записи www-data: право переключиться на нее дает правило, а sudo запрашивает пароль пользователя deploy.
Если правил, где команды выполняются от имени www-data, становится несколько, заведите для него псевдоним Runas_Alias, как показано в разделе «Псевдонимы», и используйте его вместо повторения имени пользователя в каждом правиле.
Как проверить правило
После сохранения проверьте синтаксис всей конфигурации sudo:
sudo visudo -cЧтобы проверить только один файл, укажите путь к нему:
sudo visudo -c -f /etc/sudoers.d/deployЕсли ошибок нет, посмотрите права пользователя:
sudo -l -U deployСреди разрешенных команд должно присутствовать добавленное правило.
После этого проверьте правило непосредственно от имени пользователя deploy. Переключитесь на него:
sudo -u deploy -iПосле чего выполните разрешенную команду:
sudo systemctl restart nginxЕсли правило составлено верно, команда выполнится. Попытка выполнить любую другую команду через sudo будет отклонена:
Sorry, user deploy is not allowed to execute '/usr/bin/systemctl stop nginx' as root on server Такой ответ означает, что правила для пользователя есть, но конкретная команда в них не разрешена.
Если пользователь отсутствует в файле sudoers, то есть для него нет ни персонального правила, ни правила для его группы, при попытке выполнить команду появится другая ошибка:
[sudo] password for alex:
alex is not in the sudoers file.Выполнять команды через sudo такой пользователь не сможет, пока правило для него или его группы не будет добавлено. Если правило вы создавали, проверьте имя пользователя в правиле и имя файла.
Чтобы вернуться в свою учетную запись, введите exit.
Как изменить или удалить правило
Чтобы изменить правило, снова откройте соответствующий файл:
sudo visudo -f /etc/sudoers.d/deployЧтобы удалить правило, удалите нужную строку из файла и сохраните изменения. Если файл больше не содержит нужных правил, удалите его целиком:
sudo rm /etc/sudoers.d/deployПосле изменения или удаления правила снова проверьте конфигурацию командой sudo visudo -c.
Как не выдать лишние права
Правило может выглядеть достаточно строгим, но фактически давать пользователю полный доступ к серверу. Чаще всего это происходит в трех случаях:
- Команда указана без аргументов. Например, правило
deploy ALL=(root) /usr/bin/systemctlразрешает не перезапуск одного сервиса, а любые действия с любыми юнитамиsystemd– например, подмену и запуск произвольного юнита от имениroot. Указывайте аргументы явно. - Разрешена команда, из которой можно выйти в командную оболочку. Текстовые редакторы (
vim,nano), а такжеfind,less,tar,awkумеют запускать произвольные команды или изменять любые файлы. Разрешив их черезsudo, вы фактически выдаете праваroot. - В аргументах использован шаблон. Конструкция
/usr/bin/systemctl restart *разрешает перезапуск любого сервиса, а не только нужного.
Восстановление после возникновения ошибки в файле /etc/sudoers
Не всякая ошибка в конфигурации приводит к потере доступа. Если синтаксически неверной оказалась одна строка, sudo сообщит о ней, пропустит ее и продолжит работать по остальным правилам:
/etc/sudoers:58:9: syntax error
this is broken
^~~~~~Опаснее другой случай: ошибка в строке, которая как раз и выдает права. Например, при ошибке в строке %sudo ALL=(ALL:ALL) ALL отброшена будет именно она, и все пользователи группы sudo потеряют возможность выполнять административные команды. Воспользоваться sudo, чтобы это исправить, уже не получится – права root придется получить другим способом.
Проще всего это сделать через вторую сессию с root-доступом, открытую заранее. Верните файл из резервной копии:
cp /etc/sudoers.bak /etc/sudoersЕсли такая сессия не была открыта, есть еще несколько вариантов:
- Переключиться на root командой su -. Пароль пользователя
rootдля VPS выдается при создании сервера. - Загрузить сервер в режиме восстановления. Сервер загружается в отдельную среду, где можно смонтировать его диск и отредактировать файл напрямую, без
sudo, – доступ предоставляется от имениroot.
При восстановлении из копии верните файлу Sudoers владельца и права доступа:
chown root:root /etc/sudoers
chmod 0440 /etc/sudoersЕсли файл принадлежит не root, sudo откажется работать полностью – для всех пользователей и для всех команд:
sudo: /etc/sudoers is owned by uid 1009, should be 0
sudo: error initializing audit plugin sudoers_auditК правам доступа sudo относится менее строго, но visudo -c ожидает только 0440 и при других значениях сообщает bad permissions, should be mode 0440.
После восстановления проверьте синтаксис командой visudo -c.
Заключение
Файл /etc/sudoers определяет, кому и какие команды разрешено выполнять через sudo. Редактируйте его только через visudo, а собственные правила храните отдельными файлами в каталоге /etc/sudoers.d/.
Составляя правило, выдавайте минимально необходимый набор прав: указывайте конкретные команды с фиксированными аргументами вместо ALL и конкретного пользователя вместо (ALL). После каждого изменения проверяйте синтаксис командой sudo visudo -c, а фактические права пользователя – командой sudo -l -U.
Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить, как добавить пользователя в Sudoers, или другие вопросы с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.