Скрипт оболочки - Sudo-разрешения теряются со временем - PullRequest
7 голосов
/ 03 мая 2011

Я сделал простой скрипт bash, который должен сохранять привилегии суперпользователя на протяжении всего скрипта.К сожалению, но понятно, что сценарий теряет свои sudo -высокие разрешения при появлении sleep.Плохо для меня:

sudo echo "I am sudo!" # Asks for passwords
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.

Я думал о замене sleep на цикл while, который поддерживает работу sudo, но я уверен, что есть лучшие варианты сделать sudo -разрешения остаются на протяжении всего сценария?

Спасибо

Ответы [ 6 ]

10 голосов
/ 01 июня 2011

Гибкость sudo широко недооценивается. Это приводит к очень плохим практикам (таким как sudo su - метод хирургии канонического шара).

Гораздо лучший способ - разрешить команды, которые вы хотите разрешить без использования пароля :

phill = NOPASSWD: /bin/ls, /usr/bin/lprm

При желании вы можете сделать это для определенных пользователей с определенных хостов, работающих как определенные администраторы. Вы даже можете запретить пользователям передавать экранированные символы в качестве параметров. Вы можете сделать sudo, чтобы запретить запущенной программе динамически выполнять другие приложения и т. Д. И т. Д. Вам нужно прочитать справочную страницу для sudoers (и обязательно прочитать процедуры по редактированию этого специального файла!) .

Вот небольшой вкус вещей, ( отсюда ):

User_Alias     OPERATORS = joe, mike, jude
Runas_Alias    OP = root, operator
Host_Alias     OFNET = 10.1.2.0/255.255.255.0
Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm

OPERATORS ALL=ALL
#The users in the OPERATORS group can run any command from any terminal.

linus ALL=(OP) ALL
# The user linus can run any command from any terminal as any user in the OP group (root or operator).

user2 OFNET=(ALL) ALL
# user user2 may run any command from any machine in the OFNET network, as any user.

user3 ALL= PRINTING
# user user3 may run lpc and lprm from any machine.

go2linux ALL=(ALL) ALL
# user go2linux may run any command from any machine acting as any user. (like Ubuntu)

 If you want not to be asked for a password use this form
go2linux ALL=(ALL) ALL NO PASSWD: ALL
5 голосов
/ 03 мая 2011

Вы можете настроить этот тайм-аут, добавив в / etc / sudoers

Defaults timestamp_timeout=#Number of minutes

Но запустить его намного проще

sudo ./worker.sh
4 голосов
/ 30 мая 2015

Работая строго внутри скрипта (не редактируя файл sudoers или не вызывая скрипт через sudo ./script.sh), вот что я считаю самым чистым методом:

startsudo() {
    sudo -v
    ( while true; do sudo -v; sleep 50; done; ) &
    SUDO_PID="$!"
    trap stopsudo SIGINT SIGTERM
}
stopsudo() {
    kill "$SUDO_PID"
    trap - SIGINT SIGTERM
    sudo -k
}

По сути, это определяет пару функций для включения и выключения режима sudo. Вызов startsudo перед запуском кода с использованием sudo аутентифицируется с помощью sudo, разветвляет фоновый цикл обновления sudo, сохраняет PID цикла и устанавливает прерывание сигнала для остановки режима sudo при нажатии Ctrl + C. Вызов stopsudo убивает цикл, очищает ловушку сигнала и делает недействительной предыдущую аутентификацию с помощью sudo.

После копирования этих функций в ваш скрипт используйте их следующим образом.

startsudo
echo "Sudo mode is active."
# whatever you want to do with sudo
stopsudo

Я хотел бы поблагодарить @karl за простоту встраивания цикла обновления sudo и @sehe за указание на то, что для прерывания цикла следует использовать сигнальную ловушку, если она не уничтожается нормально. Обе эти идеи улучшили мой скрипт резервного копирования btrfs , который использует цикл обновления sudo, чтобы избежать повторного запроса пользователя после того, как резервное копирование подобъема займет больше времени, чем тайм-аут sudo.

4 голосов
/ 03 мая 2011

Вот обходной путь:

sudo echo "I am sudo!" # Asks for passwords
( while true; do sudo -v; sleep 40; done ) &   # update the user's timestamp
sudoPID=$!
# ...
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.
kill -TERM $sudoPID
sudo -k  # invalidate the user's timestamp at end of script (does not require a password)
2 голосов
/ 07 февраля 2013

Это мой путь:

#!/bin/sh
echo "Working..."
# add you pass
echo "yourpass" >> file.pass ;sleep 5 
# Check if root
if [ `cat file.pass | sudo -S su root -c whoami` != "root" ]; then
echo "Not running as root. Exiting..."
sleep 2
echo "Cleaning..."
sleep 1
srm file.pass
echo "Cleaned"
exit 0
else
echo "Running as root. Good"
sleep 2
# and run any sudo with
cat file.pass | sudo -S su root -c ls #<any command>
fi

sleep 5
echo `cat file.pass | sudo -S su root -c whoami` "say bay bay"
# if pass no longer need
srm file.pass
echo "End session :)"
exit 0
0 голосов
/ 01 июня 2011

Получить root-права один раз для всех:

sudo su -
# What I need to do with root 
...