Внимание!
Статья не закончена!

Дата написания: июль 2018 г.
Автор: Graf

Сервер облачного хранилища на базе Nextcloud


Установка

Локальный IP-адрес сервера куда всё устанавливаем и где настраиваем - 192.168.10.217
IP-адрес шлюза - 192.168.10.1
Внешний IP-адрес - 77.77.77.77 (Вымышленный. Придуманный, только лишь, в качестве примера.)
Доменное имя - my-cloud.ru (Вымышленное. Придуманное, только лишь, в качестве примера.)
Nextcloud версии 13.0.4 (Обновлено с 13.0.2)

Согласно системным требованиям рекомендуется:

  1. 512 MB ОЗУ
  2. Red Hat Enterprise Linux 7 или Ubuntu 16.04 LTS
  3. MySQL/MariaDB
  4. Apache 2.4 с mod_php
  5. PHP 7+

По поводу п.1 - Испытывалось на 16 GB.

По поводу п.2 - У нас система будет круче! :) А именно - Slackware Linux 14.2 64-bit без DE и всем, что с ними связанно. После обновления всех доступных пакетов, посредством slackpkg, с ядром 4.4.132.

п.3 и п.4 - в системе уже установлены, просто настроим их.

По поводу п.5 - В Slackware Linux 14.2 установлен PHP версии 5.6, с которой текущая версия Nextcloud, будет работать. Но при запуске выдаст предупреждение о том, что текущая версия Nextcloud является последней, которая поддерживает PHP 5.6 и рекомендует обновить версию PHP до версии 7.0+, для возможности перехода на Nextcloud 14.
Поэтому, первым делом, обновим версию PHP до 7+.

PHP 7

Последнюю версию PHP можно посмотреть на http://php.net/downloads.php и скачать её с ближайшего зеркала.
Для автоматизации сборки пакета, я написал скрипт который скачает всё необходимое и запустить сборку пакета в каталоге со скриптом.
Назовём скрипт ./build.php7

#!/bin/bash
 
# Версия alpine
AV="2.21"
 
# Версия php
PHPV="7.2.6"
 
# Скачиваем php.SlackBuild и причитающееся
wget -r -nd -np -R index*,php-5* \
-e robots=off https://mirror.slackbuilds.org/slackware/slackware64-14.2/source/n/php/
 
# Скачиваем последнюю версию php
wget -O php-$PHPV.tar.xz http://pl1.php.net/get/php-$PHPV.tar.xz/from/this/mirror
 
# Для сборки php нужен пакет alpine
# Скачиваем alpine.Slackbuild и причитающееся
wget -r -nd -np -R index*,alpine-2* \
-e robots=off https://mirror.slackbuilds.org/slackware/slackware64-14.2/source/n/alpine/ -P ./alpine
 
# Скачиваем последнюю версию alpine
wget http://alpine.x10host.com/alpine/release/src/alpine-$AV.tar.xz -P ./alpine
 
# В php.Slackbuild меняем версию alpine c 2.20 на последнюю и правим путь к исходникам.
sed -i \
-e "s/ALPINE=2.20/ALPINE=$AV/" \
-e 's:CWD/../alpine:CWD/alpine:' ./php.SlackBuild
 
# В alpine.Slackbuild меняем версию  c 2.20 на последнюю
sed -i "s/VERSION:-2.20/VERSION:-$AV/" ./alpine/alpine.SlackBuild
 
# Распаковываем diff по man-страницам
gzip -d ./alpine/alpine.manpage.diff.gz
 
# В новых версия путь к man-страницам поменялся, исправляем.
sed -i 's:doc/alpine.1:doc/man1/alpine.1:' ./alpine/alpine.manpage.diff
 
# Запаковываем обратно
gzip ./alpine/alpine.manpage.diff
 
# Вытаскиваем из архива файлы php.ini-development и php-fpm.conf.in в текущий.
tar -xpvf ./php-$PHPV.tar.xz php-$PHPV/php.ini-development php-$PHPV/sapi/fpm/php-fpm.conf.in
 
# Переходим в каталог php-версия.
cd ./php-$PHPV
 
#############  работаем с php.ini-development ############
 
# Предварительно скопировав файл ./php.ini-developmentс расширением orig,
# убираем знак комментария с параметра session.save_path с указанием пути, 
sed -i'.orig' \
's:;session.save_path = \"/tmp\":session.save_path = \"/var/lib/php\":' \
./php.ini-development
 
# Добавляем необходимые extension в файл ./php.ini-development начиная с 908 строки.
sed -i '908a\extension=pspell \
extension=bcmath \
extension=bz2 \
extension=calendar \
extension=ctype \
extension=curl \
extension=dba \
extension=dom \
extension=enchant \
extension=exif \
extension=ftp \
extension=gd \
extension=gettext \
extension=gmp \
extension=iconv \
extension=intl \
extension=ldap \
extension=mbstring \
extension=mysqli \
extension=odbc \
extension=openssl \
zend_extension=opcache \
extension=pdo \
extension=pdo_mysql \
extension=pdo_sqlite \
extension=pdo_odbc \
extension=shmop \
extension=snmp \
extension=soap \
extension=sqlite3 \
extension=tokenizer \
extension=wddx \
extension=xmlreader \
extension=xsl \
extension=zip \
extension=zlib' ./php.ini-development
 
# Разницу между двумя файлами ./php.ini-development и ./php.ini-development.orig
# записываем в ./php.ini-development.diff
diff -u ./php.ini-development{.orig,} > ./php.ini-development.diff
 
# сжимаем ./php.ini-development.diff в ./php.ini-development.diff.gz
gzip ./php.ini-development.diff
 
#
#
############ закончили с php.ini-development ################
 
########## работаем с php-fpm.conf.in ###################
#
#
# Правим файл php-fpm.conf.in 
sed -i'.orig' \
-e s'/;pid =/pid =/' \
-e s'/;error_log =/error_log =/' \
-e s'/include=@/;include=@/' \
-e '$a;include=etc/php-fpm.d/*.conf' ./sapi/fpm/php-fpm.conf.in
 
# Разницу между двумя файлами php-fpm.conf.in и php-fpm.conf.in.orig
# записываем в php-fpm.conf.diff
diff -u ./sapi/fpm/php-fpm.conf.in{.orig,} > ./sapi/fpm/php-fpm.conf.diff
 
# сжимаем php-fpm.conf.diff
gzip ./sapi/fpm/php-fpm.conf.diff
 
#
#
############ закончили с php-fpm.conf.in ################
 
# Переходим в каталог с php.SlackBuild
cd ..
 
############ Подменяем diff'ы #####################
#
#
# Переименовываем старый ./php.ini-development.diff.gz в ./php56.ini-development.diff.gz
mv ./php.ini-development.diff.gz ./php56.ini-development.diff.gz
 
# Переименовываем старый ./php-fpm.conf.diff.gz в ./php56-fpm.conf.diff.gz
mv ./php-fpm.conf.diff.gz ./php56-fpm.conf.diff.gz
 
# Копируем недавно созданный php.ini-development.diff.gz в каталог с php.SlackBuild
cp ./php-$PHPV/php.ini-development.diff.gz ./
 
# Копируем недавно созданный php-fpm.conf.diff.gz в каталог с php.SlackBuild
cp ./php-$PHPV/sapi/fpm/php-fpm.conf.diff.gz ./
 
# Удаляем более не нужный каталог ./php-версия
rm -rf ./php-$PHPV
 
#
#
############ закончили подмену diff'ов ##############
 
# Меняем версии php в файле ./mod_php.conf.example предварительно переименовав с расширением orig
sed -i'.orig' s'/php5/php7/g' ./mod_php.conf.example
 
# Меняем версии php в файле ./fetch-php.sh
sed -i'.orig' "s/php-5.6.23/php-$PHPV/" ./fetch-php.sh
 
# Присваиваем бит запуска alpine.SlackBuild и php.SlackBuild
chmod +x ./alpine/alpine.SlackBuild.
chmod +x ./php.SlackBuild.
 
# запускаем сборку пакета
./php.SlackBuild

Добавим скрипту бит запуска и запустим его с выводом сообщений в файл ./build.php7.log для дальнейшего просмотра и выявления ошибок. В принципе, существенных ошибок я не нашёл, поэтому можно запустить и без использования tee. После завершения скрипта, установим получившийся пакет. Поменяем на актуальный phph.ini и mod_php.conf. И проверим версию.

# chmod +x ./build.php7
# ./build.php7 | tee -a ./build.php7.log
...
Slackware package /tmp/php-7.2.6-x86_64-1.txz created.

# upgradepkg /tmp/php-7.2.6-x86_64-1.txz 
...
Package php-5.6.23-x86_64-1 upgraded with new package /tmp/php-7.2.6-x86_64-1.txz.

# mv /etc/php.ini /etc/php56.ini
# mv /etc/php.ini.new /etc/php.ini
# mv /etc/httpd/mod_php.conf /etc/httpd/mod_php56.conf
# mv /etc/httpd/mod_php.conf.example /etc/httpd/mod_php.conf
# php -v
PHP 7.2.6 (cli) (built: Jun  8 2018 16:16:08) ( ZTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.6, Copyright (c) 1999-2018, by Zend Technologies

Всё, PHP 7 установлен. Теперь установим сам Nextcloud и, для устранения ошибок кэширования, redis.

Nextcloud и Redis

Устанавливаем sbopkg, синхронизируемся с его репозиторием попутно соглашаясь с созданием отсутствующих каталогов.

# wget https://github.com/sbopkg/sbopkg/releases/download/0.38.1/sbopkg-0.38.1-noarch-1_wsr.tgz
# upgradepkg --install-new ./sbopkg-0.38.1-noarch-1_wsr.tgz
# sbopkg -r

Устанавливаем Nextcloud и Redis.

# sbopkg -Bi "redis nextcloud-server"
# pecl install redis  (на последующие вопросы - "no")
# echo "extension=redis.so" > /etc/php.d/redis.ini

Для безошибочной работы Redis изменим параметры ядра

# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# echo "512" > /proc/sys/net/core/somaxconn
# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf

Применим параметры ядра без перезагрузки.

# sysctl -p

Запускаем Redis.

# chmod +x /etc/rc.d/rc.redis
# /etc/rc.d/rc.redis start
# ps aux | grep redis
root      6843  0.0  0.1  43116  8448 ?        Ssl  19:24   0:00 /usr/bin/redis-server 127.0.0.1:6379

Для автоматической загрузки при запуске сервера, добавим в /etc/rc.d/rc.local три строчки:

echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo "512" > /proc/sys/net/core/somaxconn
/etc/rc.d/rc.redis start

Apache и MySQL

Внесём кое-какие правки в /etc/httpd/httpd.conf, а именно:

  • удалим знак комментария с модулей cgi, cgid, rewrite
  • удалим знак комментария со строки подключения mod_php.conf
  • В DirectoryIndex добавим index.php

и запустим апач.

# sed -i'.orig' \
-e '/mod_php/s/#/ /' \
-e '/mod_cgi.so/s/#/ /' \
-e '/mod_cgid.so/s/#/ /' \
-e '/mod_rewrite/s/#/ /' \
-e '/DirectoryIndex index.html/ s/$/ index.php/' \
/etc/httpd/httpd.conf

# chmod +x /etc/rc.d/rc.httpd
# /etc/rc.d/rc.httpd start

Инициализируем каталог данных MySQL и создадим системные таблицы. Запустим MySQL и дадим пользователю root пароль.

# mkdir /var/lib/mysql/mysql
# mysql_install_db
# chown -R mysql.mysql /var/lib/mysql
# chmod +x /etc/rc.d/rc.mysqld
# /etc/rc.d/rc.mysqld start
# mysql -u root
   MariaDB [(none)]> set password for 'root'@'localhost' = password('mypassword');
   Query OK, 0 rows affected (0.00 sec)
 
   MariaDB [(none)]> FLUSH PRIVILEGES;
   Query OK, 0 rows affected (0.00 sec)

   MariaDB [(none)]> \q
   Bye

Добавим в /etc/my.cnf.d/server.cnf

[mysqld]
max_allowed_packet = 8M
table_open_cache = 2048
tmp_table_size = 256M
max_heap_table_size = 256M
thread_cache_size = 8
query_cache_size = 16M
sql_mode = NO_ENGINE_SUBSTITUTION
skip-external-locking
innodb_log_buffer_size = 32M
innodb_buffer_pool_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_large_prefix = on
innodb_flush_method = O_DIRECT
innodb_buffer_pool_instance = 1
innodb_max_dirty_pages_pct = 90

Рестарт Mysql

# /etc/rc.d/rc.mysqld restart

Настройка

Первый запуск

Продолжим настройку в веб-интерфейсе. Запустим наше облако локально, по адресу http://192.168.10.217/nextcloud/ и введём необходимые данные.

Первые два поля это:
пользователь с правами админа - например, admin :) ;
пароль пользователя с правами админа.

Если вдруг забыли пароль или его нужно сменить какому-либо пользователю:

# chmod +x /var/www/htdocs/nextcloud/occ
# sudo -u apache /var/www/htdocs/nextcloud/occ user:resetpassword admin
Enter a new password: 
Confirm the new password: 
Successfully reset password for admin

Далее. Раскрываем «Хранилище и база данных» и заполняем:
Каталог с данными - Здесь создастся каталог data, место, где будут храниться ВСЕ данные ВСЕХ пользователей, а так же логи Nextcloud. Лучше для этого выделить отдельный винчестер и в этом поле указать путь к его точке монтирования. Не забыв сделать её владельцем apache:apache.
Выбираем базу данных - MySQL/MariaDB и в поля ниже вводим соответствующие значения:
пользователь с правами администратора MySQL, у нас это - root;
пароль пользователя с правами администратора MySQL;
название создаваемой базы данных, у нас это - nextcloud;
путь к компьютеру, где установлена MySQL.

Нажимаем на «Завершить установку» и, если всё прошло гладко, увидим веб-интерфейс Nextclod.

Перейдём в основные настройки и посмотрим на ошибки.


Исправление ошибок

Исправление ошибок, связанных с HTTPS и .htaccess, описал в отдельном разделе.

Кэш

В /etc/php.ini добавим рекомендуемые параметры opcache, а для приемлемой работы с файлами большого объёма, кое-какие параметры изменим:

opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.save_comments=1
opcache.revalidate_freq=0
 
post_max_size = 16G
upload_max_filesize = 0
memory_limit = 2G
sys_temp_dir = "/var/tmp"
date.timezone = Europe/Moscow

Далее, добавим в конец файла /var/www/htdocs/nextcloud/config/config.php

// Кэширование памяти для локально сохраненных данных.
  'memcache.local' => '\\OC\\Memcache\\Redis',
 
// Кэширование памяти для блокировки файлов.
  'memcache.locking' => '\\OC\\Memcache\\Redis',
 
// Разрешаем блокировку файлов к которым происходит одновременный доступ.
  'filelocking.enabled' => 'true',
 
// Настройка redis  
  'redis' =>
  array (
    'host' => 'localhost',
    'port' => 6379,
  ),
 
// Выключить режим обслуживания  
  'maintenance' => false,
 
// Используем тему по умолчанию. Темы лежат в /var/www/htdocs/nextcloud/themes
  'theme' => '',
 
// Логи  
// Расположение файла.
  'logfile' => '/var/log/nextcloud.log',
 
// Формат даты и времени в логах.
  'logdateformat' => 'd-m-Y H:i:s',
 
// Уровень логирования. 0 = Debug, 1 = Info, 2 = Warning, 3 = Error и 4 = Fatal.  
  'loglevel' => 2,
 
// Ограничиваем общий размер лог-файла 10 Мб, после которого произойдет ротация и будет создан новый.
// (в байтах)
  'log_rotate_size' => 10485760,
 
// Часовой пояс, по умолчанию UTC.
  'logtimezone' => 'Europe/Moscow'

Назначаем хозяином логов apache.

# chown apache:apache /var/log/nextcloud.log

Рестарт apache

# /etc/rc.d/rc.httpd restart

Медленная проверка

Автоматическая проверка ошибок проходит очень и очень долго. На видео выше я не показываю всё время затраченное на проверку, я останавливаю запись, а по завершению проверки её продолжаю. Идём в «Журналирование» и видим такую ошибку:
"GuzzleHttp\Exception\ConnectException: cURL error 7: Failed to connect to www.nextcloud.com port 80: Connection timed out"

Заходим на http://blocklist.rkn.gov.ru/ и видим:

Для исправления есть два варианта:
1. исправить в файле /var/www/htdocs/owncloud/settings/Controller/CheckSetupController.php блок $siteArray заменив в нем www.nextcloud.com, например, на www.yandex.ru. При этом не забыть, что при обновлении файл будет заменен и исправление вновь нужно внести вручную. Хотя, есть вероятность того, что к очередному обновлению, IP-адрес nextcloud разблокируют;
2. В /var/www/htdocs/nextcloud/config/config.php добавить

'has_internet_connection' => false ,

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

После всех операций над php-файлами не забываем рестартануть apache.

Cron

Как советуют в пункте «Фоновые задания»:
Для оптимальной производительности важно правильно настроить выполнение задач в фоновом режиме. Для крупных развёртываний рекомендуется использовать параметр «Cron».
и, дабы не получить сообщение об ошибке:
«Последнее задание было выполнено СТОЛЬКО-ТО часов назад. Похоже, что-то не в порядке.»
настроим cron на выполнение таких заданий в фоне.

Для этого выполним:

# crontab -u apache -e

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

*/15  *  *  *  * php -f /var/www/htdocs/nextcloud/cron.php

В веб-интерфейсе выставим переключатель на «Cron».

Обновление

Обновление проходит быстро и не сложно. Главное, не забыть внести изменения в те файлы, которые изменялись в ручную до обновления (config.php к этому не относится), например, как ТУТ пункт 1.
Видео по обновлению.

HTTPS

У нас остались две, не исправленные, ошибки. Одна об использовании HTTPS вместо HTTP и другая о незащищённости файла .htaccess. Исправляем обе сразу.

Сначала, необходимо прописать наш домен в DNS. Это делается у хостеров, провайдеров, регистраторов и т.д., там где у вас есть права на изменения записей в DNS. (Кусок конфигурации зоны в bind для домена my-cloud.ru)

$TTL 86400
@       IN      SOA     my-cloud.ru.  it.my-cloud.ru. (
...
...
)
...
...
@       IN      A       77.77.77.77
www     IN      CNAME   @
...

На шлюзе пробросим порты 80 и 443 на наш сервер с nextcloud.

$IPTABLES -t nat -A PREROUTING -d $INET_IP -p tcp -m multiport --dport 80,443 -j DNAT --to-destination 192.168.10.217
$IPTABLES -I FORWARD 1 -i $INET_IFACE -o $LAN_IFACE -d 192.168.10.217 -p tcp -m multiport --port 80,443 -j ACCEPT

Смотрим, знает ли о нашем домене «мировое сообщество» :)

# nslookup my-cloud.ru
...
...
Non-authoritative answer:
Name:   my-cloud.ru
Address: 77.77.77.77

Знает!
Устанавливаем необходимые пакеты для получения бесплатных сертификатов от центра сертификации Let's Encrypt при помощи Certbot.

# sbopkg -Bi "configobj mock psutil pyrfc3339 \
python-configargparse python-parsedatetime \
python2-pythondialog werkzeug zope.component \
ndg_httpsclient python-augeas pytz python-requests \
josepy pyparsing zope.interface cryptography \
zope.event python-future six pyOpenSSL ipaddress \
enum34 cffi asn1crypto idna pycparser python-certifi \
python-urllib3 python-chardet requests-toolbelt \
augeas pbr funcsigs letsencrypt"

Теперь, настраиваем apache.
Создадим файл /etc/httpd/extra/vhosts-mycloud.conf со следующим содержимым:

# Nextcloud
<VirtualHost *:80>
 
   ServerAdmin it@my-cloud.ru
   ServerName my-cloud.ru
   ServerAlias www.my-cloud.ru 
 
   DocumentRoot "/var/www/htdocs/nextcloud"
 
   <Directory "/var/www/htdocs/nextcloud">
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Require all granted
   </Directory>
 
   ErrorLog "/var/log/httpd/my-cloud-error_log"
   CustomLog "/var/log/httpd/my-cloud-access_log" common
 
</VirtualHost>

И допишем в конец файла /etc/httpd/httpd.conf

include /etc/httpd/extra/vhosts-mycloud.conf

Перезапустим apache и войдём в браузере по адресу http://my-cloud.ru, и тут же получим ошибку:

Можно нажать на кнопку с предложением о добавлении нашего домена как доверенного в config.php, но не будем этого делать, так как для корректной и безошибочной работы, нужно добавить IP-адрес шлюза и внешний IP-адрес как доверенные. Поэтому, лучше сами отредактируем файл /var/www/htdocs/nextcloud/config/config.php изменив два параметра.

 'trusted_domains' =>
  array (
    0 => '192.168.10.217',
    1 => '192.168.10.1',
    2 => '77.77.77.77',
    3 => 'my-cloud.ru',
    4 => 'www.my-cloud.ru',
  ),
  'overwrite.cli.url' => 'http://my-cloud.ru',

После внесённых изменений перезапустим apache и ещё раз войдём в браузере по адресу http://my-cloud.ru, теперь ошибок не будет, появится приглашение для ввода логина и пароля.

Теперь получим сертификаты для доменов my-cloud.ru и для www.my-cloud.ru.

# certbot certonly --webroot -w /var/www/htdocs/nextcloud -d my-cloud.ru -d www.my-cloud.ru

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): it@my-cloud.ru

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: a

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: n
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for my-cloud.ru
http-01 challenge for www.my-cloud.ru
Using the webroot path /var/www/htdocs/nextcloud for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/my-cloud.ru/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/my-cloud.ru/privkey.pem
   Your cert will expire on 2018-09-27. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Сертификаты получили. Теперь надо сообщить apache об их расположении и настроить его на работу по HTTPS. Для этого, в файле /etc/httpd/httpd.conf уберём знак комментария в некоторых местах.

LoadModule socache_shmcb_module lib64/httpd/modules/mod_socache_shmcb.so
LoadModule ssl_module lib64/httpd/modules/mod_ssl.so
 
Include /etc/httpd/extra/httpd-ssl.conf

В файле /etc/httpd/extra/httpd-ssl.conf закомментируем весь блок <VirtualHost> и изменим файл /etc/httpd/extra/vhosts-mycloud.conf

# Добавим этот блок для автоматической смены http на https
<VirtualHost *:80>
    RewriteEngine on
    ReWriteCond %{SERVER_PORT} !^443$
    RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</VirtualHost>
 
# Nextcloud
# сменим порт 80 на 443
<VirtualHost *:443>
 
   ServerAdmin it@my-cloud.ru
   ServerName my-cloud.ru
   ServerAlias www.my-cloud.ru
 
   DocumentRoot "/var/www/htdocs/nextcloud"
 
   <Directory "/var/www/htdocs/nextcloud">
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Require all granted
   </Directory>
 
# Указываем расположение сертификатов    
    SSLCertificateFile          /etc/letsencrypt/live/my-cloud.ru/cert.pem
    SSLCertificateKeyFile       /etc/letsencrypt/live/my-cloud.ru/privkey.pem
    SSLCertificateChainFile     /etc/letsencrypt/live/my-cloud.ru/chain.pem
 
# Добавляем блок для правильной обработки заголовков
   <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
   </IfModule>
 
   ErrorLog "/var/log/httpd/my-cloud-error_log"
   CustomLog "/var/log/httpd/my-cloud-access_log" common
 
</VirtualHost>

Перезапустим apache и введя в браузере my-cloud.ru мы сразу попадём на страничку приглашения ввода логина и пароля, а в адресной строке увидим https://my-cloud.ru.
Теперь, зайдя на страничку основных настроек, в «Предупреждения безопасности и установки» ошибок не будет.

Когда же мы исправили ошибку о незащищённости файла .htaccess? ;)
Когда правильно описали блок <Directory> в файле /etc/httpd/extra/vhosts-mycloud.conf

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

# certbot renew --dry-run                                                          
...
...
Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/my-cloud.ru/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
...
...

Всё прошло успешно. Добавим в cron задание на ежедневную проверку сертификатов в 00:01

01 00 * * * /usr/bin/certbot renew 1> /dev/null

Тюнинг

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

HTTP/2.0

Как говорится в документации Nextcloud, использование HTTP2 должно ускорить работу облачного хранилища. Я особого прироста к скорости не заметил, правда, не делал каких-то особых тестов, только визуально. Тем не менее, HTTP2 я включил и оставил.
По умолчанию, поддержка HTTP2 не включена в стоковом пакете apache дистрибутива Slackware Linux 14.2. Поэтому, нам необходимо собрать его снова, включив HTTP2.
Сначала соберём и установим, при помощи sbopkg, пакет nghttp2 и jansson.
Смотрим последнюю версию nghttp2 на https://github.com/nghttp2/nghttp2/releases и меняем её в SlackBuild'e и Info. Версию jansson можно оставить. После того, как оба пакета собрались и установились, скачиваем SlackBuild и причитающееся для сборки apache, а так же последнюю версию его исходников (на момент написания статьи - 2.4.33).

# wget -r -nd -np -R index*,httpd-2.4* -e robots=off https://mirror.slackbuilds.org/slackware/slackware64-14.2/source/n/httpd/
# wget http://apache-mirror.rbc.ru/pub/apache//httpd/httpd-2.4.33.tar.bz2

В httpd.SlackBuild добавляем к configure параметр --enable-http2 и запускаем сборку, а по окончании, обновляем установленный пакет.

# chmod +x ./httpd.SlackBuild
# ./httpd.SlackBuild
...
Slackware package /tmp/httpd-2.4.33-x86_64-1.txz created.

# /etc/rc.d/rc.httpd stop
# upgradepkg /tmp/httpd-2.4.33-x86_64-1.txz
...
Package httpd-2.4.29-x86_64-1_slack14.2 upgraded with new package /tmp/httpd-2.4.33-x86_64-1.txz.

В файле /etc/httpd/http.conf добавляем загрузку нужного модуля.

LoadModule http2_module lib64/httpd/modules/mod_http2.so

И изменим файл /etc/httpd/extra/vhosts-mycloud.conf добавив блок:

<IfModule http2_module> 
   Protocols h2 h2c http/1.1
   H2Direct on 
</IfModule>

Этот блок нужно добавить во все директивы <VirtualHost> в которых планируется использование HTTP2. Запускаем apache.

# /etc/rc.d/rc.httpd start

Заходим в наше облако и в файле /var/log/httpd/my-cloud-access_log видим:

"GET /index.php/settings/admin HTTP/2.0" 200 31952
"GET /index.php/avatar/admin/32?v=0 HTTP/2.0" 304 -
"GET /index.php/apps/theming/js/theming?v=0 HTTP/2.0" 200 382
Если SSL сертификат получался на несколько доменов одновременно (используя несколько ключей -d в cerbot) и используется в разных директивах <VirtualHosts>, то HTTP2 работать не будет со вторым и последующими доменами. Нужно для каждого получать отдельный сертификат.
Будет ошибка - Misdirected Request.

PHP-FPM

В отличи от HTTP2, использование PHP-FPM дал заметный прирост в скорости. Так как он идёт в составе PHP пакета, то его надо, лишь, запустить и указать apache, что работать надо не с mod_php, а c php-fpm.

# chmod +x /etc/rc.d/rc.php-fpm
# /etc/rc.d/rc.php-fpm start

В /etc/httpd/httpd.conf комментируем строчку:

#include /etc/httpd/mod_php.conf

В директиве <VirtualHosts> добавляем блок:

<FilesMatch \.php$>
     SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

и перезапускаем apache

# /etc/rc.d/rc.httpd restart

Если в /var/log/php-fpm.log появится ошибки,
server reached pm.max_children setting (5), consider raising it
seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)

то нужно увеличить кол-во параллельных процессов php, в файле /etc/php-fpm.conf.
Эти процессы задаются переменными:

  • pm.max_children - максимальное количество дочерних процессов
  • pm.start_servers - количество процессов при старте
  • pm.min_spare_servers - минимальное количество процессов, ожидающих соединения
  • pm.max_spare_servers - максимальное количество процессов, ожидающих соединения

Для того, чтобы придать этим переменным правильное значение, сначала, выясним среднее значение памяти на один php-fpm процесс.

# ps -ylC php-fpm --sort:rss

S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S     0  3397     1  0  80   0 20092 190138 ep_pol ?       00:00:00 php-fpm
S    80  3401  3397  0  80   0 57856 192027 inet_c ?       00:00:06 php-fpm
S    80  3399  3397  0  80   0 57884 192059 inet_c ?       00:00:06 php-fpm
S    80  3398  3397  0  80   0 59900 192069 inet_c ?       00:00:07 php-fpm
S    80  3400  3397  0  80   0 62724 211134 inet_c ?       00:00:06 php-fpm

Нас интересует столбец RSS, который показывает значения потребляемой памяти в Килобайтах. Возьмём среднее значение равное 60 Мб. Учитывая то, что из имеющихся 16 Гб ОЗУ, я готов отдать под процессы php-fpm 10 Гб, получим - 10000/60≈166 дочерних процессов я могу использовать. Округлим это число до 150 и присвоим его переменной pm.max_children.
Значение переменной min_spare_servers можно начать с расчёта из количества ядер процессора умноженное на 2. У меня 4-ядерный процессор, поэтому начнём со значения 8. Значение переменной max_spare_servers можно начать с расчёта из количества ядер процессора умноженное на 4. У меня 4-ядерный процессор, поэтому начнём со значения 16. Далее следим за потребляемой памятью и нагрузкой на процессор, в том же htop, например. И, в зависимости от результатов, уменьшаем или увеличиваем значения.
Значение переменной start_servers=(pm.min_spare_servers+pm.max_spare_servers)/2. В нашем случае получаем 12.
И добавим pm.max_requests = 1000 для ограничения максимального количества запросов, которое обработает дочерний процесс, прежде чем будет уничтожен. На всякий случай, для устранения утечек памяти.

pm.max_children = 150
pm.start_servers = 12
pm.min_spare_servers = 8
pm.max_spare_servers = 16
pm.max_requests = 1000

После любых изменений в файле /etc/php-fpm.conf не забываем рестарт php-fpm.

# /etc/rc.d/rc.php-fpm restart

На самом деле, всё настройки очень индивидуальны и подбираются, часто, методом сравнительного анализа. Меня эти устроили, так и оставил.

Загрузка больших файлов

Настройка максимального размера выгружаемого файла производится в двух местах:
в веб-интерфейсе;


и в файле /var/www/htdocs/nextcloud/.htaccess при использовании mod_php в директивах <IfModule mod_php7.c> или <IfModule mod_php5.c> в зависимости от версии PHP,

  php_value upload_max_filesize 12G
  php_value post_max_size 12G
  php_value memory_limit 2G

либо в файле /var/www/htdocs/nextcloud/.user.ini при использовании php-fpm.

upload_max_filesize=12G
post_max_size=12G
memory_limit=2G

Почта

Для того, чтобы можно было получать уведомления от сервисов NC на свой адрес электронной почты, его необходимо внести в разделе «Личное» → «Личная информация» поле «E-mail» или в настройках пользователей.



И настроить или указать почтовый сервер через который будут отправляться письма в том же разделе, где мы настраивали максимальный размер выгружаемого файла, «Настройка»→«Дополнительные настройки» в разделе «Администрирование».



Есть три способа отправки: SMTP, PHP и Sendmail.
SMTP самый простой и, в данном случае, самый правильный способ, поскольку почтовый сервер находится не на том же компьютере, что и NC.
Если вы захотите использовать вариант PHP или Sendmail, то необходимо наличие почтового сервера на одном компьютере с NC. Это может быть и Postfix, и Exim, и даже, обычный, SSMTP, но их надо настраивать отдельно, а это уже другие статьи :).

Заполнив все поля, нажимаем кнопку «Отправить сообщение». И, если всё настроено правильно, то на указанную в личных настройках почту, придёт письмо с текстом - «Если вы получили это сообщение, значит электронная почта настроена правильно.»

Office

Для возможности редактировать офисные документы прямо в нашем облаке, есть 2 приложения в магазине NC. Это Onlyoffice и Collabore office.
Подробное различие описывалось ТУТ. Я подробно не изучал плюсы и минусы, но вот, что заметил:
у Onlyoffice более дружелюбный интерфейс и больше функционала, но он работает только с файлами OOXML (docx, xlsx, pptx). Правда, файлы старых версий MS Office (doc, xls, ppt) и файлы формата ODF (odt, ods, odp) он может конвертировать в OOXML.

{ТУТ БУДЕТ КУЧА ТЕКСТА}

Установим и запустим Docker.

# wget http://slackware.su/forum/files/nc/docker.tar.gz
# tar xf ./docker.tar.gz
# wget https://download.docker.com/linux/static/stable/x86_64/docker-18.03.1-ce.tgz
# tar -zxvf ./docker-18.03.1-ce.tgz --strip-components=1 -C ./docker/usr/bin/ docker/
# cd docker
# makepkg  -l y -c n /tmp/docker-18.03.1-ce-x86_64-1.txz
...
Slackware package /tmp/docker-18.03.1-ce-x86_64-1.txz created.

# upgradepkg --install-new /tmp/docker-18.03.1-ce-x86_64-1.txz
...
Package docker-18.03.1-ce-x86_64-1.txz installed.

# /etc/rc.d/rc.docker start
Starting dockerd ...

Не забываем прописать в /etc/rc.d/rc.local запуск docker'а.
Проверим версию.

# docker -v
Docker version 18.03.1-ce, build 9ee9f40

Проверим работу:

# docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9db2ca6ccae0: Pull complete 
Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Всё работает. Удалим не нужный образ. Для это сначала узнаем ID контейнера.

# docker ps -a
CONTAINER ID     IMAGE          COMMAND     CREATED          STATUS                     PORTS       NAMES
ab7ae81e8f19     hello-world    "/hello"    4 minutes ago    Exited (0) 3 minutes ago               dreamy_benz

Остановим этот контейнер (для остановки всех контейнеров можно написать docker stop $(docker ps -qa) ).

# docker stop ab7ae81e8f19
ab7ae81e8f19

Удалим этот контейнер (для удаления всех контейнеров можно написать docker rm -f $(docker ps -qa) ).

# docker rm -f ab7ae81e8f19
ab7ae81e8f19

И, теперь, удалим сам образ.

# docker rmi -f hello-world 
Untagged: hello-world:latest
Untagged: hello-world@sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
Deleted: sha256:2cb0d9787c4dd17ef9eb03e512923bc4db10add190d3f84af63b744e353a9b34
Deleted: sha256:ee83fc5847cb872324b8a1f5dbfd754255367f4280122b4e2d5aee17818e31f5

Samba каталоги

LDAP пользователи

WebDAV

Давайте подключим наш сервер облачного хранилища по WebDAV, как сетевой ресурс для пользователя graf. :-)

  • Windows:

просто подключив сетевой диск, введя адрес сервера и пароль пользователя NC.






Либо, в консоли:

 net use Z: https://my-cloud.ru/remote.php/dav/files/graf/ /user:graf ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_graf
  • Linux GUI:

На примере диспетчера файлов, Dolphin. Заходим в Сеть → Добавить сетевую папку → Веб-папка



Нажимаем кнопку «Далее».



Вводим необходимые данные и нажимаем на «Сохранить и подключиться». Появляется запрос пароля, вводим его и подключаемся.



Появляется сетевой ресурс с которым работаем, как с обычным каталогом.

  • Linux консоль:

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

# groupadd -g 230 davfs2
# useradd -u 230 -d /var/cache/davfs2 -g davfs2 -s /bin/false davfs2
# sbopkg -Bi davfs2

Затем, пользователя graf добавить в группу davfs2. Создать каталог для монтирования и файл в скрытой директории, в котором будут записаны данные для подключения.

# usermod -aG davfs2 graf
# mkdir /home/graf/mycloud
# mkdir /home/graf/.davfs2
# cp /etc/davfs2/secrets /home/graf/.davfs2/secrets

Теперь пропишем в файл /home/graf/.davfs2/secrets строку

 https://my-cloud.ru/remote.php/dav/files/graf/ graf ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_graf

и обезопасим его.

# chown graf /home/graf/.davfs2/secrets
# chmod 600 /home/graf/.davfs2/secrets

Для автоматического монтирования при логине, добавим в /etc/fstab строчку.

https://my-cloud.ru/remote.php/dav/files/graf/ /home/graf/mycloud davfs user,rw,auto 0 0

Заходим пользователем graf и пробуем монтировать:

$ mount ~/mycloud/

В /home/graf/mycloud должен примонтироваться облачный ресурс пользователя graf.

Но, если на компьютере больше одного пользователя, лучше монтировать или вручную,

# mount -t davfs https://my-cloud.ru/remote.php/dav/files/graf/ /home/graf/mycloud

Please enter the username to authenticate with server
https://my-cloud.ru/remote.php/dav/files/graf/ or hit enter for none.
  Username: graf
Please enter the password to authenticate user graf with server
https://my-cloud.ru/remote.php/dav/files/graf/ or hit enter for none.
  Password:  

или добавить эту строчку в скрипт автозапуска.

Прочее

Итог

Печать/экспорт
QR Code
QR Code wiki:articles:nc (generated for current page)