Что было. Сервер экспортирует каталог с параметрами rw, клиент монтирует без ошибок, читает, но при записи Permission denied. Администратор настраивал экспорт через веб-панель и подозревал её.
Причина. На каталоге сервера права для «остальных» были только на чтение, а пользователь клиента на сервере отображался как «остальной». NFS проверяет права так же, как локальный доступ: параметр rw в /etc/exports разрешает протоколу запись, но не отменяет права файловой системы. После исправления прав каталога запись заработала; автор также перешёл на ручную правку /etc/exports вместо панели. Подтверждено.
Как сопоставляются пользователи. При sec=sys (по умолчанию) клиент передаёт числовой uid/gid своего пользователя; сервер применяет права по этим числам. Пользователь с uid 1000 на клиенте это uid 1000 на сервере, кем бы он там ни был. Root клиента по умолчанию превращается в nobody (root_squash). Отсюда три рабочих схемы:
- Одинаковые uid/gid на клиенте и сервере (
getent passwd), права каталога для этих пользователей или общей группы. - Все клиенты как один пользователь:
all_squash,anonuid=1500,anongid=1500в экспорте и каталог, принадлежащий uid 1500. Просто и предсказуемо для общих папок. - Kerberos (
sec=krb5) с сопоставлением имён черезidmapdдля сред с доменом.
Пример экспорта и прав:
/srv/nfs/media 192.0.2.0/24(rw,sync,no_subtree_check,all_squash,anonuid=1500,anongid=1500)
chown 1500:1500 /srv/nfs/media && chmod 2775 /srv/nfs/media
exportfs -ra
Диагностика.
- На сервере:
exportfs -v(действующие опции, включая неявныеroot_squash),ls -ln /srv/nfs/media(числовые владельцы). - На клиенте:
id(ваш uid),mount | grep nfs(опции, версия),touch /mnt/media/tи, при отказе,dmesg | tail(NFS пишет причины:Permission denied,Stale file handle). no_root_squashрешает «root не может писать», но открывает серверу root любого клиента; только для доверенных машин.
Про панели. Графические инструменты часто пишут /etc/exports корректно, но не трогают права ФС и молча создают ожидания, что «rw в панели» достаточно. Файл на семь строк проще проверить руками.
Формат описан в документации Ubuntu.