Кратко

  • RFC 2054 рекомендовал TCP на порту 2049, затем UDP 2049, NFSv3 с публичным дескриптором нулевой длины и откат по конкретным ошибкам к v2, PORTMAP и MOUNT.
  • Публичный filehandle давал исходную ссылку, но не подтверждал личность, разрешение export, целостность всего пути или успешное чтение файла.
  • Многокомпонентный LOOKUP сокращал число обменов, сохраняя отдельные условия для канонического и native-пути, символических ссылок и перехода между файловыми системами.

Традиционный старт состоял из двух поисков

NFS работал как программа ONC RPC. Служба привязки на порту 111 сообщала динамический порт программы. У MOUNT не было известного порта, поэтому клиент спрашивал PORTMAP, находил MOUNT и вызывал MOUNTPROC_MNT, превращая export path в исходный дескриптор сервера. Лишь затем начиналась работа NFS.

Разделение сохраняло ответственность служб, но добавляло сетевые раунды и мешало фильтрам, которым трудно пропускать динамический порт MOUNT. RFC 2054 использовал распространенную регистрацию NFS на 2049 как обратимое предположение: попробовать TCP 2049, после отказа — UDP 2049, а к PORTMAP обращаться только при отсутствии ответа обоими способами.

Ответ порта закрывал лишь вопрос достижимости программной поверхности. Он не доказывал версию NFS, поддержку WebNFS, личность ответившего узла, права или будущую передачу данных.

Ошибка указывала уровень неверного предположения

После контакта клиент предполагал WebNFS и NFSv3 и обычно отправлял LOOKUP с публичным v3 handle. RPC-ошибка PROG_MISMATCH опровергала версию программы, поэтому следовала попытка NFSv2 с его публичным дескриптором.

Ошибки NFS3ERR_STALE, NFS3ERR_INVAL или NFS3ERR_BADHANDLE опровергали поддержку зарезервированного значения. Тогда клиент должен был найти MOUNT через PORTMAP и получить обычный исходный handle. Отказ TCP, молчание UDP, несовпадение версии и непризнанный дескриптор — разные свидетельства с разными маршрутами восстановления.

Ноль обозначал начало, а не полномочие

Обычный filehandle создавался сервером и оставался непрозрачным для клиента. Публичное исключение в NFSv2 состояло из 32 нулевых октетов, а в NFSv3 имело нулевую длину. Там не было inode, имени export, пользователя, секрета или разрешения. Значение включало особую семантику от точки, выбранной администратором.

Парный RFC 2055 не позволяет принять «публичный» за «разрешенный». Сервер обязан отказать, если конечный объект не находится в экспортированной файловой системе. Переход во второй export также не гарантирован: реализация, проверяющая доступ только через MOUNT, не может автоматически разрешить его, когда MOUNT пропущен. Больше свободы есть у сервера, проверяющего export при каждом NFS-запросе, но власть дает проверка, а не ноль.

Один LOOKUP нес несколько компонентов, а не больше истины

Обычный LOOKUP разрешал один компонент относительно дескриптора каталога. Только относительно публичного handle расширение позволяло передать a/b/c целиком и получить handle последнего компонента.

Строка с ASCII-началом выбирала канонический slash-путь и установленные escape-правила. Начальный slash задавал корень сервера, его отсутствие — каталог публичного handle. Октет 0x80 выбирал native syntax сервера. Формы определяли разные договоры интерпретации.

Сервер проходил промежуточные symbolic links. Если ссылкой был последний компонент, он возвращал ее handle, а клиент выполнял READLINK. Абсолютная цель снова разрешалась от публичной точки; относительная подставлялась на место последнего компонента. RFC 2054 определял это поведение клиента лишь для ссылки, найденной каноническим многокомпонентным поиском.

Обычный NFS LOOKUP обычно не переходил server mountpoint. Публичный поиск мог перейти только в экспортированную систему и при поддержке spanning-семантики RFC 2055. Полученный handle доказывал конкретное разрешение имени в данный момент и при данной политике, а не вечную безопасность пути.

Не складывать квитанции в доверенность

Ответ на 2049, признание нулевого handle и результат LOOKUP — три отдельных факта. Для утверждения об успешном доступе нужны ожидаемая сторона, необходимая аутентификация и целостность, права export и операции, корректное прохождение ссылок, ожидаемое содержимое и завершенный READ. Стабильное хранение и прикладной результат требуют иных наблюдений.

RFC 2054 наследовал положения безопасности NFS и RPC и допускал отдельное согласование аутентификации, целостности и конфиденциальности. Нулевое значение этих функций не получало.

Источники