Как скопировать права доступа ACL при переносе данных с сервера на сервер

Возникла необходимость перенести файлы из одной сетевой шары на линуксе на другой сервер. Оба сервера включены в домен AD. Казалась бы простая задача, бери да копируй. Права доступа должны сохраниться, ведь обе машины в одном и то же домене. Но все оказалось не так просто.

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Для меня было большим удивлением, что при простом копировании через windows машину права доступа не сохранялись. На обоих серверах была файловая система с поддержкой ACL. Установить потом права вручную можно было. То есть функционал весь был, но права доступа не сохранялись. Отмечу сразу, что сервер, с которого забирал информацию был QNAP, копировал на CentOS 7.

Вторым этапом была попытка примонтировать сразу на сервер приемник файловую шару через cifs. Но при этом права доступа ACL тоже не копировались. Стал искать информацию на эту тему в интернете и нашел, что действительно, через cifs acl права не переносятся. Там есть свои утилиты для проверки и назначения прав: getcifsacl и setcifsacl. Вручную ковыряться с этим не захотелось.

Следующим этапом была попытка использовать утилиту от Microsoft - Robocopy. Понравился ее функционал, она действительно все копирует с сохранением прав доступа и другой информации о файлах. Но вот незадача. После копирования данных с одной файловой шары на другую, появлялись права доступа в виде неизвестных SID и не переводились в группы и пользователи. Ну и доступ, соответственно, не работал. Не понимаю, почему так получалось.

robocopy копирование прав доступа

Я крепко призадумался, как же быть. У меня не было времени разбираться подробно, нужно было быстро что-то придумать. Возможно я где-то ошибся или невнимательно смотрел и этот процесс все же можно провести быстро. Был бы рад совету на эту тему. Раньше мне не приходилось заниматься переносом данных с samba шар с сохранением доступа. А данные с виндовых шар без проблем переносятся с сохранением прав доступа. Даже не знал, что могут возникнуть такие проблемы при переносе информации с шар на samba.

В итоге для переноса данных с сохранением прав доступа ACL я поступил следующим образом. На первом сервере, где лежали данные выполнил команду:

# getfacl -R /share/MD1_DATA/documents > permissions.acl

Команда рекурсивно собрала права доступа со всех каталогов и файлов и записала в текстовый файл. Если шара очень большая, то файл будет внушительных размеров. У меня на шаре с 80 000 каталогов и 500 000 файлов такой файл занимал 240мб. Дальше было бы здорово сделать на сервере приемнике команду:

# setfacl --restore=permissions.acl

И на этом закончить. Но все не так просто. Во-первых, в полученном файле были указаны пути в следующем формате:

# file: share/MD1_DATA/soft/Player

Почему-то в начале пути не стоял слеш. Команда setfacl сразу на это ругнулась. Плюс на сервере приемнике был другой путь, значит, его нужно отредактировать для всех описываемых объектов прав доступа во всем 240мб файле. Просто открыть его в текстовом редакторе и сделать замену затруднительно. Пришлось искать другое решение. На помощь пришла утилита sed:

# sed 's/share\/MD1_DATA/\/shares/g' permissions.acl > 1.acl

С помощью этой команды я заменил фразу share/MD1_DATA на /shares и получил теперь правильный путь /shares/soft/Player.

Но это было не все. Дальше в файле с правами доступа встречались не доменные пользователи, а локальные того сервера, с которого переезжали. Нужно было их тоже всех удалить, иначе команда не отрабатывала, вылетала с ошибкой. В моем случае это были пользователи: admin, guest, everyone. Я опять же с помощью sed просто удалил все строки, где встречались эти фразы. Делал это на всякий случай поэтапно с проверкой на каждом этапе. Получилось вот так:

# sed '/admin/d' 1.acl > 2.acl
# sed '/guest/d' 2.acl > 3.acl
# sed '/everyone/d' 3.acl > 4.acl

Можно было все в одной команде сделать, но я не очень силен в построении регулярных выражений, не было времени разбираться, сделал так. Утилита на удивление быстро работает. Буквально 2-3 секунды и строки удалены из файла.

После этого на сервере приемнике запустил команду:

# setfacl --restore=4.acl

И все доменные права доступа благополучно установились. Утилита работала достаточно долго, минут 15.

Надеюсь, мой опыт покажется кому-то полезным. А еще лучше, если бы мне кто-нибудь подсказал, как ту же самую операцию сделать проще и быстрее. Я почему-то убежден, что есть более простой способ. Возможно проблемы были из-за того, что один из серверов был QNAP. По идее это линукс, есть доступ по ssh, внутри samba. Но как там все подробно устроено не знаю, возможно что-то изменено.

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

6 комментариев

  1. Константин

    За статью, спасибо - натолкнула на решение копирования прав конкретного пользователя,
    решилось элементарно с помощью awk, через sed тоже можно, но слишком сложно и коряво :-)

    немного поздно, но добавлю
    лидирующий / никак не мешает если сохранять/восстанавливать ACL в таком порядке:

    cd /share
    sudo getfacl -R > ~/permissions.acl
    sudo setfacl --restore=~/permissions.acl

    в таком случае на один шаг проще
    и, перед восстановлением прав лучше проверить работоспособность
    sudo setfacl --test --restore=~/permissions.acl
    а то мало ли какие ошибки в файле будут

  2. А если просто star`ом обжать? Он сжимает со всеми правами ACL.

    • При переезде на другой сервер, все ACL, соответствующие виндовым учетным записям, превратятся просто в цифры и права доступа не будут работать. Тут проблема именно с виндовыми пользователями. На каждом linux сервере введенном в домен, стоит свое соответствие виндовых пользователей и их отображению в системе на основе какого-то соответствия в самом winbind. Чтобы перенести права доступа с одного такого сервера на другой, необходимо не только сохранить ACL права файлов, но и таблицы соответсвия виндовых пользователей этим ACL правам. Как сделать последнее, я не знаю, не разбирался.

  3. Приветствую!
    В прошлый раз, когда у меня была задача переноса данных с сервера на сервер, с сохранением прав, я как и вы мутил скрипты с getfacl и setfacl. И также как и вы понимал что должен был быть способ лучше.
    Сегодня я вспомнил про rsync. Настроил между серверами доступ по ключам и скопировал каталог с старого сервера на новый вот так:
    #/usr/bin/rsync -e 'ssh -l root -i /root/.ssh/id_rsa' --progress -lzuogthvrpA --compress-level=9 --delete-after root@oldserver:/share/Profiles/user.V2 /share/Profiles/

    Собственно за сохранение ACL прав отвечает ключик -A

    • Но ведь на разных серверах локальные uid будут разные у одного и того же доменного пользователя, если настройки winbind различаются. В таком случае этот вариант не прокатит.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar