Новинка Виртуальный VDS сервер в Нидерландах от 390р
Выберите продукт

NFSv4 на Linux VDS: exports, idmapd, firewall и systemd automount

Разберём, как поднять NFSv4 Linux на VDS для общих каталогов: подготовить сервер и клиентов, описать exports, настроить idmapd, открыть firewall NFS и подключать шары через systemd automount без зависаний при загрузке.
NFSv4 на Linux VDS: exports, idmapd, firewall и systemd automount

NFSv4 — простой и предсказуемый способ дать нескольким Linux-серверам общий каталог: медиафайлы проекта, артефакты сборки, общие uploads, резервную staging-копию или файловое хранилище для внутренних сервисов. На облачных VDS это особенно удобно, когда есть отдельный сервер с диском побольше и несколько приложений, которым нужен доступ к одним и тем же файлам.

В этой инструкции настроим NFSv4 Linux в практичном варианте: один сервер экспортирует каталог, клиенты монтируют его безопасно и без подвисания загрузки. Отдельно разберём exports, сопоставление пользователей через idmapd, права доступа, systemd automount, firewall NFS и диагностику типовых ошибок.

Главная идея NFSv4: в большинстве обычных сценариев достаточно TCP-порта 2049, понятной структуры экспортов и одинаковой модели UID/GID на сервере и клиентах.

Когда NFSv4 подходит, а когда лучше подумать дважды

NFS хорош для доверенной инфраструктуры: несколько VDS в одной приватной сети, backend-сервисы одного проекта, CI-узлы, внутренние админские задачи. Он даёт привычную файловую семантику Linux: каталоги, права, владельцы, блокировки, обычные операции чтения и записи. Для приложений это выглядит как локальная файловая система, хотя данные находятся на другом сервере.

Но NFS не стоит воспринимать как магическую замену распределённому хранилищу. Один NFS-сервер остаётся единой точкой отказа, задержка сети влияет на операции с мелкими файлами, а некорректные права быстро превращаются в «почему PHP не может записать upload». Для высоконагруженных баз данных NFS обычно плохая идея: базы любят локальный диск с предсказуемыми задержками, fsync и контролем кэша.

Хорошие сценарии для NFSv4 на VDS:

  • общий каталог медиафайлов для нескольких web-нод;
  • хранилище артефактов сборки и деплоя;
  • каталоги обмена между внутренними сервисами;
  • read-only раздача конфигураций или статических данных;
  • централизованное место для бэкапов небольших проектов, если отдельно продуманы снапшоты и копии.

Плохие или рискованные сценарии: хранение активного PostgreSQL/MySQL datadir, общие PHP-сессии без понимания блокировок и garbage collection, публично доступный NFS через интернет без строгого ограничения источников. Если выбираете между сетевыми файловыми системами для небольшой инфраструктуры, полезно отдельно сравнить NFS и SSHFS для серверного хранилища.

Схема стенда и базовые допущения

Дальше будем использовать такую схему:

  • NFS-сервер: 10.10.0.10, hostname nfs1.example.internal;
  • клиент: 10.10.0.21, hostname web1.example.internal;
  • экспортируемый каталог на сервере: /srv/nfs/projects;
  • точка монтирования на клиенте: /mnt/projects;
  • NFS-домен для idmap: example.internal.

IP-адреса и имена замените на свои. Важно, чтобы сервер и клиенты видели друг друга по сети, а firewall разрешал доступ к NFS только нужным адресам. Для production-окружения лучше использовать приватные адреса, а не открывать порт 2049 всему интернету.

Схема NFSv4: сервер, клиенты, exports и точки монтирования

Установка пакетов NFS

Пакеты отличаются по семействам дистрибутивов, но логика одинаковая: на сервер ставим NFS server, на клиент — утилиты для монтирования. Если одна и та же VDS будет и сервером, и клиентом, можно поставить оба набора.

Debian и Ubuntu

На сервере:

sudo apt update
sudo apt install nfs-kernel-server nfs-common
sudo systemctl enable --now nfs-server

На клиенте достаточно:

sudo apt update
sudo apt install nfs-common

AlmaLinux, Rocky Linux, CentOS Stream, Oracle Linux и Fedora

На сервере:

sudo dnf install nfs-utils
sudo systemctl enable --now nfs-server

На клиенте ставится тот же пакет:

sudo dnf install nfs-utils

Проверить, что серверная часть запущена, можно так:

systemctl status nfs-server
ss -ltnp | grep 2049

Для NFSv4 обычно достаточно, чтобы слушался 2049/tcp. Старые сервисы вроде rpcbind, mountd и дополнительных динамических портов важнее для NFSv3. В этой статье мы целимся именно в NFSv4, чтобы упростить firewall и поведение клиентов.

Готовим каталог и пользователей

Самый частый источник проблем — несовпадение владельцев. NFS передаёт не «имя пользователя» как красивую строку, а права, завязанные на UID/GID и механизм idmap. Если на сервере пользователь deploy имеет UID 1001, а на клиенте UID 1001 принадлежит другому пользователю, получится неприятный сюрприз.

Есть два рабочих подхода. Первый — синхронизировать UID/GID для технических пользователей на всех серверах. Второй — использовать NFSv4 idmapping с одинаковым доменом и согласованными именами. На небольших VDS-проектах проще всего комбинировать: завести одинакового пользователя и группу с одинаковыми числовыми идентификаторами.

Создадим группу и пользователя для приложения. Если пользователь уже существует, проверьте его UID/GID командой id.

sudo groupadd --gid 2000 webshared
sudo useradd --uid 2000 --gid 2000 --home-dir /nonexistent --shell /usr/sbin/nologin webshared
id webshared

На RHEL-based системах путь к nologin может быть другим:

sudo useradd --uid 2000 --gid 2000 --home-dir /nonexistent --shell /sbin/nologin webshared

Подготовим каталог на NFS-сервере:

sudo mkdir -p /srv/nfs/projects
sudo chown webshared:webshared /srv/nfs/projects
sudo chmod 2770 /srv/nfs/projects

Режим 2770 включает setgid-бит на каталоге: новые файлы и подкаталоги будут наследовать группу webshared. Это удобно, когда несколько процессов на разных клиентах пишут в общий каталог через одну группу.

Настройка /etc/exports для NFSv4

В NFSv4 часто используют псевдокорень экспорта. Это верхняя точка, относительно которой клиенты видят остальные каталоги. Например, экспортируем /srv/nfs как корень с fsid=0, а внутри него — каталог projects.

Откройте /etc/exports на сервере и добавьте правила. В примере доступ разрешён только клиенту 10.10.0.21:

/srv/nfs 10.10.0.21(rw,fsid=0,crossmnt,no_subtree_check,root_squash,sec=sys)
/srv/nfs/projects 10.10.0.21(rw,sync,no_subtree_check,root_squash,sec=sys)

Если клиентов несколько, укажите их отдельными записями или используйте подсеть. Например, для приватной сети 10.10.0.0/24:

/srv/nfs 10.10.0.0/24(rw,fsid=0,crossmnt,no_subtree_check,root_squash,sec=sys)
/srv/nfs/projects 10.10.0.0/24(rw,sync,no_subtree_check,root_squash,sec=sys)

Разберём важные параметры exports:

  • rw разрешает чтение и запись. Для статических данных лучше использовать ro.
  • fsid=0 задаёт псевдокорень NFSv4.
  • crossmnt позволяет клиенту проходить через смонтированные внутри подкаталоги, если они появятся.
  • sync заставляет сервер подтверждать запись только после сохранения данных. Это безопаснее, но может быть медленнее.
  • no_subtree_check отключает проверку поддерева, снижая количество странных ошибок при переименованиях.
  • root_squash превращает root на клиенте в анонимного пользователя на сервере. Это нормальная защитная настройка.
  • sec=sys означает обычную UNIX-аутентификацию по UID/GID.

Примените экспорт и проверьте итог:

sudo exportfs -rav
sudo exportfs -v

Если exportfs ругается на синтаксис, внимательно проверьте пробелы. В /etc/exports между адресом клиента и скобкой с опциями не должно быть пробела: 10.10.0.21(rw,...) — правильно, 10.10.0.21 (rw,...) — уже другой смысл.

Настраиваем idmapd: чтобы владельцы не превращались в nobody

Для NFSv4 сопоставление имён пользователей связано с доменом idmap. Если домен на сервере и клиентах разный, файлы могут отображаться владельцем nobody или 4294967294. Даже если запись работает, администрировать такие каталоги неудобно.

Откройте /etc/idmapd.conf на сервере и клиентах. Найдите секцию [General] и задайте одинаковый домен:

[General]
Domain = example.internal

После изменения перезапустите службы. На Debian/Ubuntu:

sudo systemctl restart nfs-idmapd
sudo systemctl restart nfs-server

На RHEL-based и Fedora чаще используется общий набор служб из nfs-utils. Если отдельный unit отсутствует, это нормально: перезапустите NFS-сервер и очистите keyring idmap на клиентах.

sudo systemctl restart nfs-server
sudo nfsidmap -c

На клиенте после правки idmapd.conf выполните:

sudo nfsidmap -c
sudo umount /mnt/projects
sudo mount /mnt/projects

Если точка ещё не была смонтирована, команда umount вернёт ошибку — это не страшно. Главное, чтобы после нового mount владельцы отображались ожидаемо:

ls -ln /mnt/projects
ls -l /mnt/projects

Команда ls -ln показывает числовые UID/GID, а ls -l — имена. Если числа правильные, но имена другие, проблема в локальной базе пользователей. Если числа неожиданные, ищите расхождение UID/GID или idmap.

Firewall NFS: открываем только нужное

Для NFSv4 без NFSv3-клиентов базовое правило простое: разрешить 2049/tcp от доверенных IP-адресов. Не открывайте NFS на весь мир. Даже если у вас строгие exports, firewall должен быть первым рубежом.

UFW на Debian/Ubuntu

sudo ufw allow from 10.10.0.21 to any port 2049 proto tcp
sudo ufw status verbose

Для подсети:

sudo ufw allow from 10.10.0.0/24 to any port 2049 proto tcp

firewalld на RHEL-based и Fedora

Если используете firewalld, лучше создать правило с источником. Пример для подсети:

sudo firewall-cmd --permanent --add-rich-rule=rule family=ipv4 source address=10.10.0.0/24 port port=2049 protocol=tcp accept
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Если у вас выделенная зона для приватного интерфейса, можно разрешить сервис NFS только в этой зоне. Но не добавляйте nfs в публичную зону без ограничения источников.

nftables

Минимальный пример правила для уже существующей цепочки input:

sudo nft add rule inet filter input ip saddr 10.10.0.0/24 tcp dport 2049 accept

Если политика по умолчанию drop, убедитесь, что разрешены established-соединения и SSH, иначе можно случайно отрезать себе доступ. Для аккуратного изменения firewall на удалённой VDS держите открытой вторую SSH-сессию и заранее подготовьте откат.

Ручное монтирование NFSv4 на клиенте

Создадим точку монтирования на клиенте:

sudo mkdir -p /mnt/projects

Так как у нас есть псевдокорень /srv/nfs с fsid=0, клиент может монтировать каталог относительно него:

sudo mount -t nfs4 -o nfsvers=4.2,proto=tcp,hard,timeo=600,retrans=2 10.10.0.10:/projects /mnt/projects

Проверьте тип файловой системы и параметры:

findmnt /mnt/projects
nfsstat -m

Создадим тестовый файл от имени пользователя, который должен писать в общий каталог. Если приложение работает под www-data, nginx, apache или отдельным deploy-пользователем, тестируйте именно им, а не root.

sudo -u webshared touch /mnt/projects/test-from-client
ls -l /mnt/projects/test-from-client

Если root может создать файл, а приложение нет, это не «NFS сломался», а обычная проблема прав. Проверьте владельца каталога, группу, setgid-бит, umask приложения и соответствие UID/GID.

Постоянное подключение через /etc/fstab

Самый простой вариант — добавить запись в /etc/fstab. Но для сетевых файловых систем важно не подвесить загрузку сервера, если NFS-сервер временно недоступен. Поэтому используем _netdev, nofail и systemd-automount.

10.10.0.10:/projects /mnt/projects nfs4 rw,nfsvers=4.2,proto=tcp,hard,timeo=600,retrans=2,_netdev,nofail,noauto,x-systemd.automount,x-systemd.idle-timeout=300 0 0

Что дают эти параметры:

  • noauto не монтирует ресурс немедленно во время boot как обычный диск;
  • x-systemd.automount создаёт automount-точку: реальное подключение произойдёт при первом обращении;
  • _netdev помечает ресурс как сетевой;
  • nofail не переводит загрузку в аварийный режим, если ресурс недоступен;
  • x-systemd.idle-timeout=300 размонтирует ресурс после 300 секунд простоя;
  • hard заставляет операции ждать восстановления сервера, а не возвращать приложению ошибку записи слишком рано.

Примените изменения:

sudo systemctl daemon-reload
sudo systemctl restart remote-fs.target
systemctl list-units --type=automount
findmnt /mnt/projects

Если findmnt ещё не показывает NFS-монтирование, обратитесь к каталогу:

ls /mnt/projects
findmnt /mnt/projects

Такой подход особенно полезен для web-серверов и воркеров: система загружается быстро, а NFS подключается только тогда, когда действительно нужен. При недоступном NFS-сервере зависнет конкретная операция доступа к каталогу, а не весь boot-процесс.

Отдельные systemd unit-файлы: когда fstab уже тесен

/etc/fstab хорош для большинства задач. Но если нужно явно описывать зависимости, таймауты и порядок запуска, можно создать пару unit-файлов .mount и .automount. Имя mount-unit зависит от пути: /mnt/projects превращается в mnt-projects.mount.

Файл /etc/systemd/system/mnt-projects.mount:

[Unit]
Description=NFSv4 projects mount
After=network-online.target
Wants=network-online.target

[Mount]
What=10.10.0.10:/projects
Where=/mnt/projects
Type=nfs4
Options=rw,nfsvers=4.2,proto=tcp,hard,timeo=600,retrans=2,_netdev

[Install]
WantedBy=multi-user.target

Файл /etc/systemd/system/mnt-projects.automount:

[Unit]
Description=Automount NFSv4 projects

[Automount]
Where=/mnt/projects
TimeoutIdleSec=300

[Install]
WantedBy=multi-user.target

Активируем automount:

sudo systemctl daemon-reload
sudo systemctl enable --now mnt-projects.automount
systemctl status mnt-projects.automount

Не включайте одновременно и fstab-запись, и ручные unit-файлы для одной точки монтирования. Выберите один способ, иначе диагностика станет запутанной: systemd может генерировать mount-unit из fstab и параллельно видеть ваш файл.

Диагностика systemd automount и firewall для NFSv4

Параметры клиента: hard, soft, таймауты и версии

Параметр hard означает, что клиент будет ждать восстановления NFS-сервера. Это хорошо для целостности данных: приложение не получает ложного успеха или случайной ошибки там, где операция записи ещё может завершиться после восстановления связи. Минус — процессы могут зависать в состоянии ожидания I/O.

soft заставляет операции завершаться ошибкой после таймаутов. Это иногда применяют для read-only ресурсов или неважных данных, но для записи пользовательских файлов лучше не использовать: риск повреждения данных и непредсказуемого поведения приложения выше, чем выгода.

Параметры timeo и retrans задают поведение повторов. В примерах выше timeo=600 соответствует 60 секундам, потому что значение указывается в десятых долях секунды. Это консервативная настройка: она не создаёт слишком агрессивных повторов при кратких сетевых паузах.

Версию NFS лучше указывать явно: nfsvers=4.2 или nfsvers=4.1. Если сервер и клиент современные, 4.2 обычно работает нормально. Если видите странные проблемы совместимости, попробуйте 4.1 и проверьте журнал.

Права доступа и root squash на практике

root_squash часто кажется неудобным: root на клиенте не может просто взять и записать файл как root на сервере. Но это защита от ситуации, когда компрометация одного клиента автоматически даёт полный root-доступ к экспортированным данным.

Правильный путь — не отключать root_squash, а настроить владельцев и группы. Например, web-приложение пишет в каталог от имени webshared или через группу webshared. Администраторские операции выполняются на NFS-сервере напрямую или через sudo с понятными правилами.

Проверочный набор команд:

id webshared
namei -l /mnt/projects
getfacl /mnt/projects
sudo -u webshared touch /mnt/projects/write-check

Если используете ACL, убедитесь, что они включены и понятны всем администраторам проекта. Простые права UNIX с общей группой обычно легче сопровождать, чем сложная сетка ACL, о которой никто не помнит через полгода.

Диагностика: что смотреть, когда не монтируется

Начинайте с сети. Клиент должен достучаться до сервера по TCP 2049:

nc -vz 10.10.0.10 2049
ss -tn dst 10.10.0.10

Если порт закрыт, смотрите firewall на сервере, маршрут между VDS и то, на каком адресе слушает NFS. На сервере полезны:

ss -ltnp | grep 2049
sudo exportfs -v
sudo journalctl -u nfs-server -n 100 --no-pager

На клиенте:

sudo mount -vvv -t nfs4 10.10.0.10:/projects /mnt/projects
sudo journalctl -b | grep -i nfs
nfsstat -m

Ошибка access denied by server while mounting обычно означает, что IP клиента не совпал с правилом в /etc/exports, экспорт не применён через exportfs -rav, или клиент монтирует не тот путь. Для NFSv4 с fsid=0 путь 10.10.0.10:/projects может быть правильным, а 10.10.0.10:/srv/nfs/projects — нет, потому что клиент видит псевдокорень, а не реальный путь сервера.

Если владельцы отображаются как nobody, проверьте /etc/idmapd.conf на всех узлах, очистите idmap-кэш и перемонтируйте ресурс. Если запись невозможна, проверьте не только exports, но и обычные права Linux на серверном каталоге.

Диагностика зависаний и stale file handle

Если процессы зависли при обращении к каталогу, сначала проверьте доступность NFS-сервера. При hard-монтировании это ожидаемое поведение: клиент ждёт восстановления. Посмотреть процессы в ожидании I/O можно так:

ps -eo pid,stat,wchan:32,cmd | grep nfs
cat /proc/mounts | grep nfs
journalctl -b | grep -i nfs

Ошибка Stale file handle появляется, когда объект на сервере был удалён, переименован или экспорт изменился так, что клиент держит устаревшую ссылку. Обычно помогает закрыть процессы, которые держат каталог, и перемонтировать ресурс:

sudo lsof +f -- /mnt/projects
sudo fuser -vm /mnt/projects
sudo umount /mnt/projects
sudo mount /mnt/projects

Если обычный umount не проходит из-за занятости, не спешите применять ленивое размонтирование в продакшене. Сначала найдите процессы через lsof и fuser. Ленивое размонтирование может скрыть проблему и оставить приложение в неожиданном состоянии.

Производительность: базовые проверки без преждевременной магии

У NFS есть параметры rsize и wsize, влияющие на размер блоков чтения и записи. Современные клиенты часто подбирают адекватные значения автоматически. Перед ручной настройкой посмотрите, что реально используется:

nfsstat -m

Для грубой проверки последовательной записи можно использовать dd, но не делайте далеко идущих выводов только по одному тесту:

dd if=/dev/zero of=/mnt/projects/test.bin bs=1M count=1024 status=progress
sync
rm /mnt/projects/test.bin

Если приложение работает с тысячами мелких файлов, важнее будет задержка сети и количество metadata-операций, а не красивая скорость последовательной записи. В таких случаях помогает кэширование на уровне приложения, упаковка артефактов, уменьшение числа файлов и отказ от NFS для горячего пути запроса.

Следите и за сервером: NFS может упереться в диск, CPU, сетевой интерфейс или лимиты виртуализации. Для первого осмотра достаточно iostat, pidstat, sar, ss и журналов. Если задержки диска растут, тюнинг NFS не спасёт — нужно разбираться с I/O.

Мини-чеклист безопасной production-настройки

  • Используйте NFSv4 и открывайте только 2049/tcp для доверенных IP.
  • Не публикуйте NFS в интернет без сетевых ограничений.
  • Держите root_squash включённым, если нет очень веской причины.
  • Синхронизируйте UID/GID или аккуратно настройте idmapd.
  • Для boot-safe подключения используйте systemd automount, nofail и _netdev.
  • Для данных на запись предпочитайте hard, а не soft.
  • Проверяйте бэкапы NFS-сервера: общий каталог не отменяет резервное копирование.
  • Документируйте, какие клиенты имеют доступ и почему они перечислены в exports.

Короткий рабочий пример целиком

На сервере: установить пакеты, создать каталог, прописать экспорт, применить настройки и открыть firewall только для клиента.

sudo mkdir -p /srv/nfs/projects
sudo chown webshared:webshared /srv/nfs/projects
sudo chmod 2770 /srv/nfs/projects
sudo editor /etc/exports
sudo exportfs -rav
sudo systemctl restart nfs-server
sudo ufw allow from 10.10.0.21 to any port 2049 proto tcp

Содержимое /etc/exports:

/srv/nfs 10.10.0.21(rw,fsid=0,crossmnt,no_subtree_check,root_squash,sec=sys)
/srv/nfs/projects 10.10.0.21(rw,sync,no_subtree_check,root_squash,sec=sys)

На клиенте: установить утилиты, создать точку, добавить automount в fstab, проверить доступ.

sudo mkdir -p /mnt/projects
sudo editor /etc/fstab
sudo systemctl daemon-reload
sudo systemctl restart remote-fs.target
ls /mnt/projects
findmnt /mnt/projects

Строка /etc/fstab:

10.10.0.10:/projects /mnt/projects nfs4 rw,nfsvers=4.2,proto=tcp,hard,timeo=600,retrans=2,_netdev,nofail,noauto,x-systemd.automount,x-systemd.idle-timeout=300 0 0

Итоги

NFSv4 на Linux VDS — несложная, но требовательная к аккуратности технология. Надёжная настройка держится на нескольких вещах: понятные exports, одинаковый idmapd-домен, согласованные UID/GID, закрытый firewall NFS и правильное подключение через systemd automount. Если сделать это сразу, общий каталог будет вести себя предсказуемо и не станет причиной долгих простоев при перезагрузке или сетевой паузе.

Для небольших и средних проектов NFSv4 остаётся хорошим инструментом: он прозрачен для приложений, легко диагностируется стандартными Linux-командами и не требует сложного кластера. Главное — не переоценивать его: важные данные всё равно нужно бэкапить, доступ ограничивать, а производительность проверять на реальной нагрузке вашего приложения.

Поделиться статьей

Вам будет интересно

Nginx debug log на VDS: включаем отладку только для нужного IP OpenAI Статья написана AI (GPT 5)

Nginx debug log на VDS: включаем отладку только для нужного IP

Показываем, как на VDS включить подробный nginx debug log не для всего трафика, а только для вашего IP: проверить сборку Nginx, на ...
Netplan на Ubuntu VDS: статический IPv4/IPv6, default route, DNS и безопасное применение по SSH OpenAI Статья написана AI (GPT 5)

Netplan на Ubuntu VDS: статический IPv4/IPv6, default route, DNS и безопасное применение по SSH

Пошаговая инструкция по Netplan для Ubuntu VDS: как найти интерфейс, прописать static IP, IPv6, default route и DNS, проверить net ...
Linux TCP backlog на VDS: somaxconn, tcp_max_syn_backlog, Nginx и PHP-FPM OpenAI Статья написана AI (GPT 5)

Linux TCP backlog на VDS: somaxconn, tcp_max_syn_backlog, Nginx и PHP-FPM

Когда сайт получает всплеск соединений, узкое место может быть не в CPU, а в очередях TCP. Поясняем, как увидеть переполнение back ...