Личное облачное хранилище данных уже давно стало такой же привычной вещью, как email, Twitter и социальные сети. Благодаря Dropbox, Google Drive и Яндекс.Диску каждый может получить в личное пользование «маленький сетевой диск», который обойдется ровно в 0 $ на практически бесконечный срок. Однако публичные облака имеют недостатки: мнимая конфиденциальность, ограничения на объем данных, зависимость от ширины интернет-канала. Решить все эти проблемы можно, создав свой собственный облачный диск.

 

Постановка задачи

Итак, нам нужен собственный сервис хранения данных в стиле Dropbox. Он должен работать под управлением Linux, иметь клиенты для всех популярных ОС, включая мобильные, обладать веб-интерфейсом, поддерживать версионность файлов и шифрование на стороне клиента. Также неплохо бы иметь поддержку многих юзеров/групп и возможность коллективной работы над файлами на тот случай, если мы захотим использовать его в корпоративной среде (а об этом мы тоже поговорим).

Порывшись в интернете и поинтересовавшись вопросом на форумах, мы заметим, что существует как минимум два проверенных временем продукта, полностью соответствующих данным требованиям. Это OwnCloud и Seafile. Оба открыты, оба построены на идеях Dropbox, оба поддерживают многих юзеров. Казалось бы, берем любой и не паримся. Однако не все так просто — между двумя проектами существенные архитектурные различия, которые делают OwnCloud далеко не лучшим выбором.

Главная проблема OwnCloud — это его требовательность к ресурсам. Сервер целиком написан на языке PHP, что делает его довольно громоздким, медлительным и жадным до ресурсов, особенно если говорить о потреблении оперативки. Seafile, в свою очередь, построен по модульному принципу, где написанное на Python веб-приложение используется исключительно для формирования веб-интерфейса и обработки запросов от клиентов, а за хранение и обмен файлами отвечают демоны, реализованные на языке си. Даже на RasPi эти компоненты создают настолько низкую нагрузку на систему, что о ней можно не задумываться (100 Мб памяти и ~5% процессора в домашней конфигурации с несколькими клиентами).

Вторая проблема — стабильность. Среди давних пользователей OwnCloud почти нет людей, кто не имел бы проблем с хранилищем. Проблемы начинаются с установки и продолжаются во время использования, а их диапазон простирается от несовместимости с базами данных до проблем с синхронизацией больших файлов. И хотя в последнее время ситуация существенно улучшилась, OwnCloud до сих пор нельзя назвать стабильным и безбажным продуктом. В противовес ему Seafile просто эталон надежности, развернуть который в целях домашнего использования может даже маленький ребенок, не поимев никаких проблем.

Кроме этого, Seafile обладает рядом черт, которых нет ни у OwnCloud, ни у других подобных решений. По своей сути Seafile не что иное, как система контроля версий Git (известна любому вменяемому программисту), оптимизированная для работы с большими бинарными файлами. Поэтому ей свойственна грамотно реализованная система версионности, которая допускает совместную работу над файлами с возможностью отследить, кто, что и когда исправил, а также возможность создания нескольких библиотек (репозиториев, в терминологии Git) с заданными настройками хранения версий. При этом каждая из библиотек может быть привязана к собственному каталогу на клиентской машине и синхронизирована независимо.

Все эти качества делают Seafile лучшим решением в области открытых Dropbox-подобных хранилищ, и именно о нем пойдет речь в следующих разделах статьи. Сразу оговорюсь, что я в курсе возможностей OwnCloud насчет совместного редактирования документов, онлайн-просмотра видео, интеграции с KDE и вкусностей веб-интерфейса, но эта статья посвящена хранению файлов, для коллективной работы есть множество других открытых и не очень инструментов помимо OwnCloud.

 

Возможности

Итак, что может дать нам Seafile? Ну, во-первых, это, конечно же, синхронизация. Принцип здесь все тот же, что у Dropbox: клиент на компе отслеживает изменения в указанном каталоге (у виндузятников — в папке) и отправляет их серверу, который сохраняет данные в облаке. Сам клиент очень легкий, минималистичный и легко справляется со своей работой, без всяких намеков на торможение системы. Версии есть как для Windows, так и для Linux и OS X. Все они написаны на плюсах с использованием библиотеки Qt и открыты, так что собрать можно и для FreeBSD. Также есть весьма вменяемые клиенты для Android (Seadroid и Seafile для iOS, оба в официальных магазинах).

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

Библиотека Seafile

Настройки хранения истории

Доступны развитые средства коллективной работы с возможностью обмена сообщениями, расшариваемыми «рабочими областями», коллективным редактированием файлов (обычный текст или Markdown), комментариями, встроенным Wiki и возможностью расшаривания как отдельных документов, так и каталогов целиком. Средств для онлайн-редактирования документов Word, календарей и планировщиков, как в OwnCloud, тут нет, но зато есть ряд встроенных просмотрщиков документов. В частности, изображения, DOC и PDF-документы открываются прямо внутри веб-интерфейса.

Все это, кстати, можно оценить, вообще не разворачивая сервер. Разработчики дают 2 Гб пространства в собственном облаке всем желающим, достаточно зарегистрироваться на cloud.seafile.com, и можно начинать работу. Интерфейс будет в точности таким же, как в случае с приватной версией облака.

Что касается администрирования и масштабируемости, то здесь все также очень неплохо. Хотя в целом Seafile заточен скорее на использование дома или внутри небольших компаний, его архитектура никак не ограничивает установку системы в кластерных конфигурациях с несколькими серверами, балансировщиком нагрузки, memcached и распределенным хранилищем данных на базе Ceph или Amazon S3. Какую производительность в этом случае покажет система, непонятно, в обычной конфигурации скорость загрузки файлов на сервер достигает 10 Мб/с (согласно замерам разработчиков).

Seafile поддерживает шифрование. И не только на уровне канала передачи файлов, но и на уровне хранилища. Шифрование файлов производится на стороне клиента с использованием ключа, зашифрованного паролем пользователя. На сервер передается только ключ, но никогда не отправляется сам пароль. В последующем этот ключ используется для получения доступа к файлам через веб-интерфейс (достаточно знать только пароль). В случае веб-версии для расшифровки ключа используется код на JavaScript, исполняемый на клиентской стороне.

Для синхронизации файлов используется другой ключ, генерируемый клиентом. При установке соединения клиент и сервер обмениваются открытыми ключами, которые используются для расшифровки передаваемых данных обеими сторонами. В качестве алгоритма шифрования используется AES-256 в режиме CBC, он же для шифрования файлов в хранилище и шифрования ключа для доступа к данным (после прогонки через алгоритм PBKDF2).

Клиент Seafile для Android


 

Блок-врезка: Как работает Seafile

Seafile базируется на технологиях системы контроля версий Git, но имеет ряд существенных отличий, таких как полное отсутствие возможностей по разделению репозиториев (библиотек, в терминологии Seafile) на ветки (branch), оптимизация для работы с большими бинарными файлами, поддержка шифрования, автоматическая синхронизация и возможность приостановки и возобновления синхронизации.

Seafile всегда оперирует только двумя ветками каждого репозитория/библиотеки: local и master. Первая — это файлы на локальной (клиентской) машине, вторая — на сервере, причем, в отличие от Git, полная история версий хранится только на сервере, а сама синхронизация (слияние веток) выполняется в полностью автоматическом режиме:

  1. Клиент Seafile обнаруживает изменения в закрепленном за библиотекой каталоге локальной машины (worktree) с помощью встроенных в ОС механизмов уведомления об изменениях в ФС (inotify в Linux, fsnotify в OS X).
  1. Далее клиент выполняет коммит изменений в локальную ветку репозитория.
  1. После этого опрашивает сервер на предмет изменений в ветке master.
  1. Если таковые есть, скачивает изменения и сливает их с локальной веткой.
  1. Сливает локальную ветку репозитория с удаленной (master).

Этот алгоритм работы очень похож на тот, что используют программисты при работе с Git, с той лишь разницей, что Git требует ручного ввода команд для выполнения каждого из этапов (сначала git pull, затем git add, git commit и так далее). Seafile делает всю эту работу автоматически в фоновом режиме, но именно поэтому он подвержен проблемам, которые могут возникнуть, если одна из этих операций даст сбой или пользователь просто отключит комп во время синхронизации.

Для решения этих проблем Seafile использует несколько подходов. Во-первых, это индексный файл репозитория, который хранит все даты изменений файлов, так что, если операция синхронизации прервется, позже клиент сможет определить, какие файлы еще требуют синхронизации. Во-вторых, Seafile не имеет системы разрешения конфликтов, когда два измененных файла сливаются с разных машин на сервер одновременно. Вместо этого сервер просто отшибает одного из них, и тот повторяет попытку позже (версия, загруженная первым клиентом, остается в истории).

Кроме того, Seafile использует отличающийся от Git алгоритм слияния веток репозитория (синхронизации) — он умеет автоматически возобновлять прерванную синхронизацию и устранять конфликты версий, что в Git требует ручного вмешательства.


 

Пробуем

Самый простой способ попробовать Seafile — это установить его на свой домашний сервер или RasPi. В этом случае можно не заморачиваться с установкой баз данных, веб-сервера и какой-либо настройкой. Достаточно просто скачать пакет и активировать службу. В Ubuntu все это делается так:

$ cd ~
$ mkdir seafile && cd seafile
$ sudo apt-get install python2.7 python-setuptools python-simplejson python-imaging sqlite3
$ wget https://bitbucket.org/haiwen/seafile/downloads/seafile-server_3.1.5_x86-64.tar.gz
$ cd seafile-server*
$ ./setup-seafile.sh

Последняя команда запускает настроечный скрипт, ответив на вопросы которого ты произведешь первичную настройку сервера:

  1. Server Name — произвольное имя сервера.
  1. This server’s IP or domain — домен или IP-адрес сервера.
  1. Порт ccnet — оставляем по умолчанию (10001).
  1. Каталог хранилища — указываем каталог с данными (по умолчанию ~/seafile-data).
  1. Порт seafile server — по умолчанию (12001).
  1. Порт seafile fileserver — по умолчанию (8082).
  1. , .

Устанавливаем Seafile

Это все. Теперь можно запустить Seafile:

$ ./seafile.sh start
$ ./seahub.sh start

Второй скрипт запустит веб-интерфейс и при первом старте попросит указать email и пароль админа. После этого можно перейти по адресу localhost:8000, чтобы получить доступ к веб-версии интерфейса. Обрати внимание, что, в отличие от публичного интерфейса на сайте Seafile, здесь есть кнопка настроек в правом верхнем углу. Используя ее, можно добавлять новых юзеров, перемещать между ними библиотеки или изменять их настройки.

Интерфейс только что установленного сервера

Все это — простейшая конфигурация Seafile, которая, как уже ты заметил, не требует для установки и запуска даже прав root. Общая схема работы такого конфига показана на схеме «Seafile на домашнем сервере». В целом сервер использует три основных компонента для выполнения своей работы:

  • Seahub — веб-интерфейс Seafile, написанный на Python с использованием фреймворка Django. В данной конфигурации работает под управлением встроенного легкого веб-сервера Gunicorn, также написанного на Python.
  • FileServer (HttpServer) — сервер, предназначенный для передачи файлов по HTTP. Нужен для того, чтобы избежать бутылочного горлышка, которое может возникнуть по причине не самой высокой производительности Gunicorn. Написан на языке си.
  • Seafile Server — демон, ответственный за хранение данных. Сердце Seafile.
  • Ccnet — сервер, осуществляющий передачу данных между компонентами Seafile и клиентом.

Для хранения метаданных и другой внутренней информации сервер использует SQLite, однако в более сложных конфигурациях его можно заменить на MySQL или PostreSQL.

Seafile на домашнем сервере


 

Боковые выносы: INFO

Установка Seafile на RasPi выполняется по аналогии с десктопной версией. Единственное различие — другой архив с системой, найти который можно на странице загрузок Seafile.

Чтобы корректно установить Seafile в ArchLinux, необходимо инсталлировать libselinux из AUR: «yaourt -S libselinux».

Для отключения синхронизации определенных типов файлов создай в нужном каталоге файл seafile-ignore.txt и добавь в него маски файлов (например, .avi, .mkv, *.mp3).

Для Seafile есть консольный клиент под названием seaf-cli. Скачать можно с официального сайта.


 

Корпоративный вариант

Само собой разумеется, описанная выше конфигурация годится только для домашнего использования и совсем небольших компаний. Но когда речь заходит об организации общего файлового хранилища для множества сотрудников, разбросанных по разным городам, SQLite и HTTP-сервер на Python неизбежно становятся узким звеном, от которого придется избавляться. Да и поддержка LDAP пригодилась бы, конечно.

К счастью, ничего сложного в создании такой конфигурации нет. Для этого достаточно поставить базу данных, веб-сервер и изменить конфиги Seafile так, чтобы сервер использовал их вместо встроенных аналогов. Рассмотрим пример установки с использованием nginx, MySQL и дистрибутива Ubuntu.

Для начала ставим MySQL:

$ sudo apt-get mysql-server mysql-client python-mysqldb

Далее создаем юзера, с правами которого будет работать Seafile (все-таки у нас не домашняя машина, а от рута запускать сетевые демоны не православно):

$ adduser seafile
$ passwd seafile
$ su - seafile

Скачиваем и распаковываем Seafile, как описано в предыдущем разделе, но вместо скрипта setup-seafile.sh запускаем setup-seafile-mysql.sh. Отвечаем на все те же шесть вопросов, следом за которыми в этот раз появятся еще девять. Они будут касаться настроек базы данных, и на большинство из них можно ответить нажатием . Исключение составляют следующие вопросы:

  • «Please choose a way to initialize seafile databases» — жмем 1, чтобы скрипт сам создал базы данных.
  • «What is the password of the mysql root user?» — вводим пароль root от MySQL.
  • «Enter the name for mysql user of seafile» — вводим «seafile».
  • «Enter the password for mysql user seafile» — придумываем пароль.

Скрипт создаст для нас MySQL-юзера seafile и набор баз данных. Далее установим nginx и пакет python-flup, который понадобится для связи веб-морды с веб-сервером:

$ su
$ apt-get nginx python-flup

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

$ openssl genrsa -out privkey.pem 2048
$ openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095

Далее создаем конфиг nginx (/etc/nginx/sites-available/seafile.conf):

server {
    listen 80;
    server_name www.example.com;
    rewrite ^ https://$http_host$request_uri? permanent;
}
server {
listen 443;
    ssl on;
    ssl_certificate /etc/ssl/cacert.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;
    server_name www.example.com;
    location / {
        fastcgi_pass    127.0.0.1:8000;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        fastcgi_param   PATH_INFO           $fastcgi_script_name;
        fastcgi_param   SERVER_PROTOCOL $server_protocol;
        fastcgi_param   QUERY_STRING        $query_string;
        fastcgi_param   REQUEST_METHOD      $request_method;
        fastcgi_param   CONTENT_TYPE        $content_type;
        fastcgi_param   CONTENT_LENGTH      $content_length;
        fastcgi_param   SERVER_ADDR         $server_addr;
        fastcgi_param   SERVER_PORT         $server_port;
        fastcgi_param   SERVER_NAME         $server_name;
        fastcgi_param   HTTPS               on;
        fastcgi_param   HTTP_SCHEME         https;
        access_log      /var/log/nginx/seahub.access.log;
        error_log       /var/log/nginx/seahub.error.log;
    }
    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;
        client_max_body_size 0;
    }
    location /media {
        root /home/seafile/seafile-server-latest/seahub;
    }
}

Конфиг довольно простой, он делает две вещи: активирует перманентное перенаправление HTTP-трафика на 443-й порт (HTTPS) и отдает его веб-интерфейсу Seahub с помощью FastCGI. Очень важный момент — обработка URL вида www.example.com/sefhttp/. По этому адресу будет доступен fileserver, занимающийся приемом и отправкой файлов, и он не должен иметь лимитов на их размер. По этой причине используется настройка «client_max_body_size 0».

Последний штрих — правка файлов /home/seafile/seafile/ccnet/ccnet.conf и /home/seafile/seafile/seahab/seahub_settings.py. В первый добавляем такую строку:

SERVICE_URL = https://www.example.com

Во второй такую:

FILE_SERVER_ROOT = 'https://www.example.com/seafhttp'

На этом все. Активируем наш сайт, перезапускаем nginx и стартуем Seafile:

$ cp /etc/nginx/sites-available/seafile.conf /etc/nginx/sites-enabled/seafile.conf
$ nginx -s reload
$ su seafile
$ ./seafile.sh start
$ ./seahub.sh start-fastcgi
 

Выводы

Seafile — отличный инструмент для создания файловых хранилищ широкого спектра использования. Он прост, производителен, легок в настройке и обслуживании, подходит как для личного использования, так и для внедрения в компании. А главное — Seafile абсолютно бесплатен и открыт.

Комментарии

Подпишитесь на ][, чтобы участвовать в обсуждении

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

Check Also

SHA 2017. Репортаж с самого яркого хакерского ивента этого лета

Still Hacking Anyway 2017 — это фестиваль, на котором собрались четыре тысячи хакеров со в…