Піднімаємо Owncloud з нуля з динамічним IP і let's Encrypt. Тисяча слонів!*



Давно хотів написати цілісний туторіал по підняттю Owncloud в умовах домашнього сервера або невеликої компанії до 500 користувачів. Owncloud — це чудовий open-source проект, який дозволяє на власній інфраструктурі підняти свій варіант сервера синхронізації. По можливостям дуже схожий на Dropbox, а в чомусь і перевершує його. Величезний плюс — відсутність обмежень за обсягами зберігання, повний контроль над сервером. Мінуси теж очевидні: вам самим доведеться стежити за всім цим неподобством і турбуватися про надійність сервера, валяющегося на антресолях або в шафі.

Зовсім недавно мені підвернулася завдання з розгортання Owncloud в домашньо-бойових умовах. Я чесно відпрацював свої два літри кошерного російського імперського стаута і вирішив поділитися своїм досвідом, зібравши все воєдино. Отже, сьогодні ми розглянемо:
  1. Розгортання актуального LEMP-stack
  2. HTTPS. Let's Encrypt для Nginx з автоматичним оновленням сертифіката
  3. Конфігурування Nginx для Owncloud
  4. Кешування php-apcu
  5. Підключення зовнішнього основного сховища по NFS

Стартовий комплект

Операційна система під наш сервер — Ubuntu 16.04.1 Server torrent). Оптимальний варіант — віртуальна машина. Це досить вдале рішення завдяки легкості міграції, можливості динамічного виділення ресурсів, снапшотов та інших плюшок. Розмір віртуальної машини — 10-15 ГБ. Цього більш ніж достатньо під систему.
Зовнішнє сховище (каталог data для owncloud), де будуть зберігатися всі ваші дані. Розмір — в залежності від ваших потреб. Я б рекомендував розглядати варіант від 100 ГБ. Поділ сховища і основний логіки сервера дає велику гнучкість конфігурації. В даному випадку — SSD для системи і HDD від NAS для даних. При підключенні зовнішнього розділу з даними з'являється гнучкість в плані міграції і можливість наростити швидкість або об'єм, якщо раптом буде потрібно.
Домен і зовнішній ip-адресу — в умовах вмираючого пулу вільних ipv4 адрес провайдери все рідше віддають просто так білий зовнішній адресу. Якщо у вас сірий адресу, то тут вже мало що можна зробити. Тільки прокидати VPN тунель на свою VPS з білим IP і танцювати звідти. Але іноді провайдери віддають цілком білі адреси, але не статику, а динаміку. Причому адреса може змінюватися просто за велінням лівої п'ятки, сесія рватися опівночі, і абонент отримує новий IP. У поточному кейсі стоїть роутер MikroTik, який вміє безкоштовний динамічний DNS, починаючи з RouterOS v6.14. Знаходиться ця радість в розділі IP/Cloud. Після підключення функції роутер отримує доменне ім'я виду 123456b7890f.sn.mynetname.net. Домен це завжди вказує на ipv4 адреса, виданий провайдером.
image

Домен віддають 4-го рівня. Звичайний StartSSL та інші сертифікаційні центри не стануть з вами працювати, якщо ви не володієте 2 рівнем. Раніше це призводило до використання самоподпісанного сертифіката, на який лаявся браузер. Тепер з'явився let's Encrypt, який вирішує проблему.

Є й альтернативні варіанти, які добре описані в публікації Домашній хостинг сайтів з динамічним IP користувачем spectreob.

Развертываем LEMP

Починати, мабуть, варто з установки найбільш звичних утиліт для роботи: htop, iotop, iftop, mc. Потім приступаємо до самого LEMP — Linux, Nginx (його вимовляють як Engine X), MySQL/MariaDB і PHP. Linux у нас вже є. Чому Ubuntu 16.04, а не, скажімо, Debian або CentOS? Я не люблю rpm, і з Ubuntu простіше в плані репозиторіїв зі свіжими версіями софту. Дуже не люблю практику «make install» на бойових серверах. Все ж більш оптимальним є шлях використання пакетного менеджера. Цього принципу і будемо дотримуватися.
Встановлюємо nginx, сконфігуріруем пізніше:
sudo apt-get install nginx

Развертываем MariDB (актуальний форк MySQL) і перевіряємо працездатність сервісу:
sudo apt-get install mariadb-server mariadb-client
sudo systemctl status mysql.service

Виконуємо hardening-процедуру, відключаючи тестові бази та інші потенційні дірки в захисті:
sudo mysql_secure_installation

Буде запущено діалог, в якому треба буде відповісти на серію питань. В цьому ж діалозі ми ставимо пароль для root. Він знадобиться пізніше, коли будемо створювати базу для owncloud.

Встановлюємо PHP7.0, php-fpm і модулі, необхідні для роботи owncloud, з супутніми сервісами:
sudo apt-get install php7.0 php7.0-mysql php7.0-fpm php7.0-gd php7.0-json php7.0-curl php7.0-zip php7.0-xml php7.0-mbstring

Також для роботи Owncloud потрібно відредагувати змінні оточення:
sudo nano /etc/php/7.0/fpm/pool.d/www.conf

Необхідно розкоментувати наступні рядки:
env[HOSTNAME] = $HOSTNAME
 
env[PATH] = /usr/local/bin:/usr/bin:/bin
 
env[TMP] = /tmp
 
env[TMPDIR] = /tmp
 
env[TEMP] = /tmp
 


Налаштовуємо let's Encrypt і конфігуруємо Nginx

image
Let's Encrypt — це некомерційна ініціатива, яка надає безкоштовний, автоматизований і відкритий центр сертифікації. За що їм величезне спасибі. Ймовірно, сертифікаційні центри, які торгують, по суті, своєю репутацією, тепер будуть змушені отримувати основний прибуток з сертифікатів високого класу — Organization Validation (OV) або Extended Validation (EV). Такий тип сертифіката доступний тільки для юридичних осіб та підтверджує факт існування умовного ТОВ «Роги і Копита». При цьому перевіряється володіння доменом, сама компанія, нотаріально завірені документи та інші нюанси.
Для особистого використання, нам цілком достатньо Domain Validation сертифіката від let's Encrypt. Цей варіант по суті лише засвідчує той факт, що ви працюєте саме з доменом example.com. І заодно захистить нас від Man-in-the-Middle атак, інжекції всякої погані на цільову сторінку (передаю привіт MosMetro Wi-Fi і стільниковим операторам) та перехоплення паролів при використанні громадських мереж. Ідеальний варіант для власного Owncloud. Чому не використовувати самопідписаний сертифікат?


У Owncloud є відмінна функція «share link», яка дозволяє передати людині посилання на файл або каталог. Дуже зручно, коли раптово потрібно передати щось вагою в 50 ГБ, а більш звичні Dropbox і Google Drive безкоштовно такого не дозволяють. Ви точно не хочете пояснювати бухгалтеру Олімпіаді Сигизмундовне, чому її браузер палає червоним і кричить, що її зламали пакистанські хакери все погано невалидного сертифіката. Тим більше, що все дуже просто.

image
Основна ідея let's Encrypt — видача автоматично сертифікати з коротким терміном дії — 90 днів. На думку авторів проекту, це збільшить безпеку завдяки автоматичному виведенню з обороту скомпрометированых сертифікатів. Для валідації домену сервіс пропонує certbot-auto з кількома сценаріями роботи:
  1. Apache — автоматично отримує і встановлює сертифікат для Apache 2.4. Використовує 443 порт
  2. Nginx — автоматично отримує і встановлює сертифікат для Nginx. Альфа версія, для продакшену рано. Використовує 443 порт
  3. webroot — створює в кореневому каталозі чинного сервера файли необхідні для валідації домену. Використовує 80 порт
  4. standalone — піднімає автономний сервер, який відповідає на необхідні запити ззовні для валідації. Використовує 80 або 443 порт. Для систем, які не мають діючого веб-сервера та інших випадків.
  5. manual — повністю ручний режим, що вимагає ручної копипасты. Застосовується в тому випадку, коли ви генеруєте ключі не на цільовій машині. Наприклад, для роутера.
В результаті ми маємо хороший універсальний набір для різних сценаріїв, включаючи ситуації, коли у вас немає повного контролю на сервером. Автоматичну установку сертифіката в Nginx ми не будемо використовувати із-за її альфа статусу, а редагування конфига робочого веб-сервера — процес дуже інтимний. Дуже не хочеться зіткнутися з кривою роботою не налагодженого скрипта. Тим не менше, процес отримання сертифіката ми автоматизуємо.

Для початку выкачаем і встановимо останню версію certbot:
cd /usr/local/sbin
sudo wget https://dl.eff.org/certbot-auto
sudo chmod a+x /usr/local/sbin/certbot-auto

Редагуємо конфіг nginx і дозволяємо доступ до того каталогу, в який буде писати webroot варіант certbot'а:
sudo nano /etc/nginx/sites-available/default

Додаємо рядок:
location ~ /.well-known {
allow all;
}

Перезапускаємо сервіс nginx:
sudo service nginx restart 

Тепер можна запустити certbot і згенерувати сертифікати для нашого домену. У нашому конкретному випадку це домен аж четвертого рівня від Mikrotik DDNS. Ніхто інший валідні для браузерів сертифікати вам не підпише навіть для третього.
sudo certbot-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d example.sn.mynetname.net

У діалоговому вікні потрібно буде ввести адресу електронної пошти та погодитися з умовами використання:
image

image
Certbot складає актуальні версії сертифікатів в каталог /etc/letsencrypt/live/, створюючи симлинки. Всередині будуть лежати файли:
  • cert.pem: сертифікат вашого домену.
  • chain.pem: chain сертифікат let's Encrypt
  • fullchain.pem: комбінований сертифікат з cert.pem і chain.pem
  • privkey.pem: приватний ключ вашого сертифіката
Генеруємо ключ Діффі — Хеллмана:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Відмінно. Тепер, прописавши в конфіги Nginx посилання на /etc/letsencrypt/live/, ми будемо мати завжди актуальну версію. Створюємо новий конфіг для нашого домену:
sudo nano /etc/nginx/sites-available/example.sn.mynetname.net

Готовий конфіг з оптимизациями, які рекомендує мануал owncloud. 80 порт автоматично редиректит на 443:
конфіг nginx
upstream php-handler {
 
#server 127.0.0.1:9000;
 
server unix:/run/php/php7.0-fpm.sock;
 
}
 

 
#Redirect from 80 to 443
 
server {
 
listen 80;
 
server_name example.sn.mynetname.net;
 
return 301 https://$host$request_uri;
 
}
 

 
# HTTPS
 
server {
 
listen ssl 443;
 

 
server_name example.sn.mynetname.net;
 

 
ssl_certificate /etc/letsencrypt/live/example.sn.mynetname.net/fullchain.pem;
 
ssl_certificate_key /etc/letsencrypt/live/example.sn.mynetname.net/privkey.pem;
 

 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 
ssl_prefer_server_ciphers on;
 
ssl_dhparam /etc/ssl/certs/dhparam.pem;
 
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
 
ssl_session_timeout 1d;
 
ssl_session_cache shared:SSL:50m;
 
ssl_stapling on;
 
ssl_stapling_verify on;
 
add_header Strict-Transport-Security max-age=15552001;
 

 
add_header Cache-Control "public, max-age=7200";
 
# Add headers to serve security related headers
 
add_header X-Content-Type-Options nosniff;
 
add_header X-Frame-Options "SAMEORIGIN";
 
add_header X-XSS-Protection "1; mode=block";
 
add_header X-Robots-Tag none;
 
add_header "X-Download-Options" "noopen";
 
add_header "X-Windows-Cross-Domain-Policies" "ні";
 

 
root /var/www/;
 

 
rewrite ^/.well-known/carddav /remote.php/carddav/ permanent;
 
rewrite ^/.well-known/caldav /remote.php/caldav/ permanent;
 

 
# Add index.php to the list if you are using PHP
 
index index.html index.htm index.nginx-debian.html;
 

 
location ~ /.well-known {
 
allow all;
 
}
 

 
location / {
 
# First attempt to serve as request file, then
 
# as directory, then fall back to displaying a 404.
 
try_files $uri $uri/ =404;
 
}
 
location = /robots.txt {
 
allow all;
 
log_not_found off;
 
access_log off;
 
}
 

 
location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README){
 
deny all;
 
}
 

 
location ~ ^/(build|tests|config|lib|3rdparty|templates|data)/ {
 
deny all;
 
}
 

 
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
 
deny all;
 
}
 
location ~ \.php(?:$|/) {
 
fastcgi_split_path_info ^(.+\.php)(/.+)$;
 
include fastcgi_params;
 
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 
fastcgi_param PATH_INFO $fastcgi_path_info;
 
fastcgi_param HTTPS on;
 
fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
 
fastcgi_pass php-handler;
 
fastcgi_intercept_errors on;
 
}
 

 
}
 



Наведений конфіг дає оцінку «A» на https://www.ssllabs.com. Звичайно, якщо вам потрібна сумісність зі старими версіями Java, Windows XP і тому подібним, доведеться вирішити деякі потенційно небезпечні протоколи.

Автоматизуємо оновлення сертифіката

Перевіряємо оновлення сертифіката:
sudo certbot-auto renew

При запуску цієї команди certbot зв'яжеться з серверами EFF і спробує відновити свою версію, якщо це можливо, а потім і сертифікати. Причому не тільки на всі доступні домени. Дуже зручно. Якщо термін зміни сертифіката не підійшов, то нічого не станеться, і скрипт про це повідомить.
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.sn.mynetname.net.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.sn.mynetname.net/fullchain.pem (skipped)
No renewals were attempted.

Тепер можна додати регулярний запуск скрипта crontab:
sudo crontab -e
 

Всередину додаємо регулярну завдання з оновлення сертифікатів та їх перезаливке в nginx:
30 2 * * 1 /usr/local/sbin/certbot-auto renew >> /var/log/le-renew.log
 
35 2 * * 1 /etc/init.d/nginx reload
 

Активуємо наш сайт:
sudo ln -s /etc/nginx/sites-available/418402b5554f.sn.mynetname.net /etc/nginx/sites-enabled/
 


Установка Owncloud

image
Є кілька варіантів, але найбільш кращим у більшості випадків є установка з репозиторію. Нехай у пакетного менеджера голова болить з приводу оновлень. Головне, не забувати робити backup перед накатыванием нових пакетів. Іноді бувають неприємні сюрпризи. Для початку необхідно додати GPG-ключ:
wget -nv https://download.owncloud.org/download/repositories/stable/Ubuntu_16.04/Release.key -O Release.key
 
sudo apt-key add < Release.key
 

Після цього додаємо репозиторій і встановлюємо пакет owncloud-файли. Звичайний пакет owncloud притягне по залежності ще і Apache, а він нам не потрібен.
sudo sh -c "echo 'deb http://download.owncloud.org/download/repositories/stable/Ubuntu_16.04/ /' > /etc/apt/sources.list.d/owncloud.list"
 
sudo apt-get update
 
sudo apt-get install owncloud-files
 

В результаті, в /var/www/owncloud у вас розгорнеться все необхідне. Так як Nginx вважає кореневий каталог /var/www-доступ до сервісу буде виглядати приблизно так: example.com/owncloud

Налаштовуємо MariaDB

Так як інсталяція у нас маленька, то в тонкощі оптимізації ми вдаватися не будемо. Тому розгортаємо з більш або менш дефолтних конфіг. Username і password підставте ті, які буде використовувати owncloud для доступу до бази даних.
sudo mysql -uroot -p
 

 
create database owncloud;
 
create user <b>username</b>@localhost identified by '<b>password</b>';
 
grant all privileges on owncloud.* to <b>username</b>@localhost identified by '<b>password</b>';
 
flush privileges;
 
exit;
 


Підключаємо зовнішнє сховище

Як я вже говорив раніше, мені здається гарною ідеєю розділяти віртуальну машину з самою логікою сервісу та сховище, куди будуть падати синхронізовані дані. Тут ви вже можете чинити на свій розсуд. Можна нічого не робити, і тоді дефолтних сховищем буде /var/www/owncloud/data. Можна поступити як я і створити каталог /mnt/data, куди через fstab буде монтуватися зовнішній тому. Це може бути SSD/HDD, він може лежати локально, а може перебувати на NAS-storage у цій же локальній мережі. Не забудьте тільки протестувати швидкість отриманого гібрида. Це потенційно вузьке місце. У моєму домашньому варіанті це samba-сервер на хост-машині, хтось може віддати перевагу NFS.

Додаткова зручність такої гібридної конструкції — легкість переїзду на більш швидкі або ємні варіанти при необхідності. Досить зупинити сервіси і залити на новий підключається тому всі файли зі старого /mnt/data, після чого змінити точку монтування у fstab і перезапустити сервіс знову. Раптом ви вирішите перенести дані зі старого HDD на SSD RAID?

Кешування

image
Важливий момент. Без memory caching owncloud може працювати відчутно задумчивее. Причому він неодмінно нагадає вам про це на сторінці адміністратора. Вибір способу кешування залежить від архітектури системи. З рекомендаціями від розробників ви можете ознайомитися тут. Якщо коротко, то для особистого використання, так і невеликих інсталяцій рекомендується використовувати тільки APCu. Для малих організацій, при установці на один сервер — APCu для локального кешування і Redis для file locking. Для установки на кластер у великій організації: Redis для всього, крім локального кешування.

Розробники вважають APCu найбільш швидким варіантом для локального кешу. Якщо вистачає оперативної пам'яті, то краще використовувати APCu для локального кешування і Redis для file locking. Якщо пам'яті недостатньо, то рекомендується використовувати Redis і для того й іншого.

В нашому варіанті ми будемо використовувати тільки APCu. Встановимо відповідний модуль для php:
sudo apt-get install php-apcu
 

Тепер буде достатньо просто додати їх в конфігураційний файл owncloud — config.php:
'memcache.local' => '\OC\Memcache\APCu',
 


Перший запуск нашого дітища

image
Перезавантажуємо машину на всяк випадок, щоб перезапустити всі сервіси. Заходимо на example.com/owncloud і
уважно тиснемо всі кнопки без розбору заповнюємо рядки админского аккаунта, паролів, розташування data католога (/mnt/data, як у цьому посібнику), логіна і пароля від owncloud-користувача бази даних. Якщо все пройшло нормально, то скоро ви завантажитеся в основне меню сервісу і зможете переконатися, що всі нахрен зламано в порядку.

*Тисяча слонів

Террі Пратчетт, Рухомі картинкиimage
Але Достабль вже не слухав. Він вказав на декілька прислоненных до стіни дощечок.

— Що це таке? — запитав він.

— А це моя ідея, — сказав Зильберкит. — Ми подумали, що було б проявом… е-е… ділового чуття, — він явно смакував ці слова, як незвичне, але вишукане ласощі, — розповідати людям про нових рухомих картинках, які ми тут робимо.

Достабль підібрав одну з дощечок і, тримаючи її в витягнутій руці, оглянув критичним оком. На ній значилося:

На будуюсчей ниделе ми пакажем

«ПЕЛИАС І МЕЛІСАНДРА»

Рамантическая Трогедия у 2 частинах

Спасибі за увагу

— Угу, — промовив він без жодного виразу.

— Хіба погано? — глухо вимовив роздавлений Зильберкит. — Ну, це, адже тут є все, що необхідно знати глядачам.

— Дозволь, — сказав Достабль, беручи зі столу Зильберкита шматочок крейди.

Деякий час він щось квапливо дряпав на звороті дошки, а потім дозволив прочитати написане:

БОГИ І ЛЮДИ СКАЗАЛИ ЭТАМУ НІ БУВАТИ АЛЕ ВОНИ НИЧИГО НІ ХАТЕЛИ СЛУХАТИ

«ПЕЛИАС І МЕЛІСАНДРА»,

Істерія Забороненою Люпви

Пристрасть Пабеждаит Прасранство та Час!

Тебе Натрясут

За Участю 1000 сланов!

Віктор і Зильберкит читали текст з настороженою увагою. Так вивчають обіднє меню на чужій мові. А мова і справді був чужим. Але що найгірше, на вигляд він був колишнім, рідним.

— Ну, не знаю… — обережно висловився Зильберкит. — Власне кажучи… Що вже там такого забороненого… е-Е… Все це засновано на реальній історії, тільки імена змінено. Я вважав, що картина буде корисна, так би мовити, підростаючому поколінню. Герої, будьте ласкаві бачити, так ніколи і не зустрілися — ось у чому трагедія. Все це, е-е… дуже-дуже сумно. — Він подивився на дощечку. — Хоча, з іншого боку, в цьому безперечно є. Е-е… — Він явно був чимось занепокоєний. — Але я, по правді сказати, не пам'ятаю ніяких слонів. — Голос його прозвучав вкрай винувато. — В день кліків я був на роботі цілий день, але зовсім не пам'ятаю тисячі слонів, хоча, напевно, помітив би їх.

Достабль свердлив його немиготливим поглядом. Звідки взялися слони, він і сам не знав, проте кожне нове розумове зусилля обдаровує його черговим, вельми певним уявленням про те, як слід проводити картини. Тисяча слонів — для початку це зовсім непогано.


Спасибі всім дочитавшим до кінця цю простирадло. Мені хотілося описати максимально повно всі деталі, щоб не довелося нишпорити по різним, часто суперечливим джерел. Я не виключаю, що міг десь допустити помилки або неточності, хоча і перевірив усі двічі. Буду дуже вдячний тыканью носом в помилки.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.