Jak zapobiec uruchamianiu określonych poleceń przez użytkowników sudo?

29

Mam bardzo wrażliwą konfigurację sieci i naprawdę nie chcę z tym popsuć. Moja sieć składa się z grupy użytkowników posiadających uprawnienia sudo.

Chcę zatrzymać ich przed uruchomieniem

service NetworkManager restart
service network restart

polecenia.

Czy jest jakiś sposób, aby to osiągnąć?

shekhar
źródło
Jakiej dystrybucji używasz? Nazwy usług są specyficzne dla dystrybucji i nie znam żadnej dystrybucji korzystającej z nazw, które tam masz. Masz na myśli networkingi network-manager? Ponadto, dlaczego Twoi użytkownicy mają sudodostęp? Nie powinny, chyba że chcesz, aby mieli pełne uprawnienia root.
terdon
@terdon Rozwiązałem to. Dziękuję Ci. Nie mogę opublikować tego jako odpowiedzi, ponieważ jestem nowym użytkownikiem
shekhar
Tak, możesz. Chciałbym również poznać odpowiedź, którą znalazłeś.
terdon
@terdon na pewno, ale mówi, że muszę poczekać 8 godzin, aby opublikować własną odpowiedź, ponieważ nie mam nawet 10 reputacji
shekhar
1
Ach tak, przepraszam, naprawdę musisz poczekać. Właśnie przegłosowałem, masz teraz przedstawiciela :)
terdon

Odpowiedzi:

47

Korzystanie z CmndAlias ALLnigdy nie będzie bezpieczne

Istnieje 1000 sposobów na uruchomienie service network restartbez robienia sudo service network restart. Oto przykład tego, co niegrzeczny użytkownik może spróbować:

$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax

Jeśli podasz użytkownikom ALLalias polecenia, a następnie spróbujesz utworzyć czarną listę, zawsze będą w stanie ją obejść. Czarna lista bash, a oni będą używać Pythona. Python z czarnej listy, a oni użyją Perla. Perl z czarnej listy, a oni będą używać PHP. Nikt tego nie chce!

Jeśli naprawdę nie chcesz, aby ktoś coś zrobił, powinieneś zrobić, jak mówi Thomas, i utworzyć białą listę rzeczy, które mogą robić.


Konfigurowanie białej listy z wyjątkiem

Przykład małej białej listy z wykluczeniem można znaleźć u dołu man sudoers:

 pete           HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root

The user pete is allowed to change anyone's password except for root on the HPPA
machines.  Note that this assumes passwd(1) does not take multiple user names
on the command line.

(W rzeczywistości ten przykład ze strony podręcznika jest niebezpieczny i można go wykorzystać do zmiany hasła roota! Zobacz komentarze poniżej).

Możemy starać się przystosować, że w Twoim przypadku, aby oferować wszystkie servicepolecenia do grupy pracowników, ale wyklucza te service networkpolecenia, które dotyczą Ciebie:

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

(Ta ALLpozycja odnosi się do Host_Alias, a nie do Cmnd_Alias ​​- mylące, prawda?)

Użytkownik nie będzie mógł uruchomić sudo bashlub sudo teelub sudo wgetlub sudo /path/to/malicious_script. Jeśli zachowasz ostrożność, możesz dodać do białej listy więcej poleceń administratora dla swoich użytkowników. Po prostu bądź konkretny!

Uwaga: dodałem *przed słowem networkpowyżej, na wypadek, gdyby servicew przyszłości do narzędzia dodano niegroźną flagę . Wyobraźmy sobie, że --verboseflaga zostanie dodana w przyszłości, a następnie użytkownicy będą mogli uruchomić następujące funkcje:

$ sudo service --verbose network restart

Musimy więc *użyć flag przed nazwą usługi. Jedyną wadą jest to, że może to blokować inne usługi, które nie mają nic przeciwko działającym użytkownikom, np. Usługa o nazwie safe-networklub network-monitorteż zostanie odrzucona.


Pozwól użytkownikom edytować plik przy użyciu uprawnień grupy

Poniżej można znaleźć różne próby użycia rnanoza pomocą, sudoaby umożliwić użytkownikom edycję pliku lub plików. Ale tak naprawdę są bardziej złożone i bardziej niebezpieczne niż powinny.

Dużo prostszym i bezpieczniejszym rozwiązaniem jest zmiana uprawnień grupy do określonych plików, dla których chcesz otworzyć uprawnienia do edycji. Oto kilka przykładów:

### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project

### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website

Jeśli potrzebujesz bardziej szczegółowej kontroli (na przykład: dostęp tylko dla 3 użytkowników, ale nie dla wszystkich pracowników), możesz utworzyć nową grupę za pomocą addgrouppolecenia i dodać do niej tylko kilku użytkowników.


Pozwól użytkownikom edytować plik sudo

Pozostała część tej odpowiedzi stała się badaniem, jak łatwo jest pozostawić dziury w sudokonfiguracji, próbując zaoferować użytkownikom elastyczność. Nie polecam robienia żadnej z poniższych czynności!

Jeśli chcesz przyznać użytkownikom dostęp do edycji określonego pliku, możesz spróbować użyć rnano:

%staff ALL = /bin/rnano /etc/nginx/sites-available/host

rnanopozwoli im tylko edytować określony plik. Jest to ważne, aby uniemożliwić złośliwemu użytkownikowi edytowanie innej usługi upstart (na przykład /etc/init.d/urandom) i dodawanie do niej wiersza, który byłby uruchomiony service network restart.

Niestety nie znalazłem sposobu na rvimwystarczające ograniczenie (użytkownik może nadal otwierać dowolny plik za pomocą :e), więc utknęliśmy nano.

Niestety umożliwienie użytkownikom edycji wielu plików jest znacznie trudniejsze ...


Pozwól użytkownikom edytować wiele plików (znacznie trudniejsze niż powinno)

1. Niebezpieczne podejścia

Uważaj na symbole wieloznaczne! Jeśli oferujesz zbyt dużą elastyczność (lub dowolną), możesz ją wykorzystać:

%staff ALL = /bin/rnano /etc/nginx/sites-available/*                # UNSAFE!

W takim przypadku złośliwy użytkownik będzie mógł edytować dowolny inny skrypt usługi wstępnej, a następnie uruchomić go:

$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system

(Sudo faktycznie uniemożliwia .i ..rozwija polecenie, ale niestety nie argumenty.)

Miałem nadzieję, że coś takiego może zadziałać, ale nadal nie jest pewne:

%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]*   # UNSAFE!

Ponieważ sudoobecnie oferuje tylko globalne wzorce, które *będą pasować do wszystkiego - nie jest to wyrażenie regularne!

(Edycja: I uznała, jeśli może uciec z powyższym w sytuacji, ponieważ nie istnieją żadne podfoldery znajdujące się pod sites-available. Zrobiliśmy popyt jeden char być dopasowane po folderze, a /... Nie uda po nazwie pliku Jednak nie jest to wykonalne rozwiązanie, ponieważ rnanoakceptuje wiele argumentów. W każdym razie nadal byłoby to niebezpieczne w przypadku folderu zawierającego podfoldery!)

Nawet jeśli nie mamy podfolderów i nie uwzględniamy żadnych wierszy zawierających /../, reguła oferująca *glob może być nadal wykorzystywana, ponieważ rnanoakceptuje wiele argumentów ( <C-X>przełączanie się między nimi , a przestrzeń jest chętnie akceptowana przez *glob).

$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system

2. Pchanie koperty (również ostatecznie niebezpieczne)

A co jeśli odrzucimy dowolne wiersze zawierające spacje lub spróbujemy dotrzeć /..? Wtedy ostatecznym wykonalnym rozwiązaniem może być:

# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.

%staff ALL =   /bin/rnano /etc/nginx/sites-available/*,    \
             ! /bin/rnano */..*,                           \
             ! /bin/rnano /etc/nginx/sites-available/,     \
             ! /bin/rnano */.,                             \
             ! /bin/rnano * *

# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.

Przyjmujemy wszystko „pod” w folderze, ale także odrzucić wszelkie wywołanie rnanoczy /..lub /.czy są przekazywane, lub jeśli folder jest kierowane bezpośrednio. (Technicznie /.wykluczenie sprawia, że /..wykluczenie jest zbędne, ale pozostawiłem oba dla jasności).

Znalazłem folder i /.wyjątki były potrzebne, ponieważ w przeciwnym razie użytkownik mógłby skierować folder na sam folder. Teraz możesz pomyśleć, rnanoże zablokuje się, jeśli wskażesz na folder, ale pomylisz się. W rzeczywistości moja wersja (2.2.6-1ubuntu1) uruchamia się z łagodnym ostrzeżeniem i pustym plikiem, a następnie <C-X>prosi mnie o podanie nazwy pliku, w którym chcę zapisać, otwierając nowy wektor ataku! Cóż, przynajmniej odmówił zastąpienia istniejącego pliku (w jednym teście, który zrobiłem). W każdym razie, ponieważ nie ma sposobu na umieszczenie podfolderów na czarnej liście w sudo, musimy stwierdzić, że takie podejście jest znowu niebezpieczne. Przepraszamy użytkowników!

To odkrycie sprawiło, że wątpię w dokładność nanotrybu „ograniczonego”. Mówią, że łańcuch jest tak silny, jak jego najsłabsze ogniwo. Zaczynam odczuwać połączenie sudoczarnej listy z czarną magią i rnanomoże nie być bardziej bezpieczny niż łańcuch stokrotek.

3. Bezpieczne, ale ograniczone podejścia

Globy są bardzo ograniczone - nie pozwalają nam wielokrotnie dopasowywać klasy postaci. Państwo mogli zaoferować wiele edycje pliku, jeśli wszystkie nazwy plików mają taką samą długość (w tym przypadku hostnastępuje jednej cyfry):

%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9]       # SAFE

Ale jeśli chcesz dać użytkownikowi dostęp do edycji różnych plików, konieczne może być jawne określenie każdego z nich:

%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost    \
             /bin/rnano /etc/nginx/sites-available/coldhost   \    # SAFE
             /bin/rnano /etc/nginx/sites-available/wethost    \
             /bin/rnano /etc/nginx/sites-available/steves_dodgy_project

Nie daj się skusić na użycie*w żadnym momencie. Dlaczego? Zobacz sekcje 1. i 2. powyżej! Pamiętaj: jeden mały poślizg może narazić na szwank całe konto administratora i cały system.

4. Napisz własny moduł do sprawdzania argumentów (bezpieczeństwo jest teraz Twoim obowiązkiem)

Mam nadzieję, że dodadzą obsługę wyrażeń regularnych sudow przyszłości; może poprawnie rozwiązać wiele problemów. Ale możemy również potrzebować możliwości sprawdzenia właściwości argumentów (aby zezwolić tylko na pliki, tylko foldery lub tylko niektóre flagi).

Ale istnieje jedna alternatywa dla stworzenia elastyczności w sudo. Zwalać odpowiedzialność:

%staff ALL = /root/bin/staffedit *

Następnie napisz własny staffeditskrypt lub plik wykonywalny, aby sprawdzić, czy argumenty przekazane przez użytkownika są zgodne z prawem, i zrealizuj ich żądanie tylko wtedy, gdy są.

joeytwiddle
źródło
5
Ta odpowiedź zajęła dużo czasu, ale w końcu myślę, że rozumiem, jak działa sudo. W przeszłości poddawałem się przy różnych okazjach, stwierdzając, że ALL=(ALL:ALL) ALLbrakuje mi semantyki, ale zawsze zakładałem, że gdzieś będzie miał przyzwoitą kontrolę argumentów ... Myliłem się. To naprawdę bardzo ograniczone. Nawet passwd wykluczenie korzeń oferowane w roboczogodziny stronie można podzielić za pomocą prostego wiersza poleceń argumentu sudo passwd -q root. Cóż, autorzy sudo wymieniają [kilka alternatyw] (sudo.ws/sudo/other.html) na swojej stronie internetowej. Mam nadzieję, że dodadzą obsługę wyrażeń regularnych w przyszłości.
joeytwiddle
Czy używasz go rnanow opisie tutaj, ponieważ jest to wersja nano, której brakuje funkcji „zapisz jako”? Nie znam programu.
Shadur
Tak. Jeśli zależy nam na bezpieczeństwie, edytor powinien edytować tylko jeden określony plik i nie powinien mieć możliwości otwarcia powłoki. Aby uzyskać informacje, $ man nanoa następnie/-R<Enter>
joeytwiddle
Korekta: Aby przełamać przykład Pete -qmusi przyjść później: sudo passwd root -q. Przykład Pete'a można zahartować przez wykluczenie *root*.
joeytwiddle
Rozważ użycie opcji, sudoeditaby bezpiecznie włączyć modyfikację pliku za pomocą sudo.
Totor
5

Najpierw otwórz plik sudoers za pomocą sudo visudo. Dodanie user ALL=!/usr/sbin/servicewill, IIRC, zabrania servicepolecenia dla użytkownika user.

Źródła: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell

Zeb McCorkle
źródło
To przestanie także uruchamiać inne usługi i nie chcę tego. Dziękuję za odpowiedź. :)
shekhar
podczas gdy twoja odpowiedź nie pomogła mi dokładnie, ale pomogła mi znaleźć rozwiązanie, dziękuję. ale wiesz, że możesz wyrazić opinię lub opublikować moją roboczą odpowiedź. Nie mam wystarczającej reputacji. Z pewnością będę wdzięczny, kiedy będę. Dziękuję Ci.
shekhar
2
Tak, ale nadal, jak twierdzili inni, musisz być bardzo ostrożny. Istnieje wiele sposobów uzyskania dostępu. Każde polecenie, które może spawnować powłokę i tak dalej. Łatwiej jest dowiedzieć się, jakich poleceń naprawdę potrzebują i pozwolić im, zamiast próbować wykluczyć wszystkie „zabronione”.
Bonsi Scott
3
Białych list nie da się utrzymać w wielu scenariuszach. Prawdziwym celem może nie być powstrzymanie ich przed zrobieniem czegoś, ale raczej powstrzymanie ich przed zrobieniem czegoś złego przez pomyłkę bez ograniczenia ich. Czarne listy są w tych przypadkach dobre. Umieszczasz na czarnej liście sposoby, w jakie rozsądny użytkownik podjąłby się tego zadania. Ale czarna lista za pośrednictwem sudo może nie być wystarczająca - ludzie mogą i używają „sudo bash”. Jednym z podejść byłoby zawinięcie polecenia „usługa”, a jeśli nie chcesz, aby ich używał, poinformuj ich. Ale nigdy nie umieścisz wszystkich dobrych działań na białej liście ani wszystkich złych na czarnej liście.
Bob Kerns
1
Zgadzam się z tobą Bob. Aby zapewnić elastyczność, bez umożliwienia pełnego dostępu, często będziesz musiał stworzyć własne rozwiązanie jako skrypt pomocniczy i umieścić na białej liście tylko ten skrypt. Białe listy sudo mogą robić to, czego potrzebujesz, ale często będą albo zbyt ograniczone, albo zbyt łatwe do wykorzystania.
joeytwiddle
5

Znalazłem rozwiązanie.

Otworzyłem terminal i zmieniłem się w użytkownika root, a su -następnie napisałem, visudoaby edytować.

potem na końcu napisałem wiersze jak

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Następnie zapisałem i zamknąłem i ponownie uruchomiłem.

Teraz, jeśli piszę jako service network restartlub service NetworkManager restartwtedy to nie pozwala mi i daje błąd podobny do

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

i podobnie service network restartrównież dla dowodzenia.

shekhar
źródło
12
Będzie to działać dla niedoświadczonych i nieszkodliwych użytkowników, ale łatwo jest ominąć ograniczenia sudo (np. sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudoI wtedy sudo /etc/init.d/network-not-in-sudo restart). Dlatego o wiele bezpieczniej jest tworzyć inkluzje zamiast wykluczeń w pliku sudoers, np. Określić, z którymi usługami mogą one wchodzić w interakcje.
Thomas
Wszystko, co robi „restart sieci serwisowej”, możesz wykonać za pomocą innych poleceń, takich jak te w skrypcie init.d sieci. Nie będę nawet próbował ich tutaj wymieniać. Ale jeśli chcesz na przykład zapobiec modyfikacjom stanu interfejsu, to wydaje mi się, że polityka SELinuksa jest dobrą drogą. To złożony temat, ale kiedy biała lista jest zbyt restrykcyjna lub uciążliwa, a czarna lista jest nieodpowiednia, to prawdopodobnie najlepsza opcja. Jest zaimplementowany w jądrze i pozwala ograniczyć dostęp do interfejsów sieciowych (i innych zasobów) nawet dla sudoid użytkowników.
Bob Kerns
Jeśli jest to możliwe dzięki SELinux, byłby bardziej zadowolony. @BobKerns Dziękujemy. Spróbuję w ten sposób.
shekhar
3

Prawdziwą odpowiedzią jest to, że tak naprawdę nie można temu zapobiec. Możesz zapobiec przypadkowemu uruchomieniu tej komendy przez złośliwych użytkowników metodami opisanymi w innych odpowiedziach, ale jeśli ktoś naprawdę chce ją uruchomić i znajduje się na liście sudoers, może ją uruchomić. Na przykład mogą wykonać następujące czynności:

joe@box:~$ sudo bash root@box:~# service network restart

Lub inne zabawne polecenie, którego mogliby użyć w celu obejścia twoich ograniczeń w pliku sudoers:

sudo visudo

Krótko mówiąc, jeśli potrafisz sudo i nie ogranicza się to do uruchamiania określonych poleceń, możesz robić prawie wszystko, co chcesz. Nawet jeśli ograniczysz je do danego zestawu poleceń, będziesz musiał upewnić się, że użytkownik nie będzie mógł skopiować innego polecenia, które chciałoby uruchomić pod tą samą nazwą, jak to, do którego miał uprawnienia ( na przykład poprzez zastąpienie polecenia, które mają uprawnienia do uruchomienia).

reirab
źródło
Tak. Należy unikać poleceń, które mogą odrodzić powłokę od wewnątrz.
Bonsi Scott
1
Problem polega na tym, że nie są to polecenia, które chcesz chronić, ale stan obiektów jądra, takich jak tabele routingu, interfejsy itp. - bez względu na to, jakie polecenie (lub wywołanie systemowe) jest używane. I chcesz go chronić przed niektórymi, ale nie wszystkimi użytkownikami root. SELinux został zaprojektowany w oparciu o taki scenariusz. Ale najpierw zacznę od przeglądu, dlaczego wszyscy ci użytkownicy mają dostęp do sudo. Jeśli muszą zrobić tylko kilka konkretnych rzeczy, operacje na białej liście w sudoerach mogą być wszystkim, czego potrzebujesz.
Bob Kerns
2

Użyj Firejail, aby ograniczyć użytkowników za pomocą piaskownicy.

https://github.com/netblue30/firejail/

Ustaw firejail jako powłokę zamiast bash w / etc / passwd, dla każdego użytkownika, którego chcesz ograniczyć. Jest bardzo łatwy w użyciu i ma dobrą dokumentację.

Przykład:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Jeff
źródło