Как скопировать права доступа ACL при переносе данных с сервера на сервер
Возникла необходимость перенести файлы из одной сетевой шары на линуксе на другой сервер. Оба сервера включены в домен AD. Казалась бы простая задача, бери да копируй. Права доступа должны сохраниться, ведь обе машины в одном и то же домене. Но все оказалось не так просто.
Для меня было большим удивлением, что при простом копировании через windows машину права доступа не сохранялись. На обоих серверах была файловая система с поддержкой ACL. Установить потом права вручную можно было. То есть функционал весь был, но права доступа не сохранялись. Отмечу сразу, что сервер, с которого забирал информацию был QNAP, копировал на CentOS 7.
Вторым этапом была попытка примонтировать сразу на сервер приемник файловую шару через cifs. Но при этом права доступа ACL тоже не копировались. Стал искать информацию на эту тему в интернете и нашел, что действительно, через cifs acl права не переносятся. Там есть свои утилиты для проверки и назначения прав: getcifsacl и setcifsacl. Вручную ковыряться с этим не захотелось.
Следующим этапом была попытка использовать утилиту от Microsoft — Robocopy. Понравился ее функционал, она действительно все копирует с сохранением прав доступа и другой информации о файлах. Но вот незадача. После копирования данных с одной файловой шары на другую, появлялись права доступа в виде неизвестных SID и не переводились в группы и пользователи. Ну и доступ, соответственно, не работал. Не понимаю, почему так получалось.
Я крепко призадумался, как же быть. У меня не было времени разбираться подробно, нужно было быстро что-то придумать. Возможно я где-то ошибся или невнимательно смотрел и этот процесс все же можно провести быстро. Был бы рад совету на эту тему. Раньше мне не приходилось заниматься переносом данных с 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. Но как там все подробно устроено не знаю, возможно что-то изменено.