Najlepsze praktyki korzystania z sudo w skrypcie bash

11

Mam długi i długotrwały skrypt bashowy, w którym garść poleceń musi być uruchamiana jako root, podczas gdy większość poleceń musi być uruchamiana jako zwykły użytkownik przed sudo, ponieważ może to zepsuć własność pliku i tym podobne.

Wymyśliłem kilka metod, ale każda z nich ma pewne problemy

Metoda 1: Używanie sudo w pliku

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

Wyglądałoby to dobrze ze sposobu pisania kodu. sudojest napisane przed kilkoma instrukcjami, które faktycznie muszą być uruchamiane przez root, ale jeśli czas między kolejnymi sudowywołaniami jest zbyt długi, sudoponownie prosi o hasło. Ponadto, jeśli pierwsze wykonanie sudonie powiedzie się, np. Z powodu niepoprawnego hasła, reszta skryptu jest nadal wykonywana.

Metoda 2: użycie sudo do wywołania pliku, a następnie w razie potrzeby powrót do pierwotnego użytkownika

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

To też jest do bani, ponieważ muszę dodać su username -cprzed prawie każdą linią. Znalezienie oryginalnej nazwy użytkownika po sudojest również możliwe, ale uciążliwe.

Czy jest lepszy sposób?

Edycja: zamieściłem tu tylko małe, bezsensowne skrypty, aby pokazać, o czym mówię. W rzeczywistym skrypcie mam kilka wierszy, które wymagają sudo (usługi uruchamiania i zatrzymywania), niektóre wiersze, w których nie ma znaczenia, czy jest sudo i całkiem sporo wierszy, które naprawdę trzeba uruchomić bez sudo.

Dakkaron
źródło
4
Jest to bardzo rzadko potrzebne. W większości przypadków wystarczy uruchomić skrypt, sudojeśli musi on mieć podwyższone uprawnienia. Ale nie ma sensu przestawiać się su username -cna uruchomienie echo. Innymi słowy, brzmi to jak [XY]. Czy mógłbyś edytować i wyjaśnić, co faktycznie zrobi twój skrypt i dlaczego uważasz, że musisz tak często zmieniać użytkowników?
terdon
1
@ElderGeek, czy wkleiłeś niewłaściwy link? To nawet nie wydaje się powiązane. Jest to prawdopodobnie duplikat polecenia Jak uruchomić polecenie „sudo” w skrypcie? ale mam nadzieję, że OP może wyjaśnić nieco więcej.
terdon
@terdon Wydawałoby się, że tak. Sprzątanie.
Starszy Geek
To tylko przykładowy skrypt. Nie chciałem tutaj wklejać ponad 200-wierszowego skryptu. Przeredaguję odpowiedź, aby uzyskać więcej informacji.
Dakkaron
Czy rozważałeś opcję sprawdzania poprawności, która jest opisana w man sudo? -v, --validate „Zaktualizuj dane użytkownika w pamięci podręcznej, w razie potrzeby uwierzytelniając użytkownika. W przypadku wtyczki sudoers wydłuża to domyślnie limit czasu sudo o kolejne 15 minut, ale nie uruchamia polecenia. Nie wszystkie zasady bezpieczeństwa obsługują buforowane poświadczenia. ” (Jeśli uruchamiasz go wystarczająco często, uwierzytelnianie sudo nie powinno
przekraczać

Odpowiedzi:

5

Jeśli chodzi o metodę 2, łatwiej jest użyć funkcji. Na przykład:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERto nazwa użytkownika sudoera. Możesz również użyć $(logname)na jego miejscu.

Uruchomiony na moim komputerze:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
źródło
2

Czytając man sudoers, widać:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

W ten sposób można zezwolić regularna machine1uruchamianie na hoście command1i command2jako root, bez uwierzytelniania hasłem za pomocą:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

ale przeczytaj każdy ze man -k sudoszczegółów.

waltinator
źródło
0

Może to może pomóc:

chmod 775 yourscript.sh

Następnie możesz używać sudo wewnątrz skryptu (bez pytania o hasło) I nie możesz używać sudo do innych poleceń w skrypcie.

1337 HaXxoR
źródło
Obawiam się, że to nie działa. chmod 775pozwala tylko na wykonanie pliku i nie zmienia użytkownika wykonującego plik ani jego uprawnień.
Dakkaron