Каталог смонтирован с rw, а root не может выполнить chown: разбираем root_squash
Знакомо: смонтировали NFS-каталог, в опциях честный rw, файлы создаются, а `chown -R app:app /mnt/data` под root отвечает «Operation not permitted». Дальше начинается лечение симптомов — chmod 777, перемонтирование, sudo, а в финале строка no_root_squash на всю подсеть. Разберу, что на самом деле происходит на проводе, как за три команды доказать причину, как я чиню это на боевых стендах без раздачи root клиентам, и что ещё прилетает сверху на NFSv4 — отображение имён и лимит в 16 групп.
rw ничего не обещает про root
Главная путаница здесь в том, что люди читают опцию rw как «мне тут всё можно». Это не так. rw описывает, разрешены ли на экспорте операции записи в принципе. Кем именно вас видит сервер — совершенно отдельный вопрос, и решает его не клиент.
NFS не пересылает вашу сессию и не спрашивает у клиента, кто вы такой. При стандартной аутентификации AUTH_SYS (она же sec=sys) клиент кладёт в RPC-запрос просто пару чисел — uid и gid вызывающего процесса — и сервер им верит. А дальше сервер применяет свои правила отображения. По умолчанию включён root_squash, и в exports(5) он описан предельно коротко: «Map requests from uid/gid 0 to the anonymous uid/gid». То есть все запросы от вашего локального root приезжают на сервер уже не от root.
Кем они приезжают — тоже написано в мануале: «By default, exportfs chooses a uid and gid of 65534 for squashed access». На Debian и Ubuntu это nobody:nogroup, на старых RHEL-ветках исторически был отдельный nfsnobody. И вот здесь ломается интуиция: 65534 не владеет вашим каталогом и не имеет на сервере CAP_CHOWN. Сменить владельца чужого файла может только владелец (и то ограниченно) или процесс с CAP_CHOWN. У анонима нет ни того, ни другого — получаете EPERM.
Самое коварное, что запись при этом работает. Если у каталога на сервере есть права на запись для others или группа совпала, файл спокойно создастся — от имени 65534. Человек видит: файлы пишутся, значит доступ есть, значит проблема в chown, значит «что-то с правами на клиенте». И начинает копать не там.
- rw — разрешение экспорта на операции записи, а не полномочия конкретного пользователя;
- root_squash — включён по умолчанию, действует ТОЛЬКО на uid/gid 0;
- anonuid / anongid — куда именно отображается сквошнутый запрос; по умолчанию 65534;
- all_squash — отображает в анонима вообще всех, не только root; по умолчанию выключен (no_all_squash);
- no_root_squash — единственная опция, которая реально отключает отображение root, и rw её не заменяет.
Диагностика за две минуты: сервер, клиент, тест
Первое, что я делаю — иду на сервер и смотрю не /etc/exports, а фактически применённые опции. Файл конфигурации врёт постоянно: его правят и забывают перечитать, а exportfs -v показывает то, что реально работает прямо сейчас, вместе с подставленными умолчаниями.
# на NFS-сервере
exportfs -v
# /srv/nfs/backup 10.10.20.0/24(sync,wdelay,hide,no_subtree_check,
# sec=sys,rw,secure,root_squash,no_all_squash)
# то же самое машиночитаемо
tr ',' '\n' < /var/lib/nfs/etab | grep -E 'squash|anon'С клиента полезно сверить, что сервер вообще отдаёт этот экспорт на ваш адрес. showmount -e спрашивает список у rpc.mountd, поэтому работает только при доступном mountd (NFSv3-инфраструктура); на чистом NFSv4-сервере с закрытым 111/20048 он молчит, и это не значит, что экспорта нет. Опций squash он не показывает — только пути и списки клиентов, так что это проверка «туда ли я стучусь», а не диагноз.
# на клиенте
showmount -e nfs.example.local
# Export list for nfs.example.local:
# /srv/nfs/backup 10.10.20.0/24Дальше иду на клиент и доказываю squash экспериментом, а не рассуждениями. Создаю файл от root и смотрю ЧИСЛОВОГО владельца — именно ls -n, а не ls -l, потому что имя nobody может нарисоваться и по совсем другой причине (об этом в разделе про NFSv4).
# на клиенте
findmnt -no SOURCE,FSTYPE,OPTIONS /mnt/backup
touch /mnt/backup/.squash_test
ls -n /mnt/backup/.squash_test
# -rw-r--r-- 1 65534 65534 0 sep 7 12:41 /mnt/backup/.squash_test
chown 1500:1500 /mnt/backup/.squash_test; echo "rc=$?"
rm -f /mnt/backup/.squash_testЧитается результат так. Владелец 65534 (или ваш anonuid) — это root_squash, вопрос закрыт, идите в раздел про лечение. Владелец — ваш реальный uid, но chown всё равно EPERM: смотрите, не смонтирован ли экспорт как ro, и не всплыл ли рядом all_squash. Файл вообще не создался с EACCES — это уже не squash, а режим каталога на сервере.
- `exportfs -v` на сервере — единственный источник правды по опциям экспорта;
- `/var/lib/nfs/etab` — те же данные в машиночитаемом виде, удобно для скриптов мониторинга;
- `showmount -e сервер` — какие пути и каким клиентам отдаются (без опций squash; нужен rpc.mountd);
- `ls -n` на клиенте — числовой владелец, снимает половину гаданий;
- `nfsstat -m` — покажет версию протокола и sec= для смонтированных точек;
- `strace -f -e trace=chown,fchownat ansible-playbook ...` — если непонятно, на каком именно вызове падает автоматика.
Четыре лечения, которые не лечат
Первое место с огромным отрывом — chmod 777 на сервере. Логика понятна: раз отказ по правам, откроем всё. Проблема в том, что режим доступа и владение — разные механизмы. Смена владельца чужого файла требует CAP_CHOWN, и никакие 777 эту способность не выдают. Вы получите ровно тот же EPERM, только теперь ещё и с каталогом, открытым всем на запись. Я снимал такие 777 у клиентов десятки раз, и почти всегда рядом обнаруживался чей-то давно забытый инсталлятор, который туда что-то положил.
Второе — перемонтирование. mount -o remount,rw, смена hard/soft, добавление вручную rw в fstab. Опции монтирования на клиенте — это в лучшем случае просьба, полномочия выдаёт сервер. Ни одна клиентская опция не отменяет root_squash, потому что решение принимается на другой машине.
Третье — sudo, su -, запуск от имени root в контейнере. Вы уже root, в этом и беда: именно uid 0 и попадает под отображение. Парадокс, к которому надо привыкнуть: обычный пользователь с uid 1500 на такой шаре часто может больше, чем локальный root.
Четвёртое, и самое вредное — поставить all_squash «чтобы уж наверняка». Эта опция отображает в анонима вообще все uid/gid, а не только нулевые. В мануале прямым текстом: no_all_squash — это дефолт. Включив all_squash, вы не почините chown (аноним по-прежнему не владелец), зато сломаете работающие приложения, у которых был свой uid, и уроните разделение доступа между отделами до состояния «все — один пользователь». Отдельно отмечу: rsync -a, tar -p и cp --preserve=ownership с клиента упрутся в тот же самый EPERM, только уже в конце многочасового копирования.
- chmod 777 — не влияет на chown вообще, только расширяет доступ;
- remount,rw и правки fstab — клиент не может отменить решение сервера;
- sudo/su — усугубляет, потому что сквошится именно uid 0;
- all_squash — ломает штатных пользователей и не решает исходную задачу;
- «просто скопировать с сохранением владельца» — падает на chown-фазе.
Как я чиню это на практике: четыре сценария по убыванию частоты
Сценарий первый и мой дефолтный: подготовить каталог на сервере. В девяти случаях из десяти chown с клиента вообще не нужен — нужен каталог, принадлежащий сервисному пользователю приложения. Создаю его руками на хранилке одной командой, с setgid-битом, чтобы всё создаваемое внутри наследовало группу.
# на NFS-сервере
groupadd -g 1500 appdata
useradd -u 1500 -g 1500 -r -s /usr/sbin/nologin appsvc
install -d -o 1500 -g 1500 -m 2770 /srv/nfs/app/dataСценарий второй: anonuid/anongid, когда клиент физически ходит только от root. Классика — агент резервного копирования, инсталлятор, systemd-юнит без User=. Здесь я не выдаю root, а перенаправляю анонима в нужного сервисного пользователя. root_squash остаётся включённым, но приземляется уже не в 65534, а в 1500 — и всё, что root напишет с клиента, окажется во владении appsvc.
# /etc/exports
/srv/nfs/app/data 10.10.20.11(rw,sync,no_subtree_check,root_squash,anonuid=1500,anongid=1500)
/srv/nfs/public 10.10.20.0/24(rw,sync,no_subtree_check,root_squash)Сценарий третий: no_root_squash — точечно и осознанно. Он бывает оправдан: бездисковые клиенты (мануал прямо называет это основным применением), разворачивание образов, лаборатория. Но пишу я его всегда на конкретный IP конкретного клиента и на конкретный экспорт, а не на подсеть. И на клиенте в этот момент обязательно nosuid,nodev в опциях монтирования.
Сценарий четвёртый, стратегический: привести uid/gid к единому виду по парку. Если ваш appsvc везде 1500, вопрос «кем меня видит сервер» исчезает как класс — вместе с половиной странных отказов доступа. Для домена это sssd/LDAP, для 15 линуксов без домена достаточно зафиксировать системные uid в Ansible или в кикстарте. Скучно, но работает лучше любых опций экспорта.
- готовим владельца на сервере — подходит почти всегда, риск нулевой;
- anonuid/anongid — когда клиент ходит только от root; root на сервере не выдаётся;
- no_root_squash — только на конкретный IP, только с nosuid,nodev на клиенте;
- единые uid/gid по парку — снимает целый класс проблем, но требует дисциплины;
- sec=krb5/krb5p — если данные того стоят: тогда доверие строится не на числах от клиента.
Разбор: «ВЭД-эксперт», 43 рабочих места — Ansible-роль, которая падала три недели
Компания занимается таможенным консультированием, декларанты работают в 1С и в программах подготовки деклараций на терминальных серверах. Пришли с формулировкой «не разворачивается новая база, плейбук падает на правах». Стенд простой: Debian 12 на файловой хранилке в роли NFS-сервера (nfs-kernel-server), экспорт /srv/nfs/1c-backup на подсеть 10.10.20.0/24, клиент — сервер приложений. Роль Ansible на шаге ansible.builtin.file: state=directory owner=appsvc group=appdata стабильно ловила «chown failed: [Errno 1] Operation not permitted». Плейбук выполнялся под root по SSH, каталог монтировался с rw — по мнению админа, всё должно было работать.
Смотрю exportfs -v — root_squash, дефолт. Смотрю историю: предыдущий подрядчик проблему «решил» дважды. Сначала прошёлся chmod -R 777 по всему дереву выгрузок (не помогло, потому что и не могло), потом дописал в /etc/exports строку с no_root_squash на всю подсеть 10.10.20.0/24. Вот это уже сработало — и заодно выдало права root на хранилке двенадцати машинам подсети, включая два терминальных сервера, куда пользователи заходят по RDP. Внутри шары при этом лежала распакованная старая сборка со своими бинарниками — то есть setuid-вектор был не теоретическим.
Переделали за один вечер, порядок был такой. Убрали no_root_squash и вернули дефолт. Завели на сервере appsvc с фиксированным uid/gid 1500 и пересоздали дерево каталогов через install -d с режимом 2770. Агенту резервного копирования, который принципиально работает от root, выделили отдельную строку экспорта на его единственный IP с anonuid=1500,anongid=1500. На клиентах в fstab добавили nosuid,nodev. И, что важнее всего, выкинули chown из самой роли Ansible: каталог создаёт сервер, роль только проверяет владельца и падает с внятным сообщением, если он не тот.
# /etc/exports (итог)
/srv/nfs/1c-backup 10.10.20.11(rw,sync,no_subtree_check,root_squash)
/srv/nfs/1c-backup 10.10.20.24(rw,sync,no_subtree_check,root_squash,anonuid=1500,anongid=1500)exportfs -ra && exportfs -v | grep 1c-backupИтог: роль зелёная, двенадцать машин лишились root на хранилке, режимы с 777 ужались до 2770. Вся работа заняла минут сорок вместе с перечиткой экспортов и проверкой бэкапа. Честно скажу про минус выбранного решения: anonuid здорово путает при ручной отладке. Вы под root на клиенте создаёте файл — и он оказывается во владении appsvc, хотя вы этого не просили. Через месяц об этом забывают все, кроме того, кто настраивал. Поэтому строку с anonuid я всегда комментирую прямо в /etc/exports и упоминаю в паспорте стенда.
- было: no_root_squash на /24, chmod -R 777, chown из плейбука;
- стало: root_squash по умолчанию, владелец готовится на сервере, anonuid только для бэкап-агента;
- клиенты: nosuid,nodev в fstab;
- автоматика: chown на NFS исключён из роли, вместо него проверка владельца.
NFSv4 сверху: nobody:nogroup, idmapd и лимит в 16 групп
На четвёртой версии протокола к squash добавляется вторая, полностью независимая история — отображение имён. В nfsidmap(5) сформулировано так: «The NFSv4 protocol represents the local system's UID and GID values on the wire as strings of the form user@domain». Доменная часть определяется так: параметр Domain в /etc/idmapd.conf, если он задан; иначе TXT-запись _nfsv4idmapdomain в DNS; иначе DNS-домен самого хоста. В idmapd.conf(5) умолчание для Domain так и записано — полное DNS-имя домена хоста. Если хост назван просто nas без домена, стороны легко получают разные домены. Если домены на клиенте и сервере разошлись, вы увидите nobody:nogroup вообще на всех файлах — при полностью выключенном root_squash. Отсюда и мой совет смотреть ls -n: числа не врут, имена врут постоянно.
Но в реальной жизни при sec=sys ядро по умолчанию обходит idmapping стороной и гонит по проводу обычные числа. Управляется это параметром модуля nfs4_disable_idmapping — отдельно на клиенте и на сервере. Значение Y означает, что при AUTH_SYS передаются числовые id; при sec=krb5* idmapping работает всегда. Проверяется одной командой, и я советую проверить прежде, чем полдня править idmapd.conf: очень часто он вообще ни на что не влияет, пока вы не включили Kerberos.
# клиент
cat /sys/module/nfs/parameters/nfs4_disable_idmapping
# сервер
cat /sys/module/nfsd/parameters/nfs4_disable_idmapping
grep -i '^Domain' /etc/idmapd.conf
nfsidmap -c # nfsidmap(8): очистить keyring с кэшем отображений
nfsidmap -l # посмотреть, что сейчас закэшированоТретья ловушка того же семейства — лимит на количество групп. В rpc.mountd(8) записано прямо: «Due to a limitation in the NFS protocol, at most 16 groups ids can be listed». Пользователь, состоящий в 25 группах, получает по NFS абсолютно случайную картину доступа: часть каталогов видит, часть нет, и на разных клиентах по-разному. Лечится флагом rpc.mountd --manage-gids (в современных nfs-utils — manage-gids=y в секции [mountd] файла /etc/nfs.conf; в Debian/Ubuntu работает и старый путь через RPCMOUNTDOPTS в /etc/default/nfs-kernel-server), при котором сервер сам определяет список групп по uid. Плата очевидна: пользователь и его группы должны существовать на сервере, иначе вы сделаете хуже.
- nobody:nogroup на всём + root_squash выключен → расходятся Domain в idmapd.conf;
- числовые id в `ls -n` при непонятных именах → idmapping отключён, работает AUTH_SYS;
- «часть людей видит каталог, часть нет» → почти наверняка лимит 16 групп, проверьте `id -G user | wc -w`;
- правили idmapd.conf и ничего не изменилось → сначала `nfsidmap -c`, потом уже думать.
Отдельный случай: хранилище Proxmox и репозиторий бэкапов на NAS
Самые частые жалобы на root_squash сегодня приходят не от Ansible, а от гипервизоров и систем резервного копирования. Proxmox VE монтирует NFS-хранилище сам (по умолчанию в /mnt/pve/<STORAGE_ID>) и работает с ним от root: создаёт подкаталоги images, dump, template, распаковывает контейнеры. Пока пишутся обычные файлы образов — всё выглядит живым, файлы просто принадлежат 65534. Ломается там, где нужна смена владельца: восстановление или создание LXC-контейнера с rootfs на такой шаре, распаковка шаблона с сохранением владельцев, иногда — удаление старых дампов, созданных до смены опций экспорта.
# на узле Proxmox: что отдаёт NAS
pvesm scan nfs 192.0.2.50
# /etc/pve/storage.cfg
nfs: nas-backup
server 192.0.2.50
export /volume1/pve-backup
path /mnt/pve/nas-backup
options vers=4.1
content backupС бэкап-репозиторием на NAS картина та же. Если Veeam или другой агент пишет в смонтированный Linux-каталог, его транспортный компонент обычно работает с правами root, и при root_squash вы получаете либо файлы от nobody, либо отказ на операциях с владельцем и правами. На коробочных NAS настройка squash спрятана в свойствах правила NFS (в DSM у Synology это поле Squash с вариантами вроде «No mapping» и «Map root to admin»), и выглядит безобидно, хотя по смыслу это тот же выбор между root_squash, anonuid и no_root_squash.
Мой рецепт для таких хранилищ: отдельная общая папка только под бэкапы, правило NFS строго на IP узлов гипервизора или бэкап-сервера, root отображается в выделенного пользователя NAS (аналог anonuid), а не в admin и не «без отображения» на подсеть. Под LXC-контейнеры NFS с root_squash я не использую вовсе — для них локальный ZFS/LVM-thin или отдельный экспорт с no_root_squash на IP конкретных узлов кластера. И обязательно проверяю восстановление, а не только успешное завершение задания: squash-проблемы любят проявляться именно при restore.
- Proxmox: смотреть `pvesm scan nfs` и /etc/pve/storage.cfg, писать правило экспорта на IP узлов, а не на подсеть;
- LXC rootfs и восстановление контейнеров на NFS с root_squash — типичная точка отказа с chown;
- NAS: «Map root to admin» на подсеть — тот же no_root_squash, только с другим названием;
- бэкап-репозиторий: выделенная папка, выделенный пользователь, правило на IP бэкап-сервера;
- после смены squash-опций — тестовое восстановление, а не только зелёный статус задания.
Чем платят за no_root_squash и мой короткий чек-лист
Скажу прямо, без запугивания: no_root_squash — это не «уязвимость», это осознанное расширение доверия. Вы объявляете, что администратору клиентской машины вы доверяете ровно так же, как администратору хранилища. Для бездисковой станции в лаборатории это нормально. Для терминального сервера, куда логинятся тридцать человек, и для подсети целиком — уже нет. Прибавьте сюда setuid-бинарник, который любой локальный root может положить в шару, и картина становится совсем неприятной.
Обвязка, которую я считаю обязательной, если no_root_squash всё-таки нужен: nosuid и nodev в опциях монтирования на клиенте, экспорт строго на IP, а не на маску, дефолтный secure (запрос только с привилегированного порта), фаервол на 2049 и no_subtree_check, который и так по умолчанию. Если данные чувствительные — переходите на sec=krb5p, там доверие строится на билете, а не на числе, которое клиент сам себе нарисовал.
Про sec=sys и krb5 коротко, чтобы не было иллюзий. При sec=sys (дефолт) сервер верит числам uid/gid, которые клиент сам положил в запрос, — root_squash защищает только от uid 0, а любой локальный root на клиенте может выполнить su в пользователя с uid 1500 и получить его файлы на шаре. sec=krb5 аутентифицирует пользователя билетом, krb5i добавляет контроль целостности, krb5p — шифрование трафика. Задаётся это в экспорте (sec=krb5p, можно списком через двоеточие) и в опциях монтирования клиента; без KDC, keytab на сервере и клиентах и согласованного Domain в idmapd.conf не взлетит, поэтому для 40 с небольшим рабочих мест я включаю Kerberos только там, где на шаре лежат действительно чувствительные данные.
Про приоритеты. В первую очередь — диагностика: exportfs -v и тест с ls -n. Это пять минут и снимает 80 % вопросов. Дальше — подготовка владельца на сервере, потому что это лечит причину, а не следствие. Затем разовая ревизия /etc/exports по всем хранилкам: ищите no_root_squash, all_squash и звёздочки в поле клиента. А на что можно спокойно забить: на тонкую настройку idmapd.conf, пока вы работаете на sec=sys, и на дискуссии про subtree_check — дефолт no_subtree_check вас устраивает.
И финальное, из практики: заведите привычку записывать выбранную схему в паспорт стенда. Строка anonuid=1500 без комментария через полгода выглядит как чья-то ошибка, и её обязательно кто-нибудь «почистит» — вместе с вашей моделью доступа.
- проверить: `exportfs -v` на всех NFS-серверах, grep по no_root_squash и all_squash;
- убрать: экспорты на * и на маску подсети там, где хватит перечня IP;
- добавить: nosuid,nodev на клиентах, где монтируются пользовательские шары;
- заменить: chown с клиента → подготовка каталога на сервере (install -d -o -g -m 2770);
- задокументировать: anonuid/anongid и все исключения — в паспорт стенда.
Частые вопросы
Почему файл на NFS-шаре создаётся, а chown на него не проходит?
Потому что это разные проверки. Запись разрешает режим доступа каталога на сервере, и сквошнутый аноним 65534 вполне может им обладать. А смена владельца требует CAP_CHOWN или владения файлом, чего у анонима нет. Отсюда и странная на первый взгляд картина: touch работает, chown отдаёт EPERM.
Достаточно ли перемонтировать каталог с опцией rw, чтобы вернуть root его права?
Нет. Опции монтирования задаёт клиент, а отображение uid 0 в анонима выполняет сервер при обработке запроса. Никакая клиентская опция root_squash не отменяет. Смотреть надо `exportfs -v` на сервере, а править — /etc/exports с последующим `exportfs -ra`.
Чем all_squash отличается от root_squash и когда он нужен?
root_squash отображает в анонима только идентификаторы 0, all_squash — вообще все uid и gid. По умолчанию действует no_all_squash. all_squash оправдан для публичных каталогов «только чтение для всех» и практически никогда — для рабочих шар: он стирает разделение доступа между пользователями и при этом всё равно не даёт права на chown.
Можно ли просто поставить no_root_squash и забыть?
Можно, но вы явно приравниваете администратора клиента к администратору хранилища. Если это бездисковый клиент или лабораторный стенд — приемлемо. Если это подсеть с терминальными серверами — нет. Пишите no_root_squash на один конкретный IP, монтируйте на клиенте с nosuid,nodev и записывайте это исключение в документацию стенда.
Почему после настройки прав все файлы всё равно показываются как nobody:nogroup?
Это уже другой механизм — отображение имён в NFSv4. Проверьте `ls -n`: если числовые id правильные, проблема только в идентификации имён (разные Domain в /etc/idmapd.conf, нет пользователя на одной из сторон). Сбросьте кэш командой `nfsidmap -c`. И проверьте параметр nfs4_disable_idmapping: при sec=sys ядро обычно передаёт числа, и idmapd.conf ни на что не влияет.
Часть пользователей видит каталог, а часть — нет, права при этом одинаковые. Что это?
Почти наверняка ограничение AUTH_SYS в 16 групп: в RPC-креденшлах помещается не больше 16 gid, лишние отбрасываются. Проверьте `id -G пользователь | wc -w` на клиенте. Лечение — запуск rpc.mountd с --manage-gids, тогда список групп определяет сервер; но пользователи и группы должны существовать и на сервере.
Proxmox пишет бэкапы на NFS-шару NAS, а восстановление контейнера падает на chown. Включать no_root_squash?
Не на всю сеть. Сначала проверьте, в кого NAS отображает root (`ls -n` на смонтированном каталоге узла). Для хранилища дампов обычно достаточно отображения root в выделенного пользователя NAS на IP узлов. Если контейнеры действительно должны жить или восстанавливаться на этой шаре, дайте no_root_squash только IP узлов кластера на отдельную папку, а после изменения выполните тестовое восстановление.
showmount -e ничего не показывает, но шара монтируется. Это нормально?
Да, если сервер работает только по NFSv4: showmount опрашивает rpc.mountd, а NFSv4-клиенту mountd и порт 111 не нужны. Опции экспорта в любом случае смотрите на сервере через `exportfs -v`, showmount их не выводит.
Источники
- exports(5), раздел User ID Mapping — Официальный man-page nfs-utils: root_squash («Map requests from uid/gid 0 to the anonymous uid/gid»), no_root_squash, all_squash/no_all_squash, anonuid/anongid и умолчание «exportfs chooses a uid and gid of 65534 for squashed access» ; «To apply changes to this file, run exportfs -ra or restart the NFS server»; каталог /etc/exports.d — https://man7.org/linux/man-pages/man5/exports.5.html
- rpc.mountd(8), опция --manage-gids — Ограничение протокола на количество групп: «Due to a limitation in the NFS protocol, at most 16 groups ids can be listed», и как сервер сам определяет группы по uid — https://man7.org/linux/man-pages/man8/rpc.mountd.8.html
- nfsidmap(5) — Отображение идентификаторов в NFSv4: «The NFSv4 protocol represents the local system's UID and GID values on the wire as strings of the form user@domain», порядок определения домена (idmapd.conf → DNS TXT _nfsv4idmapdomain → DNS-домен хоста) — https://man7.org/linux/man-pages/man5/nfsidmap.5.html
- nfsidmap(8) — Опции -c («Clear the keyring of all the keys») и -l, строка id_resolver в /etc/request-key.conf — https://man7.org/linux/man-pages/man8/nfsidmap.8.html
- idmapd.conf(5), Debian bookworm — Параметр Domain: «The local NFSv4 domain name», умолчание — полное DNS-имя домена хоста; секция [Mapping] Nobody-User/Nobody-Group — https://manpages.debian.org/bookworm/libnfsidmap1/idmapd.conf.5.en.html
- Linux kernel admin-guide: NFS ID mapper — Документация ядра о механизме upcall через request-key и /usr/sbin/nfs.idmap — https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfs-idmapper.html
- Red Hat Customer Portal, Solution 100013 — Unable to change permission to NFS share mounted at the client — разбор того же отказа со стороны поддержки RHEL (требуется учётная запись Red Hat) — https://access.redhat.com/solutions/100013
- Proxmox VE Wiki: Storage: NFS — Параметры server/export/path/options/content в storage.cfg, команда pvesm scan nfs, путь монтирования /mnt/pve/<STORAGE_ID> — https://pve.proxmox.com/wiki/Storage:_NFS
