Сетевые файловые системы


Сетевая файловая система обеспечивает возможность доступа по сети к файлам, расположенным на другом компьютере. В качестве сетевых файловых систем наиболее часто используются Network File System (NFS), изначально реализованная в UNIX, и CIFS (известна также как SMB), которая используется в Microsoft Windows. Мы рассмотрим обе файловые системы, но начнем с NFS, старого стандарта для UNIX.

Организовать совместный доступ к каталогам и разделам для UNIX- подобных систем проще всего с помощью сетевой файловой системы NFS (Network File System). Система FreeBSD изначально обладает поддержкой NFS. Настройка NFS часто пугает начинающих администраторов, но, выполнив эту процедуру пару раз, вы увидите, что в ней нет ничего сложного.

Все соединения NFS следуют модели клиент-сервер. Один компьютер играет роль сервера — он предоставляет доступ к своим файловым системам для других компьютеров. Это называется экспортирование NFS (NFS exporting), а предоставляемые файловые системы называются предметами экспорта (exports). Клиенты могут монтировать предметы экспорта почти так же, как локальные файловые системы.

Функциональная совместимость NFS

Все реализации NFS имеют некоторые различия. Можно заметить незначительные различия NFS в Solaris, Linux, BSD и других UNIX-подобных системах. NFS должна работать между всеми этими системами, но иногда может потребоваться выполнить некоторые настройки. Если вы испытываете сложности при работе с другими UNIX-подобными операционными системами, проверьте архив почтовой рассылки FreeBSD-net — ваша проблема наверняка уже обсуждалась здесь.

Интересно заметить, что NFS не имеет информации о своем состоянии, она не следит за состоянием соединения. Сервер NFS можно перезагрузить, и клиент при этом не пострадает. Конечно, пока сервер не заработает, он не сможет обращаться к файлам, находящимся в предметах экспорта, но как только сервер запустится, клиент окажется там же, где и остановился. Другие сетевые файловые системы не всегда так дружелюбны. Безусловно, отсутствие информации о состоянии вызывает некоторые проблемы, например, клиент не узнает, что файл, открытый им, был в это же время изменен другим клиентом.

Как для NFS-серверов, так и для NFS-клиентов необходимо выполнить настройку ядра, но различные команды NFS динамически загружают необходимые модули ядра. Ядро FreeBSD GENERIC имеет поддержку NFS, поэтому можно не беспокоиться по поводу настройки ядра.

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

Запуск сервера NFS

Чтобы включить поддержку сервера NFS, необходимо добавить в файл rc.conf следующие параметры настройки. Не все из этих параметров являются обязательными для всех возможных случаев, тем не менее все вместе они обеспечивают высокий уровень функциональной совместимости NFS и достаточно приличную производительность.

Первый параметр сообщает FreeBSD о необходимости загрузить модуль nfsserver.ko (1), если он еще не загружен. rpcbind(8) (2) отображает удаленные вызовы процедур (remote procedure calls, RPC) в локальные сетевые адреса. Все клиенты NFS спрашивают у демона rpcbind(8), работающего на стороне сервера, где они могут отыскать демон mountd(8), чтобы соединиться с ним. mountd(8) (3) ожидает получения запросов клиентов на соединение на одном из портов верхнего диапазона. При активации сервера NFS также запускается демон nfsd(8), который обслуживает фактический доступ к файлам. rpc.lockd(8) (4) обеспечивает блокировку файлов в NFS, a rpc.statd(8) (5) следит за клиентами NFS, чтобы сервер NFS мог освобождать ресурсы после отключения клиентов.

Эти службы можно запускать из командной строки, если вы знакомы с NFS, но после выполнения необходимых настроек лучше выполнить перезагрузку системы. После этого вы сможете увидеть rpc.lockd, rpc.statd, nfsd, mountd и rpcbind в выводе команды sockstat(1). Если какой-то из этих демонов отсутствует в списке, просмотрите содержимое файла /var/log/messages на наличие сообщений об ошибках.

Настройка экспорта NFS

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

Перечень клиентов и доступных им файловых систем и каталогов находится в файле /etc/exports. Для каждого диска на стороне сервера в этом файле отводится отдельная строка, в которой также перечисляются клиенты, обладающие правом доступа к этому устройству. Строки могут содержать до трех частей:

  • Экспортируемые каталоги или разделы (обязательное поле)
  • Параметры экспорта
  • Клиенты, которые могут монтировать этот каталог

Каждой комбинации клиентов и дискового устройства в этом файле может соответствовать всего одна строка. То есть, если на одном и том же разделе находятся каталоги /usr/ports и /usr/home, и оба эти каталога необходимо сделать доступными для одного и того же клиента, они должны быть перечислены в одной и той же строке. Невозможно экспортировать /usr/ports и /usr/home одному и тому же клиенту с разными правами доступа. Не обязательно экспортировать весь диск, можно экспортировать единственный каталог. Этот каталог не может содержать символических ссылок.

Из трех частей записи в /etc/exports обязательной является только первая — имя каталога. Например, если бы мне захотелось экспортировать свой домашний каталог всем желающим в Интернете, я мог бы добавить в файл /etc/exports следующую строку:

/home/mwlucas

Здесь отсутствуют какие-либо параметры и ограничения. Это, конечно, глупо, но вполне возможно.*

После редактирования файла /etc/exports необходимо сообщить демону mountd о том, чтобы он перечитал его.

# /etc/rc.d/mountd restart

Любые ошибки заносятся демоном mountd(8) в файл протокола /var/log/messages. Сообщения в файле протокола носят довольно загадочный характер: mountd(8) обычно сообщает, что строка содержит ошибку, но, как правило, не говорит — какую. Наиболее типичные ошибки, из тех, с которыми я сталкивался, связаны с наличием символических ссылок.

Активация клиента NFS

Настройка клиента выглядит намного проще, для этого достаточно поместить в /etc/rc.conf следующую строку:

nfsclient="YES"

После этого нужно перезагрузить систему или запустить команду /etc/rc.d/nfsclient start. В обоих случаях будет активирована поддержка клиента NFS.

Теперь можно монтировать каталоги и файловые системы, экспортируемые серверами NFS, только вместо имени устройства следует указывать сетевое имя сервера NFS и монтируемый каталог. Например, чтобы смонтировать каталог /home/mwlucas, экспортируемый сервером sardines, в каталог /mnt, можно запустить такую команду:

# mount sardines:/home/mwlucas /mnt

После этого с помощью df(1) можно убедиться, что каталог смонтирован.

# df
Filesystem             1K-blocks      Used    Avail Capacity  Mounted on
/dev/ad4s1a              1012974    387450   544488      42%  /
devfs                          1         1        0     100%  /dev
/dev/ad4s1f            109009798  12959014 87330002      13%  /usr
/dev/ad4s1e              1012974     42072   889866       5%  /var
sardines:/home/mwlucas 235492762 150537138 66116204      69%  /mnt

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

NFS и пользователи

Принадлежность файла и права доступа к нему определяются по числовым идентификаторам UID. Для идентификации владельца NFS тоже использует UID. Например, в моем ноутбуке пользователь mwlucas имеет UID, равный 1001. На сервере NFS пользователь mwlucas также имеет UID, равный 1001. Это упрощает мне жизнь, потому что я не должен беспокоиться по поводу принадлежности файлов — у меня одинаковые привилегии и на сервере, и на ноутбуке. В больших сетях, где пользователи обладают привилегиями root на своих машинах, это может вызывать проблемы. Лучший способ избежать их — создать центральный репозитарий авторизованных пользователей с доступом через Kerberos. В небольших сетях или в сетях с небольшим числом пользователей NFS таких проблем обычно не возникает — можно просто синхронизировать файлы /etc/master.passwd на всех системах или просто присвоить одно и то же значение UID каждому пользователю в каждой системе.

Однако пользователь root обслуживается несколько иначе. Сервер NFS не доверяет пользователям root с других компьютеров выполнять операции на сервере от имени root. В конечном итоге едва ли кто-то захочет, чтобы его сервер был остановлен, если злоумышленник взломает сервер NFS. Запросы, поступающие от root, можно отобразить на любую другую учетную запись. Например, можно потребовать, чтобы все запросы, поступающие от пользователя root клиентского компьютера, обслуживались с привилегиями пользователя на сервере nfsroot. При внимательном отношении к группам можно было бы дать пользователю nfsroot ограниченный доступ к файлам. Чтобы отобразить пользователя root в другого пользователя, следует указать параметр -maproot. В следующей строке производится отображение UID 0 (root) на стороне клиента в пользователя с UID 5000 на стороне сервера.

/usr/home/mwlucas -maproot=5000

Если действительно необходимо, чтобы пользователь root клиентского компьютера обладал привилегиями root на сервере, следует использовать отображение -maproot в UID 0. Такой подход может оказаться подходящим для домашней сети или для тестовой системы.

По умолчанию, если не использовать отображение -maproot, NFS будет отображать учетную запись удаленного пользователя root в учетную запись nobody:nobody на сервере.

Не забывайте перезапускать mountd(8) после редактирования файла /etc/exports.

Экспорт нескольких каталогов

Из раздела /usr можно было бы экспортировать множество каталогов. Среди наиболее вероятных кандидатов на экспорт можно было бы назвать каталоги /usr/src, /usr/obj и /usr/ports/distfiles. Список всех каталогов, находящихся на одном и том же разделе, должен располагаться в одной строке файла /etc/exports, сразу вслед за первым каталогом; разделителем должен быть пробел. Мой файл /etc/exports сейчас выглядит так:

/usr/home/mwlucas /usr/src /usr/obj /usr/ports/distfiles -maproot=5000

Здесь нет ни идентификаторов, ни разделителей между отдельными частями строки. Конечно, файл было бы проще читать, если бы описание каждого экспортируемого каталога находилось в отдельной строке, но это невозможно, так как все эти каталоги находятся на одном и том же разделе. Группа разработчиков FreeBSD могла бы ликвидировать эту проблему, но тогда формат файла /etc/exports FreeBSD окажется несовместим с форматом файла в других версиях UNIX.

Как и в случае со многими другими конфигурационными файлами, можно использовать символ обратного слэша для деления одной конфигурационной записи на несколько строк. Так, строка, которая была показана выше, может быть записана более удобочитаемым образом:

/usr/home/mwlucas \
    /usr/src \
    /usr/obj \
    /usr/ports/distfiles \
    -maproot = 5000

Ограничение клиентов

Чтобы дать право доступа к экспортируемым каталогам NFS только определенным клиентам, их следует перечислить в конце записи в файле /etc/exports. Ниже показана запись, которая разрешает доступ к разделяемым ресурсам только с одного IP-адреса:

/usr/home/mwlucas /usr/src /usr/obj /usr/ports/distfiles \
    -maproot=5000 192.168.1.200

Подобным образом, используя квантификаторы -network и -mask, можно дать право доступа только клиентам из определенной сети:

/usr/home/mwlucas /usr/src /usr/obj /usr/ports/distfiles \
    -maproot=5000 -network 192.168.0 -mask 255.255.255.0

Эта запись позволит клиентам, чьи IP-адреса начинаются с 192.168.0, получить доступ к серверу NFS. Подобные настройки я использую для быстрого обновления клиентов. Я собираю новые пакеты и ядро на сервере NFS, а затем позволяю клиентам смонтировать эти разделы и установить скомпилированные двоичные файлы через NFS.

Комбинирование клиентов и экспортируемых каталогов

Каждая строка в файле /etc/exports определяет экспортируемые каталоги из одного раздела и хост или несколько хостов клиентов. Для разных хостов можно создать совершенно разные определения экспорта.

/usr/home/mwlucas /usr/src /usr/obj /usr/ports/distfiles \
    -maproot=5000 192.168.1.200
/usr -maproot=0 192.168.1.201

В этом примере несколько каталогов из раздела /usr экспортируются клиенту NFS с IP-адресом 192.168.1.200. А клиент с адресом 192.168. 1.201 может смонтировать весь раздел /usr, и даже с правами root.

Производительность NFS и параметры

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

Во-первых, по умолчанию NFS работает через протокол UDP. Если воспользоваться параметром tcp или , для отправки запросов на монтирование клиенты будут использовать протокол TCP.

Программы предполагают, что файловая система не может исчезнуть, но когда речь идет о файловой системе NFS, всегда есть вероятность, что сервер пропадет из сети. В результате программы на стороне клиента, пытающиеся получить доступ к файловой системе NFS, могут зависнуть навсегда. Если с помощью параметра intr сделать операцию монтирования NFS прерываемой (interruptible), можно будет с помощью комбинации Ctrl-C прерывать работу процессов, зависших при попытке смонтировать недоступный раздел NFS.

FreeBSD может уведомлять клиентов в случае недоступности файловой системы. В результате вместо зависания программы будут терпеть неудачу при попытке получить доступ к файловой системе.

Наконец, можно установить размеры запросов на чтение и запись. Значения по умолчанию отлично подходили для сетей начала 90-х годов, но вы с помощью ключей -r и -w можете указать иные размеры, более подходящие для современных условий. Я установил, что для обоих параметров отлично подходит значение 32768. А теперь, объединив все вышесказанное, я мог бы на стороне клиента использовать такую команду монтирования файловой системы NFS:

# mount -o tcp,intr,soft,-w=32768,-r=32768 server:/usr/home/mwlucas /mnt

Соответствующая ей запись в файле /etc/fstab выглядит так:

server:/usr/home/mwlucas /mnt nfs rw,-w=32768,-r=32768,tcp,soft,intr 0 0

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

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

Комментарии запрещены.