Едва ли можно упомянуть команду sudo и при этом не вспомнить забавный комикс XKCD про сэндвичи.


Похоже, что команда sudo — это ключ к магическим силам, которые заставляют Linux-системы делать то, что хочет пользователь. Единственная проблема тут в том, что к подобным вещам нельзя относиться легкомысленно.

Предположим, некто сидит в интернете и гуляет по сайтам. Ему в этой ситуации совершенно не нужно входить в систему как root-пользователь. Дело в том, что если что-то нехорошее проникнет в его компьютер, оно, работая с root-правами, сможет нанести гораздо больше вреда, чем без таких прав. Но, в то же время, бывает так, что нужно выполнить некие команды, которые обычно работают только под root-пользователем, но при этом не хочется утруждать себя вводом пароля.К счастью, команда sudo способна весьма просто решить вышеописанную задачу.

Зачем пользоваться sudo без пароля?


Приведу простой пример. Предположим, вы, в конце дня, хотите выключить компьютер. Вы выполняете из терминала команду shutdown, но она не срабатывает, так как вы пользуетесь учётной записью, у которой нет root-прав. А значит, эту команду придётся выполнить снова, на этот раз снабдив её sudo, а если незадолго до этого вы sudo не пользовались, то вам придётся ещё и ввести пароль. Эх…

Я задумался об этом, когда мне надо было работать с сервисом dbus в стартовом скрипте. Мне было нужно, чтобы скрипт работал бы, под учётной записью обычного пользователя, только с этим сервисом, не выдавая при этом приглашение на ввод пароля. Особенно важным это было из-за того, что у некоторых пользователей, всё равно, не было прав, необходимых для работы sudo. В любом случае, речь идёт о необходимости сделать так, чтобы простые пользователи могли бы выполнять весьма специфические команды без предоставления этим пользователям дополнительных полномочий.

Простой, но нехороший способ решения задачи


Возможно, первым, что придёт в голову у того, кто попытается решить нашу задачу, окажется следующее: поместить код в shell-скрипт, владельцем которого является root-пользователь, и установить бит suid. В результате права этого скрипта, когда его запускает обычный пользователь, повышаются до root-уровня. Это — вполне рабочий подход, но он выглядит как потенциальная дыра в безопасности системы. В конце концов, скрипт может сделать всё что угодно. Есть ли уверенность в том, что пользователь не принудит этот скрипт сделать что-то другое? Можно ли это гарантировать?

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

Настройка системы


И тут нам на помощь приходит sudo. Есть, на самом деле, лишь одно место, где можно настроить sudo. Правда, в большинстве современных дистрибутивов сделано так, что в этом, так сказать, «первом» месте, осуществляется чтение файлов из «второго» места, и этим «вторым» местом тоже можно пользоваться. Итак, «первое» место настройки sudo — это файл /etc/sudoers, и, как несложно догадаться, для редактирования этого файла надо обладать root-правами. На самом деле, этот файл настоятельно не рекомендуется открывать в обычных текстовых редакторах. Для работы с ним стоит использовать утилиту visudo. Эта утилита защищает администратора от опасности лишить самого себя root-прав в результате неправильной работы с /etc/sudoers. Потеря root-прав может стать серьёзной проблемой в тех системах, в которых не предусмотрен непосредственный вход под root-пользователем.

При выполнении команды visudo запускается обычный текстовый редактор. В наши дни это часто, по умолчанию, nano, хотя, если взглянуть на имя утилиты, становится ясно, что изначально это был редактор vi. Если же вам нужен какой-то другой редактор — утилита позволяет указать его, используя переменную среды VISUAL или EDITOR. Ну, если в общих чертах, то так оно и есть.

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

Defaults env_reset
Defaults env_keep=VISUAL
Defaults env_keep=EDITOR
Defaults editor=/usr/bin/nano:/usr/bin/emacs:/usr/bin/vi

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

Если visudo, при сохранении файла, не понравятся внесённые изменения, если утилита решит, что в них есть синтаксические ошибки, она задаст вопрос о том, что ей делать дальше. Для того чтобы увидеть возможные варианты её действий — нажмите «?». Ей можно сообщить, чтобы она сохранила бы файл в любом случае, но я так поступать не рекомендую.

И что теперь?


Существует множество команд, обладающих таинственным синтаксисом, которые можно поместить в sudoers для получения определённых результатов. В нашем случае нужно запустить команду наподобие shutdown или service для конкретного пользователя без ввода root-пароля. Предположим, что это — пользователь jolly_wrencher:

jolly_wrencher ALL= NOPASSWD: /usr/sbin/shutdown

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

Если пользователь попытается сделать что-то такое, что здесь не разрешено, sudo, если у пользователя есть root-пароль и права на выполнение этого действия, разрешит ему это сделать. В противном случае ничего не получится.

Вот, например, две строчки, которые позволили мне решить проблему с управлением dbus, о которой я говорил выше:

jolly_wrencher ALL= NOPASSWD: /usr/sbin/service dbus status
jolly_wrencher ALL= NOPASSWD: /usr/sbin/service dbus --full-restart

Итоги


В наши дни в файле sudoers многих дистрибутивов можно найти примерно такую последнюю строчку:

#includedir /etc/sudoers.d

Тут проводится сканирование указанной директории на предмет наличия файлов (если только в их именах нет символов ~ или .) и обработка найденных файлов. В результате, в моём случае, строки, имеющие отношение к dbus, были размещены в файле /etc/sudoers.d/dbus-service. Для редактирования подобных файлов тоже нужно использовать visudo. Современным версиям этой утилиты можно просто передавать имя файла, который нужно отредактировать. А её старые версии нуждаются в опции -f. После редактирования файла система проверяет весь файл sudoers на предмет наличия ошибок. В результате это безопаснее непосредственного редактирования подобных файлов.

Конечно, с помощью sudo и sudoers можно решать ещё очень много различных задач. Но, если возникает желание широкомасштабного использования этих инструментов, это желание в себе стоит ограничить. Информационная безопасность — это такая сфера деятельности, где очень легко делать предположения, которые могут привести к серьёзным проблемам. Правда, постоянно возникают ситуации, в которых нам прямо-таки необходимы сверхвозможности, о которых мы говорили. И Linux, как всегда, даёт нам то, что нам нужно.

Возникали ли у вас ситуации, когда вам нужно было пользоваться sudo без ввода root-пароля?

Комментарии (9)