Zignoruj ​​sudo w skrypcie bash

9

Mam mały skrypt bash:

#!/bin/bash

touch dummy.txt

Jeśli wykonam ten skrypt, sudoto utworzy dummy.txton ochronę przed rootem .

Chcę zrobić:

Niezależnie od tego, czy ten skrypt jest wykonywany przy użyciu sudozwykłego użytkownika, dummy.txtczy nie , plik nie powinien być chroniony jako root.

Anonimowy
źródło
4
Cokolwiek rozumiesz przez „chroniony przed rootem”, możesz użyć chowniw chmodskrypcie, aby ustawić własność i uprawnienia zgodnie z potrzebami.
fkraiem
1
Nie jest jasne, co rozumiesz przez „chroniony przed rootem”. Czy masz na myśli, że tylko użytkownik root może odczytywać / zapisywać (np. Uprawnienia do plików są ustawione na coś takiego jak 700), czy że użytkownik root jest właścicielem pliku?
1
@DoritoStyle przepraszam za zamieszanie. Przez root chroniony rozumiem, że użytkownik root jest właścicielem pliku.
Anonimowy,

Odpowiedzi:

22

Można sprawdzić, czy skrypt jest uruchamiany poprzez sudoużyciu EUIDi SUDO_USERzmienne, a następnie wykonać touchjak SUDO_USERgdyby prawda - coś podobnego

#!/bin/bash

if [[ $EUID -eq 0 ]] && [[ -n $SUDO_USER ]]; then
  sudo -u "$SUDO_USER" touch dummy.txt
else
  touch dummy.txt
fi
steeldriver
źródło
2
Zauważ, że ==służy do porównywania ciągów. Ponieważ $EUIDma zwracać wartość całkowitą, polecam użyć -edporównania. Spacje są dozwolone w nazwach użytkowników , więc prawdopodobnie zacytuj $SUDO_USERzmienną. W przeciwnym razie dobra odpowiedź - tego osobiście bym użył.
Sergiy Kolodyazhnyy
@steeldriver tego właśnie szukałem. dzięki!!
Anonimowy,
1
Możesz ponownie uruchomić skrypt, sudo -ujeśli wykryje, że działa jako root. OP mówił o posiadaniu wielu poleceń w jednym skrypcie. Ale uważaj, aby uniknąć nieskończonej pętli błędów.
Peter Cordes,
1
Nie ma podziału na słowa, [[...]]więc nie jest absolutnie konieczne, aby cytować zmienną w instrukcji if @Serg i, jak sądzę, -edliterówka-eq
Arronical
@Arronical tak, to była literówka -eq. Nie wiedziałem, [[że nie ma podziału słów. Dzięki. Osobiście nadal zacytowałbym ze względu na dobre nawyki związane ze skryptowaniem
Sergiy Kolodyazhnyy
9

Jeśli skrypt nie ma być uruchamiany jako root, najbezpieczniejszym sposobem rozwiązania problemu jest przerwanie jego wykonywania na samym początku:

if [ "$EUID" = 0 ]; then
   echo "This script must NOT be run as root" 
   exit 1
fi

Opcjonalnie możesz ponownie uruchomić skrypt jako użytkownik rezerwowy (np. sudo -u FALLBACK_USER "$0") Zamiast po prostu przerywać.

Próba naprawienia dziwactwa poszczególnych poleceń sprawi, że skrypt będzie niepotrzebnie skomplikowany i trudny do debugowania. Za każdym razem, gdy go zmodyfikujesz, będziesz musiał wykonać wszystkie testy dwa razy (jako zwykły użytkownik, a następnie jako root) i naprawić wszystkie związane z tym rootbłędy. Można powiedzieć, że nie jest to rozwiązanie przyszłościowe.

Dmitrij Grigoriew
źródło
6

Domyślnie pliki tworzone przy użyciu roota mają takie uprawnienia:

-rw-r--r-- 1 root root 0 11 17 23:25 rootfile.txt

Plik ten należy do użytkownika root i grupy root i jest czytelny i zapisywany przez root, ale tylko dla innych.

Najprostszym podejściem byłoby po prostu chownprzywrócenie pliku do pierwotnego użytkownika.

chown username:group_name dummy.txt

Możesz użyć $SUDO_USERzmiennej, która jest dostępna tylko po sudowywołaniu, na przykład:

chown "$SUDO_USER":"$SUDO_USER" dummy.txt

Jeśli używasz skryptu jako zwykły użytkownik, ta chownczęść nie jest wcale potrzebna, więc możesz rozważyć użycie instrukcji if lub &&test do przetestowania przypadku, gdy skrypt jest uruchamiany jako root, i wykonaj następujące czynności:

#!/bin/bash
touch dummy.txt
[ $UID -eq 0 ] && chown "$SUDO_USER":"$SUDO_USER" dummy.txt

Powyższe jest zalecanym podejściem. Są też inne, na przykład używanie chmoddo zmiany uprawnień do odczytu-zapisu-wykonania dla użytkowników i grupy, ale nie jest to zalecane.

Sergiy Kolodyazhnyy
źródło
dzięki za odpowiedź. Ale w QI właśnie wyjaśniłem prosty scenariusz w prawdziwym przypadku oryginalny skrypt będzie tworzył wiele plików. Czy w Linuksie nie możemy po prostu zignorować sudo?
Anonimowy,
1
@Anonimowy, jeśli wykonujesz cały skrypt za pomocą sudo, to nie - nie możesz go zignorować. Możesz albo uruchomić skrypt jako zwykły użytkownik (czego nie rozumiem, dlaczego tego nie robisz, ponieważ po prostu tworzysz tutaj plik dla swojego użytkownika) lub zmienić właściciela pliku, tak jak pokazałem w mojej odpowiedzi.
Sergiy Kolodyazhnyy
Jest to najbardziej poprawne rozwiązanie i nie powinno być tak trudne do skalowania.
pisklęta