Samba и ZFS: расширенные ACL и их правка из винды
Постановка задачи
Возникла необходимость запилить файл-сервер на Samba и дать ряду пользователей возможность рулить правами доступа на отдельные каталоги. Система — FreeBSD 10.1 amd64, файло будет лежать на ZFS. Версия Samba — 3.6.24.
Исследование задачи показало, что стандартными правами Unix (aka «Unix mode») тут не обойтись. Надо использовать расширенный набор ACL. Например, нужно, чтобы к каталогу имели доступ более одной группы, но не все группы (т. е. разрешения для other тут не прокатит). Ну и на некоторые папки нужно давать доступ не отдельным группам, а прямо отдельным пользователям.
Общие сведения
По дефолту, как известно, в юниксах права на файлы и каталоги расставляются по схеме «ugo» — «user-group-other»). Во фре с помощью утилиты setfacl можно задавать права по двум схемам — POSIX 1.E и NFSv4, в зависимости от файловой системы. По факту же POSIX 1.E здесь сильно редуцирован — до этой самой схемы ugo. Тогда как в действительности POSIX 1.E слегка побогаче (подробности можно вкурить отсюда). Как гласит man setfacl:
The access permissions field contains up to one of each of the following: ‘r’, ‘w’, and ‘x’ to set read, write, and execute per‐ missions, respectively. Each of these may be excluded or replaced with a ‘-’ character to indicate no access.
Что в переводе означает: «Поля с разрешениями содержат букавки r, w или x для чтения, записи или выполнения соответственно».
Но это всё нам не очень интересно, так как у нас ZFS, а на ZFS ACL по умолчанию соответствуют схеме NFSv4.
Тюнинг ZFS
Поэтому прежде чем заюзать всю эту красоту с крутыми ACL на ZFS, необходимо ZFS слегка потюнить. А именно, проделать такое:
zfs set aclinherit=passtrhough storage0
В данном случае storage0 — это имя моего ZFS-пула
zfs set aclmode=passthrough делает так, что если над папкой выполняется chmod, то при наличии у папки расширенных ACEs (access control entries) (расширенные — это те, которые помимо стандартных @owner, @group, @other), то эти ACL при этом НЕ ИЗМЕНЯЮТСЯ.
Также там есть режимы:
- discard — т. е. никаких ACL сверх стандартного unix mode сохраняться не будет;
- groupmask — новые ACL по итогу будут выставляться так, чтобы они не превышали тех, которые принадлежат @group, за исключением случая, если UID пользователя в ACL совпадает с UID владельца каталога или файла. В этом случае выставляются права не выше, чем у владельца файла. Пока даже не могу предположить, для чего такой режим может использоваться.
Если коротко, то zfs set aclinherit=passthrough необходима, для того, чтобы ACL свежесоздаваемых файлов и каталогов наследовались от каталога, в котором они создаются. Есть ещё режим passthrough-x — то же самое, что passthrough, только бит «executable» выставляется только в случае, если создающее файл приложение явным образом требует у создаваемого файла выставить бит «executable». Подробности можно вкурить тут.
Правка прав доступа из винды
В условиях задачи была заявлена необходимость дать некоему пользователю возможность управления доступом на каталоги в расшаренных папках. Причём от тонкостей командной строки пользователь бесконечно далёк, но может пользоваться виндовым диалогом прав доступа (который в свойствах папок или файлов в винде на вкладке «Безопасность» находится).
Поэтому устанавливаем владельца всех папок в шаре на определённый аккаунт, который будет админским. Допустим, это будет учётка i.ivanov. Тогда делаем так:
find /mnt/storage0/share -type f -exec setfacl -m u:i.ivanov:full_set:allow {} \;
Первый find выставляет права full_set (это сокращение на «Полный доступ») на каталоги, а второй find — на файлы. Два find необходимы потому, что в синтаксисе команды setfacl при установке прав на каталог есть ещё модификатор «:fd:». Он означает, что права нижележащих каталогов должны наследоваться от вышестоящих. У файлов такого модификатора нет (т. е. в ACL на файлы он не предусмотрен). Если попытаться задать права на файл в формате -m u:i.ivanov:full_set:fd:allow, то setfacl выдаст ошибку.
Далее нам надо замапить группы Unix на группы в Samba. Если этого не сделать, то в диалоге «Безопасность» на винде будут видны пользователи файл-сервера (их отдаёт Самба), но не будет видно групп. Если же назначить группу руками через setfacl, то группа будет видна как «Unix Group\unixgroup»:

Но из виндового диалога добавить юниксовые группы не удастся — их там просто не видно. Чтобы они стали видны в этом диалоге, необходимы дополнительные телодвижения. Допустим, у нас есть на файл-сервере группы buhgalteria, common, engineers и bosses. Чтобы эти группы стали видны на Windows, делаем так:
net groupmap add unixgroup=common type=local ntgroup="Все юзеры"
net groupmap add unixgroup=engineers type=local ntgroup="Инженеры"
net groupmap add unixgroup=bosses type=local ntgroup="Начальство"
И после этого в диалоге добавления прав будут присутствовать соответствующие группы. Обращаю внимание, что если имена групп NT у вас на русском, то добавлять их в маппинг надо в кодировке UTF-8.
Настройка собственно Samba
Отключаем маппинг атрибутов DOS в файлах на exec-биты и включаем хранение атрибутов DOS в виде дополнительных файлов с атрибутами. Это не обязательно, просто меня бесит, что свеже-создаваемые в SMB-шарах файлы имеют атрибут «исполняемых» при просмотре прямо в консоли сервера. Это криво и несекурно — мало ли, кто там чо зальёт.
map hidden = no
map system = no
map archive = no
# Use extended attributes to store file modes
store dos attributes = yes
Отключаем unix extensions (они нужны для того, чтобы Самба могла работать с расширениями CIFS от HP — там можно реализовывать симлинки, хардлинки и прочее. Эти расширения могут использовать разные другие SMB-клиенты, но винда их не поддерживает. Клиенты у нас в основном на винде — поэтому unix extensions нам ни к чему. Также выставляем параметры наследования и режима обработки ACL:
nt acl support = yes
inherit acls = yes
inherit owner = yes
inherit permissions = yes
map acl inherit = yes
unix extensions = no
- nt acl support — включает режим маппинга NT-like ACL на ACL файловой системы;
- inherit acls — включает режим наследования ACL от каталога, в котором создаются новые файлы и каталоги. Без этого параметра дополнительные ACL не будут наследоваться для новых файлов, будут наследоваться только unix mode разрешения;
- inherit owner — включает режим наследования владельца каталога, в котором создаётся файл. Без этого параметра владельцем будет становиться тот пользователь, который этот файл создаёт. В рамках нашей задачи наследование требуется, поэтому включаем;
- inherit permissions — включает наследование unix mode разрешений;
- map acl inherit — Самба будет мапить флаги «наследовать права от родительского каталога» в NT acls на файловую систему.
И в настройках шары делаем так:
nfs4:acedup = merge # сливать в одну запись дублирующиеся ACE
nfs4:chown = yes # разрешаем менять влалельца файлов
На этом, собственно, всё. А теперь — дискотека! :-)