Jak wpisać hasło tylko raz w skrypcie bash wymagającym sudo

21

Dane

  • Chcę, aby użytkownicy operatora na tym komputerze montowali własne udziały cifs
  • sudoersPlik zawiera już /bin/mount -t cifs //*/* /media/* -o username=*polecenia dla wszystkich operatorów
  • Chcę, aby użytkownicy zamontowali cifsudział za pomocą skryptu wpisując hasło tylko raz, a nie dwa razy.
  • Hasło sudo i hasło cifs są identyczne.

Co już mam

Ten skrypt działa:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... ale wymaga dwukrotnego wpisania tego samego hasła!

  • Raz na sudo
  • Raz dla samego wierzchowca

Działa to również:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... ale wymagałoby to ode mnie umożliwienia wszystkim użytkownikom operatorasudo sh (poważny problem bezpieczeństwa)

Pytanie

Jak zamontować CIFS udział w bash ¹ bez wkładania shw sudoerspliku ani stworzenie stałej plik / tymczasowy ???

Uwaga 1: nie python, perl, C, Go, ... proszę?
Uwaga 2: Wiem, że mogę po prostu usunąć hasło z sudoerspliku, ale staram się zwiększyć bezpieczeństwo, a nie poluzować je, nie rezygnując z wygody ...

Fabby
źródło
2
Jak o printf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...?
muru,
Próbuję tego teraz! @Muru
Fabby,

Odpowiedzi:

24

Zamiast tego powinieneś skłonić użytkownika do wykonania polecenia sudo as sudo script. po prostu sprawdź, czy skrypt jest uruchamiany jako root, jeśli nie, poproś o niego

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

Nie próbuj przechwytywać hasła swoich użytkowników.

Braiam
źródło
1
Być może coś mi brakuje, ale czy możesz wyjaśnić, w jaki sposób zmniejsza to liczbę monitów o hasło z dwóch do jednego? W przeciwnym razie nie widzę, jak to odpowiada na pytanie.
Oliphaunt - przywróć Monikę
@Oliphaunt Nie widzę dwóch monitów o hasło, czy możesz to wyjaśnić? Również ta odpowiedź nie jest tym, czego chce OP, ale tym, czego potrzebuje. Jest czystym i właściwym rozwiązaniem, gdy trzeba uruchamiać polecenia jako root, a także jak działają inne narzędzia (sprawdź, czy root, w przeciwnym razie nie wyskoczy)
Braiam
1
Problem OP (jak rozumiem) polega na tym, że użytkownik jest proszony o podanie hasła, sudoa następnie (po pomyślnym uwierzytelnieniu) ponownie mount. W ich przypadku hasła te są identyczne, więc rozumiem, dlaczego OP chciałby, aby użytkownik musiał wprowadzić to hasło tylko raz. Nie sądzę, aby twoje rozwiązanie w tym pomogło. Zgadzam się, że nie należy przechwytywać haseł.
Oliphaunt - przywróć Monikę
Dzięki, ale mogłem trochę uprościć pytanie: to już skrypt, już zawiera ten test (oprócz 1>&2), jest w autostartie i kiedyś był tylko jednym udostępnieniem cifs, ale teraz jest trzy, więc naprawdę jedno hasło jest potrzebne. (Zawiera już ten test na wypadek, gdyby ktoś inny, nie będący członkiem grupy operatorów, próbował go uruchomić)
Fabby
@Fabby Nadal uważam, że niepoprawnie podchodzisz do problemu. W takich przypadkach istnieje pomocnik, który „zapamiętuje” hasło udziału CIFS / SMB w bezpieczny sposób ( ~/.smbcredentialsna przykład edycja ), a nawet bez potrzeby sudo (jeśli używasz gvfs, umount lub polkit).
Braiam
7

Jestem głupi!

Poniższy skrypt:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

po prostu działa i:

  1. Nie tworzy żadnych plików zawierających hasła
  2. Pozwala użytkownikowi wpisać tylko jedno hasło dla wielu udziałów (w tym Windows)
  3. Nie ma potrzeby przyznawania dodatkowych uprawnień. :-)
Fabby
źródło
1
1 pytanie: czy to echo polecenia na liście procesów?
Rinzwind,
3
@Rinzwind jako wbudowany, nie powinien być w bash ani zsh. Polecenie mount mogło jednak.
muru,
<<<można również użyć zamiast printf , ale lepszym rozwiązaniem byłoby readcałkowite upuszczenie i użycie sudo --stdinsamego. Coś w rodzaju $ printf "Type out your password\n" && sudo --stdin apt-get update użytkownik nadal może wpisać hasło sudo. i to nie umieści go na liście procesów. Ale oczywiście istnieje nieskończona ilość możliwych innych problemów związanych z bezpieczeństwem, takich jak keyloggery, potencjalne luki w zabezpieczeniach sudo, bla, bla i bla w nieskończoność
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy: Możesz edytować , stary!
Fabby
3

Nie wymagaj sudohasła do wykonania tego polecenia; monit o hasło mountpozostaje.

W sudoers, dołącz coś takiego

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

Po uwzględnieniu tego sudonie będzie już pytać o hasło do tego konkretnego polecenia; użytkownik nadal musi podać hasło do mountpolecenia.

Uwaga : wziąłem polecenie dosłownie z tego, co ujęłeś w pytaniu; Nie sprawdziłem, czy jego symbole wieloznaczne pozwolą użytkownikom zrobić coś paskudnego. Przeczytaj stronę sudoerspodręcznika, by zobaczyć przykłady nieprzyjemności. W szczególności zauważ, że ten wiersz sudoerspozwala użytkownikowi dodać dowolną liczbę -oprzełączników lub innych argumentów mount. Możesz przemyśleć swoje podejście, np. Dodając skrypt, taki jak @Braiam, który proponuje i zezwala na jego uruchomienie sudobez dodatkowego uwierzytelnienia. Skrypt zapewnia wtedy, że użytkownicy mogą uruchomić tylko określoną formę mount, którą chcesz, aby była uruchomiona.

Ponadto, zamiast zezwalać na to wszystkim użytkownikom, możesz również ograniczyć to do członków określonej grupy, np. Możesz utworzyć grupę, cifsmounta następnie mieć

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*
Oliphaunt - przywróć Monikę
źródło
@Fabby Przepraszamy, ale co w tym takiego niebezpiecznego? Być może wyczuwam nutę sarkazmu, nie jestem pewien.
Oliphaunt - przywróć Monikę
cóż, nawet jeśli sudo nie wymaga hasła, mount może nadal wymagać hasła. Plik / etc / sudoers może być wykorzystany do tego, aby sudo nie wymagało hasła. Nie wpłynie to na to, czy mount poprosi o hasło. Jeśli dana osoba nie zainstaluje się, sudo po prostu uruchomi polecenie, które się nie powiedzie, co prawdopodobnie nie stanowi problemu.
TOOGAM,
@TOOGAM To był mój zamiar. Jedno hasło zamiast dwóch.
Oliphaunt - przywróć Monikę
Moim zamiarem jest utrzymanie jednej grupy „operatorów” w pliku sudoers, więc jeśli operator próbuje zamontować własne rzeczy, nadal musi wpisać hasło, ale aby zamontować „standardowe” operacje montowania, wystarczy wpisać hasło raz zamiast 5 razy ... Ale twoje rozwiązanie może działać dla innych, więc głosowałem ... (i usunięto oryginalne komentarze)
Fabby
1

Ogólnym rozwiązaniem tych problemów jest umieszczenie następującej preambuły na górze sudo wymagającej skryptów:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

Oczywiście ma to tę wadę, że jeśli niektóre polecenia w skrypcie nie wymagają sudouruchomienia, tutaj niepotrzebnie podnosi się uprawnienia.

W każdym razie myślałem, że podzielę się tą małą wskazówką. Najmilszą rzeczą w tym jest to, że jeśli jesteś już efektywnym rootem (np. Jeśli już nazwałeś go sudo), robi to z wdziękiem. Również popełnianie błędu i zmuszanie do przepisania / ponownego uruchomienia (z sudo) jest mniej przyjazne.

Możesz także sprawdzić timestamp_timeoutzmienną, w man 5 sudoersktórej nakazuje sudozapamiętywanie poświadczeń użytkownika przez ograniczoną liczbę minut (i może być ułamkowa).

arielf
źródło
Uprościłem skrypt, aby uzyskać łatwą odpowiedź: skrypt już zawiera: #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi Chodzi o to, że zawiera także wiele montowań, wszystkie z tym samym hasłem (ponownie: usunięte), ale mimo to dziękuję ...
Fabby
1
Chodzi o to, że powyższe rozwiązanie wymagałoby tylko jednego wpisania hasła (dla sudo). Nie powinno wymagać żadnych innych. Ponadto jest to ogólny (i bardziej elegancki niż błąd i konieczność ponownego wpisania polecenia w sudo) w przypadku wszystkich podobnych problemów, nawet jeśli wymagają one wielu (więcej niż dwóch) uprzywilejowanych poleceń.
arielf
To powinno ale nie robi ! ;-) To dlatego, że każdy montaż cifs share wymaga również hasła. (ponieważ może różnić się od hasła Ubuntu, ale w tym przypadku operatorzy nie synchronizują haseł systemu Windows i Ubuntu)
Fabby