I permessi Unix sembrano semplici: tre bit per l’utente proprietario, tre per il gruppo e tre per tutti gli altri. La difficoltà arriva quando iniziamo ad applicarli a directory, home, applicazioni e alberi di file reali. Un chmod -R 750 lanciato “per rendere tutto sicuro” può rompere eseguibili, rendere eseguibili file che non dovrebbero esserlo e modificare molto più di quanto avevamo intenzione di toccare.
La sicurezza dei permessi non consiste quindi nel trovare un numero magico, ma nel capire chi deve poter fare cosa su quale oggetto.
Owner, group e other
Ogni file e directory ha almeno un proprietario, un gruppo proprietario e i mode bit tradizionali per tre classi:
ls -l file.txt
-rw-r----- 1 alice amministrazione 12450 Sep 24 12:00 file.txt
Il primo carattere indica il tipo dell’oggetto. I nove successivi sono divisi in tre gruppi:
rw- r-- ---
| | |
| | +-- other
| +------ group
+---------- owner
In questo esempio Alice può leggere e modificare il file, i membri del gruppo amministrazione possono soltanto leggerlo e gli altri utenti non hanno alcun accesso.
r, w e x cambiano significato sulle directory
Questo è uno dei dettagli più importanti dell’intero modello Unix. Su un file:
rpermette di leggerne il contenuto;wpermette di modificarlo;xpermette di tentare l’esecuzione come programma/script.
Su una directory, invece:
rpermette di elencare i nomi contenuti;wpermette di creare, cancellare o rinominare entry nella directory, se combinato con i permessi necessari;xsignifica search/traverse: permette di attraversare la directory e raggiungere un nome conosciuto al suo interno.
È quindi possibile avere una directory attraversabile ma non elencabile, per esempio 711. E la possibilità di cancellare un file dipende principalmente dai permessi della directory che lo contiene, non dal bit w del file stesso.
Notazione simbolica e ottale
I tre bit vengono anche rappresentati con i valori 4, 2 e 1:
| Permesso | Valore |
|---|---|
| read | 4 |
| write | 2 |
| execute/search | 1 |
chmod 640 file.txt
# owner rw-, group r--, other ---
chmod u=rw,g=r,o= file.txt
La forma simbolica è spesso più leggibile quando vogliamo cambiare soltanto un aspetto:
chmod g+w documento.txt
chmod o-rwx documento.txt
chmod u+x script.sh
Auditare una home prima di modificarla
Prima di qualsiasi chmod o chown ricorsivo vediamo la situazione reale:
id alice
ls -ld /home/alice
stat /home/alice
namei -l /home/alice/.ssh/authorized_keys
find /home/alice -xdev ! -user alice -ls
find /home/alice -xdev -type f -perm -0002 -ls
find /home/alice -xdev -type d -perm -0002 -ls
namei -l è particolarmente utile perché mostra i permessi di ogni componente del percorso. Un file perfettamente protetto può essere comunque irraggiungibile se manca il bit di attraversamento su una directory padre, oppure troppo esposto se una directory intermedia ha permessi inattesi.
Home privata: 0700 o 0750?
Non esiste un valore universale per tutte le home. Su una workstation personale una home 0700 è una scelta semplice: soltanto il proprietario può attraversarla. In un server in cui un gruppo amministrativo o un servizio deve accedere ad alcune parti, 0750 può avere senso se il gruppo è scelto deliberatamente.
# Home privata
chmod 0700 /home/alice
# Verifica
ls -ld /home/alice
id alice
getent group "$(id -gn alice)"
Non assumiamo che “i gruppi utente iniziano da GID 1000”. Gli intervalli UID/GID sono configurabili e dipendono dalla distribuzione e dall’ambiente. Per sapere chi appartiene a un gruppo usiamo getent, non euristiche numeriche.
Perché non usare chmod -R 750 *
Il vecchio articolo proponeva:
chmod -R 750 *
Ha almeno tre problemi:
*non include normalmente i nomi che iniziano con punto, proprio dove si trovano molte configurazioni sensibili;- applica
xa tutti i file normali, trasformando documenti e configurazioni in file marcati eseguibili; - modifica indiscriminatamente sottodirectory che possono avere esigenze differenti.
Se dobbiamo davvero rendere privato un albero conosciuto, la forma simbolica con X è meno distruttiva:
chmod -R u+rwX,go-rwx /percorso/controllato
X aggiunge execute/search alle directory e ai file che erano già eseguibili, senza rendere eseguibile ogni file. Anche questo comando va usato soltanto dopo aver verificato che l’intero albero debba davvero avere la stessa policy.
chown -R: ancora più attenzione
Forzare ricorsivamente ownership su una home può rompere file volutamente appartenenti a root o a servizi. Prima cerchiamo le eccezioni:
find /home/alice -xdev ! -user alice -printf '%u:%g %m %p\n' | head -100
Solo se sappiamo che tutto l’albero deve davvero appartenere ad Alice possiamo valutare un chown -R. La sicurezza non migliora automaticamente rendendo l’utente proprietario di ogni file che trova nella propria home.
.ssh e chiavi autorizzate
Per una home usata via SSH prestiamo particolare attenzione alla directory delle chiavi:
chmod 700 /home/alice/.ssh
chmod 600 /home/alice/.ssh/authorized_keys
chown alice:alice /home/alice/.ssh
chown alice:alice /home/alice/.ssh/authorized_keys
OpenSSH, con le normali impostazioni di strict mode, rifiuta configurazioni che permettono a soggetti non autorizzati di alterare file critici per l’autenticazione. La guida completa è Hardening SSH.
Umask: decidere i permessi alla creazione
Correggere i permessi dopo aver creato ogni file è inefficiente. La umask stabilisce quali bit non devono essere concessi automaticamente durante la creazione.
umask
# sessione molto privata
umask 077
# owner completo, gruppo leggibile/attraversabile, niente agli altri
umask 027
La umask è una maschera di bit, non una semplice sottrazione decimale. Inoltre il programma che crea il file sceglie i permessi di base: la umask può toglierli, non concederne di nuovi che il programma non aveva richiesto.
Directory condivisa: gruppo + setgid
Se più utenti devono collaborare, rendere pubbliche le rispettive home non è una buona soluzione. Creiamo invece una directory dedicata e un gruppo.
groupadd progetto
usermod -aG progetto alice
usermod -aG progetto bob
install -d -o root -g progetto -m 2770 /srv/progetto
Il primo 2 è il bit setgid sulla directory. I nuovi oggetti tendono così a ereditare il gruppo della directory invece del gruppo primario dell’utente che li crea.
ls -ld /srv/progetto
# drwxrws--- root progetto ... /srv/progetto
ACL: quando owner/group/other non bastano
I tre blocchi tradizionali sono volutamente semplici. Se dobbiamo concedere accesso a un utente o gruppo specifico senza cambiare ownership, possiamo usare le POSIX ACL.
apt install acl
setfacl -m u:carlo:rx /srv/progetto
getfacl /srv/progetto
Le default ACL permettono di definire ciò che i nuovi oggetti erediteranno:
setfacl -d -m u::rwx,g::rwx,o::--- /srv/progetto
setfacl -d -m g:progetto:rwx /srv/progetto
getfacl /srv/progetto
Quando compaiono ACL nominali esiste anche una mask che limita i permessi effettivi di utenti e gruppi aggiuntivi. Se un’ACL “sembra giusta” ma l’accesso viene negato, getfacl ci mostra sia permessi dichiarati sia effettivi.
Sticky bit: il caso /tmp
Una directory condivisa scrivibile da tutti ha un problema: normalmente chi può scrivere nella directory può anche cancellare o rinominare entry altrui. Lo sticky bit limita questa possibilità.
ls -ld /tmp
# drwxrwxrwt ...
chmod 1777 /directory/condivisa-temporanea
Lo sticky bit non rende privati i file e non sostituisce i loro permessi: limita soprattutto cancellazione e rename nella directory condivisa.
Permessi Unix non significano controllo assoluto
I mode bit e le ACL sono il livello DAC, Discretionary Access Control. Processi privilegiati possono avere capacità che superano questi limiti e sistemi come SELinux o AppArmor aggiungono ulteriori controlli obbligatori. Anche namespace e container possono cambiare il contesto in cui UID e GID vengono interpretati.
Per questo “il file è 600” è un’informazione importante, ma non è da sola una dimostrazione completa della sua sicurezza.
Checklist per una home
id alice
ls -ld /home/alice
stat /home/alice
namei -l /home/alice/.ssh/authorized_keys
find /home/alice -xdev ! -user alice -ls
find /home/alice -xdev -perm -0002 -ls
getfacl /home/alice
umask
Prima leggiamo e capiamo la policy esistente; solo dopo usiamo chmod, chown o ACL. È molto meno spettacolare di un -R sparato su tutta la home, ma tende anche a produrre meno disastri.
Riferimenti
chmod(1) · acl(5) · setfacl(1).


