Как разрешить пользователям передавать файлы другим пользователям в Linux
В нашей среде несколько тысяч пользователей работают с приложениями на 40 кластерах размером от 20 вычислительных узлов до 98 000 вычислительных узлов. Пользователи в этих системах генерируют массивные файлы (иногда> 1PB), управляемые традиционными разрешениями Unix (списки ACL обычно недоступны или практически не используются из-за специфики файловой системы).
В настоящее время у нас есть программа под названием "give", которая является программой suid-root, которая позволяет пользователю "отдавать" файл другому пользователю, когда групповые разрешения недостаточны. Таким образом, пользователь должен напечатать что-то вроде следующего, чтобы передать файл другому пользователю:
> give username-to-give-to filename-to-give ...
Получающий пользователь может затем использовать команду под названием "take" (часть программы give) для получения файла:
> take filename-to-receive
Права доступа к файлу затем эффективно передаются принимающему пользователю.
Эта программа существует уже много лет, и мы хотели бы вернуться к ней с точки зрения безопасности и функциональности.
Наш текущий план действий состоит в том, чтобы устранить "гниль" в нашей текущей реализации "Give" и упаковать его в приложение с открытым исходным кодом, прежде чем мы повторно развернем его в производство.
У кого-нибудь есть другой метод, который они используют для передачи очень больших файлов между пользователями, когда доступны только традиционные разрешения Unix?
5 ответов
Если эмитент действительно хочет отдать файл, вы можете использовать двоичный файл SUID, который перемещает файл в каталог, доступный для записи всем, и имеет липкий бит (например, /tmp
), затем меняет право собственности на нового владельца. chown(3)
уже заботится об удалении set-user-ID
а также set-group-ID
биты для вас. Таким образом, новый владелец может делать с файлом все, что он хочет, включая его перемещение.
Этот каталог, доступный для записи всем, может принадлежать домашнему каталогу пользователя, если вы хотите использовать несколько файловых систем для домашних каталогов и хотите убедиться, что вы не пересекаете границы файловой системы, поскольку производительность сразу же будет ужасной. В этом случае вы, вероятно, захотите убедиться, что получатель знает, когда предлагается новый файл.
Электронная почта сделает свое дело. Более Unixy решение было бы /etc/profile
который перечисляет ваши недавно доставленные файлы. Дополнительный бонус, если вы предлагаете эту функцию с pam_echo
(например, с file=/tmp/deliveries/%u
, увидеть pam_echo(8)
). Как и во всем, что связано с PAM, вам следует сначала убедиться, что все ваши реализации предлагают такой модуль.
Как говорит xryl669, вы можете использовать каталог для обмена файлами. Это должно выглядеть так:
$ ls -ld shared
drwxrws--- 2 root usergroup 4096 somedate shared
$ ls -l shared
drwx-wx--- 2 user1 usergroup 4096 somedate user1
drwx-wx--- 2 user2 usergroup 4096 somedate user2
drwx-wx--- 2 user3 usergroup 4096 somedate user3
drwx-wx--- 2 user4 usergroup 4096 somedate user4
Команда Give становится
#!/bin/sh
#Use a random suffix to prevent guessing
RANDOM=$(dd if=/dev/urandom count=4 2> /dev/null | sha512sum | cut -d' ' -f1)
NEWNAME=/path/to/shared/$2/$1$RANDOM
#Move the file
mv $1 $NEWNAME
#Make it readable
chmod 440 $NEWNAME
Команда take выглядит примерно так:
$ cd /path/to/shared/user
$ ls
...
$ mv somefile ~
Это, вероятно, бесполезно для вас, но для справки cp --reflink source target делает копии файлов, используя копирование при записи.
Это означает, что вы можете скопировать файл напрямую, и будут скопированы только измененные блоки. В отличие от жесткой ссылки, новый файл имеет свой собственный inode и метаданные, что означает, что вы можете затем предоставить копию файла новому пользователю, используя стандартный материал chown.
Насколько я знаю, эта функция доступна только в OCFS2 и btrfs. Я предполагаю, что это решает вашу проблему, но, учитывая, что ее наличие не очень распространено, она, вероятно, не будет полезна.
Вы можете использовать систему с общим каталогом (возможно, без perms.), Где вещи для данного пользователя архивируются с определенной структурой имени файла (to-$username_from-$username.tar
, например). Даешь делает файл и chowns
это целевому пользователю; взять извлекает файл и удаляет его.
Если вы хотите сделать это как собственно перемещение (IE, изменить расположение файла и разрешения; нет копирования из-за огромного размера файла), вы можете избежать перехода в общий каталог с -x perms (так что никто не сможет список файлов есть) и тоже самое chown
метод. mv
, chown
/ mv
,
Я бы предложил переписать приложение так, чтобы оно имитировало "давать" и "брать", а не "толкать" и "вытягивать" его из защищенного каталога. Ваш каталог может быть доступен только для приложения push / pull, которое обрабатывает перемещения файлов. Кроме того, ваше приложение / сценарий может создать случайный, временный каталог с разрешениями, которые устанавливаются только для отправителя и получателя.
Хотите иметь больше безопасности? Вы можете PGP зашифровать / подписать файл (используя открытый ключ получателя).
С точки зрения переделки с точки зрения "безопасности и функциональности", я настоятельно рекомендую не создавать SUID-программы. Если вы не удаляете права должным образом, вы можете получить доступ к любому файлу в системе. Если ваша программа содержит ошибки (переполнение буфера и т. Д.) - можно воспользоваться этим, чтобы получить root-доступ в вашей системе.