Вопрос или проблема
Я знаю, что этот вопрос может показаться дубликатом, потому что многие люди задавали связанные вопросы о наследовании прав. Тем не менее, ни один из ответов, которые я нашел, не охватывает весь спектр того, что я пытаюсь достичь, так что вот оно:
У меня есть директория “share” на файловой системе ext4 на Debian stable, которая содержит вложенные директории, принадлежащие различным пользователям. Каждый пользователь должен иметь доступ на чтение ко всему в дереве, и доступ на чтение-запись к своему собственному поддереву. Пользователи могут добавлять файлы в свои собственные поддеревья, и эти файлы происходят из бесконечного разнообразия источников, на которые я не могу влиять, поэтому их существующие права — это непоследовательный мусор, который можно без колебаний отбросить.
На данный момент я создал группу “share” и добавил в нее соответствующих пользователей, затем chown -R
установил групповую собственность на эту группу “share” и chmod -R
установил желаемые права… для всех файлов, которые уже находятся там. Используя бит SetGID, я могу распространить групповую собственность на новосозданные файлы, и используя “уместимость” Posix ACL, я могу аналогично распространять права на новосозданные файлы.
Но! Если существующий файл перемещается в дерево директории “share” из другого места, его существующий GID и права/ACL имеют приоритет, и ничего из вышесказанного не оказывает никакого эффекта. Я понимаю, что есть хорошие и важные причины, почему это нормальное поведение файловой системы (принцип наименьшей неожиданности, права, установленные пользователем, обычно выбираются по какой-то причине и т. д.)… Но в этом случае, для этого конкретного дерева директорий, я хочу отменить это поведение.
Я хочу последовательно, как можно быстрее (если нужно, силой) применить набор прав и групповой собственности ко всем файлам, директориям и символическим ссылкам, которые окажутся в этом дереве директорий, независимо от того, как они туда попадают: созданием, перемещением, копированием, rsync, scp, распаковкой, разархивацией, телепортацией, орбитальным броском, спонтанным квантовым событием или любым другим способом.
Я работаю под root на этом компьютере и готов рассмотреть альтернативные файловые системы, хотя будут рассмотрены лишь зрелые, готовые к производству файловые системы, которые хорошо поддерживаются Linux.
На данный момент наименее ужасный способ, который я вижу для достижения этой цели, это запустить что-то вроде inotify watcher (может быть, Watchman) в виде постоянно работающего сервиса systemd, чтобы наблюдать за всем деревом рекурсивно и вызывать скрипт для chown и chmod файлов всякий раз, когда наблюдатель обнаруживает изменения. Это лучше, чем запланированная работа, которая слепо будет запускать chown -R
и chmod -R
снова и снова, но это все равно грубый и неэффективный подход. Перед тем как я начну реализовывать это уродливое обходное решение, я действительно надеюсь, что кто-то из вас знает о встроенной возможности ext4 или какой-либо другой применимой файловой системы, чтобы справиться с этим эффективно и нативно.
Я не говорю, что это невозможно, но скажу, что крайне маловероятно, что Linux поддержит решение, подобное этому. Это связано с тем, как работает стек файловой системы. Но сначала немного истории.
Novell netware (конец 1980-х – середина 2000-х, в зависимости от того, что вы считаете датой смерти) имела файловую систему с хорошей функцией, которая поддерживала именно это. Если у вас была структура директорий, такая как A -> B -> C ->D
и вы установили права на B
, это автоматически и немедленно применялось к C
и D
. Это было возможно, потому что файловая система была написана так, чтобы делать запросы предков чрезвычайно быстрыми; когда кто-то открывал файл, она могла быстро проходить через все дерево до [root]
и строить эффективную модель прав, чтобы принять решение о разрешении/запрете. Это делало операции с файловой системой немного более тяжелыми, чем для более простых моделей, таких как те, которые имели комплианты Posix.
Файловая система windows ntfs не делает это таким образом. Когда вы устанавливаете права на B
, она спускается по всему дереву под B
, чтобы применить соответствующие права ко всем файлам и директориям. Это может занять часы, если вам нужно затронуть десятки или сотни миллионов файлов. Для новых файлов, созданных ниже B, права на непосредственной директории используются для определения того, какие права получит файл.
Теперь, в linux у нас больше модель Windows. Операции с файлами обращаются к объекту файла и непосредственной директории и принимают решение о разрешении/запрете на основе атрибутов там, не обращая внимания на состояние прав любого другого объекта. Это делает операции с файлами чрезвычайно быстрыми, в отличие от NetWare.
В Linux применение Posix ACL происходит на слое VFS, который находится выше конкретных файловых систем, таких как ext4, xfs и btrfs. Изменения, которые вам нужно внести, чтобы превратить файловую систему Linux в модель Windows, где изменения выше каскадируются вниз, потребуют создания специализированного демона для мониторинга изменений ACL для любой директории на интересующей файловой системе и каскадирования изменений вниз. Но также необходимо поймать любые новые файлы или события изменения ACL на любом inode файла и применять «правильную» версию. Это не стандартная настройка и должно происходить полностью в пользовательском пространстве (возможно, в виде файловой системы FUSE).
Слой VFS Linux крайне маловероятно, что поддержит модель прав NetWare по двум основным причинам:
- Это не Posix.
- Это замедляет все доступы к файлам, что людям не нравится.
Так что да. Вы нашли одно решение этой проблемы: сделать все в пользовательском пространстве.
Я поспешил с выводами. Оказывается, что Open Enterprise Server (OES) от Novell все еще существует и смог сделать именно это. Для доступа от пользователя на сервере, такого как через SSH или приложение, работающее на сервере, пользователь должен быть представлен в eDirectory (базе данных аутентификации OES), и доступ к объему NSS обходится полностью без слоя Posix. Наличие в eDirectory требуется для определения, какие права будет иметь пользователь на объеме NSS.
С архитектурной точки зрения, Novell/MicroFocus написали модули ядра, чтобы все это работало. Нет, они не поделились ими под разрешительной лицензией. OES — это платный продукт именно по этой причине.
Следующий метод работает очень хорошо:
- Монтировать диск как обычно
- Экспортировать NFS-доллары этого смонтированного диска со всеми правами, сжатым.
- Смонтировать NFS-доллар. Использовать новый смонтированный NFS-диск как общий диск без проблем с правами.
Хотя я немного запоздал, я добавлю свои 0.02. Сценарий в вопросе абсолютно действителен и реален, и я также сталкиваюсь с ним. Жаль, что стандартная разработка ядра и обычные инструменты, похоже, просто игнорируют такой сценарий. В настоящее время у меня есть довольно уродливое решение, которое работает для меня ежедневно, и оно включает небольшую правку модуля ядра ext4, которая позволяет переопределить права и собственность файлов/директорий теми, которые находятся в содержащей директории, в случае если на содержащей директории установлен SETGID. Таким образом, правка, по сути, позволяет выполнить принудительное распространение прав и собственности на всю глубину дерева. Она уже много лет работает для меня без проблем и негативных побочных эффектов, и ее было довольно просто реализовать, и она не требовала никаких дополнительных ресурсов, потребляющих ресурсы, в ядре. К сожалению, в новых ядрах это становится все сложнее сделать, и даже просто отключить ACL теперь не так просто.
Ответ или решение
К сожалению, решение вашей задачи не является тривиальным, поскольку стандартное поведение файловых систем Linux, таких как ext4, не поддерживает автоматическую наследуемость прав доступа и владения файлами и директориями. Ниже приведены возможные подходы к решению вашей проблемы, учитывающие ваши требования.
1. Настройка прав доступа с использованием ACL
Хотя Linux не поддерживает специальную функциональность, позволяющую автоматически наследовать права доступа для уже существующих файлов, вы можете использовать POSIX ACL (Access Control Lists) для управления доступом к файлам и директориям. Для этого выполните следующие шаги:
-
Установите необходимые пакеты для работы с ACL, если они еще не установлены:
sudo apt install acl
-
Включите поддержку ACL на файловой системе, если она не включена. Для этого отредактируйте файл
/etc/fstab
, добавив опциюacl
к соответствующей строке:/dev/sda1 /path/to/mount ext4 defaults,acl 0 2
-
Примените настройки и монтируйте файловую систему:
sudo mount -o remount /path/to/mount
-
Установите права доступа на основной директории:
sudo setfacl -m g:share:rwx /path/to/share sudo setfacl -R -m d:g:share:rwx /path/to/share
Таким образом, новые файлы и директории, созданные внутри /path/to/share
, будут иметь права доступа, определенные для группы share
. Однако это не будет работать для файлов, переносящихся из других мест.
2. Использование inotify для автоматического применения прав
В качестве альтернативного решения вы можете использовать inotify для отслеживания изменений в директории. Пример простого скрипта будет выглядеть так:
#!/bin/bash
WATCH_DIR="/path/to/share"
inotifywait -m -r -e create -e moved_to "$WATCH_DIR" --format '%w%f' | while read FILE
do
chown :share "$FILE" # установка группы
chmod 770 "$FILE" # установка прав доступа
done
Этот скрипт будет постоянно отслеживать директорию и применять указанные права к любым вновь созданным или перемещенным файлам. Следует учитывать, что этот подход может потреблять дополнительные ресурсы, поскольку он работает постоянно.
3. Использование NFS или других файловых систем
Использование NFS может быть еще одним вариантом. Как предложено в одном из комментариев, вы можете смонтировать директорию как NFS-общий ресурс и установить права доступа, которые будут применяться ко всему содержимому. Это может помочь вам избежать проблем с правами доступа для перемещаемых файлов, однако это может потребовать дополнительной настройки сети и управления ресурсами.
4. Постоянный анализ и модификация на уровне ядра
Если у вас есть опыт работы с ядром Linux, вы можете рассмотреть возможность написания модуля ядра, который будет управлять правами доступа на более глубоком уровне, аналогично patch’у, который вы описали. Этот подход довольно сложен и требует глубокого понимания архитектуры Linux, поэтому он подходит только для опытных пользователей.
Заключение
Хотя полный контроль над правами доступа для всех файлов в директории в Linux может быть сложной задачей, перечисленные методы могут помочь вам в достижении ваших целей. Каждый из подходов имеет свои преимущества и недостатки, и выбор подходящего решения должен основываться на анализе вашей конкретной ситуации, ресурсов и требований к производительности.