Hej, hej... Programisto, to kolejny artykuł dla Ciebie! Druga część artykułu na temat wzorców projektowych. Poznaj Adapter oraz Memento.
Dzisiaj porozmawiamy sobie o Linuxie oraz o językach skryptowych. Podczas tej serii przejdziemy także przez podstawy systemu Linux i powłoki bash. Jeśli jesteście zainteresowani, to zapraszamy do lektury!
Skrypt vs shell
W świecie Linuxa często możemy spotkać takie pojęcia jak powłoka, shell czy bash. Aby dobrze zrozumieć temat należy na początku zacząć od podstawowych pojęć. Celem powłoki systemu Linux jest ułatwienie komunikacji między użytkownikiem a jądrem systemu. Natomiast jądro jest kolejnym pośrednikiem w systemie, które ma już dostęp do części sprzętowej naszego komputera i odpowiada na przykład za zarządzanie sterownikami czy pamięcią. Komendy natomiast to interfejs najwyższego poziomu, z którego korzysta użytkownik poprzez terminal.
Rysunek 1 – Powłoka i polecenia w kontekście komunikacji z hardware w systemie Linux, źródło: mindmajix.com
Najczęściej wykorzystywaną powłoką w Linuxie jest Bash (Bourne Again Shell) oparty na powłoce Bourne shell (Sh). Jeśli bash jest tylko powłoką, która stanowi warstwę abstrakcji pomiędzy programami, a kernelem to można zadać sobie pytanie: czym jest skrypt? Spieszymy z odpowiedzią – skrypt jest po prostu plikiem, który zawiera komendy dla danej powłoki. Skrypt bashowy jest więc po prostu plikiem zawierającym sekwencję komend dla powłoki bash.
Korzystanie ze skryptów pozwala zwiększyć niezawodność, stopień automatyzacji pracy administratora i tym samym zoptymalizować działania wykonywane na systemie Linux.
Struktura skryptu
Skrypt w Linuxie zaczynamy od tzw. sekwencji shebang, która w przypadku bash’a wygląda następująco: #!/bin/bash. W ramach skryptu możemy zarówno pisać własny kod jak i wywoływać programy dostępne z poziomu powłoki.
Rysunek 2 – podstawowy skrypt w bash’u. Znak shebang oraz wywołanie komendy echo.
Bash nie implementuje mechanizmu try/catch dla błędów, więc posługujemy się kodami błędów, aby zakomunikować czy dany skrypt zakończył się poprawnie, gdzie exit 0 oznacza poprawne wykonanie skryptu.
Wywoływanie skryptu i prawa w systemie Linux
Aby wywołać poprawnie skrypt, należy mieć odpowiednie uprawnienia do jego wykonywania. Dotyczy to zarówno zewnętrznych programów wywołujących nasz skrypt, jak i potencjalnego użytkownika chcącego go uruchomić.
Klasycznie, kontrola dostępu do plików w systemie Linux to tzw. DAC – Discretionary Access Control (DAC). Model ten polega na założeniu, że to właściciel danego pliku ma nad nim kontrolę. W systemie Linux każdy plik ma więc właściciela (u – user/owner), grupę (g – group) oraz uprawnienia, określające czynności jakich można na nim dokonywać tj. odczytywanie (r – read), zapisywanie (w – write), uruchamianie (x – execute). Należy jednak mieć świadomość, że w świecie Linux’a DAC nie jest jedyną opcją i w tym temacie polecamy poniższy artykuł w temacie SELinux’a.
https://github.blog/2023-07-05-introduction-to-selinux/
Wracając do samych uprawnień, to do ich modyfikowania używane jest polecenie chmod, pozwalające użytkownikom kontrolować dostęp do swoich plików.
Uprawnienia w systemie Linux reprezentowane są przez ciąg 9 znaków, po 3 dla każdego rodzaju uprawnień. Są to kolejno uprawnienia dla właściciela, grupy właściciela oraz innych użytkowników.
Rysunek 3 – uprawnienia w systemie Linux, źródło: comentum.com
Istnieją dwa sposoby nadawania uprawnień w Linux’ie z pomocą komendy chmod. Sposób numeryczny oraz symboliczny.
Sposób numeryczny polega na przypisaniu wartości numerycznych do poszczególnych uprawnień
- 4 – Odczyt
- 2 – Zapis
- 1 – Wykonanie
Suma wartości numerycznych daje pełne informacje o uprawnieniach:
- 7 – Odczyt + Zapis + Wykonanie
- 6 – Odczyt + Zapis
- 5 – Odczyt + Wykonanie
- 4 – Odczyt
- 3 – Zapis + Wykonanie
- 2 – Zapis
- 1 – Wykonanie
- 0 – Brak uprawnień
Przykład: Nadanie właścicielowi pliku prawa do odczytu i zapisu
chmod 600 example.txt
Przykład: pełne prawa dla właściciela pliku i odczyt dla grupy oraz innych użytkowników
chmod 744 example.txt
Istnieją także kalkulatory online, gdzie wybieramy odpowiednie parametry w wygodnym GUI i wyświetla nam się komenda, którą należałoby wykonać.
Rysunek 4 – Kalkulator praw dla Linux, źródło: https://chmodcommand.com/
Sposób symboliczny polega natomiast na używaniu odpowiednich oznaczeń literowych i manipulowaniu z ich pomocą uprawnieniami.
– u – Właściciel pliku
– g – Grupa właściciela pliku
– o – Inni użytkownicy
– + – Dodaj uprawnienia
– – – Odejmij uprawnienia
– r – Odczyt (read)
– w – Zapis (write)
– x – Wykonanie (execute)
Przykład: Odebranie właścicielowi pliku prawa do odczytu i zapisu
chmod u-rw example.txt
Przykład: Nadanie prawa wykonania innym użytkownikom
chmod o+x example.txt
Rysunek 5 – zmiana uprawnień skryptu w Linux’ie
Uprawnienia specjalne
Warto także wspomnieć w temacie uprawnień w Linux’ie o tzw. uprawnieniach specjalnych, które pozwalają na rozszerzenie funkcjonalności w specyficznych przypadkach. Występują trzy rodzaje specjalnych uprawnień:
- SUID – opcja pozwalająca użytkownikom uruchomić dany plik wykonywalny z uprawnieniami jego właściciela, a nie uprawnieniami użytkownika uruchamiającego w danym momencie program. Zapewnia to tymczasowo podwyższone uprawnienia do wykonania pewnej akcji na komputerze.
Klasycznym przykładem może być program passwd służący do zmieniania hasła w systemie Linux. Program passwd musi modyfikować plik shadow (/etc/shadow), co wymaga podwyższonych uprawnień (oba pliki należą do root’a). Dlatego plik wykonywalny passwd ma ustawiony bit SUID i umożliwia zwykłym użytkownikom zmianę swoich haseł bez konieczności uzyskiwania dostępu roota. Jeśli zdecydujemy się usunąć SUID i nadać pełne uprawnienia plikowi passwd, to program nie będzie w stanie otworzyć pliku /etc/shadow w celu wprowadzenia zmian (gdyż ten nadal należeć będzie do użytkownika root). W rezultacie otrzymamy odmowę dostępu gdy spróbujemy uruchomić polecenie passwd z poziomu użytkownika.
Warto także wspomnieć, że program passwd sprawdza jednak identyfikator (UID) użytkownika, który go uruchamia. To sprawdzenie to odbywa się wewnętrznie w kodzie programu i sprawia, że użytkownik pomimo podwyższonych uprawnień dzięki SUID, nie jest w stanie modyfikować haseł innych niż swoje.
Podsumowując, SUID stosuje się w sytuacji, gdzie dany użytkownik np. root ma pewne specjalne uprawnienia, które wykorzystywane są przez dany program, a których nie może posiadać zwykły użytkownik.
Ustawienie SUID objawia się tym, że zamiast litery ‘x’ w prawach właściciela pliku pojawia się ‘s’, co możemy zaobserwować na rysunku poniżej.
Rysunek 6 – uprawnienia pliku /etc/passwd, zwróćmy uwagę, że zamiast rwx jest rws
W przypadku, kiedy dany plik nie ma ustawionego prawa wykonywania dla właściciela w miejscu znaku ‘s’ pojawia się ‘S’, co oznacza błąd. Brak prawa wykonywania dla właściciela zaprzecza całej idei SUID, ponieważ program z ustawionym SUID jest wykonywany na prawach właściciela. Jeśli właściciel nie ma praw do wykonywania, to występuje sprzeczność.
Rysunek 7 – Ustawienie SUID – różnica w prawach wykonywania dla właściciela
- SGID – Jeżeli specjalne uprawnienia są ustawione na grupę, występują dwa przypadki. W przypadku plików, podobnie jak w SUID, program zostanie wykonany z podniesionymi uprawnieniami, lecz tym razem dotyczą one grupy. Gdy SGID jest ustawiony na folder, nowo tworzone pliki wewnątrz tego katalogu dziedziczą przynależność grupy od katalogu nadrzędnego, a nie od grupy użytkownika, który tworzy plik. Przykładem zastosowania może być folder, do którego zapisują współpracujący użytkownicy, należący do jednej grupy. Dzięki temu, za każdym razem, gdy użytkownik tworzy plik, automatycznie dziedziczy grupę przypisaną do katalogu nadrzędnego.
- Sticky Bit – Jest to ostatni z trzech specjalnych ustawień uprawnień i dotyczy katalogów. Gdy jest ustawiony, wpływa na katalogi współdzielone, takie jak np. /tmp, gdzie wszyscy użytkownicy mają możliwość zapisywania plików. Istotną cechą jest, że użytkownicy nie mogą wzajemnie usuwać ani modyfikować plików w tych katalogach. Tylko właściciel danego zasobu lub użytkownik z uprawnieniami roota ma możliwość dokonywania takich zmian.
Podsumowanie
Dzisiaj mieliśmy okazję zapoznać się z kluczowymi pojęciami związanymi z systemem Linux oraz zgłębić szczegóły dotyczące nadawania uprawnień w tym środowisku. Jeżeli chcielibyście dowiedzieć się więcej w temacie Linux zapraszamy na konsultacje.
Źródła:
- https://mindmajix.com/shell-scripting-tutorial
- https://www.comentum.com/unix-osx-permissions.html
- https://www.redhat.com/sysadmin/suid-sgid-sticky-bit
- https://linuxhandbook.com/suid-sgid-sticky-bit/
- https://security.stackexchange.com/questions/199153/why-is-linux-filesystem-considered-dac-and-not-mac
- https://github.blog/2023-07-05-introduction-to-selinux/
- https://www.linuxnix.com/suid-set-suid-linuxunix