# POSIX ACL - расширенные права доступа _Файловая система · LinuxLab Knowledge Base_ **TL;DR:** POSIX ACL расширяют классические rwx-права: можно дать доступ N пользователям/группам без перекраивания owner/group. setfacl пишет, getfacl читает. Default ACL на директории - наследуется детям. ## Зачем ACL Классические [[file-permissions|rwx]] позволяют задать права для **одного владельца, одной группы и всех остальных**. Когда нужно "Алисе read+write, Бобу read, всем остальным ничего" - три set'а не хватают. Решения: - Создать новую группу с Алисой и Бобом - но Бобу нужен только read; одной группой не выразить - Дать setgid + общий группа - всё равно одинаковые права в группе - **POSIX ACL** - точечно дать права отдельным user/group ACL - **расширение rwx**, не замена. Базовые owner/group/other остаются, ACL добавляются сверху. ## Где работает Поддерживается [ext4](/kb/ext4.md), [xfs](/kb/xfs.md), [btrfs](/kb/btrfs.md), tmpfs (с RAM>=ядро 6), zfs. Не работает на FAT/NTFS, на старом vfat. Mount с `acl` (на ext часто default), на xfs default включено. Проверить: ```bash mount | grep ' / ' # ищи acl в опциях (или просто отсутствие noacl) tune2fs -l /dev/sda1 | grep -i acl ``` ## getfacl - чтение ```bash $ getfacl /home/shared/report.pdf # file: home/shared/report.pdf # owner: alice # group: team user::rw- user:bob:r-- group::r-- group:auditors:r-- mask::r-- other::--- ``` Расшифровка: - `user::rw-` - права owner'а (alice) - `user:bob:r--` - **именованный** user; бит "r" - `group::r--` - права группы (team) - `group:auditors:r--` - **именованная** group - `mask::r--` - **верхний предел** для всех ACL-entry кроме owner и other - `other::---` - все остальные Если `ls -l` показывает `+` после прав: ``` -rw-r--r--+ 1 alice team 12K May 2 14:00 report.pdf ``` это значит "файл имеет ACL". ## setfacl - запись Базовый синтаксис: ```bash setfacl -m u:bob:r-- file setfacl -m u:bob:rwx,g:auditors:rx file setfacl -m u:bob:- file # явно "ничего" setfacl -x u:bob file # удалить ACL для bob setfacl -b file # сбросить все ACL (оставить базовые rwx) setfacl --restore=acl-backup.txt # из бэкапа ``` Опции: | Опция | Что | |-------|-----| | `-m` | modify - добавить/изменить | | `-x` | remove конкретные entry | | `-b` | сбросить все | | `-k` | удалить default ACL | | `-R` | recursive | | `-d` | работать с **default** ACL (не effective) | ### Целевая аудитория записи | Префикс | Кому | |---------|------| | `u:NAME` | конкретному пользователю | | `g:NAME` | конкретной группе | | `m::` | mask | | `o::` | other | | `u::` | owner (то же что `chmod u`) | | `g::` | owning group | ## Mask - верхний предел `mask` ограничивает **эффективные** права для всех именованных user/group и owning-group: ``` user::rw- user:bob:rwx ← объявлено rwx group::rwx mask::r-- ← но mask только r other::r-- ``` Bob эффективно может только `r--`. ls показывает `effective:r--` справа от entry. Это **не баг, а фича**: сделать `chmod g-w` и гарантировать, что никакой ACL не даст write. setfacl автоматически пересчитывает mask: ```bash setfacl -m u:bob:rwx file # mask станет rwx setfacl -n -m u:bob:rwx file # -n: НЕ пересчитывать mask ``` ## Default ACL - наследование Только на **директориях**. Default ACL применяется к **новым** файлам и поддиректориям внутри: ```bash setfacl -d -m u:bob:rx /home/shared setfacl -d -m g:team:rwx /home/shared ``` Теперь любой новый файл в `/home/shared` создастся с этими ACL плюс обычная uid/gid логика. Существующие файлы не затрагиваются. Это **главный сценарий** ACL в проде: shared-папка для команды, чтобы не возиться с umask, setgid и chown'ом каждый раз. Скопировать default в effective для всех существующих: ```bash getfacl --default /home/shared > acl.tpl setfacl --set-file=acl.tpl -R /home/shared ``` ## Полный пример: shared team-folder ```bash # Создать sudo mkdir /srv/team-share sudo chgrp team /srv/team-share sudo chmod g+s /srv/team-share # setgid - наследовать group # Default ACL: команда rwx, аудиторы только r sudo setfacl -d -m g:team:rwx /srv/team-share sudo setfacl -d -m g:auditors:rx /srv/team-share sudo setfacl -d -m o::- /srv/team-share # Существующие файлы тоже привести sudo setfacl -R -m g:team:rwx,g:auditors:rx,o::- /srv/team-share ``` Теперь любой член `team` может писать в любой файл, любой `auditor` может читать, "other" не видят ничего. ## ACL и cp / tar / rsync Не все утилиты переносят ACL по дефолту: - `cp` - **сохраняет** при `-p` (preserve mode includes ACL) - `tar` - нужен `--acls` (на старых GNU tar - `--acls` поддерживается с 1.27) - `rsync` - нужен `-A` (`--acls`); добавляет к стандартному `-a` - `find ... -exec cp` - помни про `-p` Backup'ы: ```bash getfacl -R /srv/team-share > acl-backup.txt # ... setfacl --restore=acl-backup.txt ``` ## ACL vs SELinux/AppArmor ACL - **DAC** (Discretionary Access Control): владелец решает. SELinux/AppArmor - **MAC**: политика системы поверх. Они не заменяют друг друга. Если SELinux запретил - ACL не помогут; если ACL запретили - SELinux не вернёт. Подробнее в [selinux-apparmor](/kb/selinux-apparmor.md) и [capabilities](/kb/capabilities.md). ## Когда что-то пошло не так - **`setfacl: Operation not supported`** - mount без `acl` (старый ext-mount), либо ФС не поддерживает (vfat, NFSv3 без acl). - **chmod "съел" ACL** - старая семантика: `chmod g+w` менял mask и ACL вместе с group-bit. На новых ядрах `chmod` чаще трогает только classical bits, но **mask может пересчитаться**. Smarter: `setfacl -m m::rwx`. - **Default ACL не наследуется на NFS** - старые NFS-клиенты не поддерживают ACL. NFSv4 ACL (другой стандарт!) тоже отдельная история. - **`tar` потерял ACL** - не было `--acls`. Используй `bsdtar` (libarchive) или `--acls --xattrs`. - **Видно `+` но getfacl пуст** - бывает при corrupted ACL-blob; `setfacl -b` и заново. ## Альтернативы - **NFSv4 ACL** - другой стандарт, более похож на Windows/Solaris - **Richacl** - устарело, не вошёл в mainline - **xattr** напрямую через [[extended-attributes|setfattr]] - ACL хранятся именно как xattr `system.posix_acl_*` ## Команды ```bash getfacl /srv/team-share ``` Показать ACL директории - первое что смотреть ```bash setfacl -m u:bob:rx,g:auditors:r-- file.txt ``` Назначить именованным user/group - типичный setfacl ```bash setfacl -d -m g:team:rwx /srv/team-share ``` Default ACL на директорию - наследуется новыми файлами ```bash setfacl -bR /srv/team-share ``` Сбросить все ACL рекурсивно - вернуться к чистым rwx ```bash getfacl -R /srv/team-share > acl-backup.txt ``` Бэкап ACL всего поддерева - перед миграцией ```bash rsync -aA --acls /src/ /dst/ ``` rsync с переносом ACL - без -A они потеряются ```bash ls -l file.txt | grep '+$' ``` Файл с ACL - наличие плюса в правах после rwx ## См. также - [File permissions: rwx и chmod](/kb/file-permissions.md) - [SUID, SGID, sticky bit - спецбиты прав](/kb/setuid-setgid-sticky.md) - [Extended attributes (xattr) - произвольные метаданные файла](/kb/extended-attributes.md) - [Inode](/kb/inode.md) - [Filesystem Hierarchy Standard (FHS)](/kb/fhs.md)