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

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

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

2 ответа

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

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

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

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

Пример разрешения определенного пользователя т.е., боб, для выполнения выбранных команд завершения работы без пароля.

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
ответ дан 2 December 2019 в 04:46

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

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
ответ дан 2 December 2019 в 04:46

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

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