Przejdź do treści
Lekcja 15 z 117

Kurs › Moduł 1 › Lekcja 15

Kto może czytać twój plik

⏱ ok. 11 min czytania· moduł 1: Praca w powłoce

Po tej lekcji: kursant czyta uprawnienia z ls -l, zmienia je chmod literami i cyframi, zmienia właściciela i grupę, rozumie umask i wie, czemu sudo echo > plik nie działa.

Wstęp

terminal, sudo echo "127.0.0.1 test.local" >> /etc/hosts, a pod spodem czerwone Permission denied

Masz sudo. Jesteś administratorem. Piszesz komendę z sudo na początku, żeby dopisać linijkę do pliku systemowego. A system odpowiada: brak uprawnień. Tobie. Adminowi.

To nie błąd Linuksa. To błąd w tym, kto w urzędzie trzyma klucze. Dziś rozbieramy uprawnienia od środka, a na końcu ta zagadka sama się rozwiąże.

Dziesięć znaczków na początku linijki

Wracamy do budynku. Każdy pokój ma drzwi, a do drzwi są trzy komplety kluczy: jeden dla właściciela pokoju, jeden dla jego działu, jeden dla całej reszty świata. I każdy komplet otwiera inne rzeczy.

echo "Tajne dane" > raport.txt
ls -l raport.txt
-rw-rw-r-- 1 eryk eryk 11 Nov  3 15:30 raport.txt

Czytamy od lewej:

  • - to typ. Kreska to zwykły plik, d folder, l symlink z poprzedniej lekcji.
  • rw- to klucze właściciela, po angielsku user, w skrócie u.
  • rw- to klucze grupy, group, g.
  • r-- to klucze całej reszty, others, o.
  • 1 to licznik linków, już znasz.
  • eryk eryk to właściciel i grupa. Pierwszy eryk to człowiek, drugi to grupa o tej samej nazwie. Na Ubuntu i RHEL każdy użytkownik dostaje własną jednoosobową grupę, jak pokój z tabliczką „dział Eryka, skład: Eryk”.

A w każdej trójce trzy literki:

  • r, read, czytanie. Możesz zajrzeć do środka.
  • w, write, pisanie. Możesz zmieniać treść.
  • x, execute, wykonywanie. Możesz uruchomić plik jak program.
  • - znaczy „tego klucza nie masz”.

System sprawdza tylko jeden komplet. Jesteś właścicielem? Bierze pierwszą trójkę i koniec, reszty nie patrzy. Nie jesteś, ale należysz do grupy? Druga trójka. Ani to, ani to? Trzecia. Może się więc zdarzyć absurd: właściciel z --- nie przeczyta własnego pliku, choć cały świat może. Jak właściciel mieszkania, który zostawił klucze w środku, a sąsiedzi wchodzą, bo mają zapasowe.

A root? Root to dyrektor z kluczem uniwersalnym. Uprawnienia do czytania i pisania go nie dotyczą.

chmod literami

Uprawnienia zmienia chmod, od „change mode”. Pierwszy sposób to litery: komu, plus albo minus, co.

chmod g+w raport.txt; ls -l raport.txt
chmod o-r raport.txt; ls -l raport.txt
chmod u=rw,g=r,o= raport.txt; ls -l raport.txt
-rw-rw-r-- 1 eryk eryk 11 Nov  3 15:30 raport.txt
-rw-rw---- 1 eryk eryk 11 Nov  3 15:30 raport.txt
-rw-r----- 1 eryk eryk 11 Nov  3 15:30 raport.txt

g+w dodaje grupie pisanie, tu już je miała, więc nic się nie zmieniło. o-r zabiera reszcie czytanie. = ustawia dokładnie tyle, ile napiszesz, a o= z niczym po prawej zabiera wszystko. Jest jeszcze a, czyli all, wszyscy naraz: chmod a+x.

Najczęstszy przypadek w życiu: własny skrypt, który nie chce ruszyć.

printf '#!/bin/bash\necho "Dzialam!"\n' > skrypt.sh
./skrypt.sh
chmod +x skrypt.sh
ls -l skrypt.sh
./skrypt.sh
bash: ./skrypt.sh: Permission denied
-rwxrwxr-x 1 eryk eryk 28 Nov  3 15:30 skrypt.sh
Dzialam!

Bez x plik to tylko tekst. Przepis kulinarny w szufladzie. x to pieczątka „można gotować”.

chmod cyframi

Drugi sposób wygląda jak szyfr do sejfu, ale to prosta arytmetyka. Każdy klucz ma wartość: r to 4, w to 2, x to 1. Dodajesz, co chcesz dać, i dostajesz jedną cyfrę na każdą trójkę.

  • rw- to 4 + 2 = 6
  • r-x to 4 + 1 = 5
  • rwx to 4 + 2 + 1 = 7
  • r-- to 4, --- to 0
chmod 600 raport.txt; ls -l raport.txt
chmod 644 raport.txt; ls -l raport.txt
chmod 755 skrypt.sh; ls -l skrypt.sh
stat -c '%a %A %n' raport.txt
-rw------- 1 eryk eryk 11 Nov  3 15:30 raport.txt
-rw-r--r-- 1 eryk eryk 11 Nov  3 15:30 raport.txt
-rwxr-xr-x 1 eryk eryk 28 Nov  3 15:30 skrypt.sh
644 -rw-r--r-- raport.txt

Cyfr które warto znać na pamięć jest kilka: 644 zwykły plik, 600 prywatny plik, na przykład klucz SSH, 755 program albo folder, 700 prywatny folder, 640 i 750 dla plików i folderów działu. A 777? 777 to drzwi bez zamka na ruchliwej ulicy. Jeśli ktoś w internecie radzi „daj 777, to zadziała”, to zadziała. Dla wszystkich. Także dla tych, dla których nie miało.

Kiedy litery, kiedy cyfry? Cyfry, kiedy chcesz ustawić całość od zera. Litery, kiedy chcesz zmienić jedną rzecz i nie ruszać reszty.

Uprawnienia folderów to inna bajka

Na folderze te same literki znaczą coś innego. Folder to pokój z listą lokatorów na drzwiach.

  • r pozwala przeczytać listę nazw w środku.
  • x pozwala wejść do środka i przejść dalej.
  • w pozwala dopisywać i skreślać nazwy na liście, czyli tworzyć, zmieniać nazwy i usuwać pliki. Działa tylko razem z x.

Pokażę to na dwóch osobach. Folder /srv/dzial należy do Eryka, a Ania jest w grupie ksiegowosc.

ls -ld /srv/dzial
drwxr--r-- 2 eryk ksiegowosc 4096 Nov  3 16:30 /srv/dzial

Grupa ma samo r. Ania próbuje:

ania$ ls /srv/dzial
plik
ania$ cat /srv/dzial/plik
cat: /srv/dzial/plik: Permission denied
ania$ ls -l /srv/dzial
ls: cannot access '/srv/dzial/plik': Permission denied
total 0
-????????? ? ? ? ?            ? plik

Widzi nazwę na drzwiach, ale do środka nie wejdzie, więc nawet nie wie, jak plik wygląda. Same znaki zapytania. A teraz odwrotnie, Eryk daje chmod 711, czyli grupie i reszcie samo x:

ania$ ls /srv/dzial
ls: cannot open directory '/srv/dzial': Permission denied
ania$ cat /srv/dzial/plik
tajne

Listy nie widzi, ale jak zna dokładną nazwę, wejdzie i przeczyta. Pokój z zaklejoną tabliczką: wejdziesz, jeśli wiesz, kogo szukać.

I trzecia rzecz, najbardziej zaskakująca. Eryk daje grupie pełne prawa do folderu, chmod 770, a plik plik dalej jest jego i ma 644:

ania$ rm /srv/dzial/plik
ania$ ls -l /srv/dzial
total 4
-rw-rw-r-- 1 ania ania 5 Nov  3 16:30 ania.txt

Ania nie mogła zmienić ani litery w pliku Eryka, ale mogła go usunąć. Bo usunięcie to skreślenie nazwy z listy na drzwiach, a listę może zmieniać każdy z w na folderze. Zapamiętaj ten moment, w następnej lekcji poznasz łatkę na to: sticky bit. I zauważ, że nowy plik Ani dostał grupę ania, a nie ksiegowosc. To też naprawimy za tydzień.

chown i chgrp: zmiana właściciela

sudo chown ania raport.txt
sudo chown ania:ksiegowosc raport.txt
sudo chown :ksiegowosc raport.txt
sudo chgrp ksiegowosc raport.txt
sudo chown -R eryk:eryk strona/

chown to „change owner”. użytkownik:grupa zmienia oboje naraz, sam dwukropek z grupą zmienia tylko grupę, i to samo robi chgrp. -R idzie rekurencyjnie przez cały folder, klasyka po wgraniu strony WWW.

Czemu sudo? Bo zwykły użytkownik nie może oddać pliku komuś innemu:

chown: changing ownership of 'dla_ani.txt': Operation not permitted

Gdyby mógł, podrzucałby innym swoje pliki, na przykład zapełniając im limit miejsca. Jak podrzucenie komuś paczki z napisem „to twoje”. Grupę możesz zmienić sam, ale tylko na taką, do której należysz. Eryk jest w ksiegowosc, więc chgrp ksiegowosc przejdzie, a chgrp ania już nie.

umask: domyślne klucze dla nowych plików

Skąd nowy plik w ogóle bierze swoje uprawnienia? Programy proszą zwykle o 666 dla plików i 777 dla folderów, czyli „wszystko dla wszystkich”. Ale zanim plik powstanie, przechodzi przez filtr. Ten filtr to umask. Taka kratka w okienku urzędu: mówi nie „co dajemy”, tylko „czego nie wydajemy”.

umask
umask -S
touch nowy.txt; mkdir nowy_folder
ls -ld nowy.txt nowy_folder
0002
u=rwx,g=rwx,o=rx
-rw-rw-r-- 1 eryk eryk    0 Nov  3 15:30 nowy.txt
drwxrwxr-x 2 eryk eryk 4096 Nov  3 15:30 nowy_folder

Maska 002 zabiera reszcie świata pisanie. 666 minus 002 daje 664, 777 minus 002 daje 775. Root ma zwykle surowszą maskę 022, więc jego pliki wychodzą z 644.

Chcesz, żeby w tej sesji wszystko nowe było prywatne?

umask 077
touch prywatny.txt; mkdir prywatny_folder
ls -ld prywatny.txt prywatny_folder
-rw------- 1 eryk eryk    0 Nov  3 15:30 prywatny.txt
drwx------ 2 eryk eryk 4096 Nov  3 15:30 prywatny_folder

umask wpisany w terminalu działa tylko do jego zamknięcia. Na stałe wpisuje się go do plików startowych Basha, o których będzie lekcja 17.

Jak to działa pod spodem

Uprawnienia to 12 bitów w i-węźle pliku, obok numeru właściciela i grupy. Zwróć uwagę: numeru, nie nazwy. stat pokazywał Uid: (30042/eryk). Nazwę do numeru ls dopasowuje dopiero przy wyświetlaniu, patrząc do /etc/passwd. Kiedy proces otwiera plik, jądro porównuje jego numer użytkownika i numery grup z tymi w i-węźle i wybiera jedną trójkę.

I teraz zagadka z haka.

sudo echo "127.0.0.1 test.local" >> /etc/hosts
bash: /etc/hosts: Permission denied

Pamiętasz dwa głośniki z lekcji 6? Przekierowanie >> robi Twój Bash, zanim cokolwiek uruchomi. Kolejność jest taka: Bash, działający jako Eryk, próbuje otworzyć /etc/hosts do dopisywania. /etc/hosts ma 644 i należy do roota. Eryk ma tylko r. Koniec, błąd. sudo nawet nie zdążyło wystartować. A gdyby wystartowało, to z uprawnieniami roota uruchomiłoby… echo. Które umie tylko powiedzieć tekst.

To jak wysłać dyrektora z kluczem uniwersalnym, żeby głośno przeczytał list, a potem samemu próbować wrzucić ten list do zamkniętego sejfu. Dyrektor z kluczem stoi obok i grzecznie czyta.

Rozwiązanie: niech zapisuje program, który działa jako root.

echo "127.0.0.1 test.local" | sudo tee -a /etc/hosts
sudo sh -c 'echo "127.0.0.1 test.local" >> /etc/hosts'
127.0.0.1 test.local

tee z lekcji o rurach dostaje tekst z taśmy i sam otwiera plik, już jako root. -a znaczy „dopisz”, bez tego nadpiszesz cały plik. Bez -a na /etc/hosts to bardzo krótki dzień pracy. Jeśli nie chcesz, żeby tee powtarzał tekst na ekranie, dodaj na końcu > /dev/null. Drugi sposób uruchamia całą nową powłokę jako root, i to ona robi przekierowanie.

Ściąga flag

KomendaFlagaCo robi
ls-luprawnienia, właściciel, grupa
ls-ld folderuprawnienia samego folderu, nie jego zawartości
stat-c '%a %A %U %G %n'uprawnienia cyfrą i literami, właściciel, grupa
chmodu+x, g-w, o=, a+rzmiana literami: komu, plus/minus/równa się, co
chmod644, 600, 755, 750ustawienie całości cyframi (r=4, w=2, x=1)
chmod-Rrekurencyjnie przez folder
chmod-R u=rwX,g=rX,o=duże X: wykonywanie tylko folderom i plikom, które już je miały
chownużytkownik:grupazmienia właściciela i grupę (tylko root)
chown-Rrekurencyjnie
chgrpgrupazmienia grupę (na swoją, jeśli nie jesteś rootem)
umask(bez flag)pokazuje maskę cyfrowo
umask-Spokazuje, co zostaje, literami
tee-adopisuje do pliku, w duecie z sudo

⚠ Typowy błąd

chmod -R 755 albo chmod -R 644 na cały folder ze stroną.

Po chmod -R 644 strona/ wszystkie pliki są dobre, ale foldery straciły x. Nikt, łącznie z serwerem WWW, nie wejdzie do środka. Strona leży. Po chmod -R 755 strona/ działa, ale każdy plik tekstowy, obrazek i plik z hasłem do bazy jest teraz „programem”. Jak przyklejenie wszystkim pracownikom plakietki „kierownik”, żeby nie trzeba było myśleć, kto ma klucze.

Naprawa: duże X.

chmod -R u=rwX,g=rX,o= proj
ls -lR proj
proj:
drwxr-x--- 2 root root 4096 Nov  3 16:30 a
-rwxr-x--- 1 root root    0 Nov  3 16:30 s.sh

proj/a:
-rw-r----- 1 root root 0 Nov  3 16:30 f.txt

Duże X daje wykonywanie tylko folderom i plikom, które już miały je u kogoś. Folder a dostał x, skrypt s.sh je zachował, a zwykły f.txt nie. Do porządków w całym drzewie używasz właśnie tego, a nie 755 na ślepo.

✎ Zadanie

  1. Utwórz plik sekret.txt tak, żeby od razu powstał z uprawnieniami 600, bez używania chmod.
  2. Utwórz folder wspolny z uprawnieniami 750 i zapisz, jak wyglądają one literami.
  3. Sprawdź, jakie uprawnienia, właściciela i grupę mają /etc/passwd, /etc/shadow i /usr/bin/passwd. Przy ostatnim znajdziesz literę, której dziś nie omówiliśmy. Zapisz ją.
  4. Dopisz do /etc/hosts linijkę 127.0.0.1 kurs.local jedną komendą z sudo, która naprawdę zadziała.
Pokaż rozwiązanie
(umask 077; touch sekret.txt)
ls -l sekret.txt
umask
-rw------- 1 eryk eryk 0 Nov  3 21:16 sekret.txt
0002

Nawiasy uruchamiają komendy w osobnej, krótkiej powłoce. Tam maska 077, plik powstaje od razu prywatny, a po wyjściu z nawiasów Twoja maska jest dalej 002. Jak pożyczenie kluczy na jeden kurs, bez dorabiania.

mkdir -m 750 wspolny
ls -ld wspolny
drwxr-x--- 2 eryk eryk 4096 Nov  3 21:16 wspolny

mkdir -m ustawia uprawnienia od razu przy tworzeniu. Literami: rwxr-x---.

stat -c '%A %a %U %G %n' /etc/passwd /etc/shadow /usr/bin/passwd
-rw-r--r-- 644 root root /etc/passwd
-rw-r----- 640 root shadow /etc/shadow
-rwsr-xr-x 4755 root root /usr/bin/passwd

I jest: s zamiast x u właściciela, a w cyfrach nagle cztery cyfry, 4755. To nasz dzisiejszy bohater. Na RHEL /etc/shadow będzie miał w ogóle same kreski.

echo "127.0.0.1 kurs.local" | sudo tee -a /etc/hosts > /dev/null
tail -1 /etc/hosts
127.0.0.1 kurs.local

Jeśli ktoś zrobił to bez -a i w /etc/hosts została mu jedna linijka, to właśnie się nauczył, czemu admini robią kopię pliku przed edycją. Za darmo i na zawsze.

Co dalej

Litera z zadania to wstęp do następnej lekcji. Uprawnienia specjalne: SUID, dzięki któremu zwykły użytkownik może zmienić hasło w pliku, którego nie wolno mu czytać, SGID i sticky bit, które załatwią problemy Ani z folderem działu, ACL na wyjątki od reguł i plik, którego nie usunie nawet root.