Считается ли хорошей или плохой практикой использование команды sudo внутри сценария оболочки? Одно из преимуществ состоит в том, что если пользователь запускает сценарий как не-root, ему или ему по запросу будет предложено ввести пароль, а не произойдет сбой сценария. С другой стороны, если пользователь недавно запускал команду с помощью sudo, сценарий неявно запускает команды от имени пользователя root, что может не соответствовать ожиданиям пользователя.
Вот пример:
$ cat foo1
#!/bin/sh
sudo bar #implicit sudo
$ ./foo1
$ cat foo2
#!/bin/sh
bar
$ sudo ./foo2 #explicit sudo
Использование sudo - это всегда хорошая практика. Однако есть способы улучшить использование sudo. Один из методов - явно разрешить выполнение определенной команды с повышенными привилегиями.
Следующее позволит только людям из группы "users" выполнять команду foo1 без пароля.
%users ALL=(ALL) NOPASSWD: /full/path/to/foo1
Однако это не позволит выполнить foo2 в приведенном выше примере, если пользователь не введет правильный пароль.
Кроме того, часто лучше настроить sudo так, чтобы он запрашивал пароль пользователя, а не пароль root (на данный момент я забываю параметр конфигурации), и не иметь никаких записей, которые могут позволить пользователям повышать свои привилегии, например:
ALL ALL=(ALL) ALL
или
%users ALL=(ALL) ALL
Использование группы wheel или аналогичной группы для эскалации любой команды является хорошей практикой. В конце концов, лучше всего, чтобы пароль root был заперт в сейфе, чтобы никто (никогда) не мог его использовать, если только неприятный запах не попадет в вентилятор.
/ краткое мнение
Лично я считаю, что если вы не смотрите скрипт перед его запуском, любые побочные эффекты, которые происходят, в основном, являются вашей ошибкой (команды, выполняемые с sudo
которые вам не подсказывают, например), но в то же время я знаю, что каждый раз бывает сложно анализировать и анализировать весь сценарий. В целом я предпочитаю гибридную стратегию, в которой я могу сбалансировать удобство и безопасность.
/ конец мнения
Имейте в виду, вы всегда можете бежать sudo -k
перед вызовом скрипта, чтобы потребовать первый неявный sudo
вызовите запрос на ввод пароля, хотя, если он также не запускается после каждого sudo
внутри скрипта, он ТОЛЬКО запросит у вас самый первый вызов sudo
.
Есть несколько способов создать безопасный и разумный сценарий, используя sudo только при необходимости, некоторые из них более неприятны / опрометчивы, чем другие. В этом посте приводится несколько примеров / вариантов, которые я расскажу дальше. https://bitmingw.com/2017/01/22/use-sudo-in-scripts/
Вы можете запустить весь скрипт с помощью sudo
который, как вы описали, является «явным», но это также означает, что ВСЕ команды в сценарии запускаются от имени пользователя root, и если он написан плохо или вы забыли, что $USER
может измениться внутри скрипта на root
и вместо этого вам нужно было использовать $SUDO_USER
тогда вы можете оказаться в мире боли. Я случайно делал это в прошлом, и происходили странные и ужасные вещи, а затем вы (и я) в конечном итоге защищали свои скрипты с помощью if [ $EUID -eq 0 ]; then echo "Don't run as root!"; fi
или наоборот -gt 0
и вы должны не забывать ставить одного из защитников в каждый сценарий, который вы пишете (или изучать инструменты управления конфигурацией, такие как SaltStack / Puppet / Chef, которые могут автоматизировать некоторые из них).
sudo somescript.sh
Я предпочитаю использовать ВРЕМЕННО запустить sudo
с бесконечным временем кеширования, поэтому никакие другие команды sudo, выполняемые вами, не требуют повторного запроса (или, возможно, кого-либо, в зависимости от того, как вы его настроили). В идеале вы бы поместили правильно автоматизированную и протестированную функцию (или включили свой сценарий "cache_sudo.sh") в начале своих сценариев, а затем удалили бы бесконечный тайм-аут, разрешающий sudoers.d
файл, как только сценарий завершится (убит / завершен / ошибка), используя trap
а потом sudo -k
для истечения срока действия сеанса / токена после удаления файла. Видеть этот ответ для примера тестирования и добавляйте файл, только если он действителен.
Это ручная версия, не добавляйте ее в свой сценарий.
sudo visudo -f /etc/sudoers.d/infinite_cache_myuser
#Add next line to the file
Defaults:YOUR_USER_NAME timestamp_timeout=-1
Преимущества бесконечного кеша заключаются в вашем сценарии, вы можете повышать ТОЛЬКО команды, требующие root, с помощью sudo, при этом вам не нужно «понижать» ВСЕ другие команды, используя su $MY_REGULAR_USER some_command
или sudo -u $MY_REGULAR_USER some_command
для КАЖДОЙ ОДНОЙ команды. (Мне очень не нравится бессмысленно повторяющийся код для отбрасывания привилегий, если есть менее болезненный и не совсем небезопасный способ написать его для повышения только при необходимости).
Один из способов уменьшить повторяющийся код - определить короткий командный «префикс», который добавляет sudo
или su $MY_USER
в зависимости от того, будет ли скрипт запускаться с sudo ./myscript.sh
или ./myscript.sh
с участием sudo
внутри.
Вы могли бы написать sudoers
правило, разрешающее выполнение целевого скрипта с sudo
и без запроса пароля, но я думаю, что это такая же плохая идея, как и первый вариант, он помогает лишь незначительно, если вы хотите запустить sudo из задания cron, которое выполняется как пользователь без полномочий root, но необходимо изменить что-то, что требует root или другой пользователь, хотя вам нужно будет прочитать man sudoers
чтобы изучить синтаксис, позволяющий пользователю выдавать себя за другого пользователя.
# Customize line below and add to /etc/sudoers or /etc/sudoers.d/my_script_runner
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/abs/path/to/your/script
Вы также можете разрешить sudo без пароля только для тех команд, которые этого требуют, что позволяет запускать скрипт без полномочий root и по-прежнему получать доступ к этим командам.
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get update
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get upgrade
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/updatedb
Этот вариант, вероятно, является моим вторым выбором после трюка с бесконечным кешем. Обратной стороной является то, что вы редактируете файл sudoers каждый раз, когда находите новую команду, для которой требуется root, а не просто можете добавить sudo
перед командой в вашем скрипте. Плюс в том, что вы разрешаете только без пароля sudo
при необходимости, и вы все равно можете потребовать пароль для других sudo
команды, таким образом, оставаясь намного безопаснее.