Монтируем шары для юзеров

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всем привет. Монтируете ли вы шары, как их монтирую я? Вероятно, нет, т. к. очень крутой опции multiuser на просторах интернета уделено слишком мало внимания, а man mount.cifs в её отношении весьма немногословен и скуп на наглядные примеры. Именно это и сподвигло меня поделиться с вами парой «рецептов», которые могут облегчить вам и вашим пользователям движение в сторону отечественных десктопов и ИТ-инфраструктур.

Как обычно у меня на стенде российская RedOS 7, просто как образец операционной системы с не самым древним набором пакетов и инициализацией посредством systemd. С другими дистрибутивами вы справитесь самостоятельно. Юзеры и компьютеры живут в виндовом домене, а из отягчающих обстоятельств — наличие многопользовательских рабочих мест (сменный персонал).

Отечественные операционные системы (а это в основном Linux) дают нам возможность монтировать сетевые файловые системы несколькими методами, которые создавались с целью обойти какие-либо ограничения безопасности, либо для снижения сложности ручной процедуры монтирования конечным пользователем. Это и классическое монтирование через fstab или просто ручной вызов mount, варианты automount/autofs, а также монтирование в пространстве пользователя посредством gvfs. Способов много, и все они имеют несомненные достоинства, основное из которых — они работают.

При этом и недостатков также хватает: тут и проблемы с безопасностью (установка бита суидности), неудобство с ручным монтированием, пугающее количество опций, низкая производительность и нечеловеческие пути в случае gvfs, уникальность путей для каждого юзера на многопользовательских машинах, а при глобальном монтировании получаем «анонимный» доступ к сетевому ресурсу (несколько пользователей системы работают с файлами на сетевом ресурсе с правами пользователя, под которым выполнено монтирование). Это далеко не полный список.

На мой взгляд, решением всех этих проблем является монтирование сетевых ресурсов с опцией multiuser. Данная опция позволяет иметь одновременный доступ к сетевому ресурсу по одному подключению нескольким пользователям под своими учётными данными и со своими правами. Пользователь root, либо система при загрузке, как обычно монтируют удалённую файловую систему в каталог, и каждый пользователь видит в нём только те файлы/каталоги, на которые у него назначены права на файловом сервере. Почти как NFS, только с учётом особенностей «однопользовательского» протокола CIFS.

В чём основные плюсы данного решения:

  • Настраивается глобально, конфигурация рабочих мест унифицирована.
  • Чёткое разграничение прав. Каждый пользователь видит только то, что ему разрешено, а root монтирует файловые ресурсы под весьма ограниченным в правах «техническим» пользователем.
  • У всех пользователей одинаковые пути — можно обмениваться абсолютными ссылками и пропадают проблемы с программами, не умеющими работать с gvfs.
  • Высокая производительность.
  • Отсутствует необходимость выдачи избыточных прав пользователям.

Далее прорабатываем два варианта в зависимости от методов аутентификации.

▍ Рецепт 1. Монтирование с логином/паролем


Стандартная ситуация, когда для доступа к ресурсу необходимо ввести логин и пароль. Варианты такие не редкость, например, у меня эксплуатируется старенький NAS, который решили не интегрировать в домен, а пользоваться его внутренней базой пользователей.

На клиентской машине добавляем строчку монтирования в fstab:

//NAS/FOTO	/mnt/foto	cifs	cred=/root/.config/cifscred,multiuser,file_mode=0600,dir_mode=0700	0 0

Как видим, опций немного. Обязательно указываем multiuser, а опцией cred задаём файл, содержащий данные для аутентификации на сервере. Можно вместо опции cred использовать совокупность опций username/password/domain (man mount.cifs), но это несколько несекьюрно с моей точки зрения :) Соответственно, у рута создаём файлик ~/.config/cifscred вот такого вида:

username=needly
password=P@ssw0rd
domain=CORP

Перезагружаемся и видим следующую картину:



  1. Ресурс смонтировался.
  2. Пользователь root кое-что видит. На самом деле иногда удобно не держать его бесправным, а дать доступ к каким-нибудь полезным папкам.
  3. Обычный пользователь ничего не увидел. Почему?

Всё дело в том, что пользователи должны повесить на ядрёный брелок (kernel keyring) свои логин/пароль. Тогда ядро сможет получать с сервера необходимые ресурсы, используя эти данные.

С командной строки это можно сделать утилиткой cifscreds из пакета cifs-utils:

$ cifscreds add -u alef13 -d CORP
Password: P@ssw0rd

В примере выше заданы пароль/логин на домен. Они будут применяться при доступе к любому серверу, входящему в этот домен/рабочую группу.

Можно сделать иначе и указать учётные данные на конкретный сервер:

$ cifscreds add -u alef13 nas.corp.ru
Password: P@ssw0rd

Посмотреть наличие аутентификационных данных (но не их содержимое!) можно командой keyctl из пакета keyutils:

$ keyctl show
Session Keyring
  30364231 --alswrv      0     0  keyring: _ses
 500025711 --alswrv      0 65534   \_ keyring: _uid.0
 497176618 ----sw-v      0     0   \_ logon: cifs:d:CORP
 343241234 ----sw-v      0     0   \_ logon: cifs:a:192.168.0.2

Впрочем, свои учётные данные можно загонять в брелок с помощью команды keyctl (и так даже проще скриптовать):

$ keyctl add logon cifs:d:CORP alef13:P@ssw0rd @s

Или

$ keyctl add logon cifs:a:192.168.0.2 alef13:P@ssw0rd @s

После таких манипуляций картина совершенно другая:



  1. Проверяем, что видит root.
  2. Проверяем, что видит обычный пользователь
  3. Вешаем на брелок наш логин/пароль. Проверили, как висит.
  4. Пользователь имеет доступ! И обратите внимание, что видит он больше, чем рут.

Напрягать пользователя на дополнительный ручной ввод своих учётных данных не хочется, поэтому сделаем, чтобы они вводились автоматом. Если логин/пароль для доступа к ресурсу совпадают с учётными данными, под которыми пользователь авторизуется в системе, то всё решается подключением pam_cifscreds. Для настройки достаточно прочитать соответствующий man. Только не забывайте синхронизировать пароль рабочей учётной записи и пароль на общем ресурсе, иначе можно заблокироваться при безуспешных попытках входа.

Если учётки/пароли не совпадают, то надо создать скрипт, который будет вызываться из папки автостарта вашего Desktop Environment и загонять необходимые парольные пары в ядро при входе пользователя в систему. Это либо простейший bash-скрипт с вызовом keyctl, как я показал выше, либо скрипт на Python.

Для любителей Питона
Чтобы написать скрипт на Python, надо научиться работать с keyring ядра. Штатных библиотек я не нашёл, вроде есть какие-то древние исходники на GitHub, но и они нам не понадобятся.

Для начала подсмотрим, как работает с keyring утилита cifscreds.

alef13 ~ $ strace cifscreds add -u alef13 192.168.0.2 2>&1| grep key
openat(AT_FDCWD, "/lib64/libkeyutils.so.1", O_RDONLY|O_CLOEXEC) = 3
keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 0) = 67942699
keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_USER_SESSION_KEYRING, 0) = 956021303
keyctl(KEYCTL_SEARCH, KEY_SPEC_SESSION_KEYRING, "logon", "cifs:a:192.168.0.2", 0) = -1 ENOKEY (Required key not available)
Password: P@ssw0rd
add_key("logon", "cifs:a:192.168.0.2", "alef13:P@ssw0rd\0", 15, KEY_SPEC_SESSION_KEYRING) = 697036719
keyctl(KEYCTL_SETPERM, 697036719, KEY_POS_VIEW|KEY_POS_WRITE|KEY_POS_SEARCH|KEY_USR_VIEW|KEY_USR_WRITE|KEY_USR_SEARCH) = 0

Видна полезная нагрузка — это подтягивание libkeyutils.so.1 и вызов add_key. Соответствующий сниппет Python-кода:

keyutils = ctypes.CDLL('libkeyutils.so.1')

key_id = b'cifs:a:192.168.0.2'
key_value = b'alef13:P@ssw0rd\0'

n = keyutils.add_key(b'logon', key_id, key_value, len(key_value), -3)
print(n)

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

▍ Рецепт 2. Монтирование с аутентификацией kerberos


Штатная опция mount.cifs, отвечающая за метод аутентификации, называется sec, и для kerberos имеет значения krb5 и krb5i. Выбираете подходящий и будете аутентифицироваться при монтировании ресурса с помощью билетика kerberos, лежащего в вашем кэше.

Опять клиенту в /etc/fstab добавляем запись типа:

//srv1/shara1	/mnt/shara1	cifs	domain=CORP,sec=krb5,multiuser,file_mode=0600,dir_mode=0700	0 0

Здесь, по сравнению с «Рецептом 1», ситуация противоположная — входя в систему, пользователь аутентифицируется в домене, и билетик автоматически складывается в кэш kerberos-а, а вот руту этот кэш необходимо пополнить принудительно при старте системы. Для этого мы сделаем простейший сервис, который посредством kinit будет получать билетик при загрузке системы, а чтобы избежать интерактивности (ввод пароля) будем использовать keytab.

Работа с утилитами kerberos это практически отдельная статья, при желании вы найдёте их в интернете в достаточном количестве. Здесь я приведу минимальный набор только лишь для того, чтобы стартануть и потестировать предлагаемый метод монтирования.

Прежде всего необходимо сформировать keytab-файл. Для этого запускаем команду ktutil, и в приглашении вводим следующие заклинания:

# ktutil
ktutil: addent -password -p needly -k 1 -e rc4-hmac
Password for needly@CORP: P@ssw0rd
ktutil: wkt /etc/krb5.keytab
ktutil: q

Кратко по параметрам: -password — аутентификация по паролю, -p needly — «технический» пользователь (principal), который будет логиниться к разделяемому ресурсу, -k 1 — версия записи KVNO (из нескольких идентичных записей будет использоваться с большим номером), -e rc4-hmac — метод шифрования.

Далее авторизуемся, чтобы сгенерировать кэш (заодно протестируем наш keytab).

# kinit -k -V needly
Using default cache: /tmp/krb5cc_0
Using principal: needly@CORP
Authenticated to Kerberos v5

Прошу обратить внимание, что кейтаб наш работает, пока не истёк пароль учётной записи, а также в домене должен существовать пользователь needle с паролем P@ssw0rd.

Итак, кейтаб подготовлен, теперь необходим сервис для обновления кэша kerberos при загрузке системы.

Формируем текстовый файл /etc/systemd/system/root_krb_init.service:

[Unit]
Description=Updating k-ticket root
After=network-online.target

[Service]
ExecStart=/usr/bin/kinit -k -t /etc/krb5.keytab needly

[Install]
WantedBy=remote-fs-pre.target

Далее стандартно:

# systemctl daemon-reload && systemctl enable root_krb_init.service

Перезагружаемся и пробуем:



  1. Пользователь root ничего не видит (просто на этом сервере ему ничего не выдали), но и ошибок никаких нет.
  2. Обычный пользователь ничего не видит (тут я забыл заскриншотить пустой вывод klist), есть ошибки.
  3. Получаем билетик.
  4. Профит!!!

▍ Специи и приправы


Унифицированной точки монтирования и правильного разграничения доступа мы добились, однако внедрять по рабочим местам ещё рановато — надо дать необходимые пояснения и красиво это подать пользователю.

  • Многие обратили внимание, что изменения вносятся в fstab, а не в модули systemd. Я знаю и умею их писать, однако работа с fstab мне нравится больше — всё в одном месте, редактировать легко, все опции удобны и понятны. Более того, Леннарт Пёттеринг (автор systemd) также рекомендует вносить изменения в /etc/fstab — смотрите man systemd.mount в разделе FSTAB. Там же находятся и опции, позволяющие определить порядок монтирования и другие полезные директивы, используемые в unit-файлах для файловых систем (кстати, в рецепт с собакой необходимо в строчку монтирования ресурса добавить опцию x-systemd.after=root_krb_init.service ).
  • В примерах строчек для монтирования я указал права на ресурсы — файлы 600, каталоги 700. Система прав Linux (точнее POSIX) довольно примитивна, но и она вызывает затруднения у некоторых товарищей, из которых они выходят простейшим образом — дают на файлы и каталоги права 777. Это ужасно, хоть и работает в большинстве случаев. При таком подходе существует ненулевая вероятность поймать троянского коня, вот примерно такого — «Файлы полиглоты или как картинка с котиком станет угрозой для безопасности вашей информации». Самое опасное — это права выполнения на все файлы. Поэтому рекомендую ставить как я написал выше, про группу и прочих не волнуйтесь — права хоть и будут отображаться, но опция multiuser работает только с пользователями, предоставившими свои учётки для доступа к серверу.
  • Чтобы смонтированный сетевой ресурс появился на рабочем столе и в файловом менеджере, нам необходимо монтировать их в каталоги /media, $HOME или /run/media/$USER. Если стандартные точки монтирования не нравятся, монтируем куда хочется, только добавляем опцию x-gvfs-show в соответствующую строку fstab, и тогда ресурс также отобразится на десктопе. Дополнительные визуальные параметры описаны здесь what-is-shown.txt.
    Если решите опцией x-gvfs-name дать своему ресурсу красивое имя на рабочем столе, то учтите — пробелы в чистом виде использовать не получится, и их не заэкранировать слэшами со всякими кавычками. Просто вместо пробелов и спецсимволов используйте их шестнадцатеричное (x-gvfs-name=my%20cool%20share) представление.
  • Формирование кэша с помощью kinit — рабочий вариант, но есть и получше. Я имею в виду kstart, который позволяет автоматически продлевать билет и восстанавливать его при обрыве связи. К сожалению, в коробку с РедОС его не положили, поэтому разбирайтесь с ним самостоятельно. Если остаётесь на kinit, то постарайтесь сделать так, чтобы пользователи ежедневно выключали систему.
  • Когда возникают проблемы — отключайте антивирус :) В данном случае это хоть и выглядит шуткой, однако при проработке решений он попортил у меня немало крови. Как оказалось, один отечественный антивирус игнорирует исключения путей, внесённые в настройки задач, а ведёт себя адекватно только когда точки монтирования прописаны в глобальные исключения.

▍ Финал


Обозначенные ранее цели достигнуты — это безопасно, унифицировано, прозрачно для любого пользователя, и вдобавок у них одинаковые фиксированные пути к любому сетевому ресурсу. Настройки сделаны удалённо на всех рабочих местах, можно идти к пользователю и показывать красивую иконку диска «R» на рабочем столе. Изначально писал как некую шпаргалку для себя и своих коллег, но надеюсь, и вам этот небольшой туториал поможет немного упростить задачу импортозамещения.

Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх
Источник: https://habr.com/ru/companies/ruvds/articles/744036/


Интересные статьи

Интересные статьи

Иногда на барахолках могут попадаться очень интересные гаджеты с небольшими дефектам за очень приятную цену. Бывает и так, что за условную тыщу рублей можно купить вполне неплохой смартфон, планше...
Всем привет! Это создатель игры Dev's Battle (Образовательной MMO-RPG игры для разработчиков в Телеграмм). В этой статье я решил рассказать про наш опыт создания продукта в телеграмм. Надеюс...
Мой рабочий компьютер - Macbook Air 2020 (Intel), и его вполне хватает для написания кода и прочих задач. Однако, когда потребовалось смонтировать небольшой видеоролик, в...
В отличие от большинства отечественных IT-эмигрантов, моим первым домом в Америке стала не Калифорния и не Нью-Йорк. В этой статье я поделюсь простым уроком, который я усвоил на в...
На днях столкнулся с задачей примонтировать в OSX 10.14 iPad в качестве внешнего диска, с возможностью осуществлять файловые операции из консоли. В интернете я нашел довольно много инструкций как...