Uruchamiaj tylko części skryptu jako sudo, wpisując hasło tylko raz

14

Piszę skrypt (właściwie kombinację skryptów i makefile), który instaluje zależności zewnętrzne: niektóre apt-getpolecenia, niektóre gitklonowanie, budowanie, instalowanie, dodawanie użytkowników do grup, ...

Niektóre operacje w tych skryptach wymagają uprawnień administratora, inne nie.

Do tej pory prowadziłem cały proces make z sudo, ale ma on pewne wady:

  • gitrepos, które klonuję, otrzymuję rootjako właściciel, co oznacza, że ​​nie mogę ich później modyfikować bez sudolubchown
  • skrypty, które dodają użytkowników do grup, od czasu whoamipowrotu nie wiedzą, którego użytkownika dodaćroot

Jaki jest najlepszy sposób działania jako superużytkownik tylko tych poleceń, które go wymagają? Idealnie byłoby, gdyby cały proces wymagał ode mnie wpisania sudohasła, ale tylko raz na samym początku procesu instalacji. Wtedy zapomniałby o tym na samym końcu, ale do tego czasu należy go cały czas utrzymywać (może to potrwać kilka godzin).

Rozwiązania, które znalazłem w Internecie, obejmują:

  • sudo -vna początku skryptu, ale jeśli dobrze rozumiem, ten limit czasu. Mój skrypt może działać przez kilka godzin
  • uruchamianie skryptu za pomocą sudo, ale polecenia, które nie wymagają administratora sudo -u $(logname) <command>. To właśnie robię teraz, ale wydaje się, że powinno być na odwrót.

Idealnie chciałbym, aby mój skrypt:

  1. poprosić o poświadczenia administratora
  2. uruchom normalne polecenia jako zalogowany użytkownik
  3. uruchom polecenia sudo z poświadczeniami wprowadzonymi w kroku 1
  4. sudo -k aby zamknąć sesję administratora
Gauthier
źródło
2
Nadal możesz uruchamiać wszystko jako sudo, a twój skrypt może sprawdzić SUDO_USERzmienną środowiskową. Jeśli jest obecny, będzie on zawierał nazwę użytkownika wywołującego sudo. Możesz więc (jako root) przeszukać $ SUDO_USER: $ SUDO_GID $ twoje_pliky. Podobnie możesz sprawdzić te zmienne, aby twoje komendy adduser wiedziały, którego użytkownika dodać.
roadmr
... lub uruchom wszystko jako root i używaj su $SUDO_USER -c commandpoleceń jako normalny użytkownik.
Rmano

Odpowiedzi:

7

Ponieważ masz dostęp do sudo, utwórz plik sudoers dla siebie, a następnie usuń go po zakończeniu skryptu:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Glenn Jackman
źródło
2

Jednym ze sposobów, że nie byłoby generalnie zalecane jest, aby odczytać hasło siebie i wykorzystanie sudo„s -Sopcja przekazać hasło jak i gdy są potrzebne:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

Od man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.
muru
źródło
1
Czy to jest bezpieczne? echo "$password"??
αғsнιη
@ KasiyA echo "$password"nie byłoby, ale heredoki i ciągi znaków są nieco bardziej bezpieczne. Nie są widoczne w wierszu poleceń pokazanym przez zwykłe narzędzia.
muru
1
Myślę, ściśle mówiąc, echo "$password"po lewej stronie rury jest bezpieczny w skrypcie bash. echojest wbudowaną powłoką; /bin/echonie działa, gdy jest wywoływany tak prosto echo .... Niektóre inne muszle mają echowbudowane ( dashna przykład), ale muszle w stylu Bourne'a nie są wymagane . Myślę więc, że echo "$password" |jest to akceptowalne w bash, ale najlepiej można tego uniknąć, jeśli ktoś przeniesie skrypt do innej powłoki bez zauważenia problemu. Używam nieprzenośnego w tym skrypcie[[ zamiast tego samego problemu. @KasiyA[
Eliah Kagan