Попросіть права доступу до сценарію


23

У мене є сценарій, який може працювати як sudo script.shабоpkexec script.sh

З точки зору користувача було б набагато приємніше, якби скрипт запитував пароль у користувача, коли він просто запускався за ім'ям script.sh.

Як я можу "вставити" запит до pkexecабо sudoзапустити весь скрипт із привілеєм root?

Зауважте, що запускати все за допомогою sudo sh -cможе бути не найкращим рішенням, оскільки у мене є функції в сценарії.

Відповіді:


55

Це працюватиме:

echo "$(whoami)"

[ "$UID" -eq 0 ] || exec sudo "$0" "$@"

приклад:

./test.sh 
blade
[sudo] password for blade: 
root

3
Що в цьому добре - це рекурсія exec- виклич себе, але водночас замінивши процес, тому ми не породимо декількох примірників сценарію
Сергій Колодяжний

1
Рекурсія на допомогу !!! Нагадуйте мені за кілька днів додати цю суму!
Фабі

6
Що слід пам’ятати, роблячи це - ескалація привілеїв; в основному, чим більше команд, які ви запускаєте як root, тим більше можливостей зловмисного хакера щось використовувати, щоб отримати доступ до кореневого облікового запису. Я не кажу, що завжди неправильно змушувати весь сценарій виконуватись як корінь, але варто додати трохи думки до нього, перш ніж зважитися на це. Я думаю, було б непогано (хоч і не потрібно), якби відповідь торкнулася цього.
David Z

Якщо у / etc / sudoers встановлено гідне значення тайм-аута, ви можете додатково поставити sudo перед кожною командою в сценарії, який дійсно потребує кореневого доступу, і він запитає лише один раз. Я часто плутаю те, що викликати такий скрипт з gui не вийде, тому що sudo отримує / dev / null для введення пароля і не дає змоги. Це те, що gksudo та kdesudo були розроблені для обробки, оскільки вони будуть використовувати gui для запиту пароля.
Джо

1
@ Coder256: Я не думаю, що ваша редакція була правильною. "$@"розшириться до кількох слів, по одному для кожного параметра.
jwodder

12

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

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

діалогове вікно sudo

Для цього використовується whiptail, який ви можете встановити, якщо у вас його ще немає:

sudo apt-get install whiptail

1
Чому ви зберігаєте пароль у змінній?
heemayl

10
Не дзвоніть exec echo [PASSWORD]! Він породжує процес із паролем у командному рядку, який може бачити будь-який користувач. Або використовуйте вбудовану команду echo( builtin echoпримушуйте вбудовану версію за допомогою ) або башизм <<<(наприклад :) sudo ... <<< "$pass"; Ш та інші снаряди мають тут документи для цих випадків. Також вкажіть пароль, якщо він містить спеціальні символи.
Девід Фоерстер

Крім того, поставте whiptailкоманду в окремий сценарій і використовуйте щось на зразок, SUDO_ASKPASS=/path/to/askpass-with-whiptail.sh sudo -A -p "My password prompt" -- "$0" "$@"щоб мати sudoсправу з користувацьким запитом пароля.
Девід Фоерстер

@DavidFoerster Це може спрацювати, але тоді вам або потрібні два сценарії, або ви пишете свій скрипт askpass у тимчасовий файл, а потім передаєте його в sudo.
Майкл Хемптон

Добре, проте інші вже відзначали, що небажано передавати пароль змінній. Підхід до цього методу полягає в тому, щоб передати вихідний діалог до названої труби, як я показав тут askubuntu.com/a/704643/295286
Сергій Колодяжний,

11

відповідь blade19899 - це справді шлях, але можна також зателефонувати sudo bashв шебанг:

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

Очевидний застереження полягає в тому, що це буде працювати лише до тих пір, поки скрипт викликається, ./scriptі не вийде, як тільки скрипт викликається bash script.


5
Це одна з причин, чому ніколи не слід вводити bash scriptкомандний рядок для виклику сценарію. Якщо у скрипті вказано щось інше, ніж bashу #!рядку, то виклик його bash scriptне вдасться. Якби я спробував викликати скрипт python, використовуючи bash script.pyйого, також не вдалося.
kasperd

1
Ви можете запустити його perl script, хоча. Perl, прагнучи бути справді дуже приємним, перевіряє лінію shebang, і якщо вона не викликає perl, вона запускає правильну програму.
tbodt

Це погано, оскільки він виконує кожну команду в сценарії з sudo. Краще виділити кілька команд, які справді потребують судо, і додати їх там, де це необхідно. Не включайте оцінку функцій у ці дзвінки дзюдо; вони повинні бути максимально чіткими і мінімальними.
Дуглас Хелд

@DouglasHeld Хоча я можу погодитися з цим, ось що задається питанням: "Як я можу" вставити "запит на pkexec або sudo для запуску всього сценарію з привілеєм root?". Досить впевнений, що будуть випадки використання, коли можливість зробити це було б корисно.
kos

6

Я заздалегідь готую команди в скрипті, до яких потрібен кореневий доступ, sudo- якщо користувач ще не отримав дозволів, сценарій вимагає ввести пароль у цей момент.

приклад

#!/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>. В будь-якому випадку він запитає пароль лише один раз.


2
Проблема тут полягає в тому, що може бути кілька команд, яким потрібен кореневий доступ, а це означає виклик sudo25 зайвих команд зайвих - простіше викликати sudo один раз. Однак, причина, по якій ваш сценарій викликає sudo лише один раз, полягає в тому, що sudo має час на 15 хвилин - команди, що займають більше часу, повинні бути перероблені. Ваш спосіб працює просто. . . не так, як мені це потрібно для роботи.
Сергій Колодяжний

@Serg Невеликий сценарій, як я був, був швидким та легким - я справді не елегантний програміст!
Чарльз Грін

Ви найкращий програміст, який розміщує цю сторінку. Ви використовуєте sudo саме так, як слід використовувати - лише там, де це потрібно, і очікуються дуже чіткі результати.
Дуглас Хелд

4

Схоже, ніхто більше не вирішив тут очевидного занепокоєння. Введення sudoв сценарій, який ви розповсюджуєте, сприяє поганим звичкам користувача . (Я припускаю, що ви поширюєте його, оскільки ви згадуєте "з точки зору користувача".)

Правда полягає в тому, що в застосуванні програм та сценаріїв є настанова, яка схожа на принцип безпеки в банківській справі: Ніколи не роздавайте свою особисту інформацію тому, хто телефонує вам, і каже, що вони дзвонять "з вашого банку" , і який існує з подібних причин.

Правило для додатків:

Ніколи не вводьте свій пароль, коли буде запропоновано, якщо ви не впевнені, що з ним робиться. Це потрійно стосується тих, хто має sudoдоступ.

Якщо ви вводите свій пароль, тому що ви бігли sudoв командному рядку, чудово. Якщо ви вводите це через те, що ви виконали команду SSH, добре. Якщо ви вводите це під час входу на комп’ютер, звичайно, чудово.

Якщо ви просто запускаєте іноземний скрипт або виконуваний файл і приручно вводите свій пароль, коли буде запропоновано його, ви не маєте поняття, що з ним робить сценарій. Це може бути збереження його у тимчасовому файлі в простому тексті, бо все, що ви знаєте, і навіть не зможе очистити його після себе.

Очевидно, є окремі та додаткові занепокоєння щодо запуску невідомого набору команд як root, але те, про що я тут говорю, - це підтримка безпеки самого пароля . Навіть припускаючи, що додаток / скрипт не є шкідливим, ви все одно хочете, щоб ваш пароль надійно оброблявся, щоб запобігти захопленню інших програм та його зловмисному використанню.

Отже, моя особиста відповідь на це: найкраще, що потрібно вкласти у свій сценарій, якщо йому потрібні кореневі привілеї, це:

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

# do privileged stuff, etc.

Хоча я повністю згоден з вами, користувач, який щось працює, не знаючи, що він робить, так sudo script_nameсамо вразливий, це те саме. Можливо, ця ідея популяризує шкідливі звички - я нічого про це не скажу. Але головне - знати, що робить програма, і це відповідальність за користувача. Ось і вся ідея програмного забезпечення з відкритим кодом. Щодо мого власного сценарію, добре. . . сценарій - це звичайний текст - користувачі можуть його прочитати, якщо хочуть знати, що це робить
Сергій Колодяжний

@SergiyKolodyazhnyy це схоже, але якщо ви вводите свій пароль прямо в сценарій, це насправді гірше. Сценарій, запущений з sudo, досі не знає ваш пароль.
Wildcard

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.