Развертываем облачный сервис Seafile CE для хранения и синхронизации данных в связке с Nginx + MariaDB + Memcached + Fail2ban.
Будут использоваться.
- Debian Bullseye (x86_64);
- Seafile Server CE | [Debian x86_64 (v10.0.1) [link]
- Client for Windows v9.0.1 [link];
- Client for Android (seadroid) [link];
- Nginx, работающий через https;
- MariaDB, создание баз в ручном режиме;
- Memcached, кеширование для ускорения работы веб-интерфейса;
- Настройка Fail2Ban;
INFO. Компоненты сервера::
- Seahub (django): веб-интерфейс. Пакет сервера Seafile содержит легкий Python скрипт HTTP-сервера обслуживающий веб-сайт. Имеется возможность настройки Seahub для запуска в режиме fast-cgi, за Nginx или Apache. Это рекомендуется для производительного решения.
- Seafile server (seaf-server): демон службы данных. Обрабатывает загрузку и синхронизацию файлов. Сервер Seafile по умолчанию прослушивает порт 8082. Можно настроить Nginx или Apache для проксирования трафика на локальный порт 8082.
- Ccnet-сервер (ccnet-server): демон RPC-службы. Обеспечивает связь между несколькими компонентами. Ccnet используется только для внутренней связи.
Auto install Seafile Server CE and PRO: [link]
В скрипте описаны основные этапы установки. Например, какие пакеты нужны для работы, как реализована настройка компонентов и автозапуск демона Seafile.
OS:
Подготавливаем дистрибутив.
Создаем пользователя:
C отключенным шелом и одноименной группой.
# useradd seafile -b /home/ -m -U -s /bin/false
- задаем пароль:
# passwd seafile
Создаем необходимые каталоги:
# mkdir -p -m 710 /home/seafile/www/{cloud.open-networks.ru,logs}
Предоставляем пользователю seafile права на них:
# chown -R seafile:seafile /home/seafile/www
Предоставим Nginx, доступ в домашнюю директорию пользователя seafile:
Добавив пользователя "www-data" в группу "seafile".
# usermod -a -G seafile www-data - Добавить пользователя www-data в группу seafile.
# gpasswd -d www-data seafile - Удалить пользователя www-data из группы seafile.
# id www-data - Проверить в какие группы входит пользователь www-data.
Обновляем список зеркал / пакеты:
# apt update && apt upgrade
Устанавливаем необходимые пакеты:
- Для 10.0.x:
# apt install python3 python3-{setuptools,pip,ldap} lib{mariadb,memcached}-dev memcached nginx mariadb-server letsencrypt sudo
# pip3 install --timeout=3600 django==3.2.* future==0.18.* mysqlclient==2.1.* pymysql pillow==9.3.* pylibmc captcha==0.4 markupsafe==2.0.1 jinja2 sqlalchemy==1.4.3 psd-tools django-pylibmc django_simple_captcha==0.5.* djangosaml2==1.5.* pysaml2==7.2.* pycryptodome==3.16.* cffi==1.15.1 lxml
MySQL:
Настройка MariaDB:
# mysql_secure_installation
Cоздаем пользователя и БД:
Т.к. будкм устанавливать в ручном режиме.
# Логинимся к БД:
# mysql -u root -p'QO-(o]%5}kmc"!#'
# Создаем пользователя:
MariaDB> create user 'seafile'@'localhost' identified by '[pass]';
# Создаем БД:
MariaDB> create database `ccnet_db` character set = 'utf8';
MariaDB> create database `seafile_db` character set = 'utf8';
MariaDB> create database `seahub_db` character set = 'utf8';
# Присваиваем права:
MariaDB> GRANT ALL PRIVILEGES ON `ccnet_db`.* to `seafile`@localhost;
MariaDB> GRANT ALL PRIVILEGES ON `seafile_db`.* to `seafile`@localhost;
MariaDB> GRANT ALL PRIVILEGES ON `seahub_db`.* to `seafile`@localhost;
MariaDB> FLUSH PRIVILEGES;
MariaDB> quit;
Seafile:
Скачиваем Seafile:
- x86_64
# wget -P /tmp https://download.seadrive.org/seafile-server_10.0.1_x86-64.tar.gz
# tar -xf /tmp/seafile-server_10.0.1_x86-64.tar.gz -C /home/seafile/www/cloud.open-networks.ru
Установка:
Во время установки скрипт предложит автоматически создать пользователя и базу данных, для этого нажимаем 1. Или же 2, если у нас присутствуют необходимые настройки. Воспользуемся ручной настройкой.
- Переходим в директорию нашего сервера Seafile:
# cd /home/seafile/www/cloud.open-networks.ru/seafile-server*
- и приступаем к установке:
# ./setup-seafile-mysql.sh
Основные настройки:
Данные облака будут распологаться на примонтированном диске в "/mnt/data/seafile-data".
[ server name ] cloud
[ This server's ip or domain ] cloud.open-networks.ru
[ default "8082" ]
[ 1 or 2 ] 2
[ default "localhost" ]
[ default "3306" ]
[ mysql user for seafile ] seafile
[ password for seafile ] ********
[ ccnet database ] ccnet_db
[ seafile database ] seafile_db
[ seahub database ] seahub_db
- Или в автоматическом режиме:
# ./setup-seafile-mysql.sh auto --server-name 'cloud' --server-ip 'cloud.open-networks.ru' --use-existing-db 1 --mysql-user seafile --mysql-user-passwd '[pass]' --ccnet-db ccnet_db --seafile-db seafile_db --seahub-db seahub_db
Nginx:
При использовании самоподписанных сертификатов:
# mkdir -p /etc/ssl/nginx
# openssl req -x509 -nodes -days 1095 -newkey rsa:2048 -keyout /etc/ssl/nginx/cloud.open-networks.ru.key -out /etc/ssl/nginx/cloud.open-networks.ru.crt
# openssl dhparam -out /etc/ssl/nginx/dhparam_s.pem 2048
Настройка основного конфига: nginx.conf [GitHub_Gist]
# cp /etc/nginx/nginx.conf{,.bkp}
# nano /etc/nginx/nginx.conf
Настройка сайта: cloud.open-networks.ru.conf [GitHub_Gist]
- уаляем дефолтные настройки Nginx:
# rm /etc/nginx/sites-enabled/default
- и приступаем к настройке конфига сайта:
# nano /etc/nginx/sites-available/cloud.open-networks.ru.conf
Включаем наш конфиг Nginx созданием симлинка:
# ln -s /etc/nginx/sites-available/cloud.open-networks.ru.conf /etc/nginx/sites-enabled/cloud.open-networks.ru.conf
- Проверяем настройки:
# nginx -t
- Перезапускаем Nginx:
# nginx -s reload
Компоненты сервера:
Проверяем настройки ccnet.conf: [link]
# nano ../conf/ccnet.conf
[Database]
#MAX_CONNECTIONS = 100
Настроим seahub_settings.py: [link]
Включим кеширование Memcached, капчу, Two-Factor Authentication, время хранения сессии и языки.
+++ Показать листинг -> seahub_settings.py: +++
# nano ../conf/seahub_settings.py
SERVICE_URL = 'https://cloud.open-networks.ru'
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
},
}
# Security settings;
ALLOWED_HOSTS = ['.open-networks.ru', '[local-ip-address-seafile]']
#CSRF_TRUSTED_ORIGINS = CSRF_TRUSTED_ORIGINS = ['cloud.open-networks.ru:1212']
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'Strict'
# User management options;
ENABLE_SIGNUP = False
ACTIVATE_AFTER_REGISTRATION = False
SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER = False
SEND_EMAIL_ON_RESETTING_USER_PASSWD = False
NOTIFY_ADMIN_AFTER_REGISTRATION = False
LOGIN_REMEMBER_DAYS = 1
LOGIN_ATTEMPT_LIMIT = 3
FREEZE_USER_ON_LOGIN_FAILED = False
USER_PASSWORD_MIN_LENGTH = 6
USER_PASSWORD_STRENGTH_LEVEL = 3
USER_STRONG_PASSWORD_REQUIRED = False
FORCE_PASSWORD_CHANGE = True
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_SAVE_EVERY_REQUEST = False
ENABLE_WIKI = False
ENABLE_WEBDAV_SECRET = True
WEBDAV_SECRET_MIN_LENGTH = 8
WEBDAV_SECRET_STRENGTH_LEVEL = 1
ENABLE_FORCE_2FA_TO_ALL_USERS = True
# Library snapshot label feature;
ENABLE_REPO_SNAPSHOT_LABEL = False
# Library options;
ENABLE_ENCRYPTED_LIBRARY = True
ENCRYPTED_LIBRARY_VERSION = 2
REPO_PASSWORD_MIN_LENGTH = 8
SHARE_LINK_FORCE_USE_PASSWORD = False
SHARE_LINK_PASSWORD_MIN_LENGTH = 8
SHARE_LINK_PASSWORD_STRENGTH_LEVEL = 3
SHARE_LINK_EXPIRE_DAYS_DEFAULT = 1
SHARE_LINK_EXPIRE_DAYS_MIN = 1
SHARE_LINK_EXPIRE_DAYS_MAX = 3
UPLOAD_LINK_EXPIRE_DAYS_DEFAULT = 1
UPLOAD_LINK_EXPIRE_DAYS_MIN = 1
UPLOAD_LINK_EXPIRE_DAYS_MAX = 3
SHARE_LINK_LOGIN_REQUIRED = True
ENABLE_WATERMARK = False
DISABLE_SYNC_WITH_ANY_FOLDER = True
ENABLE_REPO_HISTORY_SETTING = True
ENABLE_USER_CREATE_ORG_REPO = True
ENABLE_SHARE_TO_ALL_GROUPS = True
ENABLE_USER_CLEAN_TRASH = True
ENABLE_SHARE_LINK_REPORT_ABUSE = True
# Options for online file preview;
USE_PDFJS = True
FILE_PREVIEW_MAX_SIZE = 30 * 1024 * 1024
TEXT_PREVIEW_EXT = """bat, py, sh, ps1, txt"""
ENABLE_THUMBNAIL = True
THUMBNAIL_IMAGE_SIZE_LIMIT = 30
ENABLE_VIDEO_THUMBNAIL = False
THUMBNAIL_VIDEO_FRAME_TIME = 5
THUMBNAIL_ROOT = '/cloud.open-networks.ru/seahub-data/thumbnail/thumb/'
THUMBNAIL_SIZE_FOR_ORIGINAL = 1024
# Cloud Mode;
CLOUD_MODE = False
ENABLE_GLOBAL_ADDRESSBOOK = False
# External authentication;
ENABLE_ADFS_LOGIN = False
ENABLE_KRB5_LOGIN = False
ENABLE_SHIBBOLETH_LOGIN = False
# Other options;
ENABLE_SETTINGS_VIA_WEB = True
TIME_ZONE = 'Europe/Moscow'
LANGUAGE_CODE = 'ru'
LANGUAGES = (
('en', 'English'),
('ru', 'Russian'),
)
SITE_NAME = 'Open-Networks'
SITE_TITLE = 'Private Cloud'
SITE_ROOT = '/'
MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD = 10
#SHARE_LINK_EMAIL_LANGUAGE = ''
UNREAD_NOTIFICATIONS_REQUEST_INTERVAL = 3 * 60
ENABLE_DELETE_ACCOUNT = False
ENABLE_UPDATE_USER_INFO = False
ENABLE_CHANGE_PASSWORD = False
ENABLE_GET_AUTH_TOKEN_BY_SESSION = True
#LOGOUT_REDIRECT_URL = ''
ENABLE_TERMS_AND_CONDITIONS = False
ENABLE_TWO_FACTOR_AUTH = True
#TWO_FACTOR_DEVICE_REMEMBER_DAYS = 90
#LIBRARY_TEMPLATES = {
# 'Template1': ['/MTv/Test', '/Test2'],
# 'Template2': ['/Assets', '/Assets/Computer']
#}
ENABLE_CHANGE_PASSWORD = False
ENABLE_FILE_COMMENT = True
ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER = False
Далее добавим необходимые переменные в seafile.conf: [link]
# nano ../conf/seafile.conf
[fileserver]
# Использовать файловый сервер golang;
use_go_fileserver = true
# TCP порт для файлового сервера;
port = 8082
# Количество рабочих потоков для http-запросов сервера;
#worker_threads = 10
# Настройки upload/download = Мб;
#max_upload_size=200
#max_download_dir_size=100
# Количество одновременных потоков для индексации;
#max_indexing_threads = 1
# Размер блоков для upload файлов = Мб;
#fixed_block_size=8
# Время действия токена для авторизации операции загрузки = Сек;
#web_token_expire_time=3600
# Очистка директории httptemp = Сек;
http_temp_file_ttl = 86400
http_temp_scan_interval = 3600
# Ограничить скорость загрузки/скачивания файлов = Кб/c;
#upload_limit = 100
#download_limit = 100
[database]
# Размер пула соединений;
#max_connections=100
[notification]
enabled = true
host = 127.0.0.1
port = 8083
log_level = info
jwt_private_key = [generate jwt_private_key - # openssl rand -base64 32]
[quota]
# Размер дисковой квоты для всех пользователей = Гб;
default = 1
[history]
# Количество дней хранения истории изменений файлов;
keep_days = 7
[library_trash]
# Количество дней, после которых произойдет авто очистка корзины;
expire_days = 14
[zip]
#Изменить кодировку для скачивания папки в виде zip-архива;
#windows_encoding = iso-8859-1
Сгенерировать и отредоктировать jwt_private_key:
# sed -i "s/jwt_private_key =.*/jwt_private_key = $(openssl rand -base64 32)/" ../conf/seafile.conf
Включаем WebDAV: [link]
# nano ../conf/seafdav.conf
[WEBDAV]
enabled = true
port = 8080
share_name = /seafdav
workers = 5
timeout = 1200
Настраиваем права на каталоги:
- Применяем рекурсивно права:
# chown -R seafile:seafile /home/seafile/www/cloud.open-networks.ru/
# cd /home/seafile/www/cloud.open-networks.ru/
# find . -type d -exec chmod 0710 {} \;
# find . -type f -exec chmod 0644 {} \;
# chmod +x seafile-server-latest/seafile.sh ; chmod +x seafile-server-latest/seahub.sh ; chmod +x seafile-monitor.sh
# chmod -R 755 seafile-server-latest/seafile/bin/
Symlink: Для нашего примонтированного диска:
# mv seafile-data/ /mnt/data/
# ln -s /mnt/data/seafile-data/ /home/seafile/www/cloud.open-networks.ru/seafile-data
# chown -R seafile:seafile /mnt/data/seafile-data/
Рестартуем демон Nginx:
# systemctl restart nginx.service
Готово! Теперь можно Запускать:
В процессе первого запуска задаем почту (логин) и пароль администратора.
# sudo -u seafile seafile-server-latest/./seafile.sh start
# sudo -u seafile seafile-server-latest/./seahub.sh start
Автозапуск Seafile: Systemd [link]
Можно использовать демон инициализации "systemd", либо через скрипт, расположенный в "/etc/init.d/".
+++ seafile.service: +++
# nano /etc/systemd/system/seafile.service | # systemctl edit --full --force seafile
[Unit]
Description=Seafile
After=network.target mariadb.service
[Service]
Type=forking
ExecStart=/home/seafile/www/cloud.open-networks.ru/seafile-server-latest/seafile.sh start
ExecStop=/home/seafile/www/cloud.open-networks.ru/seafile-server-latest/seafile.sh stop
LimitNOFILE=infinity
User=seafile
Group=seafile
[Install]
WantedBy=multi-user.target
+++ seahub.service +++:
# nano /etc/systemd/system/seahub.service | # systemctl edit --full --force seahub
[Unit]
Description=Seafile hub
After=network.target seafile.service
[Service]
Type=forking
ExecStart=/home/seafile/www/cloud.open-networks.ru/seafile-server-latest/seahub.sh start
ExecStop=/home/seafile/www/cloud.open-networks.ru/seafile-server-latest/seahub.sh stop
User=seafile
Group=seafile
[Install]
WantedBy=multi-user.target
Включаем запуск службы при загрузке системы:
# systemctl daemon-reload
# systemctl enable seafile.service seahub.service
Перезагружаемся и проверяем:
# systemctl status seafile.service seahub.service
Чистка кеша:
/mnt/data/seafile-data/storage/blocks
# sudo -u seafile bash seafile-server-latest/seaf-fsck.sh
Настройка Fail2ban + Nftables: [link]
# systemctl start nftables.service
# systemctl status nftables.service
# systemctl enable nftables.service
# apt install fail2ban
# systemctl status fail2ban.service
seahub_settings.py:
# nano /home/seafile/www/cloud.open-networks.ru/conf/seahub_settings.py
TIME_ZONE = 'Europe/Moscow'
# systemctl restart seahub.service
# systemctl status seahub.service
Настройка основного конфига F2B: fail2ban.conf
Зададим время, после которого необходимо удалять баны из базы данных. Должно быть ">=" чем "bantime".
# cp /etc/fail2ban/fail2ban.{conf,local}
# cat > /etc/fail2ban/fail2ban.local << EOF
[Definition]
dbpurgeage = 3w
EOF
Настройка конфига: jail.local
# cp /etc/fail2ban/jail.{conf,local}
# cat > /etc/fail2ban/jail.local << EOF -или- (# cat << EOF > /etc/fail2ban/jail.local)
[DEFAULT]
findtime = 1d
bantime = 2w
maxretry = 1
ignoreip = 127.0.0.1 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
# banning action
banaction = nftables-multiport
banaction_allports = nftables-allports
EOF
../action.d/nftables.conf:
В файле ../action.d/nftables.conf в разделе [Init] - можно просмотреть дополнительные настройки. Например (blocktype = reject, table = f2b-table).
- Задаем действие для заблокированных IP в цепочке f2b-chain:
# nano /etc/fail2ban/action.d/nftables.conf
[Init]
blocktype = drop
Правила F2B:
Три неудачных попытки входа приведут к добавлению одной строки в "seahub.log". Fail2ban c maxretry = 1, равнлсильно 3 попыткам.
- Jail:
# nano /etc/fail2ban/jail.d/seafile.conf
[seafile]
enabled = true
port = http,https
filter = seafile-auth
logpath = /home/seafile/www/cloud.open-networks.ru/logs/seahub.log
- Filter:
# nano /etc/fail2ban/filter.d/seafile-auth.conf
[INCLUDES]
before = common.conf
[Definition]
_daemon = seaf-server
failregex = Login attempt limit reached.*, ip: <HOST>
ignoreregex =
- Перезапускаем сервисы:
# systemctl restart nftables.service
# systemctl restart fail2ban.service
- Перечитать настройки:
# fail2ban-client reload
Проверка работы:
- f2b:
# fail2ban-client status
# fail2ban-client status seafile
# fail2ban-client set seafile unbanip 1.2.3.4 | banip - забанить
# fail2ban-client unban --all
- nft:
# nft list ruleset
# nft list table inet f2b-table
- Проверка Regex:
# fail2ban-regex /home/seafile/www/cloud.open-networks.ru/logs/seahub.log /etc/fail2ban/filter.d/seafile-auth.conf
Обновление Seafile: [link]
Router DNAT:
Если Seafile из LAN доступен по LAN-IP(FQDN):443, а снаружи по WAN-IP(FQDN):1212 (используется DNAT), то будет ошибка в "seahub.log" вида.
[WARNING] django.security.csrf:224 log_response Forbidden (Referer checking failed - https://cloud.open-networks.ru:1212/accounts/login/?next=/ does not match any trusted origins.): /accounts/login/
Для исправления, необходимо добаить в "seahub_settings.py" параметр:
CSRF_TRUSTED_ORIGINS = CSRF_TRUSTED_ORIGINS = ['cloud.open-networks.ru:1212']
И перезапустить seahub.service
и nginx.service
.