Общая сетевая папка NFS+SAMBA с правами для всех

Цель: расшарить директорию через NFS и CIFS так, чтобы для обоих протоколов был общий доступ и файлы, залитые через один протокол, были доступны на чтение и запись через второй.

NFS

Метод, до которого дошел я (возможно не единственный), реализуется через дополнительного пользователя на сервере, с которого шарится директория. В моем случае это пользователь «user» с UID 1000 (входит в одноименную группу с GID 1000).

Файл /etc/exports выглядит так

/etc/exports
 
  1. "/share/Public" *(rw,nohide,async,no_subtree_check,crossmnt,all_squash,anonuid=1000,anongid=1000)

ключевыми параметрами являются:

  1. all_squash — опция говорит что все подключения будут считаться анонимными
  2. anonuid=1000 — определяет UID пользователя от имени которого будет осуществляться доступ для анонимных подключений
  3. anongid=1000 — аналогично определяет GID

Таким образом все файлы и папки, создаваемые на сервере через NFS будут иметь владельца «user»

 
 
ls -la /share/Public/test_dir/
 
 
total 12
drwxr-xr-x  3 user user 4096 Jan 14 16:18  .
drwxrwxrwx 14 user user 4096 Jan 14 16:18  ..
drwxr-xr-x  2 user user 4096 Jan 14 16:18 'nfs dir'
-rw-r--r--  1 user user    0 Jun 19  2020 'nfs file.txt'

Настройка монтирования через autofs:

 
 
  1. public -fstype=nfs4,rw,soft,tcp,retry=0 "192.168.1.2:/share/Public"

 

SAMBA

Теперь можно переходить к настройке самбы. Приведу весь свой конфиг /etc/samba/smb.conf

/etc/samba/smb.conf
 

    workgroup = WORKGROUP
    dns proxy = no
    log file = /var/log/samba/log.%m
    max log size = 200
    panic action = /usr/share/samba/panic-action %d
    server role = standalone server
    passdb backend = tdbsam
    obey pam restrictions = yes
    unix password sync = yes
    passwd program = /usr/bin/passwd %u
    passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
    pam password change = yes
    map to guest = bad user
    security = user
    usershare allow guests = yes
    acl allow execute always = true
    allow insecure wide links = yes
    # WinXP/Android X-Plore compatibility:
    ntlm auth = yes
    server min protocol = NT1
[Public]
    path = /share/Public
    mangled names = no
    writeable = yes
    follow symlinks = yes
    wide links = yes
    browsable = yes
    guest ok = yes
    guest only = yes
    force user = user
    force group = user
    create mask = 666
    directory mask = 777
  #recycle
    vfs objects = recycle
    recycle:repository = .Trash-1000/files/%U
    recylce:exclude_dir = /.Trash-1000
    recycle:keeptree = Yes
    recycle:versions = Yes
    recycle:touch = Yes

Здесь ключевыми являются опции директории:

  1. guest ok = yes — пускать юзера без аутентификации
  2. guest only = yes — пускать только анонимусов
  3. force user = user — работа с файлами ведется от имени указанного юзера «user» (аналог nfs-ного «anonuid=1000»)
  4. force group = user — аналогично для группы (аналог nfs-ного «anongid=1000»)

Настройка монтирования через autofs:

 
 
  1. public -fstype=cifs,rw,iocharset=utf8,file_mode=0666,dir_mode=0777,uid=1000,gid=1000 ://192.168.1.2/Public

 

Корзина

Отдельно прокомментирую вот это кусок

 
 
#recycle
    vfs objec ts = recycle
    recycle:repository = .Trash-1000/files/%U
    recylce:exclude_dir = /.Trash-1000
    recycle:keeptree = Yes
    recycle:versions = Yes
    recycle:touch = Yes

Дело в том, что при удалении файлов из директории, смонтированной через NFS, скорее всего (это зависит от файлового менеджера)  в точке монтирования будет создана директория корзины «.Trash-1000». В то же время клиенты Windows для сетевых путей корзину не используют, но именно для этого существуют опции самбы, которые включают сетевую корзину и позволяют указать — в какой именно директории хранить удаляемые файлы. В моем случае опция «recycle:repository» указывает правило хранения, которое соответствует правилам удалению в корзину в линуксе. То есть, при такой настройке, файлы что удаленные в линуксе через NFS, что в виндусе через SMB — попадут в один каталог. В винде, конечно, они не появятся в виндовой «корзине», но как минимум их можно будет достать из папки «.Trash-1000».

Однако при этом возникает парадоксальная ситуация, что в винде данную «корзину» очистить не получится, так как она лежит в той же шаре. То есть удаляемые файлы будут валиться в нее же. Поэтому указывается дополнительная опция, исключающая саму папку корзины из действия самба-корзины.

HOW-TO по миграции файловых серверов

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

В моем случае речь ведется о переносе шар с исходного сервера в одном домене на целевой сервер в другом домене, размер шар достигает сотен гигабайт (в некоторых случаях больше терабайта), шара на целевом сервере подключается к серверу DFS.

Итак, первым делом на целевом сервере я создаю папку work, например на диске E:, и расшариваю ее под именем «workE$». Права доступа: полный доступ для SYSTEM, OLDDOMAIN\Domain Admins, NEWDOMAIN\Domain Admins — это позволит копировать конкретные расшареные папки со старого сервера по сети внутрь work с сохранением исходных прав доступа.

Аналогичные права доступа будет очень нелишним добавить и на исходную расшареную папку и ее содержимое, потому что эти права будут копироваться как есть на целевой сервер и возможны ситуации, когда вы, будучи администратором, или не можете получить полные права доступа на файлы на исходном сервере, или, уже скопировав их на целевой, — не имеете прав на изменений атрибутов скопированных файлов. Отдельно нужно следить за папками внутри исходной, на которых отключено наследованием прав — это, к сожалению, вполне распространенная практика в моем случае — на них также нужно проставить полный доступ админам домена(-ов).

Далее, на исходный сервер устанавливается утилита robocopy и изготавливается вот такой скрипт:

rcopy.cmd
 
chcp 1251
robocopy "d:\MyShare" "\\fs-new.local\worke$\MyShare" /MIR /SEC /NS /NC /NDL /R:1 /W:1  /UNILOG:"\\fs-new.local\worke$\MyShare.txt" /TEE
pause

(первая строка нужна на случай, если исходная папка называется по-русски — без этого у меня ломалась кодировка и все файлы копировались с кракозябрами. )

Запускаете cmd с повышенными правами и стартуете скрипт. Он полностью копирует исходную папку на целевой сервер. Что важно — робокопи с этими ключами делает копию директории, а при повторном запуске — актуализирует ее (обновляет измененные файлы, добавляет новые, удаляет те которые были удалены из исходной папки). Поэтому даже если исходная шара была очень большой и копировалась несколько суток, то путем второго-третьего запуска можно уже довольно быстро актуализировать состояние на целевом сервере и пользователи не потеряют те изменения, которые были сделаны во время копирования.
Отдельно замечу что robocopy пишет в лог все ошибки копирования (строго говоря при первом запуске в лог улетают все копируемые файлы, так что лог может быть большим, но при повторном запуске туда попадают только изменения и ошибки, что довольно удобно — как раз видно, например, что на какую-то папку нет прав доступа)

Я так и делаю. Во время копирования или актуализации, пока выполняется скрипт, уже можно на целевом сервере расшарить папку и назначить права доступа к шаре, если они были настроены каким-то специфическим образом. Как только файлы актуализированы (обычно, конечно, актуализацию приходится проводить в нерабочее время) — на старом сервере шара отключается, и поднимается с тем же именем, правами только на чтение, и с двумя файликами: текстовым файлом с содержанием «уважаемые пользователи, файловые ресурс смигрирован на новый адрес: \\новый\адрес, пожалуйста запомните его или скопируйте себе ярлык»,  и ярлыком на новое место, то есть на шару на целевом сервере. Таким образом пользователи, заходя по старому адресу, обнаруживают что ничего не работает, но у них есть подсказка. Из своего опыта могу сказать что даже если у пользователей есть ярлыки куда-то вглубь, то все равно так или иначе они добираются до корня старой шары с подсказкой и вопросов возникает минимум, так что этот метод вполне стрессоустойчив для администратора =)

В моем случае я дополнительно собираю целевые шары на сервере DFS (рекомендую прочитать отдельный пост на тему настройки DFS: Перенастройка DFS для использования DNS-резолвинга), постольку поскольку целевых серверов в моем случае много и хочется дать пользователям единую точку входа. Комментарием тут может быть разве что рекомендация скрывать шару на целевом сервере, то есть реализовывать такую схему:

исходный сервер: \\old-srv\myshare
целевой сервер: \\new-srv\myshare$
dfs-сервер: \\dfs\rootname\myshare

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

Всё вышеописанное есть изложение моего личного опыта, возможно есть какие-то лучшие пути, но описанный вариант является вполне рабочим — могу его с чистой совестью рекомендовать.