Зачем это надо?
Удобная доставка контента конечному пользователю, минуя возню с FTP и невозможность (из-за NDA) воспользоваться публичными сервисами и облаками для передачи файлов (BTsync, Google-\Mail-\Yandex-Disk\Dropbox\etc).
Предисловие
Наш офис имеет определенную инфраструктуру, в неё входит в том числе и ActiveDirectory, в которой у нас находятся сотрудники, состоящие в группах.
Во время сеанса работы за ПК, после логина, средствами настроенных политик, у каждого сотрудника монтируется сетевой диск. Через него время-от-времени идет обмен данными. В диске есть определенная структура папок, права на которые настроены через эти самые группы. Каждый видит то, что ему позволено настройками.
Обычно, для отдачи данных во внешний мир — поднимается, либо отдельный FTP, либо данные выгружаются на уже имеющийся. Признаюсь, это далеко не всегда удобно — как минимум, создание и управление временными логинами и паролями (например, когда партнёрам нужно отдать готовый контент), контроль места на FTP-сервере, ручная выгрузка на FTP-сервер перед “отправкой”.
В какой-то момент нам потребовалось иметь возможность напрямую отдавать конечным пользователям данные во внешний мир именно с нашего сетевого диска и, желательно, чтобы это было относительно безопасно: можно создать ссылку для скачивания (у нее имелось время жизни, пароль, разграничение прав на исходные данные и так далее).
На такую идею нас натолкнули одни из партнеров, так как у них имелся внутренний сервис, но там он был самописным.
Готовых вариантов с ходу в поисковике не нашлось (если у вас есть оные на примете — отпишитесь, пожалуйста в комментариях), а тратить потенциально много человеко-часов на разработку с нуля, тестирование и поддержку — не было желания и ресурсов ни у кого. Да и зачем изобретать велосипед, если зачастую все уже придумано до. Так на ум и пришел сервис NextCloud, который умеет подключать к себе внешние ресурсы.
Речь пойдет о последней стабильной, на данный момент версии — 19, но наш метод настройки подойдет и для более ранних версий — мы изначально реализовали это на 16 версии и потом постепенно обновлялись. Недавно я как раз поднимал его с нуля на последней (19), и опираясь на неё пишу статью.
Что мы хотим получить в конечном итоге:
- Только сотрудники могут заходить в наш сервис и только через ActiveDirectoty\LDAP, точно так же как заходят на офисный пк, в Jira, Confluence, Nexus и пр.
- После авторизации в веб интерфейсе NextCloud, сотруднику должен быть подключен наш сетевой диск, с точно такими-же правами, как это происходит при заходе с рабочего компьютера.
- При первом входе в NextCloud — у каждой учетной записи создаются файлы-примеры в домашнем каталоге, которые занимают места на диске. По хорошему, от этого надо избавиться.
- Сотрудник не должен иметь возможность загружать что либо, как на подключенный диск, так и в аккаунт NextCloud .*Это просто наша хотелка, на самом деле — она не обязательная.
- Сотрудник может создавать временные ссылки, защищенные паролем на любые доступные ему ресурсы — будь то папка или отдельный файл. А также управлять ими (ссылками) — отзывать, менять срок жизни и прочее.
- Конечному пользователю, кому отправлена защищенная ссылка, достаточно её открыть и ввести пароль, чтобы получить возможность скачать расшаренные ему данные.
Развёртка и настройка зависимостей
Для начала, нам надо иметь отдельную виртуалку или сервер, где можно установить операционную систему, и после — NextCloud.
На Хабре есть не одна статья, посвященная развёртке системы и сервиса.
AlexanderS достаточно хорошо и подробно описал процесс от установки системы до самой настройки облака (включая актуализацию статей по годам). Не вижу смысла в очередной раз это всё повторять.
1. Так как мы подключаем в NextCloud сетевой диск, то нам понадобятся пакеты в систему: smbclient, libsmbclient , php-ldap, и php-smbclient.
FROM nextcloud:latest
RUN apt update -y && apt install -y --allow-unauthenticated smbclient libsmbclient libsmbclient-dev
RUN pecl install smbclient
RUN docker-php-ext-enable smbclient
2. Из-за особенностей настроек нашего сервера samba (отключена поддержка smb1), на машине с nextcloud, в файлах /etc/samba/smb.conf и /usr/share/samba/smb.conf пришлось поменять строки, отвечающие за протокол:
[global]
client min protocol = SMB2
client max protocol = SMB3
RUN rm -frv /etc/samba/smb.conf /usr/share/samba/smb.conf
ADD smb.conf /etc/samba/
ADD smb.conf /usr/share/samba/
В ином случае, nextcloud так и не смог подключиться к диску.
Настройка nextcloud
Итак, Nextcloud уже установлен, зависимости поставлены, а в сервисе заведен один внутренний юзер, который создался во время установки.
Шаг первый. Подготовка шаблона аккаунтов сотрудников.
Поскольку у нас будет не один сотрудник в системе, а постепенно их количество будет меняться — если заранее не настроить шаблон создаваемого пользователя — у каждого будет в домашней папке несколько файлов-примеров. Хорошо что по этому поводу у nextcloud есть отдельная настройка — skeleton files, которая настраивается в config.php.
'skeletondirectory' => '/var/www/html/data/donotdeletme',
То есть, можно создать пустую папку и указать в конфиге полный путь к ней.
Шаг Второй. Делаем пользователей «read-only»
Достаточно указать квоту в «1 B» (1 байт) в разделе настроек пользователей (http(s)://nextcloud.domain.tld/settings/users).
Шаг третий — заранее чиним ZipStreamer
ZipStreamer — библиотека, используемая в бекенде NextCloud, она служит для создания архивов «на лету», то есть во время скачивания пачки файлов.
Это связано с тем, что по этой кнопке система в режиме реального времени создает и отдает вам на скачивание архив (в большинстве случаев .zip, в редких кейсах — .tar)
Кстати, в силу особенности этой технологии, возобновление приостановленных загрузок в этом случае невозможно.
Похожее поведение есть у и аналогичных сервисов: Google Drive, Яндекс.Диск, и т.д.
Проблема кроется в том, что по неизвестным причинам, заложенная в NextCloud логика переключения zip в zip64 сбоит, и при случае, если в папке больше 65536 файлов, и\или их общий вес будет превышать 4гб — скорее всего вы столкнетесь с проблемой, что скачанный файл будет либо побит, либо загрузка будет прерываться после скачанных 4гб.
Данной проблеме выделяли достаточное время, на GitHub даже есть, и не один, закрытый тикет (#1755, #15871, #8798), но несмотря на то, что якобы проблема решена — у нас она так и осталась, и с переменным успехом воспроизводилась, очень мешая работе. Пришлось решать её более радикально.
<папка, где установлен nextcloud>/lib/private/Streamer.php:
- $this->streamerInstance = new ZipStreamer(['zip64' => false]);
+ $this->streamerInstance = new ZipStreamer(['zip64' => true]);
Поэтому просто в лоб замапить файл в условном /var/www не получится — при запуске файл либо перетрется оригиналом, либо контейнер запустится и упадет сразу с ошибкой.
Так что мы подменяем патченым файлом исходный в папке /usr/src/nextcloud/lib/private/ еще при сборке в CI нашего форкнутого образа. Получается, наш поправленный файл будет гарантированно всегда использоваться.
RUN rm -frv /usr/src/nextcloud/lib/private/Streamer.php
ADD Streamer.php /usr/src/nextcloud/lib/private/
RUN chown nobody:nogroup /usr/src/nextcloud/lib/private/Streamer.php
Эти манипуляции, по крайней мере при использовании докер-образа, в Панели Администрирования точно завалят вам встроенную проверку на подлинность, имейте это ввиду.
Но лично нас пока это устроило.
Шаг четвертый — настраиваем параметры ссылок
В параметрах публикации настраиваем правила так, как будет удобно. Например, делаем обязательную защиту паролем и ставим обязательный срок жизни.
Шаг пятый — подключаем сетевой диск
- Переходим в настройку внешних хранилищ. (http(s)://nextcloud.domain.tld/settings/admin/externalstorages)
- Выбираем добавление SMB \ CIFS хранилища.
- Заполняем поля имени, домена, папки и тд.
- Выбираем «Учетные данные, хранить в базе данных» — именно этот пункт позволяет при заходе пользователя по его связке логина и пароля подключать диск к его учетной записи в NextCloud. (Пункт хранение логина и пароля во время сессии не взлетел).
- Не забываем в меню <...> отметить чекбоксами «Только чтение» и разрешение предоставление общего доступа.
Шаг шестой — запускаем пользователей через LDAP
Теперь, когда мы все подготовили — ставим из маркетплейса плагин, и сразу после подключаем LDAP. В нашей системе, мы давали доступ сотрудникам, которые находятся в группе NextcloudAccess. Можете сделать аналогично.
Заключение
Всё, после всех этих нехитрых, но местами не самых очевидных манипуляций — сервис работает, диск подключен, сотрудники добавлены, а пользователи качают и довольны.
FROM nextcloud:latest
ENV DEBIAN_FRONTEND noninteractive
#installing smbclient
RUN apt update -y && apt install -y --allow-unauthenticated smbclient libsmbclient libsmbclient-dev
RUN pecl install smbclient
RUN docker-php-ext-enable smbclient
#fix of ZipStreammer
RUN rm -frv /usr/src/nextcloud/lib/private/Streamer.php
ADD Streamer.php /usr/src/nextcloud/lib/private/
RUN chown nobody:nogroup /usr/src/nextcloud/lib/private/Streamer.php
#fix of smb config
RUN rm -frv /etc/samba/smb.conf /usr/share/samba/smb.conf
ADD smb.conf /etc/samba/
ADD smb.conf /usr/share/samba/
Нагрузочное тестирование
«Как дела с нагрузкой?» — спросите вы напоследок.
Наш инстанс сервиса крутится на ~ 6Gb Ram + 6CPU в виртуальной машине среди других VM.
При пике нагрузки на сеть — оперативной памяти использовалось чуть более 2.5Gb, процессор забит не был, а отдача в среднем была около 5Gbit/s (рекорд — доходило и до 8Gbit/s).
Единственное, что заметили — при отдаче сверх 6Gbit/s во внешний мир, у нас периодически отваливается web-интерфейс, но сами загрузки у пользователей продолжают идти.
Выявленные недостатки:
- В NextCloud нету возможности глобального контроля над всеми созданными ссылками. Они отображаются только внутри каждого аккаунта в отдельном разделе.
- Если вы расшарите по ссылке корень подключенного диска — это может служить потенциальной утечкой данных, так как в ссылке расшарятся все доступные вашему аккаунту папки.
- Заметил, что за год использования поднятого сервиса, на данный момент, в базе данных таблица oc_filecache весит ~29Gb и имеет около ~100кк строк (мы используем ванильную MySQL 5.7.x). Это связано с багами #16834, #6395, #7312, #20349. Пока идет наблюдение на втором инстансе.
Спасибо, что дочитали. Если у вас есть вопросы, замечания или пожелания — не стесняйтесь, всегда рад конструктивной критике.
Проверено на: nextcloud 16, 17, 18, 19
Дата написания: 26.07.2020
Дата правок: 05.08.2020
Что поправлено: Поправил формулировку о режиме работы zip\zip64.
Версия: 1.0.0.8
Nomad1
У нас вообще NextCloud работает как оболочка для Amazon S3 — интерфейс проще, права настраиваются, можно приложение для синхронизации поставить, есть прямые ссылки. Под эту нагрузку вполне хватает бесплатного инстанса Amazon EC2, выходит хороший довесок к облачному хранилищу. До этого был Google Cloud Storage для хранилища, вот там не все хорошо со скоростью и интеграцией.
А если вообще на локальный диск его направлять, то можно о коммерческих облаках и не задумываться, если, конечно, с бекапами вопрос продуман.