Запросить права root из скрипта

У меня есть скрипт, который может работать как sudo script.sh или pkexec script.sh

. Было бы намного лучше с точки зрения пользователя, если бы скрипт попросил пароль у пользователя, когда он его запускал по имени script.sh.

Как я могу «вставить» запрос в pkexec или sudo для запуска всего скрипта с правами root?

Обратите внимание, что запуск всего с sudo sh -c может быть не лучшее решение, поскольку у меня есть функции в скрипте.

1
задан 16 March 2016 в 18:16

5 ответов

Если вам нужен хороший диалог, попробуйте что-то вроде этого. Я разорвал это прямо из чего-то другого, что написал, поэтому у него есть лишний материал, который вам может не понадобиться или не нужен, но он показывает общую идею:

brand="My Software"

# Check that the script is running as root. If not, then prompt for the sudo
# password and re-execute this script with sudo.
if [ "$(id -nu)" != "root" ]; then
    sudo -k
    pass=$(whiptail --backtitle "$brand Installer" --title "Authentication required" --passwordbox "Installing $brand requires administrative privilege. Please authenticate to begin the installation.\n\n[sudo] Password for user $USER:" 12 50 3>&2 2>&1 1>&3-)
    exec sudo -S -p '' "$0" "$@" <<< "$pass"
    exit 1
fi

Это использует whiptail , которую вы можете установить, если у вас его еще нет:

sudo apt-get install whiptail
12
ответ дан 23 May 2018 в 12:50
  • 1
    Почему вы сохраняете пароль в переменной? – heemayl 16 March 2016 в 07:52
  • 2
    Не называть exec echo [PASSWORD]! Он будет генерировать процесс с паролем в командной строке, который может видеть любой пользователь. Используйте либо встроенную команду echo (принудительно встроенную версию с builtin echo), либо башизм <<< (например: sudo ... <<< "$pass"); Sh и другие оболочки имеют здесь Documents для этих случаев. Кроме того, укажите пароль, если он содержит специальные символы. – David Foerster 16 March 2016 в 07:58
  • 3
    @DavidFoerster Все хорошие идеи, спасибо! – Michael Hampton 16 March 2016 в 08:03
  • 4
    В качестве альтернативы, поместите команду whiptail в отдельный скрипт и используйте что-то вроде SUDO_ASKPASS=/path/to/askpass-with-whiptail.sh sudo -A -p "My password prompt" -- "$0" "$@", чтобы иметь sudo дело с запросом пользовательского пароля. – David Foerster 16 March 2016 в 08:12
  • 5
    @DavidFoerster Это может работать, но тогда вам либо нужны два сценария, либо вы пишете свой скрипт askpass временному файлу, а затем передаете его в sudo. – Michael Hampton 16 March 2016 в 08:15

Ответ на лезвие19899 - это действительно способ пойти, однако можно также называть sudo bash в shebang:

#!/usr/bin/sudo bash
# ...

Очевидное предостережение - это будет работать только до тех пор, пока скрипт вызывается с ./script и выйдет из строя, как только скрипт вызывается с помощью bash script.

11
ответ дан 23 May 2018 в 12:50
  • 1
    Это одна из причин, почему вы никогда не должны вводить bash script в командной строке для вызова скрипта. Если в строке #! скрипт указывает на что-либо, отличное от bash, то вызов его с bash script будет завершен. Если я попытался вызвать скрипт python с помощью bash script.py, он также потерпит неудачу. – kasperd 16 March 2016 в 16:48
  • 2
    Однако вы можете запустить его с помощью perl script. Perl, чтобы быть действительно действительно приятным, проверяет строку shebang, и если он не вызывает perl, он запускает правильную программу. – tbodt 17 March 2016 в 02:23
  • 3
    Это плохо, потому что он запускает каждую команду в скрипте с помощью sudo. Лучше выделить несколько команд, которые действительно нуждаются в sudo и добавлять их там, где это необходимо. Не включайте оценку функций в эти sudo-вызовы; они должны быть максимально ясными и минимальными. – Douglas Held 17 March 2016 в 15:23
  • 4
    @DouglasHeld Хотя я могу согласиться с этим, вот что задает вопрос: «Как я могу« вставить »? запросить pkexec или sudo для запуска всего скрипта с привилегиями root? & quot ;. Довольно точно были бы случаи использования, в которых возможность сделать это была бы полезна. – kos 17 March 2016 в 15:33

Я предикаю команды внутри скрипта, которым нужен root-доступ с sudo - если пользователь еще не получил разрешений, скрипт запрашивает пароль в этой точке.

example

#!/bin/sh 
mem=$(free  | awk '/Mem:/ {print $4}')
swap=$(free | awk '/Swap:/ {print $3}')

if [ $mem -lt $swap ]; then
    echo "ERROR: not enough RAM to write swap back, nothing done" >&2
    exit 1
fi

sudo swapoff -a && 
sudo swapon -a

Этот сценарий может быть запущен как sudo <scriptname> или как <scriptname>. В любом случае он будет запрашивать пароль только один раз.

6
ответ дан 23 May 2018 в 12:50
  • 1
    Проблема здесь в том, что может быть несколько команд, которым нужен корневой доступ, что означает, что вызов sudo для 25 разных команд избыточен - проще называть sudo один раз. Здесь, однако, причина, по которой ваш скрипт вызывает sudo только один раз, заключается в том, что sudo имеет время из 15 минут - команды, которые занимают больше времени, должны будут быть перепрофилированы. Твой путь работает просто. , , не так, как мне нужно, чтобы работать. – Sergiy Kolodyazhnyy 15 March 2016 в 20:41
  • 2
    @Serg Для небольшого скрипта, как я был, это было быстро и просто - я действительно не элегантный программист! – Charles Green 16 March 2016 в 23:28
  • 3
    Вы - лучшая публикация программиста на этой странице. Вы используете sudo точно так, как он должен использоваться - только там, где это необходимо, и с очень четкими результатами. – Douglas Held 17 March 2016 в 15:26

Похоже, что никто другой не обратился к очевидной проблеме здесь. Помещение sudo в ваш скрипт, который вы затем распространяете, способствует плохим привычкам пользователя. (Я предполагаю, что вы распространяете его, потому что вы упоминаете «с точки зрения пользователя».)

Правда в том, что есть руководство по использованию приложений и скриптов, которые аналогичны принципу безопасности в банковском деле: никогда не выдавайте свою личную информацию тому, кто звонит вам, и говорит, что они звонят «из вашего банка» и существуют по аналогичным причинам.

Правило для приложений: [!d4 ]

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

Если вы вводите пароль, потому что вы выполнили sudo по команде линия, отлично. Если вы печатаете его, потому что вы управляете SSH-командой, отлично.

Если вы просто запускаете внешний скрипт или исполняемый файл и вводите свой пароль при появлении запроса на него, у вас есть [d3 ] Никогда не выдавайте свою личную информацию тому, кто звонит вам, и говорит, что они звонят «из вашего банка» , что сценарий делает с ним. Он может хранить его во временном файле в открытом тексте, насколько вам известно, и даже может не очиститься после себя.

Очевидно, что существуют отдельные и дополнительные проблемы при запуске неизвестного набора команд в виде [ f5], но то, о чем я говорю, это поддержка безопасности самого пароля. Даже если приложение / сценарий не является вредоносным, вы все равно хотите, чтобы ваш пароль обрабатывался безопасно, чтобы другие приложения не овладели им и не использовали его злонамеренно.

Итак, мой собственный личный ответ на это, лучше всего добавить в свой скрипт, если ему нужны привилегии root:

#!/bin/bash
[ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;}

# do privileged stuff, etc.
3
ответ дан 23 May 2018 в 12:50
  • 1
    Хотя я полностью согласен с вами, пользователь, который запускает что-то, не зная, что он делает, как sudo script_name, так же уязвим, это то же самое. Может быть, эта идея способствует плохим привычкам - я ничего не скажу об этом. Но ключ - это знать, что делает программа, и это ответственность пользователя. В этом вся идея программного обеспечения с открытым исходным кодом. Что касается моего собственного сценария, ну. , , сценарий - простой текст - пользователи могут его прочитать, если они хотят знать, что он делает – Sergiy Kolodyazhnyy 21 March 2016 в 13:34

Я сделал это так:

echo -n "Enter password for sudo rights: "
read -s pass

echo $pass | sudo -S [your command here]
1
ответ дан 23 May 2018 в 12:50

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

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