Diagrama permisiuni fisiere Linux cu comenzi chmod, chown si ACL
Linux

Permisiunile fisierelor in Linux: chmod, chown, umask si ACL

Mai devreme sau mai tarziu, oricine are un VPS da peste unul din doua mesaje: o pagina in browser care spune 403 Forbidden sau un terminal care raspunde sec Permission denied. Solutia pe care o gasesti recomandata peste tot pe internet e chmod -R 777 si, da, eroarea dispare, exact cum dispare si problema cu o yala blocata daca scoti usa din balamale. In ghidul asta iti explicam cum functioneaza de fapt permisiunile fisierelor in Linux, ca sa le poti citi dintr-o privire, sa le schimbi constient cu chmod si chown, sa controlezi valorile implicite cu umask si sa folosesti ACL-uri atunci cand modelul clasic proprietar, grup si restul lumii nu mai ajunge.

Tot ce urmeaza functioneaza pe un VPS proaspat cu Debian 13 sau Ubuntu 24.04, iar acolo unde cele doua distributii se comporta diferit, iti spunem explicit. Folosim nginx ca exemplu de server web, dar logica e aceeasi pentru Apache, Caddy, PHP-FPM, aplicatii Node.js si orice alt serviciu care ruleaza sub propriul utilizator.

De ce ai nevoie

  • Un server Linux cu Debian 13 sau Ubuntu 24.04. Cel mai mic VPS e mai mult decat suficient, permisiunile nu consuma nici RAM, nici CPU.
  • Acces SSH cu un utilizator normal care are drept de sudo. In exemple il numim deploy, inlocuieste-l cu numele tau.
  • Optional, pentru partea de server web: nginx instalat cu sudo apt install nginx si un site in /var/www.
  • Cam 30 de minute si un director de test pe care ai voie sa-l strici.

Hai sa facem directorul de test (il numim laboratorul) ca sa poti incerca fiecare comanda fara risc:

mkdir -p ~/perm-lab && cd ~/perm-lab
touch notes.txt script.sh
mkdir shared
ls -l

Primele trei comenzi nu afiseaza nimic; ls -l listeaza cele trei intrari noi. Decodam listarea imediat.

Ideea din spatele permisiunilor in Linux

Linux e un sistem multi-utilizator, chiar si pe un VPS unde esti singurul om. Orice program pornit, adica orice proces, ruleaza ca un anumit utilizator. Unii utilizatori sunt oameni (deploy, root), multi sunt conturi de serviciu care exista doar ca un program sa ruleze cu drepturi limitate: nginx si PHP-FPM ruleaza ca www-data, PostgreSQL ca postgres si asa mai departe. Un grup e pur si simplu o lista cu nume de utilizatori, care iti permite sa dai acelasi acces mai multor conturi deodata.

Vezi cine esti si din ce grupuri faci parte:

id
id www-data

Rezultat tipic:

uid=1000(deploy) gid=1000(deploy) groups=1000(deploy),27(sudo)
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Lista ta poate contine mai multe grupuri, e normal. www-data are acelasi UID 33 si pe Debian, si pe Ubuntu.

Fiecare fisier si director are exact un utilizator proprietar, un grup proprietar si un set de biti de mod. Cand un proces incearca sa deschida un fisier, kernel-ul pune trei intrebari, in ordine, si se opreste la primul “da”:

  1. Procesul ruleaza ca proprietarul fisierului? Atunci se aplica bitii de user.
  2. Procesul face parte din grupul fisierului? Atunci se aplica bitii de grup.
  3. Altfel, se aplica bitii pentru ceilalti (others).

Regula “primul care se potriveste castiga” are o consecinta amuzanta: daca un fisier are modul 047, proprietarul lui nu are niciun acces, desi toti ceilalti il pot citi. Rar in practica, dar arata ca clasele nu se aduna. Singura exceptie mare e root, care sare complet peste verificarile de citire si scriere.

Cum citesti permisiunile cu ls -l

Ruleaza din nou ls -l in laborator. Vei vedea ceva de genul:

total 4
-rw-r--r-- 1 deploy deploy    0 Nov 10 08:00 notes.txt
-rw-r--r-- 1 deploy deploy    0 Nov 10 08:00 script.sh
drwxr-xr-x 2 deploy deploy 4096 Nov 10 08:00 shared

Daca vezi -rw-rw-r-- si drwxrwxr-x, umask-ul tau e 0002 in loc de 0022, lucru frecvent pentru utilizatorii normali pe Ubuntu. Despre umask vorbim mai jos. Partea interesanta e prima coloana:

Anatomia unei linii ls -l-rwxr-x---deploywww-dataTipUser (u)Grup (g)Altii (o)Owner : grup- fisierd dir, l link4+2+1 = 74+0+1 = 50+0+0 = 0chmod 750 = rwxr-x---
Primul caracter e tipul, apoi trei grupuri de cate trei biti pentru user, grup si altii. Fiecare grup se aduna intr-o singura cifra octala.

Dupa caracterul de tip (- fisier, d director, l link simbolic) urmeaza noua caractere in trei grupuri: ce are voie sa faca user-ul (proprietarul), ce are voie grupul si ce au voie ceilalti (toata lumea in rest). O liniuta inseamna “permisiunea asta nu e acordata”. Apoi vin numarul de link-uri, proprietarul, grupul, dimensiunea, data si numele.

Daca preferi cifrele, stat iti arata ambele forme deodata:

stat -c '%A %a %U:%G %n' /etc/passwd /etc/shadow
-rw-r--r-- 644 root:root /etc/passwd
-rw-r----- 640 root:shadow /etc/shadow

E un exemplu real foarte bun: oricine poate citi lista de conturi, dar doar root si grupul shadow pot citi hash-urile parolelor.

Ce inseamna r, w si x pe fisiere si pe directoare

De aici vine cea mai mare parte din confuzie, pentru ca aceleasi litere inseamna altceva pe un director:

BitValoarePe un fisierPe un director
r4citesti continutullistezi numele din el (ls)
w2modifici continutulcreezi, stergi si redenumesti intrari (are nevoie si de x)
x1il rulezi ca programintri in el si ajungi la ce e inauntru (cd, deschidere dupa cale)

Trei consecinte de tinut minte:

  • Stergerea unui fisier depinde de director, nu de fisier. Daca ai w si x pe director, poti sterge un fisier read-only din el.
  • Un director fara x e o usa incuiata. Doar cu r vezi numele, dar nu poti deschide nimic.
  • Ca sa ajungi la /a/b/c/fisier, ai nevoie de x pe /, a, b si c. Regula asta explica majoritatea erorilor 403 de pe serverele web, cum vom vedea.

chmod: cum schimbi permisiunile fisierelor in Linux

chmod (change mode) schimba cei noua biti de permisiune. Noul mod il poti scrie cu cifre sau cu litere. Doar proprietarul fisierului (sau root) poate rula chmod pe el.

Notatia octala: matematica 4-2-1

Fiecare permisiune are o valoare: r = 4, w = 2, x = 1. Le aduni pentru fiecare clasa si obtii trei cifre: user, grup, altii. Deci 7 e rwx (4+2+1), 5 e r-x (4+1), 6 e rw- (4+2), iar 0 inseamna nimic.

cd ~/perm-lab
chmod 640 notes.txt
chmod 750 script.sh
chmod 750 shared
ls -l

Acum notes.txt arata -rw-r----- (proprietarul citeste si scrie, grupul citeste, restul nimic), iar script.sh arata -rwxr-x---. Notatia octala e perfecta cand vrei sa setezi tot modul dintr-o miscare.

Notatia simbolica: u, g, o cu +, - si =

Literele sunt mai bune cand vrei sa schimbi un singur bit si sa lasi restul neatins. Alegi cui (u user, g grup, o altii, a toti), un operator (+ adauga, - scoate, = seteaza exact) si permisiunile:

chmod u+x script.sh          # proprietarul il poate rula
chmod g-w notes.txt          # grupul nu mai poate scrie
chmod o= notes.txt           # ceilalti nu primesc nimic
chmod u=rw,g=r,o= notes.txt  # acelasi lucru ca 640, scris cu litere

Daca nu apare nimic, a mers. Verifica cu ls -l dupa fiecare daca vrei sa vezi efectul.

Schimbari recursive fara sa strici tot

Greseala clasica e chmod -R 644 director. Scoate x de pe toate subdirectoarele si, pentru ca x e cel care te lasa sa intri intr-un director, tot arborele devine inaccesibil. Exista doua variante sigure.

X mare inseamna “executie, dar doar pentru directoare si pentru fisierele care au deja un bit x undeva”:

chmod -R u=rwX,g=rX,o= ~/perm-lab

Sau tratezi separat directoarele si fisierele cu find, ceea ce folosim si pe serverele web:

find ~/perm-lab -type d -exec chmod 750 {} +
find ~/perm-lab -type f -exec chmod 640 {} +

-type d prinde directoarele, -type f fisierele obisnuite, iar {} + da multe cai unui singur apel chmod, deci merge repede si pe arbori mari.

Fituica cu modurile uzuale

ModLitereFolosire tipica
644rw-r–r–fisiere de config publice, fisiere statice pe un server cu un singur user
640rw-r—–fisiere citite doar de un grup (continut web cu grupul www-data)
600rw——-secrete: chei SSH, fisiere .env, chei TLS private
755rwxr-xr-xprograme si directoare publice
750rwxr-x—directoare pentru un proprietar si un grup
700rwx——directoare private precum ~/.ssh
2770rwxrws—director comun de grup, fisierele noi mostenesc grupul
1777rwxrwxrwt/tmp: toata lumea scrie, doar proprietarii sterg

chown si chgrp: cine detine un fisier

Bitii de permisiune au sens doar impreuna cu proprietarul si grupul, iar chown (change owner) le seteaza pe amandoua. Doar root poate da un fisier altui utilizator, deci ai nevoie de sudo:

sudo chown www-data notes.txt         # doar proprietar nou
sudo chown deploy:www-data notes.txt  # proprietar si grup
sudo chgrp www-data shared            # doar grupul
ls -l

Cateva detalii care economisesc timp:

  • chown deploy: fisier (doua puncte, nimic dupa) seteaza grupul la grupul principal al lui deploy.
  • sudo chown -R deploy:www-data /var/www/example.com schimba tot arborele. Implicit, -R nu urmeaza link-urile simbolice in alte locuri, exact ce vrei.
  • Poti schimba grupul unui fisier fara sudo doar daca esti proprietarul lui si faci parte din grupul tinta.

Cum adaugi un utilizator intr-un grup

Grupurile sunt modul prin care imparti accesul fara sa cedezi proprietatea. Ca sa-l adaugi pe deploy in grupul www-data:

sudo usermod -aG www-data deploy

-a (append) e esential: usermod -G www-data deploy fara -a inlocuieste toate grupurile secundare si iti poti pierde grupul sudo dintr-o singura apasare de tasta. Apartenenta la grupuri se citeste la login, asa ca iesi si intra din nou, apoi verifica cu id. Doar pentru shell-ul curent, newgrp www-data deschide un subshell cu noul grup activ.

Bitii speciali: setuid, setgid si sticky

In fata celor trei cifre obisnuite exista o a patra cifra octala, cu trei biti speciali:

  • setuid (4000): un program ruleaza cu drepturile proprietarului lui, nu ale celui care il porneste. Asa poate passwd (detinut de root) sa modifice /etc/shadow. Apare ca s pe pozitia de executie a user-ului.
  • setgid (2000) pe un director: fisierele noi create inauntru mostenesc grupul directorului, nu grupul principal al celui care le creeaza. E ingredientul secret al directoarelor comune si al structurii web de mai jos. Apare ca s pe pozitia de executie a grupului.
  • sticky (1000) pe un director: intr-un director in care toata lumea poate scrie, fiecare isi poate sterge doar propriile fisiere. Apare ca t la final.
ls -ld /tmp /usr/bin/passwd
chmod 2770 ~/perm-lab/shared
ls -ld ~/perm-lab/shared
drwxrwxrwt 10 root root  4096 Nov 10 08:00 /tmp
-rwsr-xr-x  1 root root 118168 Mar 20  2026 /usr/bin/passwd
drwxrws---  2 deploy deploy 4096 Nov 10 08:00 /home/deploy/perm-lab/shared

Dimensiunile si datele de pe serverul tau vor fi altele. Un S sau T mare inseamna ca bitul special e setat, dar lipseste x-ul corespunzator, de obicei o greseala. O ciudatenie GNU: chmod 750 pe un director nu sterge un bit setgid existent; foloseste chmod g-s director cand chiar vrei sa-l scoti.

umask: permisiunile implicite pentru fisierele noi

Cand un program creeaza un fisier, de obicei cere modul 666 (fisiere) sau 777 (directoare). umask-ul e o masca, per proces, cu bitii care se scot din cererea respectiva. Scoate biti, nu scade cifre: umask 022 transforma 666 in 644 si 777 in 755.

umask
umask -S
0022
u=rwx,g=rx,o=rx

Ce vezi depinde de distributie si de cont. Root primeste 0022 pe amandoua. Utilizatorii normali primesc des 0002 pe Ubuntu, din cauza regulii “user private groups” aplicate la login de pam_umask (fiecare user are propriul grup, deci e inofensiv ca acel grup sa poata scrie), in timp ce Debian da de obicei 0022. Nu ghici, ruleaza umask.

Fisier nouDirector nou0369Biti acordati (din 9)644755664775640750600700umask 022umask 002umask 027umask 077Valoare umask
Ce fac patru valori uzuale de umask cu fisierele si directoarele noi. Inaltimea barei numara cati din cei noua biti rwx sunt acordati; etichetele arata modul rezultat (calculat, nu masurat).

Ca sa-l schimbi pentru shell-ul curent, ruleaza umask 027. Ca sa ramana permanent pentru user-ul tau, adauga linia in ~/.bashrc (shell-uri interactive) sau ~/.profile (shell-uri de login). Valoarea implicita pe tot sistemul sta in UMASK din /etc/login.defs, aplicata la login de pam_umask.

Important: umask-ul se mosteneste de la procesul parinte la copil, deci setarea din shell-ul tau nu afecteaza serviciile pornite de systemd. Pentru un serviciu, il setezi intr-un fisier drop-in:

sudo systemctl edit myapp.service

Adauga liniile de mai jos in editorul care se deschide, salveaza, apoi ruleaza sudo systemctl restart myapp.service:

[Service]
UMask=0027

Cum repari 403 Forbidden si “permission denied” pe un server web

Acum partea practica. Intai, afla cine cere fisierele. nginx porneste un proces master ca root (are nevoie de root ca sa asculte pe porturile 80 si 443) si serveste cererile din procese worker care ruleaza ca www-data:

ps -o user,cmd -C nginx
USER     CMD
root     nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data nginx: worker process

La fiecare cerere, worker-ul deschide fisierul ca www-data. Kernel-ul verifica apoi fiecare director din cale pentru x si fisierul pentru r:

BrowserGET /index.htmlWorker nginxruleaza ca www-dataVerificare in kernelcate una pe fiecare nivel/varwwwexample.compublicindex.htmlx okx okx okfara x: 403neatinsnevoie de rwww-data are nevoie de x pe fiecare director din cale si de r pe fisier.Un singur bit lipsa oriunde in lant e suficient pentru un 403.
Cum e verificata o cerere pentru un fisier static. Aici directorul site-ului nu are bitul x pentru www-data, deci nginx nici nu ajunge la fisier.

O capcana foarte frecventa: site servit din directorul home. Debian 12 si versiunile mai noi creeaza directoarele home cu modul 0700, Ubuntu 21.04 si mai noi cu 0750, deci pe amandoua www-data nu poate traversa /home/deploy. Solutia curata e sa tii site-urile in /var/www. Daca chiar trebuie sa servesti din home, da doar drept de traversare (fara listare, fara citire) printr-un ACL, explicat mai jos: sudo setfacl -m u:www-data:x /home/deploy.

Iata procedura pe care o urmam la orice 403, in sase pasi:

Repararea unui 403: sase pasi123456Citeste logulParcurge caleaTest ca www-dataRepara ownerRepara modurileVerificaerror.lognamei -lsudo -u www-datachown -Rfind + chmodcurl -IPasii 1 la 3 diagnosticheaza, pasii 4 la 6 repara si confirma
Procedura pentru 403. Pasii 1 la 3 gasesc exact bitul lipsa, pasii 4 la 6 repara proprietarul si modurile si confirma rezultatul. Fiecare pas are titlul lui mai jos.

Pasul 1: Citeste logul de erori

Nu ghici, logul iti spune exact ce a esuat:

sudo tail -n 20 /var/log/nginx/error.log

Liniile care conteaza arata asa:

open() "/var/www/example.com/public/index.html" failed (13: Permission denied)
"/var/www/example.com/public/index.html" is forbidden (13: Permission denied)

(13: Permission denied) inseamna o problema de permisiuni pe sistemul de fisiere, treci la pasul 2. Doua mesaje seamana, dar nu sunt probleme de permisiuni:

  • directory index of "/var/www/example.com/public/" is forbidden inseamna ca lipseste index.html (sau index.php) si listarea directorului e oprita. Adauga fisierul sau corecteaza directiva index.
  • connect() to unix:/run/php/php8.4-fpm.sock failed (13: Permission denied) e o problema de socket PHP-FPM, tratata la depanare mai jos.

Pe Apache logul e /var/log/apache2/error.log, iar mesajul tipic e AH00035: access to / denied ... because search permissions are missing on a component of the path, adica exact cazul “lipseste x pe un director”.

Pasul 2: Parcurge calea cu namei

namei -l (din util-linux, instalat pe ambele distributii) afiseaza permisiunile fiecarei componente dintr-o cale, adica exact ce verifica si kernel-ul:

namei -l /var/www/example.com/public/index.html
f: /var/www/example.com/public/index.html
drwxr-xr-x root   root   /
drwxr-xr-x root   root   var
drwxr-xr-x root   root   www
drwx------ deploy deploy example.com
drwxr-xr-x deploy deploy public
-rw------- deploy deploy index.html

Citeste de sus in jos, punandu-te in pielea lui www-data. /, var si www dau x celorlalti, totul bine. example.com e drwx------: www-data nu e nici proprietar, nici in grupul deploy, iar ceilalti nu primesc nimic. Acolo e 403-ul. Si chiar daca trecem de el, index.html are 600, deci ar pica din nou. Doua probleme, ambele acum la vedere.

Pasul 3: Testeaza ca utilizatorul serverului web

Confirma diagnosticul intreband direct kernel-ul, ca www-data:

sudo -u www-data test -r /var/www/example.com/public/index.html && echo "readable" || echo "NOT readable"
sudo -u www-data ls /var/www/example.com/public/

Inainte de reparatie primesti NOT readable si ls: cannot access '/var/www/example.com/public/': Permission denied. www-data nu are shell de login, dar sudo -u ruleaza comanda direct, deci merge. Acelasi truc functioneaza pentru orice user de serviciu: postgres, user-ul aplicatiei tale si asa mai departe.

Pasul 4: Repara proprietarul

Structura pe care o recomandam: user-ul de deploy detine codul (ca sa poti edita, face git pull sau rsync fara sudo), grupul e www-data (ca serverul web sa poata citi), iar ceilalti nu primesc nimic:

sudo chown -R deploy:www-data /var/www/example.com

Observa ce nu facem: nu il facem pe www-data proprietar. Daca serverul web ar detine codul, orice vulnerabilitate dintr-un script PHP ti-ar putea rescrie tot site-ul.

Pasul 5: Repara modurile pentru directoare si fisiere

Directoarele primesc 2750 (proprietarul tot, grupul intra si listeaza, setgid ca fisierele noi sa ramana cu grupul www-data), fisierele primesc 640 (proprietarul citeste si scrie, grupul citeste):

sudo find /var/www/example.com -type d -exec chmod 2750 {} +
sudo find /var/www/example.com -type f -exec chmod 640 {} +

Daca aplicatia trebuie sa scrie undeva (upload-uri, cache, sesiuni), deschide pentru grup doar acel director:

sudo chmod 2770 /var/www/example.com/public/uploads

Fisierele create acolo de PHP-FPM vor fi detinute de www-data, cu grupul www-data datorita setgid. User-ul deploy le poate sterge in continuare (detine directorul), dar nu le poate edita; sectiunea despre ACL arata cum rezolvi si asta. Daca folosesti o aplicatie care isi actualizeaza singura codul din interfata web, ea are nevoie de drept de scriere pe cod, un compromis de securitate pe care il faci constient; multi prefera sa faca update-urile din linia de comanda.

Pasul 6: Verifica

Permisiunile se verifica la fiecare cerere, deci nginx nu are nevoie de reload pentru reparatia asta (doar daca i-ai schimbat si configuratia, caz in care rulezi sudo nginx -t && sudo systemctl reload nginx). Testeaza ca user, apoi ca un client:

namei -l /var/www/example.com/public/index.html
sudo -u www-data test -r /var/www/example.com/public/index.html && echo "readable"
curl -I -H "Host: example.com" http://127.0.0.1/

namei ar trebui sa arate acum drwxr-s--- cu grupul www-data pe directoarele site-ului si -rw-r----- pe fisier, testul afiseaza readable, iar curl raspunde cu HTTP/1.1 200 OK.

ACL: cand permisiunile clasice nu mai ajung

Modelul clasic are o limita clara: un singur proprietar si un singur grup per fisier. Mai devreme sau mai tarziu ai nevoie de “deploy il detine, www-data il citeste si alice, al doilea developer, il poate edita” sau de “user-ul de backup poate citi arborele asta, nimic mai mult”. Daca schimbi grupul, strici serverul web; daca o pui pe alice in www-data, ii dai acces la toate site-urile de pe server. Access Control Lists (ACL) rezolva problema atasand intrari suplimentare, per user si per grup, peste bitii normali.

Instalarea uneltelor ACL

sudo apt install acl

Imaginile de Ubuntu server au de obicei deja pachetul acl, instalarile minimale de Debian uneori nu; comanda e inofensiva in ambele cazuri. Sistemele de fisiere pe care le intalnesti pe un VPS (ext4, XFS, Btrfs) suporta ACL din cutie, fara optiuni speciale la montare.

Cum citesti si setezi ACL-uri

Da-i lui alice drept de citire si scriere pe tot site-ul, plus x pe directoare (din nou X mare):

sudo setfacl -R -m u:alice:rwX /var/www/example.com
getfacl /var/www/example.com/public/index.html
# file: var/www/example.com/public/index.html
# owner: deploy
# group: www-data
user::rw-
user:alice:rw-
group::r--
mask::rw-
other::---

-m inseamna modify (adauga sau actualizeaza intrari), u:alice:rwX e intrarea, g:nume:... ar fi un grup. Bitii normali de proprietar, grup si altii sunt tot acolo, ca user::, group:: si other::. In ls -l, fisierul arata acum un + la final, -rw-rw----+, semnul ca e cazul sa rulezi getfacl. Acelasi mecanism rezolva si cazul cu directorul home de mai sus, sudo setfacl -m u:www-data:x /home/deploy, care il lasa pe nginx sa treaca fara sa listeze sau sa citeasca ceva de acolo.

ACL implicite: fisierele noi mostenesc accesul

Comanda de mai sus a atins doar fisierele care exista azi. Un fisier creat maine nu va avea intrarea lui alice. ACL-urile implicite (default), setate pe directoare, sunt sabloane pe care fisierele si subdirectoarele noi le mostenesc:

sudo setfacl -R -m u:alice:rwX,d:u:alice:rwX /var/www/example.com
getfacl /var/www/example.com/public
# file: var/www/example.com/public
# owner: deploy
# group: www-data
# flags: -s-
user::rwx
user:alice:rwx
group::r-x
mask::rwx
other::---
default:user::rwx
default:user:alice:rwx
default:group::r-x
default:mask::rwx
default:other::---

Prefixul d: face dintr-o intrare una implicita; cu -R, setfacl aplica intrarile implicite doar pe directoare. Retine ca atunci cand un director are ACL implicit, umask-ul e ignorat pentru fisierele noi din el, decid intrarile implicite.

Acelasi truc rezolva si problema cu upload-urile de la pasul 5, ca deploy sa poata edita fisierele create de PHP:

sudo setfacl -R -m u:deploy:rwX,d:u:deploy:rwX /var/www/example.com/public/uploads

Capcana mastii ACL

Linia mask:: e maximul pe care il poate primi orice intrare de user sau grup cu nume. Capcana: odata ce un fisier are ACL, chmod pe bitii de grup schimba masca, nu intrarea grupului. Uite:

sudo chmod 640 /var/www/example.com/public/index.html
getfacl /var/www/example.com/public/index.html
user::rw-
user:alice:rw-          #effective:r--
group::r--
mask::r--
other::---

Intrarea lui alice inca spune rw-, dar masca a taiat-o la r--. De asta, daca rulezi din nou find ... chmod 640 de la pasul 5 pe un arbore cu ACL, ii iei pe tacute dreptul de scriere. Regula practica: rulezi intai comenzile chmod, apoi comenzile setfacl, care recalculeaza masca. Ca sa repari doar masca: sudo setfacl -m m::rw fisier.

Backup, copiere si stergere de ACL-uri

getfacl -R -p /var/www/example.com > ~/example-acl.txt
sudo setfacl --restore="$HOME/example-acl.txt"

Prima comanda salveaza toate ACL-urile cu cai absolute (ruleaz-o cu sudo daca unele directoare nu iti sunt accesibile), a doua le restaureaza. Pentru stergere: sudo setfacl -x u:alice fisier scoate o intrare, sudo setfacl -R -k director scoate ACL-urile implicite, sudo setfacl -R -b director scoate toate ACL-urile si lasa doar bitii clasici.

Uneltele de copiere trebuie rugate sa pastreze ACL-urile: cp -a le pastreaza, rsync are nevoie de -A (rsync -aAX), iar tar de --acls si la creare, si la extragere:

sudo tar --acls -cpzf ~/site-backup.tar.gz -C /var/www example.com
sudo chown "$USER": ~/site-backup.tar.gz

chown-ul conteaza: o arhiva creata cu sudo e detinuta de root, iar tu vrei s-o poti copia de pe server ca user normal. Restaurezi cu sudo tar --acls -xpzf ~/site-backup.tar.gz -C /var/www.

Depanare si greseli frecvente

  • “Am dat chmod 777 si acum merge.” Merge pentru ca acum orice user si orice proces de pe server pot modifica fisierele, inclusiv un script PHP compromis. Repara cu pasii 4 si 5.
  • Dupa chmod -R 644 a disparut site-ul. Directoarele au pierdut x. Ruleaza din nou cele doua comenzi find de la pasul 5.
  • usermod -G mi-a luat accesul sudo. Ai uitat -a. Intra ca root din consola oferita de provider si adauga grupurile inapoi cu usermod -aG sudo deploy.
  • M-am adaugat intr-un grup si nu s-a schimbat nimic. Lista de grupuri se citeste la login. Iesi si intra din nou sau foloseste newgrp, apoi verifica cu id.
  • ./script.sh: Permission denied. Fisierului ii lipseste x (chmod u+x script.sh) sau se afla pe un sistem de fisiere montat cu noexec. Verifica cu findmnt -T ./script.sh -o TARGET,OPTIONS; bash script.sh il ruleaza oricum, pentru ca atunci bash trebuie doar sa-l citeasca.
  • sudo echo "x" > /etc/fisier da permission denied. Redirectarea o face shell-ul tau, nu sudo. Foloseste echo "x" | sudo tee /etc/fisier > /dev/null.
  • Paginile PHP dau 502 si in log apare eroarea de socket. Socket-ul PHP-FPM e /run/php/php8.4-fpm.sock pe Debian 13 si /run/php/php8.3-fpm.sock pe Ubuntu 24.04 (serviciile se numesc php8.4-fpm si php8.3-fpm). Verifica listen.owner, listen.group si listen.mode in /etc/php/<versiune>/fpm/pool.d/www.conf; valorile implicite (www-data, www-data, 0660) se potrivesc cu nginx. Reporneste PHP-FPM dupa modificari.
  • Un container Docker nu poate scrie intr-un bind mount. In container, aplicatia ruleaza cu un UID numeric care poate diferi de al tau; numele nu conteaza, cifrele da. Afla-l cu docker compose exec app id si ruleaza sudo chown -R <uid>:<gid> ./data pe host.
  • Fisierele apar ca nobody:nogroup, iar chown da “Operation not permitted” chiar si ca root. Probabil esti intr-un container LXC unprivileged, unde root-ul din interior e mapat pe un user neprivilegiat pe host. Fisierele dintr-un bind mount de pe host detinute de UID-uri nemapate nu pot fi schimbate din interior; proprietarul se repara pe host. chmod, chown si ACL-urile pe sistemul de fisiere propriu al containerului functioneaza normal.
  • Modurile sunt corecte, accesul e tot refuzat. Atat Debian, cat si Ubuntu activeaza AppArmor implicit. Daca un program are profil AppArmor, acesta poate bloca cai din afara profilului indiferent de biti. Cauta apparmor="DENIED" cu sudo journalctl -k | grep -i apparmor.
  • Bitii de grup din ls -l par gresiti pe un fisier cu +. Coloana aceea arata masca ACL, nu intrarea grupului. Ai incredere in getfacl.

Note de securitate

  • Privilegii minime, implicit. Serverul web trebuie sa citeasca codul, nu sa-l scrie. Da drept de scriere doar directoarelor care chiar au nevoie.
  • Fara 777, fara 666. Cauta din cand in cand fisiere pe care oricine le poate scrie: sudo find / -xdev -type f -perm -0002 -ls 2>/dev/null. Pe un server sanatos lista e scurta sau goala.
  • Stii ce binare setuid ai. sudo find / -xdev -type f -perm -4000 -ls 2>/dev/null listeaza programele care ruleaza cu drepturile proprietarului. Orice surpriza de acolo merita investigata.
  • Secretele au 600 (sau 640 cu un grup dedicat). Fisiere .env, parole de baza de date, chei private. chmod 600 .env dureaza o secunda.
  • SSH e strict intentionat. Cu setarea implicita StrictModes yes, sshd iti ignora cheile daca home-ul, ~/.ssh sau authorized_keys pot fi scrise de altii. Foloseste chmod 700 ~/.ssh si chmod 600 ~/.ssh/authorized_keys.
  • ACL-uri inguste in loc de grupuri largi. O intrare ACL pentru un user pe un arbore e mai sigura decat sa pui acel user intr-un grup care deschide multi arbori.
  • Pastreaza o evidenta. Salveaza iesirea getfacl -R -p inainte de schimbari mari, ca sa poti reveni.

Deci, ce retii din toate astea?

Permisiunile fisierelor in Linux nu mai sperie din momentul in care le vezi asa cum le vede kernel-ul: cine cere, in care din cele trei clase intra si daca fiecare director de pe drum are x-ul lui. Cu ls -l, stat si namei poti citi orice situatie, cu chmod si chown o repari precis, umask-ul tine fisierele noi in limite sanatoase, iar ACL-urile acopera cazurile in care un proprietar si un grup nu ajung. Data viitoare cand apare un 403, sari peste 777 si parcurge cei sase pasi.

Vrei un loc unde sa exersezi? Porneste un VPS la noi in cateva minute si strica permisiuni fara grija. Daca preferi ca altcineva sa-ti proiecteze o structura curata de useri, grupuri si permisiuni pentru site-uri, echipa noastra de administrare servere face exact asta in fiecare zi.

Intrebari frecvente

Care e diferenta dintre chmod 755 si 644?

755 (rwxr-xr-x) adauga bitul de executie pentru toti, care pe un director inseamna “poti intra in el”. 644 (rw-r--r--) nu are bit de executie. Foloseste moduri de tip 755 pentru directoare si programe si moduri de tip 644 pentru fisiere obisnuite. Pe un server web cu grupul www-data, variantele mai stricte 750 si 640 sunt si mai bune.

E vreodata in regula chmod 777?

Practic niciodata pe un server. Singurul loc unde e normal ca oricine sa poata scrie sunt directoarele temporare comune precum /tmp, iar acelea au si bitul sticky (1777), ca userii sa nu-si poata sterge fisierele unii altora. In rest, repara proprietarul si grupurile.

De ce site-ul meu da tot 403 dupa ce am schimbat permisiunile?

Uita-te din nou in logul de erori. Fie alt director din cale tot nu are x (ruleaza namei -l), fie mesajul e de fapt “directory index is forbidden” (lipseste fisierul index), fie accesul e blocat de altceva decat modurile fisierelor, cum ar fi o regula deny in nginx sau un profil AppArmor.

ACL-urile functioneaza pe orice sistem de fisiere?

Pe sistemele de fisiere uzuale din Linux (ext4, XFS, Btrfs) da, implicit. Unele sisteme de fisiere de retea sau straine, precum FAT sau anumite configuratii NFS, nu suporta ACL POSIX. Daca setfacl raspunde cu “Operation not supported”, sistemul de fisiere e cauza.

Avem Incredere & Suntem Membri

Suntem membri ai principalelor organizatii de infrastructura internet.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX