ACL: getfacl и setfacl
Права для отдельных пользователей и групп сверх rwx владельца/группы/остальных; маска и default ACL
Обычные права (chmod) знают только трёх субъектов: владельца, группу и остальных. ACL (access control list) добавляет к ним записи для конкретных пользователей и групп: «alice может читать и писать, группа devs — только читать». getfacl показывает ACL, setfacl меняет. Пакет acl; файловые системы ext4, xfs, btrfs, tmpfs поддерживают ACL по умолчанию.
Синтаксис
getfacl [опции] файл…
setfacl [опции] -m записи файл… # добавить или изменить
setfacl [опции] -x записи файл… # удалить
Формат записей
| Запись | Кому |
|---|---|
u:alice:rw | пользователю alice (u = user) |
g:devs:r | группе devs (g = group) |
u::rwx / g::r / o::- | владельцу / группе-владельцу / остальным (то же, что chmod) |
m::rw | маске — потолку прав для всех записей, кроме владельца и остальных |
d:u:alice:rwx | запись default ACL каталога (то же, что -d -m u:alice:rwx) |
Права пишут буквами rwx, - — нет права. X (заглавная) — x только для каталогов и файлов, у которых уже есть x у кого-нибудь. Несколько записей — через запятую: u:alice:rw,g:devs:r. Для -x права не указывают: -x u:alice.
Опции setfacl
| Опция | Что делает |
|---|---|
-m записи | добавить или изменить записи |
-x записи | удалить записи |
-b | удалить весь расширенный ACL, оставить обычные права |
-k | удалить только default ACL каталога |
-d | применять -m/-x к default ACL (наследуется новыми файлами) |
-R | рекурсивно по каталогу |
--set записи | заменить ACL целиком; нужны u::, g::, o:: |
-M файл / -X файл | взять записи для -m / -x из файла (- — stdin) |
--restore=файл | восстановить ACL из вывода getfacl -R |
-n | не пересчитывать маску |
--test | показать, что получится, ничего не меняя |
-L / -P | с -R: заходить / не заходить по символическим ссылкам |
Опции getfacl
| Опция | Что делает |
|---|---|
-c | без заголовка # file / # owner / # group |
-R | рекурсивно |
-a / -d | только access ACL / только default ACL |
-s | пропускать файлы без расширенного ACL — найти, где ACL вообще есть |
-n | числа вместо имён пользователей и групп |
-e / -E | показывать #effective у всех записей / не показывать никогда |
-p | не убирать начальный / из путей |
-t | табличный вывод |
Как читать вывод
# file: proj/f
# owner: root
# group: root
user::rw- ← владелец
user:alice:rw- #effective:r-- ← запись alice, но маска режет до r--
group::r-- ← группа-владелец
group:devs:r--
mask::r-- ← потолок для alice, group, devs
other::---
В ls -l файл с ACL помечен + после прав: -rw-rw----+. Средняя тройка прав в таком случае показывает маску, а не права группы.
Маска — максимальные права для именованных пользователей, групп и группы-владельца. Реальные права записи = права записи ∩ маска; если они меньше записанных, getfacl пишет #effective:. setfacl -m пересчитывает маску автоматически как объединение этих записей.
Default ACL бывает только у каталога. Он не влияет на сам каталог, а копируется в ACL каждого нового файла и подкаталога внутри (подкаталог получает его и как свой default — наследование идёт вниз).
Примеры
mkdir -p /srv/proj && echo data > /srv/proj/report.txt
# дать alice чтение и запись одного файла
setfacl -m u:alice:rw /srv/proj/report.txt
getfacl /srv/proj/report.txt
# группе devs — чтение всего каталога; X даёт вход в каталоги, но не делает файлы исполняемыми
setfacl -R -m g:devs:rX /srv/proj
# чтобы новые файлы тоже получали эти права — default ACL
setfacl -d -m g:devs:rX /srv/proj
setfacl -d -m u:alice:rwX /srv/proj
# убрать alice, убрать default ACL, убрать всё расширенное
setfacl -x u:alice /srv/proj/report.txt
setfacl -k /srv/proj
setfacl -R -b /srv/proj
# найти файлы с ACL
getfacl -R -s -p /srv 2>/dev/null | grep '^# file'
# сохранить и восстановить ACL дерева (восстанавливай из того же каталога)
cd /srv && getfacl -R proj > /tmp/proj.acl
cd /srv && setfacl --restore=/tmp/proj.acl
# скопировать ACL с одного файла на другой
getfacl file1 | setfacl --set-file=- file2
Подводные камни
chmodменяет маску. На файле с ACLchmod g-wилиchmod 600урезает маску, и у всех именованных записей появляется#effective:---. Записи остались, но не действуют. Верни маску:setfacl -m m::rw файл.- Без
xна каталогах доступа нет. Право на файл бесполезно, если пользователь не может войти в каталог: нужно хотя быxна каждом каталоге пути (setfacl -m u:alice:x /srv). - Default ACL не трогает существующие файлы. Для уже созданных нужен отдельный
setfacl -R -m …без-d. - Default ACL сильнее umask, но не сильнее режима создания: файл, созданный с
0644, получит маскуrw-, поэтомуrwxиз default ACL станет#effective:rw-. Так и должно быть: обычные файлы не делаются исполняемыми. cpбез-p/-aтеряет ACL — у копии не будет+.mvв пределах одной ФС сохраняет.tarсохраняет ACL только с--acls(и при упаковке, и при распаковке),rsync— с-A.- Несуществующий пользователь в записи даёт «Invalid argument near character 3» и код 2 — опечатка в имени, а не в синтаксисе.
getfacl -Rубирает начальный/из путей, поэтому--restoreприменяет пути относительно текущего каталога.