Лучшие практики использования sudo в скрипте bash

11

У меня есть длинный и продолжительный скрипт bash, где несколько команд нужно запускать от имени пользователя root, в то время как большинство команд нужно запускать от имени обычного пользователя до sudo, потому что это может испортить владение файлами и тому подобное.

Я придумал несколько методов, но у каждого из них есть свои проблемы

Способ 1: использование sudo внутри файла

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

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

Способ 2: используя sudo для вызова файла, а затем при необходимости переключитесь обратно на первоначального пользователя

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

Это также отстой, потому что мне нужно добавить su username -cперед почти каждой строкой. Также возможно найти оригинальное имя пользователя после sudo, но громоздко.

Есть ли способ лучше?

Изменить: я только разместил здесь небольшие бессмысленные сценарии, чтобы показать, о чем я говорю. В реальном скрипте у меня есть несколько строк, которым нужен sudo (запуск и остановка служб), некоторые строки, где не имеет значения, есть ли sudo, и довольно много строк, которые действительно нужно запускать без sudo.

Dakkaron
источник
4
Это очень редко нужно. В большинстве случаев вы просто запускаете скрипт, sudoесли ему нужны повышенные разрешения. Но нет смысла переключаться su username -cна запуск echo. Другими словами, это звучит как [XY]. Не могли бы вы отредактировать и объяснить, что на самом деле будет делать ваш скрипт и почему вы чувствуете, что вам нужно так часто переключать пользователей?
тердон
1
@ElderGeek ты вставил не ту ссылку? Это даже не похоже на связь. Вероятно, это дубликат Как я могу запустить команду 'sudo' внутри скрипта? но я надеюсь, что ОП может объяснить немного больше.
тердон
@terdon Казалось бы, так. Убираться.
Старейшина Компьютерщик
Это всего лишь пример сценария. Я не хотел вставлять здесь 200+ строчный скрипт. Я отредактирую ответ для более подробной информации.
Даккарон
Рассматривали ли вы вариант проверки, который описан в man sudo? -v, --validate Обновите кэшированные учетные данные пользователя, аутентифицируя пользователя при необходимости. Для плагина sudoers это продлевает время ожидания sudo еще на 15 минут по умолчанию, но не запускает команду. Не все политики безопасности поддерживают кэшированные учетные данные. ' (Если вы запускаете его достаточно часто, аутентификация sudo не должна
прерываться

Ответы:

5

Что касается метода 2, проще использовать функцию. Например:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERэто имя пользователя sudoer. Вы также можете использовать $(logname)на своем месте.

Бег на моей машине:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
источник
2

Читая man sudoers, вы видите:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

Таким образом, вы можете разрешить regularна хосте machine1выполнять command1и command2как корень, без пароля аутентификации с:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

но прочитайте каждую из них man -k sudoдля деталей.

waltinator
источник
0

Может быть, это может помочь:

chmod 775 yourscript.sh

Затем вы можете использовать sudo внутри скрипта (без запроса пароля) и не можете использовать sudo для других команд внутри скрипта.

1337 HaXxoR
источник
Я боюсь, что это не работает. chmod 775только позволяет выполнить файл и не меняет пользователя, который выполняет файл или их права.
Даккарон