Як зупинити запуск сценарію, якщо він не root (і відлуння "Не працює як root! Вихід ...")


17

Ось моє джерело:

#!/bin/bash

echo "Running script to free general cached memory!"
echo "";
echo "Script must be run as root!";
echo "";
echo "Clearing swap!";
swapoff -a && swapon -a;
echo "";
echo "Clear inodes and page file!";
echo 1 > /proc/sys/vm/drop_caches;
echo "";

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

Приклад:

"Running script to free general cached memory!"
"Warning: script must be run as root or with elevated privileges!"
"Error: script not running as root or with sudo! Exiting..."

Якщо працювати з підвищеними привілеями, він просто працює як звичайний. Будь-які ідеї? Спасибі!


Можливий дублікат того, як завадити root виконувати скрипт
muru

2
@muru, за винятком того, що інше питання стосується зворотного: відмовте скрипт, якщо він працює як root.
Стефан Шазелас

3
@ StéphaneChazelas ах, мій поганий. Прибиралися
Мура

Альтернативою є обмеження обсягу виконаної роботи, як rootза допомогою префіксації префікса всіх команд, які повинні виконуватися як rootз sudo.
reinierpost

Відповіді:


47
#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

Користувач root має UID 0 (незалежно від назви облікового запису "root"). Якщо ефективний UID, що повертається, id -uне дорівнює нулю, користувач не виконує скрипт з привілеями root. Використовуйте id -ruдля перевірки реального ідентифікатора (UID користувача, який викликає сценарій).

Не використовуйте $EUIDв сценарії, оскільки це може бути змінено непривілейованим користувачем:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

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


1
Примітка: на Solaris 5.10, /bin/id -uдає/bin/id: illegal option -- u Usage: id [-ap] [user]
jrw32982 підтримує Моніку

1
@ jrw32982 Вам слід було мати /usr/xpg4/binранній $PATHдоступ, щоб отримати доступ до утиліт POSIX на Solaris.
Kusalananda

1
Справа в тому, що -uваріант idне є універсальним, і тому це рішення є універсальним лише з застереженням, що версія POSIX idмає бути першою у вашій PATH.
jrw32982 підтримує Моніку

1
@ jrw32982 Щоб ваш скрипт підбирав правильні утиліти POSIX у Solaris, модифікуйте $PATHвгорі сценарію так, як /usr/xpg4/binце було раніше /bin. Якщо ви наполягаєте на використанні не-POSIX id, то, очевидно, вам доведеться придумати більш портативне рішення.
Kusalananda

1
@Harry Так, щоб сценарій міг використовувати PATH=$( getconf PATH )або встановити інший явний шлях за замовчуванням або використовувати явний шлях для виклику id.
Кусалаланда

19

Я думаю, що ви хочете скоріше перевірити, що у вас є привілеї суперкористувача, тобто ваш ефективний ідентифікатор користувача 0.

zshі bashзробити це доступним у $EUIDзмінній, щоб ви могли:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

З будь-якими оболонками, схожими на POSIX, ви можете використовувати idстандартну команду:

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

Зауважте, що всі id -unабо whoamiабо $USERNAMEзмінна в zshотримає вам перше ім’я користувача для uid. У системах, у яких інші користувачі мають ідентифікатор 0, це може бути rootнавіть, якщо процес є нащадком того, хто був ідентифікований як root.

$USERбуде , як правило , дають вам користувачеві , що перевірка справжності, але покладатися на нього досить тендітними. Це не задаються оболонкою, але, як правило , встановлюється командою перевірки автентичності (наприклад login, su(на системах GNU / Linux, не обов'язково інші), sudo, sshd(одного з OpenSSH , по крайней мере) ...). Це не завжди, хоча (зміна uid автоматично не встановлює цю змінну, це повинно бути зроблено явно за допомогою програми, що змінює uid), а також вона могла бути змінена деяким іншим процесом в родові оболонки. $LOGNAME, з тим самим застереженням є більш надійним, як це визначено POSIX (спочатку від FIPS 151-2)


12

Ви можете використовувати $USERабо whoamiперевірити поточного користувача.

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

1
НП. Я пропоную буквально просто читати через посібник з bash [ gnu.org/software/bash/manual/bashref.html] . Це насправді напрочуд легко готова. Зокрема, для цієї відповіді пропоную посилання: 3.2.4.2 Conditional Constructs 3.5.4 Command Substitution
Jesse_b

9
Команда id -uз -nопцією або без неї є альтернативою використанню whoami. Без -n і порівняння з нулем краще відповідати тесту, який насправді робить ядро. Все, що хвилює ядро, - це ідентифікатор, а не ім'я з файлу пароля.
ікар

6
Я вважаю, що використовувати $(id -u)краще. У деяких (зловмисних) випадках $USERможе помилятися.
Василь Старинкевич

1
Для тих, хто цікавиться посиланням, яке надає @Jesse_b: є помилка друку. Він повинен бути gnu.org/software/bash/manual/bashref.html
Kryten

1
Деякі системи не використовують "root" як ім'я привілейованого облікового запису, який має uid 0. QNAP сприймається як один. Тож слід перевірити лише uid 0, а не ім’я кореневого акаунта.
roaima

10

Насправді ви хочете визначити, чи є у вас доступ до цих операцій. Вважається поганою практикою перевіряти, чи не є ви кореневі замість цього.

Якщо система налаштована таким чином, щоб дозволити користувачеві, який не має права доступу, змінювати кеш-файли підкачки та падіння сторінки, чому він не повинен запускати цей сценарій?

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

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi

Некористувацький користувач, який вимикає своп?
Kusalananda

2
Так. Ви можете налаштувати це за допомогою SELinux. Так само ви можете відключити кореневий процес від цього.
той інший хлопець

1
Ви можете не захотіти, exitколи щось не вдасться, на випадок, якщо користувач захоче зробити, як тільки може, зі своїми поточними привілеями. (Але для типової системи, де все це потребує коріння, вихід буде кориснішим / менш галасливим.)
Пітер Кордес

2
Я б не пішов так далеко, щоб сказати, що це "погана практика", щоб перевірити, чи ви коренева чи ні. Особливо, якщо це саме те , що ви хочете знати. Я вважаю, що найкраще перевірити, чи є у вас достатньо дозволів робити те, що ви хочете.
Ерік Беннетт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.