ACL

Материал из Etersoft wiki
Перейти к: навигация, поиск

Access Control Lists

В этой статье попробуем описать работу с ACL применительно к файлам в стандартных файловых системах (ext и т.п.), укажем основные нюансы при переходе от стандартных прав к расширенным и приведём конкретные примеры практического использования ACL.

Зачем оно нужно

Как известно «из коробки» нам доступен стандартный набор прав на файлы: «пользователь — группа — остальные» («user-group-others») плюс такие «бонусы» как SUID, SGID и Sticky биты. Подробнее об этом написано ТУТ (где ???). Возможности, предоставляемые стандартным набором прав, достаточно велики, чтобы потребовалось нечто большее, но бывают ситуации, когда нужно дать доступ отдельным пользователям (группам) на файлы, собственниками которых они не являются, либо, наоборот, сделать явный запрет не для всех.

Проверка на возможность работы с ACL

Вообще говоря, ACL должны поддерживаться файловой системой (раз) и сама файловая система должна быть смонтирована с поддержкой ACL.

Иначе изменять ACL правила будет невозможно, но имеющиеся все же применяться будут. Может быть, наоборот: изменять acl будет возможно, но применяться они не будут?

Монтировать нужно с параметром acl.

Проверим это командой:

 # mount
 ...
 /dev/sda on / type ext4 (rw,relatime,user_xattr,acl,barrier=1,data=ordered)
 ...

Кроме того нам необходим нехитрый инструментарий, который в ALTLinux содержится в пакете acl:

 # epmi acl

Так мы получим две команды: setfacl и getfacl

Расширенные права

Если рассмотреть файл с точки зрения расширенных прав, то теперь мы оперируем следующим:

  • владелец
  • другие отдельные пользователи (поименно)
  • группа владельца
  • отдельные группы (тоже списком)
  • остальные
  • mask (важное дополнение)

И помимо этого, только для каталогов, есть те же самые «структурные единицы», права которых будут применяться по-умолчанию для всех объектов, создаваемых в этом каталогов.

На каждого пользователя/группы и остальных действуют права по принципу rwx, аналогично стандартным (для файла — читать, изменять, выполнять; для каталога — листинг, изменение, доступ к содержимому).

Однако, те права, которые назначены группе пользователя, другим группам, а также пользователям, отличных от владельца, ещё и обрабатываются параметром mask. Таким образом, эффективное значение прав доступа для указанных групп (нетронутыми остаются только сам владелец и «остальные») является логическое «И» начального значения и маски.

Ликбез по getfacl

Посмотреть полные права файла или каталога:

 $ getfacl file
 $ getfacl dir
  • Полезный параметр: показывать номера uid/gid, вместо имен: -n
  • Если нужно показать права файлов в папке (обработать рекурсивно): -R
  • Остальные опции — см. man getfacl

Ликбез по setfacl

Каталоги обрабатываются как файлы.

  • Удалить все расширенные права ACL:
setfacl -b file
  • Удалить отдельные записи ACL:
setfacl -x u:mister,g:mister file
  • Изменить ACL записи:
пользователя setfacl -m u::rw chmod u=rw
именованного пользователя setfacl -m u:mister:rx
группы setfacl -m g:mister:r chmod g=r
именованной группы setfacl -m g:mister:x
остальным setfacl -m o:--- chmod o=
параметр mask setfacl -m m:r-x

Преобразование прав. Параметр mask

Если раньше маски у файла не было (не путать с параметром umask — он здесь ни при чём), то как он назначается? Дело в том, что, когда файлу дают дополнительные права, то происходит «преобразование» исходных прав до полного комплекта ACL. Пример:

$ touch file
$ ls -l file
-rw-r--r-- 1 guest guest 0 Янв 18 14:02 file
$ getfacl file
# file: file
# owner: guest
# group: guest
user::rw-
group::r--
other::r--

Даём пользователю mister права на чтение и запись файла file:
$ setfacl -n -m u:mister:rw- file
$ ls -l file
-rw-r--r--+ 1 guest guest 0 Янв 18 14:02 file
$ getfacl file
# file: file
# owner: guest
# group: guest
user::rw-
user:mister:rw-    #effective:r--
group::r--
mask::r--
other::r--

Проанализируем вывод:

  1. В выводе ls после списка прав появился знак "плюс", что указывает на неполноту информации - следует использовать getfacl для получения всей информации о правах.
  2. getfacl дает две новые строчки: mask::r-- и user:mister:rw- #effective:r-- Результат применения маски на те права, что мы дали mister'у очевиден, но откуда взялась сама маска ? Ответ: при расширении стандартных прав до полных ACL маска становится такой же, как права группы до модификации. В нашем случае, r--.
  3. Значение group также осталось неизменным, но это не обязательно, так как если файл создается в директории, на которую назначены права по-умолчанию, то применяться к файлу будут именно они. И еще одно правило: при работе с расширенными правами параметр umask силы не имеет, но mode действует: файлы (в отличие от директорий) создаются без права на исполнение.

Замечу, что параметр mask создается в том случае, когда задается хотя бы одна именованная запись (группа или пользователь). Соответственно, своя маска для прав файла и дефолтная - для директорий. Если же просто добавить неименованные default записи к стандартному файлу, mask тоже не создается. Воспользуемся этим:

$ mkdir dir
$ setfacl -m d:o:rwx dir
$ ls -ld dir
drwxr-xr-x+ 2 guest guest 4096 Янв 18 16:19 dir
$ getfacl dir
# file: dir
# owner: guest
# group: guest
user::rwx
group::r-x
other::r-x
default:user::rwx
default:group::r-x
default:other::rwx

$touch dir/file
$ls -l dir/file
-rw-r--rw- 1 guest guest 0 Янв 18 16:21 dir/file
$ mkdir dir/dir2
$ ls -ld dir/dir2
drwxr-xrwx+ 2 guest guest 4096 Янв 18 16:21 dir/dir2
$ getfacl dir/dir2
# file: dir/dir2
# owner: guest
# group: guest
user::rwx
group::r-x
other::rwx
default:user::rwx
default:group::r-x
default:other::rwx

Теперь мы видим:

  1. Маска нигде не создается. И ограничений от нее нет. (Иначе group превратилась бы в mask и "испортила" права.)
  2. Файлы создаются в "ACL-ной" директории обычные, а вот новые директории перенимают default права.
  3. Файлам не дается право запуска (mode ограничение).

Если же мы добавим права конкретного пользователя к директории:

$ setfacl -nm u:mister:rwx,d:u:mister:rwx dir
$ getfacl dir
# file: dir
# owner: guest
# group: guest
user::rwx
user:mister:rwx			#effective:r-x
group::r-x
mask::r-x
other::r-x
default:user::rwx
default:user:mister:rwx		#effective:r-x
default:group::r-x
default:mask::r-x
default:other::rwx

$ touch dir/file2
$ getfacl dir/file2
# file: dir/file2
# owner: guest
# group: guest
user::rw-
user:mister:rwx			#effective:r--
group::r-x			#effective:r--
mask::r--
other::rw-

$ mkdir dir/dir3
$ getfacl dir/dir3
# file: dir/dir3
# owner: guest
# group: guest
user::rwx
user:mister:rwx			#effective:r-x
group::r-x
mask::r-x
other::rwx
default:user::rwx
default:user:mister:rwx		#effective:r-x
default:group::r-x
default:mask::r-x
default:other::rwx

То тут же получим весь букет ограничений от маски для измененного файла/директории (но не вложенных !)

Отличие setfacl при (не)использовании опции -n

Теперь нужно покончить с маской, определив в чем особенность опции '-n' команды setfacl. Видимо, маска кому-то уже "мешалась под ногами", поэтому при применении команды setfacl по-умолчанию (т.е. без опции -n) происходит расширение маски до "минимально допустимого набора прав, при котором не ограничиваются все остальные". То есть mask дополняется настолько, чтобы effective права совпадали с предписанными.

$ getfacl dir/file2
# file: dir/file2
# owner: guest
# group: guest
user::rw-
user:mister:rwx			#effective:r--
group::r-x			#effective:r--
mask::r--
other::rw-

$ setfacl -m u::rw dir/file2 #Увы, надо хоть что-то модифицировать, чтобы показать скрытый эффект
$ getfacl dir/file2
# file: dir/file2
# owner: guest
# group: guest
user::rw-
user:mister:rwx
group::r-x
mask::rwx
other::rw-

Как видим, теперь маска "расширилась" до предела (из-за того, что user:mister требует всех прав). К сожалению, только явное использование команды setfacl скрыто меняет маску. Если мы копируем/перемещаем обычный файл в директорию, у которой есть именованные дефолтные пользователи или группы, то файл обязан будет получить параметр mask и, внимание, получит его не от параметра default:mask директории, а от своего значения для группы ! Посмотрим на примере:

$ setfacl -m m:rwx,d:m:rwx,g::rwx,d:g::rwx dir
$ getfacl dir
# file: dir
# owner: guest
# group: guest
user::rwx
user:mister:rwx
group::rwx
mask::rwx
other::r-x
default:user::rwx
default:user:mister:rwx
default:group::rwx
default:mask::rwx
default:other::rwx

$ touch ~/extfile   #Файл создан со стандартной umask 0022 
$ cp ~/extfile dir/
$ getfacl dir/extfile 
# file: dir/extfile
# owner: guest
# group: guest
user::rw-
user:mister:rwx			#effective:r--
group::rwx			#effective:r--
mask::r--
other::r--

Видно, что:

  1. Параметр group::rwx взят из default:group: родительского каталога (в отличие от остальных, где, например, запрет на запуск появился).
  2. Параметр mask взял значение из стандартного group и "задушил" права group и user:mister

Самым надежным способом избавиться от последствий маски считаю явное ее переопределение:

 $ setfacl -r m:rwx dir   # '-r' = recursive

Но метод плох, так как явно назначает маску и тем файлам, которые в этом не нуждаются (имеют только стандартные права)...

Вопросы на проверку

  • Если файл уже имеет ACL записи, то применение команды chmod 0600 "умножит на ноль" права группы владельца или уже маски ? Ответ остается в силе, если маска еще не задается (неименованные ACL записи только) ? Проверить при разном изменении прав: 0777, a+x, g-r и т.п.

Ответ: Если ACL права уже есть, то применение команды chmod 0600 действует не на группу, а на маску, если она задана! В примере ниже это явно видно:

$ touch file1
setfacl -nm u:user1:rwx,g:user1:rwx file1
setfacl -nm m:rwx file1 
$ getfacl file1

# file: file1
# owner: guest
# group: guest
user::rw-
user:user1:rwx
group::r--
group:user1:rwx
mask::rwx
other::r--

$ chmod 0700 file1
$ getfacl file1

# file: file1
# owner: guest
# group: guest
user::rwx
user:user1:rwx                  #effective:---
group::r--                      #effective:---
group:user1:rwx                 #effective:---
mask::---
other::---

Причем применение синтаксиса chmod g+rw file1 также изменит именно маску !

$ chmod g+rw file1
$ ls -l file1
-rwxrw----+ 1 guest guest    0 Июн  7 14:35 file1
$ getfacl file1
# file: file1
# owner: guest
# group: guest
user::rwx
user:user1:rwx                  #effective:rw-
group::r--
group:user1:rwx                 #effective:rw-
mask::rw-
other::---

Если маска еще не задана, то применение chmod меняет права группы, маска не появляется:

$ mkdir dir1
$ setfacl -nm d:o:rwx dir1
$ setfacl -nm d:g::rwx dir1
$ getfacl dir1

# file: dir1
# owner: guest
# group: guest
user::rwx
group::r-x
other::r-x
default:user::rwx
default:group::rwx
default:other::rwx

$ mkdir dir1/dir2
$  ls -ld dir1/dir2
drwxrwxrwx+ 2 guest guest 4096 Июн  7 14:50 dir1/dir2
$ getfacl  dir1/dir2
# file: dir1/dir2
# owner: guest
# group: guest
user::rwx
group::rwx
other::rwx
default:user::rwx
default:group::rwx
default:other::rwx

$ chmod 0700 dir1/dir2
$ getfacl  dir1/dir2
# file: dir1/dir2
# owner: guest
# group: guest
user::rwx
group::---
other::---
default:user::rwx
default:group::rwx
default:other::rwx

Вывод: утилита chmod меняет только биты атрибутов файлов, совершенно не понимая, что именно они означают: маска или группа.

  • Изменяет ли применение команд setfacl метку файлов mdate, другие (...)date ?

Ответ: при назначении прав через setfacl или при перемещении обычного файла в директорию с именными default ACL правами меняется только ctime (время последней смены атрибутов), getfacl - не меняет ничего. (Тесты выполнялись с применением утилиты stat.)

  • Как разруливается конфликт прав, если после смены владельца/группы имеется ACL запись, которая совпадает по имени пользователя/группы и имеет другой уровень прав ? Не применяется ли предписанный ACL уровень прав на права нового владельца при chown ?

Ответ: права, предписанные в полях owner и group сохраняются при chown и являются неукоснительными для владельца (именные ACL-записи игнорируются, даже если есть совпадение). В примере ниже файл не дает себя запустить новому владельцу несмотря на ACL-запись, а основные права не изменились совсем:

touch file
$ setfacl -nm u:user1:rwx,g:user1:-,m:rwx file
$ getfacl file
# file: file
# owner: guest
# group: guest
user::rw-
user:user1:rwx
group::r--
group:user1:---
mask::rwx
other::r--

$ sudo chown user1:user1 file

$ getfacl file
# file: file
# owner: user1
# group: user1
user::rw-
user:user1:rwx
group::r--
group:user1:---
mask::rwx
other::r--

Вывод: утилита chown понятия не имеет об ACL'ных правах, как и chmod.

  • Операция chmod -R a+rwx сделает все каталоги доступными, а файлы запускаемыми. Как обрабатываются файлы, если к ним применить дефолтные ACL права явно или рекурсией ? Будут ли сообщения об ошибках ?

Применение дефолтных прав возможно двумя видами записей: или setfacl -R -d -nm u:user1:rwx или setfacl -R d:u:user1:rwx . Последний вариант не выдает ошибок даже если явно и без рекурсии применить его к файлу, а не каталогу. Разумеется, никакие атрибуты фактически не изменятся:

$ mkdir -p dir1/dir2/dir3
$ touch dir1/dir2/dir3/file

$ setfacl -R -nm d:u:user1:rwx dir1

$ getfacl dir1/dir2/dir3
# file: dir1/dir2/dir3
# owner: guest
# group: guest
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:user1:rwx          #effective:r-x
default:group::r-x
default:mask::r-x
default:other::r-x

$ getfacl dir1/dir2/dir3/file 
# file: dir1/dir2/dir3/file
# owner: guest
# group: guest
user::rw-
group::r--
other::r--

Другой вариант тоже молча выполняет изменение прав директорий, ни слова не говоря о файле. Файл же остается нетронутым. Вывод - применение "дефолтных" прав к файлу молча подавляется, даже не расширяя базовый набор его прав до ACL'ных.


Ссылки