СЕРГЕЙ ЯРЕМЧУК, фрилансер. Автор более 800 статей и шести книг. С «СА» с первого номера. Интересы: сетевые технологии, защита информации, свободные ОС
Расширяем права доступа в Linux с помощью ACL
Одноуровневой модели прав доступа пользователей, которая применяется в Linux и во всех UNIX-подобных операционных системах, на сегодняшний день явно недостаточно. Вам придётся очень постараться, чтобы правильно распределить права доступа к объекту. Списки контроля доступа позволяют более гибко решить эту задачу.
Девять бит плюс три специальных бита позволяют определить права доступа к файлу (чтение, запись, исполнение) только для трех класов пользователей – владелец, группа и остальные. Такой механизм в большинстве случаев не пригоден для решения даже относительно простых задач. Чтобы определить доступ к какому-нибудь документу или ресурсу, пользователя обычно включают в определенную группу. Все, кто входит в эту группу, имеют одинаковые права, т.е. используется принцип «всё или ничего». Списки контроля доступа ACL (Access Control Lists) позволяют установить права доступа к файлам не только для владельца и группы, но и индивидуально для любого другого пользователя или группы, без каких-либо ограничений по количеству устанавливаемых пользователей/групп.
Кроме того, технология ACL может использоваться, например, для доступа к SUID-файлам, определяя пользователей, которым действительно необходим запуск таких файлов. Операционные системы Windows на ядре NT и Novell Netware изначально поддерживают более гибкий механизм доступа к файлу. В мир Linux эта технология пришла относительно недавно (в ядре поддержка ACL появилась с версии 2.5, хотя патчи были доступны еще с версий 2.2.12), и сейчас она реализована для основных файловых систем ext2, ext3, XFS, ReiserFS, JFS и NFS. В настоящее время известны две разработки, реализующие списки контроля доступа для Linux, о которых сегодня и поговорим.
Проект Linux Extended Attributes and ACLs
Этот проект [1] предоставляет патчи к ядрам версий 2.4 (ext2, ext3, nfs) и 2.6 (nfs), реализующие расширенные атрибуты (EA – Extended Attributes) и POSIX ACL, а также библиотеки и инструменты для работы с ними.
Напомню, что ядра версии 2.6 уже поддерживают ACL для ext2, ext3, jfs и xfs, поэтому необходимости в использовании патча для этих файловых систем нет, хотя на сайте можно получить ссылки на все текущие исправления. Для ядра 2.4 доступен комбинированный патч, включающий все необходимые компоненты (ea+acl+nfsacl+sec), либо можно устанавливать каждый патч отдельно. Для включения ACL при конфигурировании ядра необходимо в «File System» активировать пункт «Extended Attributes» и затем «POSIX Access Control Lists» выбранной файловой системы (см. рис. 1).
Рисунок 1. Для включения POSIX ACL необходимо отметить при конфигурировании ядра соответствующие пункты
Для тех, кто редактирует конфигурационный файл вручную, список параметров выглядит так:
# grep 'XATTR\|POSIX_ACL' /usr/src/linux/.config
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_POSIX_ACL=y
# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS_XATTR is not set
# CONFIG_CIFS_XATTR is not set
После того как ядро перекомпилировано, можно приступать к работе.
Работа Linux ACLs базируется на использовании EA для хранения данных о правах пользователей и групп на файлы. Расширенные атрибуты представляют собой произвольные пары имя/значение, которые навсегда привязаны к определенному inode (файлу, каталогу, устройству и пр.), подобно тому как строка запуска связана с процессом. EA могут быть использованы для загрузки системных объектов, обеспечивающих, например, дополнительные характеристики безопасности, ACL или объектов пользователя, а также типа MIME, кодировки и прочего. Подробности смотрите в man attr(5).
Пользователи ALTLinux могут получить необходимые утилиты, использовав apt-get.
# apt-get install acl attr
Мне неизвестно другое применение EA, кроме ACL (ну разве метки каталогу присваивать), поэтому перейдем непосредственно к теме статьи.
Для создания EA используется утилита setfattr, получить информацию об EA можно, использовав getfattr из комплекта сoreutils (ранее fileutils). Но перед тем как начать работать, необходимо перемонтировать дисковый раздел, добавив опцию acl и/или user_xattr (по умолчанию раздел монтируется с опциями noacl и nouser_xattr.).
# mount /home -o remount,acl
Соответственно, для того чтобы использовать ACL при загрузке, запись в /etc/fstab будет выглядеть приблизительно так:
/dev/hda5 /home reiserfs defaults,acl 1 1
Переходим в смонтированный раздел, создаем каталог и устанавливаем право на чтение/запись пользователю sergej и группе sales на чтение/запись/выполнение (напомню, выполнение для каталога означает получение списка файлов). Опция -m (--modify) означает модификацию разрешений. В случае если нужно сразу установить несколько разрешений, то перечисляем их через запятую.
# mkdir test_acl
# setfacl -dm user:sergej:rw,group:sales:rwx test_acl
Смотрим, что получилось.
# getfacl test_acl
# file: test_acl
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:sergej:rw-
default:group::r-x
default:group: sales: rwx
default:mask::rwx
default:other::r-x
|
В результате получим информацию о пользователе-владельце и группе-владельце. Строки user, group и other являются базовыми данными и соответствуют стандартным правам доступа. Аналогичные строки, начинающиеся с default, соответствуют значению по умолчанию ACL для каталога (указываются с помощью опции -d), при создании нового подкаталога или файла внутри этого каталога этот параметр наследуется. Естественно, файлы не могут иметь по умолчанию ACL, только каталоги, поэтому такая команда будет завершена с ошибкой.
# setfacl -dm u:sergej:rw test_file
setfacl: test_file: Only directories can have default ACLs |
Строка default:mask показывает маску эффективных прав, которую не могут превысить пользователь или группа. Используя маску, можно задать общие права для всех пользователей и групп, например:
#setfacl -m m::rx file
Как видите, для пользователя sergej и группы sales установлены отличные от всех остальных права. При этом, если вы попытаетесь установить параметры для несуществующего пользователя или группы, утилита завершит выполнение с ошибкой.
Кстати, установить новые разрешения в файловой системе, смонтированной без опции ACL, не получится.
# setfacl -dm u:sergej:rw /home/sergej/acl
setfacl: /home/sergej/acl: Operation not supported |
Проверим наследование атрибутов.
# mkdir test_acl/subdir
# getfacl test_acl/subdir
И в качестве вывода получим:
# file: test_acl/subdir
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:sergej:rw-
default:group::r-x
default:group: sales: rwx
default:mask::rwx
default:other::r-x
|
Теперь пробуем создать файл в каталоге:
# mount /home -o remount,acl
Смотрим атрибуты:
# getfacl test_acl/test_file
# file: test_acl/test_file
# owner: root
# group: root
user::rw-
user:sergej:rw- #effective:rwx
group::r-x
group:sales:rwx #effective:r-x
mask::rw-
other::r—
|
Пользователь sergej и группа sales унаследовали права. Убедимся, что стандартные права доступа все еще существуют.
# ls -al test_acl
итого 1
drwxr-xr-x 2 root root 80 Окт 22 16:10 .
drwxr-xr-x 21 root root 592 Окт 22 16:00 ..
-rw-rw-r-- 1 root root 0 Окт 22 16:10 test_file
|
В некоторых дистрибутивах команда ls для файлов и каталогов, в которых используется ACL, дополнительно выводит знак +, например drwxr-xr-x+. От чего зависит присутствие плюса в выводе, мне, к сожалению, неизвестно. Команда chmod также работает с такими файлами и каталогами, только теперь изменяются не права доступа пользователей, а значение маски доступа.
Сохранение расширеных прав при копировании и перемещении
В документации сказано, что при копировании и перемещении расширенные права доступа должны сохраняться, что сейчас и проверим:
# mv test_acl work
# getfacl work/test_acl
# file: work/test_acl
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:sergej:rw-
default:group::r-x
default:group: sales: rwx
default:mask::rwx
default:other::r-x
|
Все атрибуты на месте, т.е. команда mv перемещает файлы вместе с привязанными к ним списками контроля доступа. Теперь переместим тестовый каталог в раздел смонтированный без ACL и проверим разрешения:
# mv test_acl /home/sergej/
# getfacl /home/sergej/test_acl
# file: home/sergej/test_acl
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
|
Из увиденного можно сделать однозначный вывод: без указания при монтировании дискового раздела опции ACL списки контроля доступа работать не будут. Утилита getfacl при использовании на таком разделе выведет стандартные права доступа.
А вот при копировании получились несколько другие результаты. Создадим файл и еще один тестовый каталог, но при установке разрешения для каталога не будем использовать опцию -d:
# touch test_acl_file
# setfacl -m u:vasja:rw,g:webmaster:rwx test_acl_file
Проверяем:
# getfacl test_acl_file
# file: test_acl_file
# owner: root
# group: root
user::rw-
user: vasja:rw-
group::r--
group:webmaster:rwx
mask::rwx
other::r--
|
Теперь сделаем копию файла в текущем каталоге:
# apt-get install acl attr
Проверяем разрешения:
# getfacl test_acl_2
# file: test_acl_2
# owner: root
# group: root
user::rw-
group::r-x
other::r--
|
Как видите, разрешения изменились и соответствуют стандартным установкам, определенным переменной umask. Теперь копируем файл в каталог test_acl, в котором при создании разрешений использовался параметр -d.
# cp test_acl_file test_acl
# getfacl test_acl/test_acl_file
# file: test_acl/test_acl_file
# owner: root
# group: root
user::rw-
user:sergej:rw- #effective:rwx
group::r-x
group:sales:rwx #effective:r-x
mask::rw-
other::r--
|
Разрешения изменились и соответствуют файлу test_file, который был создан в этом каталоге.
# mkdir dir
# setfacl -m u:fedja:rw,g:netadmin:rwx test_acl_file
# getfacl dir
# file: dir
# owner: root
# group: root
user::rwx
user: fedja:rw-
group::r-x
group:netadmin:rwx
mask::rwx
other::r-x
|
Теперь копируем в этот каталог тестовый файл.
# cp test_acl_file dir
И проверяем:
# getfacl dir/test_acl_file
# file: dir/test_acl_file
# owner: root
# group: root
user::rw-
group::r-x
other::r--
|
Если при создании каталога не использовался параметр -d, разрешения не наследуются и при копировании (создании) файлов и каталогов права доступа соответствуют стандартным разрешениям UNIX, т.е. фактически обнуляются.
И еще один интересный момент, о котором стоит упомянуть. Операции копирования и перемещения были проделаны и другими инструментами. Результат эксперимента с Midnight Commander совпал с результатом использования утилит ср и mv, а вот Konqueror при перемещении не сохранил расширенные права. Почти аналогично ведут себя kate и Kwrite. Если сохранять результат в текущий файл, то права сохраняются, а если в новый, то теряются. Все это выглядит несколько странно, потому что за операции с правами по идее должно отвечать ядро. Как видите, при использовании ACL необходимо очень тщательно отбирать и инструменты, т.к. при работе с некоторыми утилитами права теряются. Ошибка может привести к тому, что любая «неправильная» утилита может сделать бесполезной всю безопасность с ACL.
Некоторые опции утилит setfacl и getfacl
При помощи связки getfacl/setfacl можно сохранить и восстановить списки контроля доступа, это может понадобиться при архивировании данных или переносе в другую систему.
# getfacl -R --skip-base . > backup.acl
# setfacl --restore=backup.acl
Если для некоторого файла или каталога требуется установить разрешения, которые сходны с уже имеющимися, то можно поступить так (опции, написанные с заглавной буквы, применяются при использовании в качестве ввода результата работы другой утилиты).
# getfacl -a dir | setfacl -M - dir
# getfacl file1 | setfacl -S- file2
Чтобы удалить разрешение, используйте опцию -х. Например, удалим права для группы sales:
# setfacl -x g:sales test_acl
Опция -m модифицирует (а фактически сохраняет) старые разрешения, добавляя к ним новые. В некоторых случаях проще установить новые права на файл или каталог, полностью затерев старые. Для этих целей используется флаг -s.
# setfacl -m u:fedja:rw,g:netadmin:rwx test_acl_file
Установленную для каталога маску доступа, используемую по умолчанию, можно изменить так:
# setfacl -m default:u::rx acldir
Поддержка ACL в NFS и Samba
Поддержка ACL в NFS еще не закончена, но 4 версия протокола уже поддерживает стандартизованные удаленные вызовы процедур на получение и установку разрешений ACL. Причем правильно обрабатывает запросы демон, работающий в пространстве ядра. Демон, работающий в пространстве пользователя, поддерживает только вторую версию протокола и неправильно обслуживает запросы. Клиенты, работающие со второй версией протокола, используют традиционные девять бит, поэтому при передаче информация об ACL искажается. Уже в третьей версии клиенты для запроса прав пользователя опираются на вызов ACCESS, и точное разрешение этого вопроса предоставляется клиенту. Хотя стоит отметить, что существуют решения, позволяющие использовать ACL поверх NFS, но это тема другого разговора. Пока же разработчики рекомендуют использовать ACL при работе с NFS осторожно.
Зато списки контроля доступа могут использоваться вместе с Samba, что позволяет объединить Linux-сервер и Windows Active Directory. Хотя стоит отметить, что POSIX ACL и Windows NT/2000/XP ACL имеют отличия, но сервер Samba достаточно близко может работать с разрешениями, принятыми в Windows-среде, обеспечивая практически все действия. Для работы Samba с ACL необходимо не только установить поддержку ACL в ядре, но и собрать Samba с опцией --with-acl-support. А в конфигурационном файле smb.conf в разделе предоставляемого ресурса должно быть прописано nt acl support = yes. Для установки и просмотра разрешений можно использовать не только утилиты администрирования Windows, но и консольную утилиту smbcacls, запускаемую на стороне сервера. Формат запуска утилиты такой:
smbcacls //server/share filename [options]
Неудобно, что опции несколько отличаются от setacl. Так опция -А добавляет разрешение к файлу или каталогу сохраняя предыдущее, опция -s устанавливает новые разрешения затирая старые. При помощи опции -M изменяется маска доступа, а опции -С и -G позволяют указать нового владельца и группу-владельца.
Кроме стандартных rwx для файлов и каталогов можно установить дополнительные права:
- D - разрешение на удаление.
- P – изменение разрешения ка объекту.
- O - установка владельца.
И комбинированные:
- READ – эквивалентно RX.
- CHANGE – эквивалентно RWXD.
- FULL – эквивалентно RWXDPO.
Проект Trustees
Разработчикам проекта Trustees [2] схема, применяемая в POSIX ACL, показалась неудобной. Для поддержания в рабочем состоянии системы POSIX ACL требуются инструменты, позволяющие рекурсивно обходить каталоги, необходимые для установки или изменения разрешений. Кроме того, при большом количестве объектов такая схема требует особого внимания и контроля. Схема, используемая в Novell Netware, несколько проще, т.к. для установки разрешений используется один конфигурационный файл, который будет полностью контролироваться системным администратором и не потребует разработки дополнительного инструментария либо сложных скриптов. Именно такой подход применен в trustees. В июне 2005 года стал наконец доступен стабильный релиз новой версии 3.0, о котором пойдет речь далее.
Trustees позволяет дать доступ пользователю или группе пользователей к дереву каталогов, а не единственному файлу, что является отходом от стандарта POSIX ACL. В принципе в большинтсве случаев создание каталога и определение к нему доступа, является типичной задачей, доступ к отдельному файлу регулируется реже и является частным решением. Поэтому такой подход вполне себя оправдывает. К тому же в этом случае не требуется установка тысяч разрешений для каждого файла, что может привести при невнимательности к ошибке, и теперь администратору легче контролировать разрешения т.к. все ограничения для каталога и подкаталогов записываются в одной строке. Кроме того в этом случае снимается зависимость от используемой файловой системы и сервиса. Поэтому Trustees в принципе можно использовать при работе с Samba, ftp, NFS, http.
Кроме принципа организации доступа Novell Netware в проекте использованы наработки Java Security.
В архиве размером 26.3 Кб содержатся патчи к ядрам версии 2.6 (2.6.8-2.6.13-rc3), исходные тексты для компиляции модуля и утилиты settrustees. Trustees можно скомпилировать вместе с ядром или установить как модуль.
Для первого варианта необходимы исходные тексты ядра с номером версии, для которого имеется патч (при отсутствии такового можно попробовать ближайший по номеру, с большой вероятностью он будет работать). Далее поступаем обычным образом:
# cd /usr/src/linux-2.6.11
# patch -p1 < ../2.6.11.diff
patching file security/trustees/trustees.h
patching file security/trustees/init.c
patching file security/trustees/funcs.c
patching file security/trustees/fs.c
patching file security/trustees/Kconfig
patching file security/trustees/trustees_private.h
patching file security/trustees/Makefile
patching file security/trustees/security.c
patching file security/Kconfig
patching file security/trustees/Kbuild
patching file security/Makefile
|
При конфигурировании необходимо включить пункт Trustees ACLS в Security options (рис. 2).
Рисунок 2. После пропатчивания в Security options появится новый пункт Trustees ACLS, который необходимо включить
При ручном редактировании раскомментируем следующие строки в файле .config:
#
# Security options
#
CONFIG_SECURITY=y
CONFIG_SECURITY_TRUSTEES=y
После чего ядро компилируется и устанавливается обычным образом.
При установке в качестве модуля необходимо наличие исходных текстов рабочего ядра (оно должно быть обязательно собрано с опцией CONFIG_SECURITY). Далее переходим в каталог module распакованного архива trustees и вводим make install. Если при компиляции не будут найдены исходные тексты, то следует указать их местонахождение вручную.
# make KDIR=/usr/src/linux-2.6.11 install
После успешной компиляции модуля переходим в подкаталог src и вводим make, получившийся исполняемый файл settrustees копируем в /usr/sbin, чтобы он был доступен только пользователю root. Теперь все готово к работе. Загружаем модуль modprobe trustees.ko, либо перегружаем систему с новым ядром.
Для задания разрешения по умолчанию используется конфигурационный файл /etc/trustees.conf, но его можно переопределить опцией -f. Все записи по одной в строку состоят из устройства с каталогом/файлом и параметров доступа к нему.
[/block/device]/any/path:usr1:flags:+grp1:flags...
[/network/share]I/any/path:+grp2:flags:*:flags...
Обратите внимание на флаг I во втором примере. С его помощью указываются на чувствительные к регистру букв устройства. Иначе для //smb/share/DIR и //smb/share/dir будут установлены одни и те же права доступа. Каталоги, находящиеся на определенном устройстве, описываются без указания точки монтирования, т.е. если прописывается каталог /home/sergej, а раздел /home смонтирован на /dev/hda5, то указывается он так:
[/dev/hda5]/sergej
а не так:
[/dev/hda5]/home/sergej
В качестве указания параметров доступа используются следующие флаги:
- R – разрешение на чтение любых файлов;
- W – разрешение на запись файлов и каталогов;
- B – просмотр (Browse) списка файлов в каталоге (подобно установке права на исполнение для каталогов);
- E – чтение (rEad) каталогов;
- X – выполнение (eXecute) файлов;
- U – установка стандартных прав доступа UNIX (по умолчанию).
Пустой параметр означает запрет всех полномочий. Вместе с флагами могут использоваться следующие модификаторы, которые могут устанавливаться, например для временного переопределения прав:
- C – очистка (Clear) разрешений;
- D – запрет (Deny) доступа;
- ! – запись для всех, кроме указанных пользователей или групп;
- O – один уровень, т.е. все файлы и каталоги внутри, но без подкаталогов;
- * – означает всех пользователей.
Пустые линии игнорируются, знак решетки (#) означает комментарий.
Для примера занесем в файл информацию, запрещающую пользователю sergej запись в каталог, находящийся на разделе с файловой системой FAT, традиционно имеющий права доступа 777, и ограничимся одним уровнем рекурсии.
[/dev/hda6]/win/test:sergej:REBO
Теперь создаем тестовый каталог и указываем модулю на необходимость монтирования виртуальной файловой системы.
# mkdir /mnt/win/test
# mount -t trusteesfs none /mnt/win/test
Так монтируются каталоги индивидуально, если требуется смонтировать все каталоги из файла /etc/trustees.conf, то вызывается утилита settrustees.
Можно проверить:
# mount | grep trusteesfs
none on /mnt/win/test type trusteesfs (rw) |
Пробуем создать файл:
# touch /mnt/win/test/test_file
touch: невозможно выполнить touch для "test_file": Permission denied |
Что и следовало ожидать. Стоит отметить, что создание файла на уровень выше или ниже тестового каталога пройдет без проблем. Чтобы остановить использование виртуальной файловой системы, достаточно набрать:
# settrustees -D
Более жизненный пример. Позволим веб-серверу считывать данные из каталога с документами, а веб-мастерам, кроме того и изменение файлов:
[/dev/hda3]/httpd/htdocs:apache:REBX
[/dev/hda3]/httpd/htdocs:+web_editors:RWEBX
Выводы
Итак, применение ACL позволяет использовать более сложные модели доступа, чем традиционная реализация, применяемая в UNIX-системах. Используя ACL, даже при небольшом количестве пользователей администратор может существенно упростить процесс распределения полномочий пользователей. Но на сегодняшний день без боязни можно использовать лишь консольные утилиты, остальные нуждаются в предварительном тестировании перед использованием в промышленной среде.
Ссылки:
- Сайт проекта Linux Extended Attributes and ACLs – http://acl.bestbits.at.
- Сайт проекта Trustees – http://www.aeruder.net/trustees.
- SUSE Linux Administration Guide – http://www.suse.de/~agruen/acl/chapter/fs_acl-en.pdf.
- POSIX Access Control Lists on Linux – http://www.suse.de/~agruen/acl/linux-acls.
- Сайт проекта Linux NFSv4 – http://www.citi.umich.edu/projects/nfsv4.