Kontrola privilegija — root, sudo i SUID

Na Linuxu postoji jedan nalog koji sme sve — root, sa UID-om 0. Kernel za njega ne proverava dozvole; one koje vidiš u ls -l za njega jednostavno ne važe.

Otud i celo pitanje kontrole privilegija: kako uraditi ono za šta ti trebaju root prava, a da pri tome ne radiš kao root ceo dan.

Zašto se ne radi kao root

Nije stvar navike nego posledica. Kao root:

  • Ne postoji ništa što te zaustavi. Greška u kucanju briše sistemske fajlove bez pitanja.
  • Svaki program koji pokreneš ima puna prava — uključujući i onaj koji si preuzeo sa interneta.
  • U logovima piše samo „root", pa se ne zna ko je šta uradio.

Klasičan primer razlike:

$ rm -rf /usr /lib/nesto
rm: cannot remove '/usr': Permission denied

Kao običan korisnik — bezopasna greška. Kao root — kraj sistema. Razmak na pogrešnom mestu je isti u oba slučaja; razlikuju se samo prava.

Zato je pravilo: radi kao običan korisnik, a prava podigni samo za onu komandu kojoj su stvarno potrebna.

Ko sam i šta smem

$ id
uid=1000(alen) gid=1000(alen) groups=1000(alen),27(sudo),4(adm)

Članstvo u grupi sudo (na Debian i Ubuntu sistemima) ili wheel (na Fedora i RHEL sistemima) je ono što ti daje pravo na podizanje privilegija. Detaljnije na stranici id.

Šta ti je konkretno dozvoljeno:

$ sudo -l
Matching Defaults entries for alen on server:
    env_reset, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

User alen may run the following commands on server:
    (ALL : ALL) ALL

Ovo je prva komanda koju pokreneš na nepoznatom sistemu — kaže ti tačno dokle sežu tvoja prava.

su i sudo

Dva pristupa istom problemu, sa važnom razlikom.

su Postaješ drugi korisnik. Traži njegovu lozinku. Ostaješ root dok ne kucaš exit.
sudo Izvršavaš jednu komandu sa tuđim pravima. Traži tvoju lozinku. Sve ostaje zabeleženo.

Razlika sa lozinkom je suštinska. Sa su svako ko treba root prava mora znati root lozinku — a lozinka koju zna petoro ljudi više nije tajna. Sa sudo root lozinka ne mora ni da postoji, a pristup se oduzima uklanjanjem iz grupe.

$ sudo systemctl restart nginx      # jedna komanda
$ sudo -i                           # cela sesija, ako baš treba

Detaljnije na stranicama su i sudo.

Zašto na modernim sistemima root nema lozinku

$ su -
Password:
su: Authentication failure

Na Ubuntu sistemima root nalog je zaključan i to je namerno — nema lozinke koju bi neko pogađao. Provera u /etc/shadow:

$ sudo grep "^root:" /etc/shadow
root:!:19856:0:99999:7:::

Uzvičnik umesto heša znači zaključan nalog. Prijava je moguća samo kroz sudo.

Fajl sudoers

Pravila stoje u /etc/sudoers i u fajlovima unutar /etc/sudoers.d/.

Nikada ih ne otvaraj običnim editorom. Greška u sintaksi znači da niko više ne može koristiti sudo — uključujući tebe. Za to postoji:

$ sudo visudo
$ sudo visudo -f /etc/sudoers.d/backup

Radi na privremenoj kopiji i proverava sintaksu pre snimanja:

>>> /etc/sudoers: syntax error near line 22 <<<
What now?

Kako se čita pravilo

alen    ALL=(ALL:ALL) ALL

Četiri dela: ko, na kojim mašinama, kao ko sme da izvršava, i šta.

Grupa se piše sa znakom procenta:

%sudo   ALL=(ALL:ALL) ALL

Ograničena prava

Ovde sudo pokazuje pravu vrednost — možeš dati tačno onoliko koliko treba:

# samo restart web servera, bez lozinke
marko   ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx

# operater sme da gleda logove, ali ništa drugo
%operateri  ALL=(ALL) /usr/bin/journalctl, /usr/bin/tail

# skripta za backup radi kao korisnik backup
jenkins ALL=(backup) NOPASSWD: /opt/skripte/backup.sh

Uvek koristi apsolutne putanje. Bez njih pravilo pogađa bilo šta tog imena u PATH-u.

Zamke pri ograničavanju

Pravilo koje izgleda usko ume da bude širom otvoreno:

marko   ALL=(ALL) NOPASSWD: /usr/bin/vi

Deluje bezopasno. Ali iz vi-ja se pokreće shell:

:!/bin/bash

I Marko je root. Isto važi za less, find, awk, tar, python i još desetak alata — svaki od njih ume da pokrene komandu.

Za izmenu fajlova postoji bezbedna varijanta:

marko   ALL=(ALL) sudoedit /etc/nginx/nginx.conf
$ sudo -e /etc/nginx/nginx.conf

Ovo kopira fajl, otvara ga tvojim editorom sa tvojim pravima, pa vrati izmene. Editor nikada ne radi kao root.

Druga česta zamka je džoker:

marko   ALL=(ALL) /bin/chown * /var/www

Zvezdica pogađa i argumente koje nisi predvideo. Pravila sa džokerima skoro uvek daju više nego što je nameravano.

Zasebni fajlovi umesto glavnog

$ sudo visudo -f /etc/sudoers.d/nadzor
%nadzor  ALL=(ALL) NOPASSWD: /usr/bin/systemctl status *

Isti razlog kao kod /etc/profile.d/: nadogradnja sistema ne dira tvoje fajlove, a pravilo se uklanja brisanjem jednog fajla. Ime bez tačke u sebi — fajlovi sa tačkom se ignorišu.

SUID, SGID i sticky bit

Druga strana kontrole privilegija: kako običan korisnik menja svoju lozinku, kad je /etc/shadow čitljiv samo rootu?

$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Mar 23  2026 /usr/bin/passwd

Slovo s umesto x na mestu vlasnika je SUID bit: program se izvršava sa pravima svog vlasnika, a ne onoga ko ga je pokrenuo. Dok passwd radi, radi kao root.

SUID (4000) Na fajlu: izvršava se sa pravima vlasnika. Vidi se kao s u prvoj trojci.
SGID (2000) Na fajlu: prava grupe. Na direktorijumu: novi fajlovi nasleđuju grupu direktorijuma.
Sticky (1000) Na direktorijumu: fajl sme obrisati samo njegov vlasnik. Vidi se kao t na kraju.
$ ls -ld /tmp
drwxrwxrwt 10 root root 4096 Aug 22 14:02 /tmp

Slovo t na kraju je razlog zašto u /tmp svi mogu da pišu, a niko ne može obrisati tuđe fajlove. Bez njega bi svako mogao obrisati sve — jer se za brisanje traže prava nad direktorijumom, a ne nad fajlom, kako je objašnjeno u lekciji Inode-ovi i linkovi.

Postavljanje

$ sudo chmod u+s program        # SUID
$ sudo chmod g+s direktorijum   # SGID
$ sudo chmod +t direktorijum    # sticky

$ sudo chmod 4755 program       # isto, brojčano
$ sudo chmod 2775 direktorijum
$ sudo chmod 1777 direktorijum

SGID na direktorijumu je najkorisniji od tri — svi fajlovi koje tim tamo napravi automatski pripadaju zajedničkoj grupi. Detaljno na stranici chmod g+s.

Veliko S umesto malog

$ ls -l program
-rwSr--r-- 1 root root 8192 Aug 22 14:10 program

Veliko S znači da je SUID postavljen, ali fajl nije izvršan — bit stoji uzalud. Popravka je chmod u+x.

SUID je i bezbednosni rizik

Svaki SUID program je potencijalni ulaz do root prava. Ako u njemu postoji propust, napadač ga koristi sa punim pravima.

Popis takvih fajlova na sistemu:

$ sudo find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/su
/usr/bin/mount
/usr/bin/chsh
/usr/bin/newgrp

Ovaj spisak vredi znati na svom serveru. Ako se u njemu pojavi nešto što ne prepoznaješ — naročito /bin/bash ili nešto u /tmp — to je ozbiljan znak upada:

-rwsr-xr-x 1 root root 1234376 Aug 22 03:14 /tmp/.sistem

Dve stvari koje treba znati:

  • SUID ne radi na shell skriptama — Linux ga tamo namerno ignoriše, jer bi bio prelak za zloupotrebu. Za skriptu kojoj trebaju prava koristi pravilo u sudoers.
  • Opcija nosuid pri montiranju isključuje SUID na celoj particiji. Standardna praksa za /tmp i prenosive medije.

Capabilities — sitnija podela prava

SUID daje sve ili ništa. Ali programu poput ping treba samo jedno pravo — otvaranje mrežnog soketa — a ne cela root prava.

$ getcap /usr/bin/ping
/usr/bin/ping cap_net_raw=ep

Zato moderni sistemi ping više ne isporučuju kao SUID. Dodela:

$ sudo setcap cap_net_bind_service=+ep /usr/bin/mojserver

Ovo dozvoljava vezivanje na port ispod 1024, bez ijednog drugog root prava. Pregled svih na sistemu:

$ sudo getcap -r / 2>/dev/null

Nivoi kontrole, po redosledu provere

Kad proces pokuša da pristupi fajlu, provera ide ovako:

  1. Da li je root? Ako jeste, prolazi (osim uz SELinux ili AppArmor).
  2. Klasične dozvole — rwx za vlasnika, grupu, ostale. Vidi Pregled prava pristupa.
  3. ACL — dodatna prava za pojedinačne korisnike, kad tri kategorije nisu dovoljne. Vidi Lista kontrole pristupa.
  4. SELinux ili AppArmor — poslednja reč. Mogu zabraniti i ono što je po dozvolama dozvoljeno, čak i rootu. Vidi SELinux.

Poslednja stavka objašnjava situacije u kojima su dozvole naizgled ispravne, a pristup i dalje odbijen. Kad ls -l kaže da bi trebalo da radi, a ne radi — proveri SELinux pre nego što nastaviš da menjaš chmod.

Praksa koja se isplati

Daj minimum prava

Ne ALL ako je dovoljna jedna komanda. Ne chmod 777 ako je dovoljno 775. Ne root ako je dovoljna grupa.

$ sudo chmod 775 /var/www/sajt
$ sudo chgrp www-data /var/www/sajt
$ sudo chmod g+s /var/www/sajt

Umesto 777, koje daje pravo pisanja svakome na sistemu.

Ostavi trag

$ sudo grep sudo /var/log/auth.log | tail -3
Aug 22 14:02:11 server sudo: alen : TTY=pts/0 ; PWD=/home/alen ;
    USER=root ; COMMAND=/bin/systemctl restart nginx

Svaka sudo komanda ostaje zabeležena. To je razlog više da se sudo -i koristi retko — u sesiji se beleži samo ulazak, ne i ono što je unutra rađeno. Ko se kada prijavljivao, gleda se komandama sa stranice who, w i last.

Proveri pre nego što restartuješ

$ sudo nginx -t
$ sudo sshd -t

Naročito kad menjaš nešto kroz šta si povezan.

Grupe umesto pojedinačnih pravila

$ sudo groupadd operateri
$ sudo usermod -aG operateri marko

Pravilo se piše jednom za grupu, a ljudi se dodaju i uklanjaju. Više na stranicama /etc/group i gpasswd.

Napomena: zaboravljeno -a u usermod briše sve ostale grupe korisnika. Uvek -aG, nikad samo -G.

Kratka referenca

  • id — ko sam i u kojim grupama · sudo -l — šta smem
  • sudo komanda — jedna komanda · sudo -i — cela sesija
  • sudo -e fajl — bezbedno uređivanje bez root editora
  • sudo visudo — jedini ispravan način izmene pravila
  • /etc/sudoers.d/ime — zasebna pravila, otporno na nadogradnje
  • chmod u+s SUID · g+s SGID · +t sticky
  • find / -perm -4000 -type f — popis SUID programa
  • getcap, setcap — sitnija prava umesto SUID
  • usermod -aG grupa korisnik — dodaj u grupu (sa -a!)

Vežba

  1. Utvrdi šta ti je sve dozvoljeno kroz sudo i u kojoj grupi je taj pristup definisan.
  2. Pronađi sve SUID programe na sistemu i objasni sebi zašto passwd mora biti među njima.
  3. Napravi direktorijum sa SGID bitom i grupom, pa proveri kojoj grupi pripada fajl napravljen u njemu.
  4. Napravi pravilo u /etc/sudoers.d/ koje jednom korisniku dozvoljava samo restart jednog servisa, bez lozinke. Testiraj ga.
  5. Objasni sebi zašto pravilo koje dozvoljava sudo find nije ograničenje, i pronađi bezbednu alternativu.

Peti zadatak je razlika između pravila koje izgleda usko i pravila koje to zaista jeste.


Podizanje prava je detaljno na stranicama su i sudo, dozvole nad fajlovima na stranicama Pregled prava pristupa i chmod, a podrazumevane dozvole novih fajlova na stranici umask.

Cela lekcija je deo vodiča Linux osnove.

Comments

Popular posts from this blog

Početak u Linuxu — šta je i zašto se uči

groupadd

Konverzija tipova podataka u Pythonu