Командная строка 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, чтобы не пропустить новые посты😉.
Спасибо, что читаете. Успехов вам! И старайтесь все делать со здравой толикой безопасности.