Запускать только части скрипта как sudo, вводя пароль только один раз

14

Я пишу сценарий (на самом деле комбинация сценариев и make-файла), который устанавливает внешние зависимости: некоторые apt-getкоманды, некоторые gitклонирование, сборка, установка, добавление пользователей в группы, ...

Некоторые операции в этих сценариях требуют прав суперпользователя, а некоторые - нет.

До сих пор я запускал весь процесс make с помощью sudo, но у него есть некоторые недостатки:

  • gitРЕПО клонировать получить в rootкачестве владельца, а это значит , что я не могу изменить их впоследствии без sudoилиchown
  • скрипты, которые добавляют пользователей в группы, не знают, какого пользователя добавить, так как whoamiвозвращаетсяroot

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

Решения, которые я нашел в Интернете, включают в себя:

  • sudo -vв начале сценария, но если я правильно понимаю, это время ожидания. Мой сценарий может быть запущен в течение нескольких часов
  • запуск скрипта с помощью sudo, но команды, которым не нужен суперпользователь с sudo -u $(logname) <command>. Это то, что я делаю сейчас, но кажется, что все должно быть наоборот.

В идеале я хотел бы, чтобы мой сценарий:

  1. запросить учетные данные суперпользователя
  2. запускать обычные команды как зарегистрированный пользователь
  3. Запустите команды sudo с учетными данными, введенными на шаге 1
  4. sudo -k закрыть сеанс суперпользователя
Готье
источник
2
Вы все равно можете запускать все как sudo, и ваш скрипт может проверять SUDO_USERпеременную окружения. Если он присутствует, он будет содержать имя пользователя, вызывающего sudo. Таким образом, вы можете (как пользователь root) chown $ SUDO_USER: $ SUDO_GID $ your_files. Точно так же вы можете проверить эти переменные, чтобы ваши команды adduser знали, какого пользователя добавить.
roadmr
... или запустите все от имени пользователя root и используйте su $SUDO_USER -c commandкоманды для запуска от имени обычного пользователя.
Rmano

Ответы:

7

Поскольку у вас есть доступ к sudo, создайте файл sudoers для себя, а затем удалите его, когда скрипт будет выполнен:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Гленн Джекман
источник
2

Один из способов, что я не буду вообще рекомендую, чтобы прочитать пароль самостоятельно, а также использование sudo«s -Sвозможность передать пароль , как и в случае необходимости:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

От man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.
Мур
источник
1
Это безопасно? echo "$password"??
αғsнιη
@KasiyA echo "$password"не будет, но heredocs и herestrings немного более безопасны. Они не видны в командной строке, показанной обычными инструментами.
Муру
1
Я думаю , что , строго говоря, echo "$password"на левой стороне трубы является безопасным в Баш скрипт. echoвстроенная оболочка; /bin/echoне работает, когда это называется просто echo .... У некоторых других оболочек есть echoвстроенные ( dashнапример), но оболочки типа Bourne не обязательно иметь такую . Поэтому я думаю, что echo "$password" |это приемлемо в bash, но лучше избегать его, если кто-то переносит скрипт в другую оболочку, не замечая проблемы. Я использую непереносимый, [[а не [в этом сценарии, чтобы предотвратить такую ​​же проблему. @KasiyA
Каган