Командная строка Linux, повышение привилегий: команды su, sudo
Приветствую!
Продолжаем изучать командную строку Linux. Сегодня узнаем, как правильно запускать команды от имени другого пользователя, в том числе пользователя root. Познакомимся с командами su и sudo, а также изучим, как правильно предоставлять ограниченные полномочия для пользователей и групп.
Заодно разберем, почему sudo su – это как сказать: “Откройте мне дверь“, а потом еще раз потребовать: “И впустите меня немедленно!“😁.
Присоединяйтесь к нашему каналу в телеграм: t.me/r4ven_me, уведомления о новых постах приходят туда в день публикации. А если у вас есть вопросы или просто желание пообщаться по тематике – заглядывайте в чат: t.me/r4ven_me_chat.
Если вы новичок в мире Linux, то рекомендую изучить мои предыдущие статьи по командной строке:
- Введение: типы команд, plain text, файловая система, shell prompt
- Навигация в системе и просмотр директорий: команды pwd, ls, cd
- Вывод и чтение содержимого: команды echo, cat, less
- Работа с файлами: команды touch, mkdir, cp, mv, rm
- Ссылки на файлы (links): команда ln
- Перенаправление ввода и вывода: операторы “>”, “<“, “|”
- Контроль выполнения команд: операторы “&&”, “||”, “;” и “&”
- Процессы: команды jobs, fg, bg, ps, pgrep, kill, pkill, htop
- Права на файлы: команды id, chmod, chown
Предисловие
Тема привилегий в Linux очень обширна. В данной статье мы только разберем работу с командами su и sudo, как наиболее популярными инструментами. Но существует также множество других механизмов, например capabilities, SELinux, AppArmor и в целом PolicyKit, ну и конечно ACL (Access Control Lists). Голову сломать можно, только от разнообразия🤯.
Команда su
su (Substitute User или Set UID или Switch User или Super User — замена/переключение пользователя, суперпользователь) — это классическая команда и одноименная утилита в Unix-подобных операционных системах, позволяющая пользователю войти в систему под другим именем, не завершив текущий сеанс. Чаще всего используется для выполнения некоторых команд или временного входа с правами суперпользователя с целью выполнения административных задач. Просто и понятно 😉.
Автором данной программы является Dennis Ritchie. Если верить англоязычной википедии, то первый релиз данной утилиты был 3 ноября, 1971 года. Почти 53 года назад😲. И несмотря на это, она до сих пор пользуется популярностью. Вот уж прям, философия Unix в действии: “программа должна выполнять одну задачу и делать это хорошо“.
su [ключи] [-] [имя_пользователя]
Если не передать команде имя пользователя явно, будет использовано имя root.
Особенностью команды является запрос пароля при каждом ее выполнении. Только если она уже не выполняется от имени root пользователя.
-или-l(login) – имитировать “полноценный” вход под оболочкой пользователя (make the shell a login shell);-c(command) – выполнить переданную далее команду (в кавычках);-g(group) – выполнить подмену группы пользователя, работает только для root.
Приступим к практике. Если ввести в терминал:
su -
У нас запросят пароль суперпользователя root, после чего мы переключимся на него.
Если команде явно передать имя желаемого пользователя, например:
su - ivan
То, соответственно, мы активируем сеанс оболочки от его имени.
Существует принципиальная разница, между указанием ключа - или -l и его отсутствием. Если ключ не указать, то при переходе на другого пользователя, ваш текущий рабочий каталог и часть окружения пользователя (env) не изменятся. Вот пример:
whoami echo $USER su whoami echo $USER
Команда whoami выводит в терминал имя текущего пользователя.Тут видно, что после перехода под учетную запись суперпользователя, переменная окружения $USER, содержащая имя текущего пользователя, не обновилась. Про этот нюанс необходимо помнить, особенно при написании скриптов, если в них используется команда su.
Теперь попробуем выполнить единичную команду, без смены пользователя:
su -c 'whoami'
А теперь с использованием дефиса:
su -c 'pwd' su - -c 'pwd'
Команда pwd (print working directory) выводит в терминал текущий рабочий каталог пользователя.Надеюсь, разницу вы поняли. Ну и еще парочку примеров для закрепления.
su - su - ivan -c 'whoami'
su -c 'whoami && pwd'
Оператор контроля выполнения команд – && позволяет выполнить вторую команду, только при успешном выполнении предыдущей. Подробнее про такие операторы тут.Команда sudo
sudo (англ. Substitute User and do, дословно «подменить пользователя и выполнить») — также является командой и одноименной утилитой, позволяющей делегировать определенные привилегированные ресурсы пользователям с ведением журнала их действий.
И я почти все время думал, что sudo = super user do 😳
sudo поставляется с большинством UNIX и UNIX-подобных операционных систем, но, к примеру, “чистый” Debian в этот список не входит. В случае данного дистрибутива, утилиту sudo необходимо устанавливать отдельно!
В отличие от классической su, sudo предоставляет более гибкие инструменты для настройки повышения привилегий. Чаще всего, с помощью sudo, задают четкий перечень команд, доступных для выполнения от имени другого пользователя, в т.ч. root.
sudo [ключи] команда
-s(shell) – запустить оболочку от имени другого пользователя, тоже, что иsudo bash(как пример);-i– также запустить оболочку от имени другого пользователя, но аналогично нативному входу в систему (login shell);-u(user) – позволяет указать пользователя, от имени которого будет выполнена команда;-e(edit) – выполнить редактирование файла, с использованием заданного в переменной$EDITORконсольного редактора (nano, vim);-l(list) – вывести список доступных к запуску, с помощьюsudo, команд;-S(stdin) – принимать пароль из стандартного потока ввода (stdin);-E(env) – запускать команды с сохранением окружения (env) текущего пользователя.
Ну а практику мы начнем, пожалуй, с одной распространенной, но весьма комичной ситуации – когда для получения root полномочий используют команду:
sudo su
По сути, в ней нет ничего страшного, но она неверна в синтаксическом плане.
Вместо нее рекомендуется использовать следующие команды:
sudo -s # или sudo -i # или su -
Дело в том, что при выполнении sudo su вы создаете лишний процесс. Получается одновременный запуск двух разных команд.
sudo su ps exit sudo -s ps
Как видно в верхней части скрина, на один процесс больше🤷♂️.
Теперь попробуем выполнить отдельную команду, без перехода на другого пользователя:
sudo -u postgres 'whoami'
В данном примере используется пользователь postgres, от имени которого, по умолчанию, запускаются процессы СУБД PostgreSQL.А чтобы перейти в оболочку другого пользователя (аналог su - <пользователь>) выполним:
sudo -iu postgres whoami pwd
В таком случае и рабочая директория и окружение будут целевого пользователя.
Файлы sudoers
Плавно подходим в основной фишке утилиты sudo – файлы sudoers. Это такие файлы, в которых следуя правилам строгого синтаксиса, можно тонко настроить разграничение полномочий для пользователей и групп.
Основной файл конфигурации расположен по пути: /etc/sudoers. Обычно он уже заполнен дефолтными и прокомментированными значениями.
По умолчанию, в данном файле уже заданы максимальные привилегии для группы sudo в Deb системах (Debian, Ubuntu, Linux Mint) и wheel для RPM (RHEL, Centos, Fedora, OpenSuse).
Почему wheel? Вероятно так исторически сложилось. Гугл перевод из англ. википедии: В операционных системах Unix термин «колесо» относится к учетной записи пользователя с битом колеса — системной настройкой, которая предоставляет дополнительные специальные системные привилегии, которые позволяют пользователю выполнять ограниченные команды, к которым обычные учетные записи пользователей не имеют доступа.
Пользователи такой группы имеют возможность выполнять переход в учетную запись root.
sudo cat /etc/sudoers groups
Чтобы расширить стандартную конфигурацию sudo, рекомендуется создавать отдельные файлы в директории /etc/sudoers.d. Часто в разных дистрибутивах, там уже есть какие-то файлы. Например в Linux Mint лежит:
ls -l /etc/sudoers.d
Создавать такие файлы рекомендуется с помощью специальной команды visudo, которая перед сохранением файла проверяет его синтаксис, и в случае ошибки выводит предупреждение.
Давайте создадим такой файл. Но сперва выберем консольный редактор по умолчанию такой командой (для Deb систем):
sudo update-alternatives --config editor
Разумеется мы выбираем vi/vim/nvim😉, потому что я давненько не перезагружал компьютер😁
Перед внесением любых изменений в файлыsudoers, необходимо открыть несколько резервных терминалов с root сессией. Если допустить хотя бы одну ошибку в синтаксисе файла, root доступ через sudo пропадёт. Придется входить под root напрямую или использоватьsu. Я вас предупредил.
Теперь создадим файл с перечнем доступных команд для УЗ из примера выше – postgres и группы – ivan:
sudo visudo -f /etc/sudoers.d/postgres
Ключ -f используется для явного указания пути до sudoers файла.Пример наполнения может быть такой:
Cmnd_Alias PG = \
/usr/sbin/ldconfig, \
/usr/sbin/setcap CAP_NET_ADMIN\,CAP_NET_BIND_SERVICE+epi /usr/lib/postgresql/16/bin/postgres, \
/usr/bin/systemctl status postgresql, \
/usr/bin/systemctl start postgresql, \
/usr/bin/systemctl stop postgresql, \
/usr/bin/systemctl restart postgresql, \
/usr/bin/journalctl * postgresql, \
/usr/bin/cat /var/log/auth.log
postgres ALL = (root) NOPASSWD: PG
%ivan ALL = (postgres) NOPASSWD: ALLСами команды я расписывать не буду, опишу лишь директивы sudoers:
Cmnd_Aliasопределяет псевдоним списка команд –PG(произвольный), который, собственно и содержит команды, разделенные запятой. Символ обратного слэша – это символ экранирования. Используется, например, для экранирования символов перевода строки или символа запятой, которая к слову, в sudoers является частью синтаксиса!postgres ALL = (root) NOPASSWD: PGв этой строке:postgres– учетная запись, для которой задается список команд, доступных черезsudo;ALL =– хосты, для которых разрешено использоватьsudo;(root)– пользователь, от имени которого разрешено выполнение указанных команд;NOPASSWD:– отключение запроса пароля при выполнении команды черезsudo;PG– алиас, заданный параметромCmnd_Alias%ivan ALL = (postgres) NOPASSWD: ALLв этой строке:%ivan– системная группа (в данном примереivan), пользователи которой могут выполнять команды с помощьюsudoот имени указанного далее пользователя;ALL =– хосты, для которых разрешено использоватьsudo;(postgres)– пользователь, от имени которого разрешено выполнение указанных команд;NOPASSWD:– отключение запроса пароля при выполнении команды черезsudo;ALL– возможность выполнять любые команды доступные указанному пользователю и от его имени.
Сохраняем и выходим из редактирования.
Если допустить ошибку, вы увидите такое сообщение с указанием места, где ошиблись:
Введите e и нажмите Enter для возврата в редактор. Про букву e нужно знать, т.к. никаких подсказок программа не дает, сурово однако🤔.
Если все заполнили корректно, то visudo позволит сохранить файл и закрыть редактор.
В примере выше, мы настроили полный доступ к пользователю postgres для членов группы ivan. А ему (postgres) в свою очередь, разрешили выполнять строгий перечень команд от имени root.
sudo -l sudo -iu postgres sudo -l
При вводе разрешенной команды, она просто выполнится🤷♂️. А при использовании команды не из разрешенного списка, sudo у вас запросит пароль суперпользователя, и если его у вас нет, соответственно запретит ее выполнение. Пример:
sudo systemctl status postgresql sudo systemctl enable postgresql
Ах да, совсем недавно я узнал, что при использовании sudo, переменная окружения $PATH становится неактуальной. Для утилиты sudo задается специальная директива secure_path в файле /etc/sudoers со списком директорий, где хранятся исполняемые файлы:
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/opt/bin"
Послесловие
Мы с вами сделали еще один шаг на пути изучения командной строки Linux. Как я уже сказал в начале статьи, тема привилегий, да и безопасности в целом, в мире Linux – очень обширна и будет всегда актуальной. Поэтому старайтесь уделять время не только изучению каких-то технологий, но и их безопасному использованию.
Если остались вопросы, приглашаю в вороний чат🐧. И, конечно, в наш канал Telegram: @r4ven_me, чтобы не пропустить новые посты😉.
Спасибо, что читаете. Успехов вам! И старайтесь все делать со здравой толикой безопасности.