#bash #shell #ubuntu #sudo
#bash #оболочка #ubuntu #sudo
Вопрос:
Я создал простой скрипт 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
разрешения на протяжении всего сценария?
Спасибо
Комментарии:
1. почему вы не разрешаете пользователю запускать его
sudo
?
Ответ №1:
Гибкость sudo сильно недооценивается. Это приводит к очень плохим практикам (таким как sudo su -
метод операции canon-ball).
Гораздо лучший метод — специально разрешить команды, которые вы собираетесь разрешить, без использования пароля:
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
Ответ №2:
Работая строго в скрипте (и не редактируя файл sudoers или вызывая скрипт через sudo ./script.sh
), вот какой, на мой взгляд, самый чистый метод.
startsudo() {
sudo -v
( while true; do sudo -v; sleep 50; done; ) amp;
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.
Ответ №3:
Вы можете настроить это время ожидания, добавив в /etc /sudoers
Defaults timestamp_timeout=#Number of minutes
Но его намного проще запустить
sudo ./worker.sh
Ответ №4:
Вот обходной путь:
sudo echo "I am sudo!" # Asks for passwords
( while true; do sudo -v; sleep 40; done ) amp; # 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)
Комментарии:
1. Если вы собираетесь взломать его таким образом, ПО крайней мере, убедитесь, что kill и
sudo -k
зарегистрированы в вашем скрипте как ловушки сигналов. Это требует больших дыр в безопасности. (прервать скрипт с помощью Ctrl-C, sudo автоматически поддерживается на неопределенный срок)
Ответ №5:
Это мой способ:
#!/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
Комментарии:
1. Это выглядит как правильный ответ, но сохранение пароля пользователя в файл кажется довольно небезопасным. Кроме того, что делает
srm
команда? В моем дистрибутиве Linux этого нет.
Ответ №6:
Получите привилегии root раз и навсегда:
sudo su -
# What I need to do with root