Подскажите пароль sudo до тех пор, пока не будет задан правильный, и сохраните его в переменной сценария bash [duplicate]

В этом вопросе уже есть ответ: Как запустить команду «sudo» внутри скрипта? 7 ответов Как я могу изменить количество попыток ввода пароля, разрешенных sudo? 1 ответ

Я хотел бы удалить необходимость вводить пароль несколько раз для сценария bash, который запускает команды sudo. Как я могу зацикливать пароль, пока что-то вроде sudo echo не вернет 0, а затем сохранит пароль в переменной, чтобы использовать скрипт?

2
задан 30 October 2017 в 16:41

4 ответа

Конечно, можно удалить необходимость вводить пароль sudo для определенных команд или даже целых скриптов.

Ваш предложенный путь хранения пароля в локальной переменной в скрипте довольно неразумный. Любой, имеющий права чтения на /proc/<pid>/environ, может читать локальные переменные. Любой, кто получает доступ на чтение к скрипту с жестко закодированными учетными данными, может использовать эти учетные данные для эскалации привилегий для root и собственной системы. В одной пользовательской системе это все еще неразумно, так как все больше удаленных атак, нацеленных на пользователей Linux.

Без специфики вашего скрипта я могу только посоветовать вам прочитать Ubuntu Community Wiki - Sudoers. Затем измените файл sudoers, запустив sudo visudo, чтобы добавить в файл определенные команды.

Вероятно, вы должны добавить две строки, чтобы добавить псевдоним команды, а второй - разрешить пользователям выполнять эти команды.

Пример предоставления определенному пользователю, т. е. bob, выполнения выбранных команд выключения без пароля.

Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS

Следующий сценарий - пример того, как включить в скрипт возможность установки, удаления или редактирования строк примера в /etc/sudoers.

#!/bin/bash #Set Script Name variable SCRIPT=`basename ${BASH_SOURCE[0]}` #Initialize variables to default values. OPT_i=i OPT_u=u OPT_e=e OPT_m=m #Set fonts for Help. NORM=`tput sgr0` BOLD=`tput bold` REV=`tput smso` #Help function function HELP { echo -e \\n"Help documentation for ${BOLD}${SCRIPT}.${NORM}"\\n echo -e "${REV}Basic usage:${NORM} ${BOLD}$SCRIPT file.ext${NORM}"\\n echo "Command line switches are optional. The following switches are recognized." echo "${REV}-1${NORM} --Installs lines in /etc/sudoers to allow script to be run without entering password multiple times." echo "${REV}-u${NORM} --Unistalls lines in /etc/sudoers." echo "${REV}-e${NORM} --Launces visudo to edit /etc/sudoers." echo "${REV}-m${NORM} --Launces main." echo -e "${REV}-h${NORM} --Displays this help message. No further functions are performed."\\n exit 1 } #Install function function INSTALL { echo "launching Install" echo -e '#script_append'\\n'Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot'\\n'bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS' | sudo EDITOR='tee -a' visudo } #Unnstall function function UNINSTALL { echo "launching uninstall" bash -c 'printf ",g/^#script_append$/d\nw\nq\n" | sudo EDITOR='ed' visudo' bash -c 'printf ",g/^Cmnd_Alias.*reboot$/d\nw\nq\n" | sudo EDITOR='ed' visudo' bash -c 'printf ",g/^bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS$/d\nw\nq\n" | sudo EDITOR='ed' visudo' } #Main function function MAIN { echo "launching editor via main" sudo visudo } #Check the number of arguments. If none are passed, print help and exit. NUMARGS=$# echo -e \\n"Number of arguments: $NUMARGS" if [ $NUMARGS -eq 0 ]; then HELP fi ### Start getopts code ### #Parse command line flags #If an option should be followed by an argument, it should be followed by a ":". #Notice there is no ":" after "h". The leading ":" suppresses error messages from #getopts. This is required to get my unrecognized option code to work. while getopts ":iuemh" FLAG; do case "${FLAG}" in i) #set option "i" OPT_i=${OPTARG} echo "-i used: $OPTARG" if sudo grep -q '#script_append' /etc/sudoers then echo "Sudoers apperes to have already been installed" exit else INSTALL fi ;; u) #set option "u" OPT_u=$OPTARG echo "-u used: $OPTARG" UNINSTALL ;; e) #set option "e" OPT_e=$OPTARG echo "-e used: $OPTARG" sudo visudo ;; m) #set option "m" OPT_m=$OPTARG echo "-m used: $OPTARG" MAIN ;; h) #show help HELP ;; \?) #unrecognized option - show help echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed." HELP #If you just want to display a simple error message instead of the full #help, remove the 2 lines above and uncomment the 2 lines below. #echo -e "Use ${BOLD}$SCRIPT -h${NORM} to see the help documentation."\\n #exit 2 ;; esac done shift $((OPTIND-1)) #This tells getopts to move on to the next argument. ### End getopts code ###
2
ответ дан 18 July 2018 в 04:24

Мой текущий подход, который, кажется, работает, выглядит следующим образом:

read_sudo_pwd() { read -s -p "[sudo] password for $USER: " sudo_pwd until (echo $sudo_pwd | sudo -S echo '' 2>/dev/null) do echo -e '\nSorry, try again.' read -s -p "[sudo] password for $USER: " sudo_pwd done } read_sudo_pwd echo $sudo_pwd | sudo -S echo 'Hello' echo $sudo_pwd | sudo -S echo 'World'
-1
ответ дан 18 July 2018 в 04:24

Конечно, можно удалить необходимость вводить пароль sudo для определенных команд или даже целых скриптов.

Ваш предложенный путь хранения пароля в локальной переменной в скрипте довольно неразумный. Любой, имеющий права чтения на /proc/<pid>/environ, может читать локальные переменные. Любой, кто получает доступ на чтение к скрипту с жестко закодированными учетными данными, может использовать эти учетные данные для эскалации привилегий для root и собственной системы. В одной пользовательской системе это все еще неразумно, так как все больше удаленных атак, нацеленных на пользователей Linux.

Без специфики вашего скрипта я могу только посоветовать вам прочитать Ubuntu Community Wiki - Sudoers. Затем измените файл sudoers, запустив sudo visudo, чтобы добавить в файл определенные команды.

Вероятно, вы должны добавить две строки, чтобы добавить псевдоним команды, а второй - разрешить пользователям выполнять эти команды.

Пример предоставления определенному пользователю, т. е. bob, выполнения выбранных команд выключения без пароля.

Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS

Следующий сценарий - пример того, как включить в скрипт возможность установки, удаления или редактирования строк примера в /etc/sudoers.

#!/bin/bash #Set Script Name variable SCRIPT=`basename ${BASH_SOURCE[0]}` #Initialize variables to default values. OPT_i=i OPT_u=u OPT_e=e OPT_m=m #Set fonts for Help. NORM=`tput sgr0` BOLD=`tput bold` REV=`tput smso` #Help function function HELP { echo -e \\n"Help documentation for ${BOLD}${SCRIPT}.${NORM}"\\n echo -e "${REV}Basic usage:${NORM} ${BOLD}$SCRIPT file.ext${NORM}"\\n echo "Command line switches are optional. The following switches are recognized." echo "${REV}-1${NORM} --Installs lines in /etc/sudoers to allow script to be run without entering password multiple times." echo "${REV}-u${NORM} --Unistalls lines in /etc/sudoers." echo "${REV}-e${NORM} --Launces visudo to edit /etc/sudoers." echo "${REV}-m${NORM} --Launces main." echo -e "${REV}-h${NORM} --Displays this help message. No further functions are performed."\\n exit 1 } #Install function function INSTALL { echo "launching Install" echo -e '#script_append'\\n'Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot'\\n'bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS' | sudo EDITOR='tee -a' visudo } #Unnstall function function UNINSTALL { echo "launching uninstall" bash -c 'printf ",g/^#script_append$/d\nw\nq\n" | sudo EDITOR='ed' visudo' bash -c 'printf ",g/^Cmnd_Alias.*reboot$/d\nw\nq\n" | sudo EDITOR='ed' visudo' bash -c 'printf ",g/^bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS$/d\nw\nq\n" | sudo EDITOR='ed' visudo' } #Main function function MAIN { echo "launching editor via main" sudo visudo } #Check the number of arguments. If none are passed, print help and exit. NUMARGS=$# echo -e \\n"Number of arguments: $NUMARGS" if [ $NUMARGS -eq 0 ]; then HELP fi ### Start getopts code ### #Parse command line flags #If an option should be followed by an argument, it should be followed by a ":". #Notice there is no ":" after "h". The leading ":" suppresses error messages from #getopts. This is required to get my unrecognized option code to work. while getopts ":iuemh" FLAG; do case "${FLAG}" in i) #set option "i" OPT_i=${OPTARG} echo "-i used: $OPTARG" if sudo grep -q '#script_append' /etc/sudoers then echo "Sudoers apperes to have already been installed" exit else INSTALL fi ;; u) #set option "u" OPT_u=$OPTARG echo "-u used: $OPTARG" UNINSTALL ;; e) #set option "e" OPT_e=$OPTARG echo "-e used: $OPTARG" sudo visudo ;; m) #set option "m" OPT_m=$OPTARG echo "-m used: $OPTARG" MAIN ;; h) #show help HELP ;; \?) #unrecognized option - show help echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed." HELP #If you just want to display a simple error message instead of the full #help, remove the 2 lines above and uncomment the 2 lines below. #echo -e "Use ${BOLD}$SCRIPT -h${NORM} to see the help documentation."\\n #exit 2 ;; esac done shift $((OPTIND-1)) #This tells getopts to move on to the next argument. ### End getopts code ###
2
ответ дан 24 July 2018 в 18:04
  • 1
    Я не храню пароль в скрипте (который является установщиком, который должен запускать некоторые команды как sudo, а некоторые - как пользователь). Я хочу беспокоить пользователя паролем только один раз во время запуска скрипта. Я попробовал несколько подходов с ОС Tails (поддерживаемая ОС), чтобы отключить приглашение к паролю, но редактирование /etc/sudoers.d/always-ask-password не устранило его надежно. Что касается visudo, пользователь должен был бы самостоятельно редактировать, и я не хочу этого. Я попробовал echo 'Defaults timestamp_timeout=-1' | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/always-ask-password'), но это тоже не сработало. – maqp 28 October 2017 в 21:01
  • 2
    «Любой, имеющий права на чтение в / proc / & lt; pid & gt; / environ, может считывать локальные переменные. & quot; ... это правда, но только для переменных, с которых начался процесс. Изменения или дополнения, сделанные в результате этого процесса, не отражаются в environ. Локальные неэкспортируемые переменные даже не будут видны в дочернем процессе environ. – muru 30 October 2017 в 14:45

Мой текущий подход, который, кажется, работает, выглядит следующим образом:

read_sudo_pwd() { read -s -p "[sudo] password for $USER: " sudo_pwd until (echo $sudo_pwd | sudo -S echo '' 2>/dev/null) do echo -e '\nSorry, try again.' read -s -p "[sudo] password for $USER: " sudo_pwd done } read_sudo_pwd echo $sudo_pwd | sudo -S echo 'Hello' echo $sudo_pwd | sudo -S echo 'World'
-1
ответ дан 24 July 2018 в 18:04
  • 1
    -1 Плохая конструкция: $PWD - переменная среды, поэтому лучше всего, если вы ее не перезапишете. Используйте более описательную, строчную переменную типа $password_sudo. – wjandrea 29 October 2017 в 10:18

Другие вопросы по тегам:

Похожие вопросы: