Фон
Для экспорта/обмена NFSv4 включенная по умолчанию опция root_squash заставит NFS изменить root клиента на анонимный ID. Это, по сути, повысит безопасность, предотвращая миграцию владельца учетной записи root из одной системы в другую.
Overlayfs позволяет монтировать локальную, прозрачную файловую систему поверх другой файловой системы. К сожалению, похоже, что она обращается к базовой файловой системе с помощью пользователя root, а не фактического пользователя. По крайней мере, такой вывод я сделал из следующего эксперимента.
Зачем монтировать Overlayfs поверх общего ресурса NFS? Чтобы позволить менее доверенной машине делать вид, что она может писать в общую файловую систему.
Испытательная установка
Сначала установите сервер ядра NFS, соответствующий вашему дистрибутиву. Затем убедитесь, что вы экспортируете только NFSv4. (Хотя, возможно, это не важно для этой проблемы, но это хорошая мера предосторожности.)
$ sudo cat /proc/fs/nfsd/versions
-2 -3 +4 +4.1 +4.2
Если нет, посмотрите /etc/nfs.conf
и установите vers3=n
.
Затем создайте файловую систему Ext4 в разреженном файле и смонтируйте ее в локальной файловой системе. Это будет файловая система, лежащая в основе нашего общего ресурса NFS.
$ truncate -s 512M 512BM-ext4.img
$ mkfs.ext4 512BM-ext4.img
$ sudo mkdir /mnt/ext4-file
$ sudo mount -o loop,noacl 512BM-ext4.img /mnt/ext4-file
Затем поделитесь/экспортируйте эту файловую систему по сети с помощью NFSv4 на соответствующую машину. В этом примере я буду использовать localhost, но это может быть любая машина в локальной сети. Сделайте это, отредактировав /etc/exports
строку так, чтобы она выглядела как следующая.
/mnt/ext4-file/ localhost(ro,fsid=123123)
Затем перезапустите NFS-сервер на вашем компьютере, служебные файлы могут отличаться в вашей ОС.
$ sudo systemctl restart nfs-server.service nfs-mountd.service
$ sudo exportfs -v
/mnt/ext4-file localhost(sync,wdelay,hide,no_subtree_check,fsid=123123,sec=sys,ro,secure,root_squash,no_all_squash)
Убедитесь, что root_squash
и ro
включено.
Теперь должно быть возможно смонтировать общий ресурс NFSv4 на предполагаемом клиенте.
$ sudo mount -t nfs -o ro localhost:/mnt/ext4-file /mnt/nfs-share/
$ findmnt /mnt/nfs-share
TARGET SOURCE FSTYPE OPTIONS
/mnt/nfs-share localhost:/mnt/ext4-file nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255
И затем мы монтируем overlayfs2 поверх этого общего ресурса.
$ mkdir -p /tmp/overlay/{work,upper}
$ sudo mkdir /mnt/overlay
$ sudo mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
Для нашего эксперимента мы создадим папку в файловой системе, которую может читать и записывать только пользователь, а читать — группа. Я выбрал группу, принадлежащую моему пользователю.
$ sudo mkdir /mnt/ext4-file/rovanion
$ sudo chown rovanion:rovanion /mnt/ext4-file/rovanion
$ sudo chmod 2750 /mnt/ext4-file/rovanion
$ touch /mnt/ext4-file/rovanion/hi-from-ext4
$ ls -la /mnt/nfs-share/rovanion/
totalt 8,0K
drwxr-s--- 2 rovanion rovanion 4,0K sep 6 14:14 .
drwxr-xr-x 4 root root 4,0K sep 6 14:12 ..
-rw-rw-r-- 1 rovanion rovanion 0 sep 6 14:14 hi-from-ext4
$ touch /mnt/nfs-share/rovanion/hi-from-nfs
touch: cannot touch '/mnt/nfs-share/rovanion/hi-from-nfs': Read-only file system
Мы можем просмотреть содержимое /mnt/nfs-share/rovanion
, но не можем коснуться файловой системы, хотя у нас есть разрешение, потому что общий ресурс NFS смонтирован только для чтения. Все как и ожидалось.
Отказ
Но вот тут-то и возникает проблема.
$ ls -la /mnt/overlay/rovanion/
ls: cannot open directory '/mnt/overlay/rovanion/': Permission denied
$ ls -l /mnt/overlay/
total 28K
drwx------ 2 root root 16K Sep 6 13:04 lost+found
drwxr-s--- 2 rovanion rovanion 4.0K Sep 6 14:14 rovanion
$ whoami
rovanion
$ groups
rovanion sudo
Нам отказано в доступе к списку, /mnt/overlay/rovanion
хотя система разрешений должна позволять нам это сделать.
Моя лучшая догадка относительно происходящего заключается в том, что Overlayfs осуществляет весь доступ к базовой файловой системе, которая root
с помощью корневого доступа NFS сопоставляется с тем, nobody
кому не разрешен доступ к папке, поскольку nobody
он не принадлежит к группе rovanion
, а другим не разрешено просматривать содержимое папки.
Вопрос
Тогда мой вопрос: можно ли обойти эту проблему? Разрешить пользователю доступ к папке через Overlayfs, к которой имеет доступ только выбранная группа, без отключения root_squash на экспорте/общем доступе NFS или добавления o+rx
в папку.
решение1
Следующий разделДокументация ядра Linux на Overlayfsописывает модель разрешений.
Проверка разрешений в оверлейной файловой системе следует следующим принципам:
1) permission check SHOULD return the same result before and after copy up 2) task creating the overlay mount MUST NOT gain additional privileges 3) non-mounting task MAY gain additional privileges through the overlay, compared to direct access on underlying lower or upper filesystems
Это достигается путем выполнения двух проверок разрешений на каждый доступ.
a) check if current task is allowed access based on local DAC (owner, group, mode and posix acl), as well as MAC checks b) check if mounting task would be allowed real operation on lower or upper layer based on underlying filesystem permissions, again including MAC checks
Проверка (a) обеспечивает согласованность (1), поскольку владелец, группа, режим и posix acls копируются. С другой стороны, это может привести к игнорированию разрешений, накладываемых сервером (например, NFS) (3).
Проверка (b) гарантирует, что ни одна задача не получит разрешения на доступ к базовым слоям, которых нет у задачи монтирования (2).Это также означает, что можно создавать настройки, в которых правило согласованности (1) не выполняется; однако обычно задача монтирования будет иметь достаточные привилегии для выполнения всех операций.
Выделение мое. Я считаю, что мне удалось создать такую ситуацию. Когда задача монтирования, запущенная как root, не имеет привилегий для перечисления папки, и поэтому Overlayfs запрещает пользователю доступ к папке.
Если бы мы смонтировали Overlayfs как пользователь, имеющий доступ к файлам, но не root, чтобы UID не был сжат, то, возможно, мы могли бы вывести список каталогов и создать в них файлы?
$ unshare --mount --map-root-user
# mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
# ls -la /mnt/overlay/
totalt 28K
drwxrwxr-x 1 root root 4,0K sep 6 14:08 .
drwxr-xr-x 7 nobody nogroup 4,0K sep 6 14:09 ..
drwx------ 2 nobody nogroup 16K sep 6 13:04 lost+found
drwxr-s--- 2 root root 4,0K sep 6 14:14 rovanion
# touch /mnt/overlay/rovanion/hi-from-overlay
И это мы можем! И файл существует только в оверлее.
$ ls /mnt/ext4-file/rovanion/
hi-from-ext4
$ ls /tmp/overlay/upper/rovanion/
hi-from-overlay
Хотя это решение имеет свои собственные интересные последствия. Теперь мы должны включить пользовательские пространства имен на наших не на 100% доверенных машинах, и мы внезапно оказываемся в пространстве, где наш UID кажется 0, но сопоставлен с нашим обычным идентификатором пользователя для внешнего мира. К сожалению, unshare --mount
без этого --map-root-user
не представляется возможным.