sudo w nieinteraktywnym skrypcie

9

Mam skrypt, który wykonuje trzy funkcje: A && B && C.

Funkcja Bmusi być uruchomiony jako super-użytkownika, podczas Ai Cnie.

Mam kilka rozwiązań, ale żadne z nich nie jest satysfakcjonujące:

  1. sudo cały skrypt: sudo 'A && B && C'

    To wydaje się złym pomysłem do uruchomienia Ai Cjako superużytkownik, jeśli nie jest potrzebne

  2. uczyń skrypt interaktywnym: A && sudo B && C

    Być może będę musiał wpisać hasło, ale chcę, aby mój skrypt nie był interaktywny, ponieważ każda funkcja może zająć trochę czasu i nie chcę, aby skrypt na mnie czekał. Właśnie dlatego jest to przede wszystkim skrypt, więc nie muszę go oglądać.

  3. Głupie rozwiązanie: sudo : && A && sudo -n B && C

    Po pierwsze, wydaje się głupotą, aby najpierw uruchomić no-op sudo, a także muszę kciuka, że ​​A nie zajmie więcej niż $sudo_timeout.

  4. Hipotetyczne rozwiązanie (chciałbym, żebyś mi powiedział, że istnieje):

    sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'

    Spowodowałoby to podanie mojego hasła na początku, a następnie użycie tych poświadczeń tylko w razie potrzeby.

Jakie jest twoje zdanie na ten temat? Byłbym bardzo zaskoczony, że nie ma rozwiązania tego problemu, ponieważ uważam, że jest to dość powszechny problem (co z tym make all && sudo make install)

Antoine Pelisse
źródło
3
Możesz utworzyć skrypt, który wykonujesz za pomocą sudo, ale w skrypcie jawnie użyj części Ai . Brak problemów z przekroczeniem limitu czasu i brak uprawnień dla A i C. Nie sądzę, że 4 jest możliwe, wydaje się „globalnym stanem” dla użytkownika. Csu -l some_non_priviliged_usersudo
Anthon

Odpowiedzi:

7

Myślę, że najlepszą rzeczą, jaką możesz zrobić, jest uruchomienie skryptu, sudoa następnie uruchomienie procesów, które chcesz uruchomić jako zwykły użytkownik, jawnie za pomocą su userlub sudo -u user:

#!/usr/bin/env bash

## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)

## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $USER = "root" ]
then
    echo "The script needs to run as root" && exit 1
fi

## Run the job(s) that don't need root
sudo -u $usr commandA

## Run the job that needs to be run as root
commandB
terdon
źródło
9

Dodaj skrypt do /etc/sudoerspliku z NOPASSWDatrybutem, aby zezwolić na uruchomienie bez pytania o hasło. Możesz powiązać to z konkretnym użytkownikiem (lub zestawem użytkowników) lub zezwolić na uruchamianie go sudoprzez każdego w twoim systemie.

Przykładowa linia skryptu o nazwie /usr/local/bin/bossymoże wyglądać mniej więcej tak

ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy

I wtedy użyłbyś czegoś takiego

A && sudo bossy && C

W tym przykładzie założyłem, że PATHobejmuje /usr/local/bin. Jeśli nie, skorzystaj z pełnej ścieżki do skryptu, tjsudo /usr/local/bin/bossy

roaima
źródło
Poproś o najbezpieczniejsze podejście.
eyoung100
0

Możesz skorzystać z !requirettyopcji w, sudojak również z NOPASSWDopcji. Pamiętaj jednak, że zmniejsza to bezpieczeństwo.

Steve Wills
źródło
1
Ponieważ problem jest definiowana jako nie chcąc skrypt być interaktywne, nr 2 z /etc/sudoerswejściem dla użytkownika do wykonania polecenia Bze NOPASSWDjest prawidłowa odpowiedź.
Andrew
To jest „możesz zrobić X lub Y”, to było „możesz zrobić X i Y”. Tylko oba rozwiążą problem. Być może powinienem przeformułować moją odpowiedź.
Steve Wills
0

Opierając się na mojej odpowiedzi na wstępne autoryzowanie sudo? (Aby można go było uruchomić później) , napisz dwa skrypty:

  • ABC_script:

    #!/bin/sh
    sudo -b ./B_script
    A  &&  > A_is_done
    while [ ! -f B_is_done ]
    do
            sleep 60
    done
    rm -f B_is_done
    C
  • B_script:

    #!/bin/sh
    while [ ! -f A_is_done ]
    do
            sleep 60
    done
    rm -f A_is_done
    B  &&  > B_is_done

Uruchom ./ABC_script:

  • Będzie działać sudo -b ./B_script. To prosi o hasło ( natychmiast po uruchomieniu ABC_script). Zakładając, że prawidłowe hasło nie zostanie wprowadzone, ikra B_scriptw b ackground (ponieważ -bzostał określony) jako root. To wydaje się być równoważne z sudo sh -c "./B_script &".
  • B_scriptzaczyna działać asynchronicznie, równolegle z ABC_scriptB_scriptsprawdza istnienie pliku o nazwie A_is_done i zapętla się, aż się pojawi.
  • Równolegle ABC_scriptdziała A. Jeśli / kiedy Azakończy się pomyślnie, skrypt tworzy plik o nazwie A_is_done.
  • ABC_scriptnastępnie sprawdza istnienie pliku o nazwie B_is_done i zapętla się, aż się pojawi.
  • Równolegle B_scriptwykrywa istnienie A_is_donei przerywa pętlę. Usuwa A_is_doneplik i uruchamia się B. Pamiętaj, że B_scriptdziała jako root, więc działa Bjako root. Jeśli / kiedy Bzakończy się pomyślnie, skrypt tworzy plik o nazwie B_is_donei kończy działanie.
  • Równolegle ABC_scriptwykrywa istnienie B_is_donei przerywa pętlę. Usuwa B_is_doneplik. Pamiętaj, że B_scriptdziałał jako root, więc B_is_donejest własnością root, a chcesz go użyć, rm -faby uniknąć żądania potwierdzenia. ABC_scriptnastępnie biegnie Ci wychodzi.

Uwagi do dalszego udoskonalenia:

  • ABC_scriptpowinien B_scriptraczej przebiegać bezwzględną ścieżką niż ./.
  • Zamiast A_is_donei B_is_done, ABC_scriptprawdopodobnie powinien generować losowe, niepowtarzalne nazwy plików.
  • Musi istnieć przepis przewidujący, że skrypt oczekujący na spin zostanie powiadomiony, jeśli program, na który czeka, zakończył się, ale nie powiódł. (W tej chwili, jeśli się Anie powiedzie, oba skrypty przechodzą w nieskończoną pętlę oczekiwania.) Może to być tak proste, jak zmiana

    A  &&  > A_is_done

    do

    A; echo $? > A_is_done

    a następnie modyfikacja spin-czeka, aby odczytać X_is_donepliki, i kontynuuj, jeśli zawiera 0, i wyjdź w przeciwnym razie.

Scott
źródło
-3

Milczeć. użyj wielu linii.

if A; then

    if sudo B ; then
        C
    fi
fi
Robert Jacobs
źródło
jak to rozwiązuje mój problem? Problem nie ma nic wspólnego&&
Antoine Pelisse
&& zatrzymuje wykonywanie, gdy pierwsze polecenie nie powiedzie się. Instrukcje if robią to bardziej szczegółowo. Chodzi mi o to, aby wykonać swoją pracę, nawet jeśli nie jest ładna.
Robert Jacobs,
1
To nic więcej niż Bardziej szczegółowa wersji wariantu 2: A && sudo B && C. Tak jak wyjaśnia Antoine w pytaniu; nie prosi o podanie hasła, dopóki się Anie skończy, i nie chce na to czekać ani czekać na skrypt.
Scott