[Из песочницы] Облака — белогривые лошадки или безопасный ownCloud для «маленьких» в FreeNAS
ownCloud, как утверждает Википедия — это Свободное и открытое веб-приложение для синхронизации данных, расшаривания файлов и удалённого хранения документов в «облаке». И, как мне кажется, довольно интересное решение для организации собственного домашнего облака.Однако, ownCloud, устанавливающийся в виде плагина в системе FreeNAS, да и просто из коробки, имеет ряд недостатков, от которых хотелось бы избавится даже при использовании дома:
Во-первых, устанавливается в связке с SQLite, что подходит только если у вас небольшое кол-во файлов и пользователей, и абсолютно не подходит, если вы планируете синхронизацию с помощью клиента. У меня же хранилище уже расползлось почти на 5Tb и установленный таким образом ownCloud просто отказывался видеть часть файлов. Да и без синхронизации отдача от облака не велика. Заменим базу данных на MariaDB. Во-вторых, отсутствует работа по https, а мне совсем не нравится мысль о том, что кто-то может перехватить мои файлы. Включим https. В-третьих, начисто отсутствует защита от банального подбора пароля методом брутфорса. Защитимся от брутфорса с помощью fail2ban. В-четвёртых, мне лень часто просматривать логи на предмет взлома, но очень хочется оперативно узнавать о таких попытках. Настроим push-оповещения о попытках подбора пароля с помощью сервиса pushover.net. Хочу сразу оговориться. Я не являюсь IT-специалистом, я всего лишь менеджер проектов в одном из российских системных интеграторов, а данная «инструкция» родилась в попытках настроить все 4 указанных пункта на своей домашней системе, FreeNAS работающей из-под Esxi. Инструкция написана новичком для новичков, поэтому если где-то есть явные ляпы или ошибки в командах и конфигах, то прошу указать их в комментариях.Все настройки будем делать из консоли, ручками, максимально приближено к тому, как это, как мне видится, делают «взрослые» айтишники.
1 Подготовка Jail для ownCloud1.1 Создаём Jail Данный шаг описывать не буду. Если у вас получилось установить FreeNAS и он у вас работает, то проблем с данным шагом у вас быть не должно. Создание первого Jail может занять довольно продолжительное время.1.2 Открываем доступ по SSH к данному Jail Удобнее всего дальнейшую настройку выполнять не через web-терминал, а через полноценную программу-терминал. Например, putty. Для этого откроем доступ по SSH к нашему Jail и создадим нового пользователя, от которого и будем проводить дальнейшую настройку.Выбираем в web-интерфейсе FreeNAS созданный нами Jail и нажимаем внизу кнопку Shell.
В веб-консоли Jail вводим:
# sysrc sshd_enable=«YES» Запускаем демон для работы ssh: # service sshd start Создаём пользователя от имени которого будем потом настраивать нашу систему. Пользователь будет иметь привилегии superuser, для чего мы включим его в группу wheel. # adduser Настройки adduser Usrname: Новый пользователь от имени которого мы будем производить все манипуляции в терминале. Вводим, например, superstepa.Full name: Полное имя этого пользователя. Вводим, например, Dyadya Stepa Policeman.Uid (Leave empty for default): Ну раз просят оставить пустым, то так и сделаем. Смело жмём Enter.Login group [superstepa]: Мы хотим чтобы наш пользователь обладал всеми правами местного администратора — superuser, а следовательно включаем его в группу wheel.Login group is wheel. Invite superstepa into other groups? []: Нажимаем Enter.Login class [default]: Жмём Enter.Shell (sh csh tcsh git-shell nologin) [sh]: Оставляем по-умолчанию sh. Просто жмём Enter.Home directory [/home/superstepa]: И опять Enter.Home directory permissions (Leave empty for default): И снова Enter.Use password-based athentications? [yes]: Хотим чтобы аутентификация этого пользователя проходила по паролю? Конечно да! Жмём Enter.Use an empty password? (yes/no) [no]: Мы же за безопасность и не хотим чтобы у нового пользователя с правами superuser был пустой пароль. А значит очередной раз жмём Enter.Use a random password? (yes/no) [no]: Я просто уверен, что придуманный нами пароль самый надежный. И мы хотим использовать именно его. А следовательно Enter.Enter password: Ага, а вот и он. Вводим свой пароль.Enter password again: Вводим его снова.Lock out the account after creation? [no]: Нет, блокировать этот аккаунт не нужно. Просто Enter.OK? (yes/no): Проверяем всё ли верно и если да, то пешем yes.Add another user? (yes/no): Других пользователей нам не надо. No.
2 Установка и подготовка к работе ownCloud Присоединяемся с помощью программы-терминала к нашему Jail.Вводим имя созданного нами пользователя и его пароль.На приглашение командной строки $ пишем su. Теперь приглашение командной строки сменится на что-то типа root@ownCloud:/usr/home/superstepa #, а все наши команды будут выполняться от имени superuser.Для упрощения, приглашение командной строки я буду обозначать символом #, а мои комментарии, которые вводить не надо, буду начинать с //.2.1 Устанавливаем необходимые пакеты Сначала обновляем текущие пакеты: # pkg upgrade Затем устанавливаем необходимые для работы ownCloud пакеты (на все возникающие вопросы отвечаем yes): # pkg install mariadb100-server php56-extensions php56-bz2 php56-curl php56-exif php56-fileinfo php56-gd php56-mbstring php56-mcrypt php56-pdo_mysql php56-openssl php56-zip php56-zlib pecl-APCu pecl-intl Для того, чтобы включить работу по https, собираем с нужными нам пакетами, а затем и устанавливаем из портов, web-сервер nginx: # portsnap fetch extract // скачиваем копию коллекции портов, это может занять много времени # cd /usr/ports/www/nginx && make config // конфигурируем и собираем web-сервер nginx В процессе сборки убеждаемся, что выбраны следующие пакеты: IPV6HTTPHTTP_CACHEHTTP_DAVHTTP_FLVHTTP_GZIP_STATICHTTP_PERLHTTP_REWRITEHTTP_SSLHTTP_STATUSWWW
# make install 2.2 Создаём самоподписанные ключи и сертификаты # cd /usr/local/etc/nginx/ Создаём корневой ключ server.key (алгоритм шифрования des3, длиной 1024 bit): # openssl genrsa -des3 -out server.key 1024 Для этого система дважды попросит ввести парольную фразу. Придумываем её и вводим.Создаём корневой сертификат:
# openssl req -new -key server.key -out server.csr Отвечать на вопросы можно как угодно. Главное: — на первый запрос Enter pass phrase for server.key ввести правильный пароль от корневого ключа созданного ранее, — обязательно ответить на все вопросы, иначе клиент ownCloud в дальнейшем может отказаться от синхронизации файлов, — запомнить введённые данные, чтобы в дальнейшем можно было легко вспомнить, что сертификат именно Ваш, — запомнить пароль введённый на вопросе A challenge password []:.Можно изменить срок действия нашего сертификата, например до 10000 дней, добавив в команду выше аргумент -days 10000. # cp server.key server.key.org //копируем наш ключ # openssl rsa -in server.key.org -out server.key //удаляем пароль из ключа # openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt // Генерируем сертификат 2.3 Включаем автозапуск web-сервера, PHP и базы данных # sysrc nginx_enable=«YES» php_fpm_enable=«YES» mysql_enable=«YES» 2.4 Устанавливаем редактор для удобного редактирования конфигов Всё-таки мы еще «маленькие» и пользоваться предустановленным редактором vi нам еще сложновато, поэтому поставим простенький редактор nano (на все возникающие вопросы отвечаем yes). # pkg install nano Внимание: После установки редактора, попробуйте его запустить командой nano. В каких-то непонятных пока мне случаях что-то идёт не так и вместо запуска появляется следующая ошибка: Shared object «libiconv.so.2» not found, required «libgmoudle-2.0.so.0
Для того чтобы это исправить выполним всего 2 команды:
# pkg delete -f gettext
# pkg upgrade
2.5 Корректируем конфиг веб-сервера nginx
Как настоящие администраторы, всегда перед корректировкой конфига делаем его копию, чтобы в случае возникновения проблем всегда можно было откатиться назад:
# cp /usr/local/etc/nginx/nginx.conf /usr/local/etc/nginx/nginx.old
И редактируем файл конфига:
# nano /usr/local/etc/nginx/nginx.conf
Всё содержимое конфига заменяем на следующее:
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr — $remote_user [$time_local] »$request» '
access_log logs/access.log main;
sendfile off;
keepalive_timeout 65;
gzip off;
ssl_certificate /usr/local/etc/nginx/server.crt; // для того чтобы работал https
ssl_certificate_key /usr/local/etc/nginx/server.key; // для того чтобы работал https
server {
listen 443 ssl; // для того чтобы работал https
root /usr/local/www;
location = /robots.txt { allow all; access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
location ^~ /owncloud {
index index.php;
try_files $uri $uri/ /owncloud/index.php$is_args$args;
client_max_body_size 512M; // максимальный размер файла для загрузки
location ~ ^/owncloud/(?:\.|data|config|db_structure\.xml|README) {
deny all;
}
location ~ \.php (?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on;
}
location ~* \.(?: jpg|gif|ico|png|css|js|svg)$ {
expires 30d; add_header Cache-Control public;
}
}
}
}
Выход из редактора по нажатию Ctrl+X. Не забываем при выходе сохранять изменения.2.6 Корректируем конфиг php
# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
# nano /usr/local/etc/php.ini
В файле находим следующие строки (используем Ctrl+W для поиска) и даём им указанные значения:
always_populate_raw_post_data = -1 // не забываем убирать ; в начале строки
date.timezone = Europe/Moscow // либо указать Ваш часовой пояс
cgi.fix_pathinfo=0
upload_max_filesize = 512M // либо указать максимальный размер файла доступный для загрузки в наше облако
post_max_size = 512M // либо указать максимальный размер файла доступный для загрузки в наше облако
2.7 Корректируем php-fpm.conf:
# cp /usr/local/etc/php-fpm.conf /usr/local/etc/php-fpm.old
# nano /usr/local/etc/php-fpm.conf
В файле находим следующие строки (используем Ctrl+W для поиска) и даём им указанные значения:
listen = /var/run/php-fpm.sock
listen.owner = www // не забываем убирать ; в начале строки
listen.group = www
env[PATH] = /usr/local/bin:/usr/bin:/bin
2.8 Корректируем /var/db/mysql/my.cnf:
# cp /var/db/mysql/my.cnf /var/db/mysql/my.old
# nano /var/db/mysql/my.cnf
В файле будет пусто, поэтому внесём в него следующие строки:
[server]
skip-networking
skip-name-resolve
innodb_flush_method = O_DIRECT
skip-innodb_doublewrite
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table
expire_logs_days = 1
2.9 Запускаем веб-сервер nginx, PHP, MariaDB и настраиваем базу данных:
# service nginx start && service php-fpm start && service mysql-server start
Если всё было сделано верно, то всё запустится без ошибок и можно попробовать пройти в браузере по адресу https://
Настраиваем базу данных MariaDB:
# mysql_secure_installation Настройки MariaDB: Enter current password for root (enter for none): По умолчанию пароля нет, жмём Enter.Set root password? [Y/n]: Вводим Y.New password: Вводим новый пароль root.Re-enter new password: Повторяем введённый ранее пароль.На все остальные вопросы отвечаем Y, либо просто жмём Enter
Настраиваем базу данных ownСloud введя свои значения, где owncloud — название базы, ownclouduserdb — имя пользователя для работы с базой, а passwordownclouddb — пароль этого пользователя: # mysql -u root -p CREATE DATABASE owncloud; GRANT ALL PRIVILEGES ON owncloud.* TO 'ownclouduserdb' IDENTIFIED BY 'passwordownclouddb'; FLUSH PRIVILEGES; quit; 2.10 Скачиваем и устанавливаем актуальную версию OwnCloud По ссылке смотрим текущую актуальную версию ownCloud. На момент написания статьи это была версия 8.0.2.Скачиваем архив, где вместо 8.0.2 указываем текущую актуальную версию:
# fetch «http://download.owncloud.org/community/owncloud-8.0.2.tar.bz2» Разархивируем: # tar jxf owncloud-*.tar.bz2 -C /usr/local/www Удаляем ненужный теперь нам архив: # rm owncloud-*.tar.bz2 Назначаем системных владельцев (пользователя и группу) ownCloud: # chown -R www: www /usr/local/www/owncloud /mnt/files 2.11 Создаём задание в crone: # setenv EDITOR nano // для редактирования будем использовать установленный нами редактор nano # crontab -u www -e Прописываем в нём: */15 * * * * /usr/local/bin/php -f /usr/local/www/owncloud/cron.php Если всё было прописано верно, то мы получим следующее системное сообщение: crontab: installing new crontab
Идём теперь в браузере по адресу https://
Наш ownCloud уже готов к работе.
3 Дополнительные настройки 3.1 Просим поисковых роботов (Yandex, Google и т.д.) не индексировать наш сайт: # ln -s /usr/local/www/owncloud/robots.txt /usr/local/www 4 Защита от подбора пароля 4.1 Устанавливаем fail2ban из портов: # cd /usr/ports/security/py-fail2ban # make install clean Структура каталогов fail2ban Fail2ban лежит по следующему пути: /usr/local/etc/fail2ban. Структура расположенных там каталогов и файлов: папка action.d — содержит файлы действийпапка filter.d — файлы фильтровфайл fail2ban.conf — основной файл конфигурациифайл jail.conf — файл настройки защиты конкретных сервисов
4.2 Настраиваем логирование в ownCloud: Создаём файл в который будут писаться логи ownCloud при неудачной попытке входа: touch /var/log/owncloud-acces.log Файл должен быть доступен для записи пользователю www: # cd /var/log/ # chown www: www owncloud-acces.log Включаем логирование неудачных входов в ownCloud: # nano /usr/local/www/owncloud/config/config.php В файле находим или добавляем перед самой последней строкой следующие строки (пользуйтесь поиском Ctrl+W) и даём им указанные значения: 'logtimezone' => 'Europe/Moscow', // или другой Ваш часовой пояс 'logfile' => '/var/log/owncloud-acces.log', 'loglevel' => '2', 'log_authfailip' => true, Проверим ведётся ли логирование неудачных входов: Несколько раз пробуем войти в web-интерфейс ownCloud с заведомо неправильным паролем или именем пользователя.Затем выполним в консоли команду:
# nano /var/log/owncloud-acces.log Если всё сделано правильно, то в файле появятся записи вида: {«reqId»: «es09787k250rv52fu0iu44124z494687», «remoteAddr»:»192.168.1.1», «app»: «core», «message»: «Login failed: 'Admin' (Remote IP: '192.168.1.10', X-Forwarded-For: '')», «level»:2, «time»:»2015–04–04T18:59:50+03:00»}
4.3 Создаём файл фильтра для fail2ban:
nano /usr/local/etc/fail2ban/filter.d/owncloud.conf
В файле пишем следующее:
[Definition]
failregex={«app»: «core», «message»: «Login failed: user '.*' , wrong password, IP: HOST>», «level»:2, «time»:».*»} // для версий ownCloud<= 7.0.1
{"app":"core","message":"Login failed: '.*' \(Remote IP: '
4.6 Настраиваем действия, которые будут производится в случае неудавшихся попыток входа: # cp /usr/local/etc/fail2ban/action.d/bsd-ipfw.conf /usr/local/etc/fail2ban/action.d/bsd-ipfw.local # nano /usr/local/etc/fail2ban/action.d/bsd-ipfw.conf Оставляем в нём всё по умолчанию. В нём уже прописано правило, что при отправке в бан, ip-адрес добавляется в table (1) файервола ipfw: actionban = ipfw table \