ownCloud: Je eigen cloud

Doel 

Google de deur uit en overstappen op je eigen cloud

Benodigdheden 
Tutorial 

Al jaren had ik de wens om af te stappen van Gmail, Google Calendar, Google Contacts en Dropbox, services waar veel gebruik van maak. Met ownCloud kun je zonder veel moeite de laatste 3 services vervangen, zelf ben ik dan ook helemaal over. In combinatie met Android merk ik het verschil niet eens.

Let op! OwnCloud is een vrij zwaar pakket, de eerste Raspberry Pi's zullen het wel kunnen draaien maar het zal in de praktijk langzaam aanvoelen. Als je voornamelijk files gaat syncen met de mobiele en desktop-apps zal je daar waarschijnlijk niets van merken maar om de webinterface echt soepel te laten werken is een RPi2 wel lekker. Het is maar een waarschuwing, ik wil je er zeker niet van weerhouden het te proberen op een RPi1, ik hoor ook graag hoe het werkt. Een alternatief voor de RPi kan in dit geval ook een virtual private server (VPS) zijn, bijvoorbeeld bij Digital Ocean (deze website draait ook op zo'n VPS, je betaald daar per minuut dat je je server gebruikt, 24 uur kost je 16 cent).

ownCloud

De ownCloud server software is een webapp welke net als deze website draait op een webserver (in dit geval Nginx) met PHP (in dit geval PHP-fpm) en een database server (bijvoorbeeld MySQL of MariaDB). Out-of-the-box kan ownCloud bestanden hosten net als Dropbox, om te syncen met mobiele apparaten zijn er apps voor Android, iPhone en BlackBerry. Voor computers zijn er apps voor Linux, OSX en Windows. Je files zijn ook meteen bereikbaar via Webdav (als een netwerkschijf maar dan over internet) en via een mooie webinterface. Binnen ownCloud kun je ook contactenlijsten en agenda's aanmaken, deze kunnen eveneens gesynct worden naar allerlei apparaten via de open standaarden Caldav en Carddav. Het filmpje hieronder geeft een goed beeld van wat je allemaal kunt in ownCloud 8.

Naast de grote hoeveelheid standaard functies kun je ook apps installeren die nog meer functionaliteit bieden, zoals webmail of een app voor het maken en syncen van notities.

Nginx met PHP

Als eerste moet er een webserver met PHP geïnstalleerd worden, de mensen van ownCloud raden Apache met mod_php aan maar wij zijn eigenwijs en prefereren het nieuwe en snellere Nginx met het snellere PHP-fpm. Hoe je dat installeert staat hier beschreven, volg eerst deze tutorial en kom dan hier terug.

We gaan er hier vanuit dat ownCloud het enige is wat op je RPi zal draaien qua webapps, Nginx kan oneindig veel websites draaien maar daar gaan we in een andere tutorial verder op in. Als je wilt dat je ownCloud installatie vanaf het internet te bereiken is, is het zeer aan te raden om SSL (HTTPS) te gebruiken, daarvoor heb je een certificaat nodig; ook daar komen we later in deze tutorial op terug.

Als eerste moeten we een berg PHP modules installeren (maar eerst updaten we de apt-get database):
sudo apt-get update
En dan:
sudo apt-get install php5-common php5-fpm php5-cli php5-json php5-mysql php5-curl php5-intl php5-mcrypt php5-memcache php-xml-parser php-pear php5-user-cache php5-mysql php5-curl php5-cli
Vervolgens gaan we Nginx configureren, hoe we dat doen hangt af van of je SSL gaat gebruiken of niet.

SSL

OwnCloud zou je alleen moeten gebruiken met SSL, als je dat niet doet stuur je je wachtwoord, je contacten, je agenda en alle files die je synct met ownCloud zonder encryptie over het internet. Dat is niet handig om meerdere redenen. Het is echter nog best lastig om een goedgekeurd certificaat te krijgen. Je hebt nu dus drie keuzes: je gaat door met SSL en maakt zelf certificaten, je gaat door met SSL en vraagt een goedgekeurd certificaat aan bij een CA (Certificate Authority) of je gaat door zonder SSL. De tweede optie behandelen we een andere keer. Ga hier direct onder verder als je zelf certificaten wilt maken (en sla "Verder zonder SSL over"), sla anders de volgende alinea over en ga verder met "Verder zonder SSL".

Verder met zelf gemaakte SSL certificaten

Zelf certificaten maken is qua encryptie net zo veilig als een certificaat halen bij een CA maar als je in dat geval naar je ownCloud site surft krijg je allerlei waarschuwingen dat de identiteit van de site niet bevestigd kan worden. Dat schrikt mensen af (en terecht, als dat bij je bankwebsite gebeurd moet je snel weg want dan is er iets mis met je verbinding!). CA's bestaan zodat browsers kunnen checken of een certificaat wat een webserver presenteert echt bij dat domein hoort. Als je zelf een certificaat maakt kan dat niet gecheckt worden. Je hebt verder wel alle voordelen van encryptie dus als je je ownCloud server gaat blootstellen aan het internet is dit wel de beste optie. Gelukkig zijn certificaten zo gemaakt. We maken de certificaten meteen op de plaats waar Nginx ze al verwacht (/etc/ssl/nginx/). We maken eerst die map en gaan er heen:
mkdir /etc/ssl/nginx
cd /etc/ssl/nginx
Vervolgens maken we een persoonlijke key en een zelfgetekend certificaat van 4096 bit welke 10 jaar geldig is:
openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/nginx/cloud.example.com.crt -keyout /etc/ssl/nginx/cloud.example.com.key -newkey rsa:4096
Vul de gevraagd de informatie in maar let op, deze informatie is zichtbaar voor iedereen die je website bezoekt, ik heb zelf dan ook niet alles ingevuld.

We hebben ook een nieuwe Nginx configuratie nodig, maak eerst een back-up van het bestaande bestand (niet door het te kopiëren (cp) maar door het te verplaatsen (mv)):
sudo mv /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup
Nu maken we een nieuwe file:
sudo nano /etc/nginx/sites-available/default
In deze file plakken we de volgende tekst (bron doc.owncloud.org, met een kleine wijziging:

upstream php-handler {
  #server 127.0.0.1:9000;
  server unix:/var/run/php5-fpm.sock;
  }

server {
  listen 80;
  server_name cloud.example.com;
  # enforce https
  return 301 https://$server_name$request_uri;
  }

server {
  listen 443 ssl;
  server_name cloud.example.com;

  ssl_certificate /etc/ssl/nginx/cloud.example.com.crt;
  ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key;

  # Path to the root of your installation
  root /usr/share/nginx/www/;
  # set max upload size
  client_max_body_size 10G;
  fastcgi_buffers 64 4K;

  # Disable gzip to avoid the removal of the ETag header
  gzip off;

  # Uncomment if your server is build with the ngx_pagespeed module
  # This module is currently not supported.
  #pagespeed off;

  rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
  rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
  rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;

  index index.php;
  error_page 403 /core/templates/403.php;
  error_page 404 /core/templates/404.php;

  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
    }

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

  location / {
   # The following 2 rules are only needed with webfinger
   rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
   rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

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

   rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;

   try_files $uri $uri/ /index.php;
   }

   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_pass php-handler;
   }

   # Optional: set long EXPIRES header on static assets
   location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
       expires 30d;
       # Optional: Don't log access to assets
         access_log off;
   }

  }
Sluit nano: ctrl-x, y, enter.
Je kunt je nieuwe Nginx configuratie testen door te typen:
nginx -t
En zou geen foutmelding mogen zijn. Ga nu verder met "MariaDB, de database".

Verder zonder SSL

Als we geen SSL gebruiken voorkomen we waarschuwingen van de browser maar er zal ook geen encryptie zijn. Ik raad deze optie alleen aan als je ownCloud binnen je eigen netwerk gaat gebruiken.

We beginnen met het maken van een nieuwe Nginx configuratie nodig, maak eerst een back-up van het bestaande bestand (niet door het te kopiëren (cp) maar door het te verplaatsen (mv)):
sudo mv /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup
Nu maken we een nieuwe file:
sudo nano /etc/nginx/sites-available/default
In deze file plakken we de tekst hieronder (bron doc.owncloud.org, ik heb de volgende wijzigingen aan het origineel doorgevoerd:
Detele het eerste server{} blok, verander ook het listen argument in het tweede (nu het eerste) server{} blok van "443 ssl" naar "80", zet een "#" voor de twee regels die beginnen met "ssl". Je config file ziet er nu zo uit (deze kun je dus knippen-plakken in het lege /etc/nginx/sites-available/default):

upstream php-handler {
  #server 127.0.0.1:9000;
  server unix:/var/run/php5-fpm.sock;
  }

server {
  listen 80;
  server_name cloud.example.com;

  #ssl_certificate /etc/ssl/nginx/cloud.example.com.crt;
  #ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key;

  # Path to the root of your installation
  root /usr/share/nginx/www/;
  # set max upload size
  client_max_body_size 10G;
  fastcgi_buffers 64 4K;

  # Disable gzip to avoid the removal of the ETag header
  gzip off;

  # Uncomment if your server is build with the ngx_pagespeed module
  # This module is currently not supported.
  #pagespeed off;

  rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
  rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
  rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;

  index index.php;
  error_page 403 /core/templates/403.php;
  error_page 404 /core/templates/404.php;

  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
    }

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

  location / {
   # The following 2 rules are only needed with webfinger
   rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
   rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

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

   rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;

   try_files $uri $uri/ /index.php;
   }

   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_pass php-handler;
   }

   # Optional: set long EXPIRES header on static assets
   location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
       expires 30d;
       # Optional: Don't log access to assets
         access_log off;
   }

  }
Sluit nano: ctrl-x, y, enter.
Nu zou nginx -t geen foutmelding mogen geven. Wat we nu nog nodig hebben is een database.

MariaDB, de database

MariaDB is de database server die ownCloud straks gaat gebruiken om allerlei dingen op te slaan. MariaDB is een fork van MySQL, ontstaan nadat Oracle de ontwikkeling van MySQL overnam van Sun. MariaDB wordt onderhouden door de originele ontwikkelaars van MySQL. Oracle is een bedrijf wat niet erg open-source vriendelijk is dus gebruiken wij MariaDB, wat op vrijwel elke manier een drop-in vervanging is van MySQL. Goed... we beginnen met de installatie:
apt-get install mariadb-server
vul een wachtwoord naar keuze in voor de root gebruiker (overigens, het is misschien is verwarrend maar MariaDB luistert nog steeds naar commando's die beginnen met "mysql", om compatibiliteit te bewaren) en laat de installer zijn gang gaan, als apt-get klaar is draaien we een script om MariaDB meteen veiliger te maken, typ:
mysql_secure_installation
en druk op enter. Voer je root wachtwoord in en zeg dat je het niet wilt veranderen. Verder is het goed om de default keuzes te accepteren. Als het script klaar is gaan we inloggen in MariaDB en een database aanmaken:
mysql -u root -p
Log in maak een database aan:
create database owncloud;
Je kunt kijken of de database inderdaad bestaat met:
show databases;
Ik neem aan dat "owncloud" in het lijstje staan. We gaan verder met de databases toewijzen aan een gebruiker met een wachtwoord. Vervang in het onderstaande commando "gebruiker" en "wachtwoord" door waardes die je zelf kiest. Onthoud de waardes voor later bij de installatie van ownCloud.
grant all privileges on owncloud.* to gebruiker@localhost IDENTIFIED BY 'wachtwoord';
Sluit MariaDB met ctrl-d. Dat was het, we hebben een webserver die PHP begrijpt en er staat een lege database klaar voor ownCloud, tijd om het pakket zelf te downloaden.

ownCloud installeren

We beginnen met navigeren naar de map waar we de ownCloud files gaan neerzetten, onze webroot:
cd /usr/share/nginx/www/
Om de files te downloaden is wget een onmisbare tool en het staat standaard al geïnstalleerd, met het commando hieronder downloaden we de op dit moment laatste versie (8.1) maar let op, dat is nu misschien niet de laatste versie en dan moet het commando aangepast worden:
wget https://download.owncloud.org/community/owncloud-8.1.0.tar.bz2
we pakken het pakket uit (en met strip-components zorgen we dat de files gelijk in de huidige map staan en niet in een submap):
tar --strip-components=1 -xvjpf owncloud-8.1.0.tar.bz2
om het netjes te houden verwijderen we het tar.bz2 bestand meteen:
rm owncloud-8.1.0.tar.bz2
Om onszelf de verdere installatie makkelijk te maken geven we alle files tijdelijk even aan de webserver, met andere worden, we geven de www-data gebruiker alle rechten over alle ownCloud files:
chown -R www-data *
Nu gaan we verder met de installatie in de browser.

In de browser van de computer waar je nu op werkt, of een andere, surf je naar het IP adres van je RPi, als je dat adres niet weet typ je in de terminal even: ip addr, je krijgt de volgende output:

freek@home:~$ ip addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: p2p1:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether bc:ee:7b:87:f8:79 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 brd 192.168.1.255 scope global p2p1
       valid_lft forever preferred_lft forever
    inet6 fe80::beee:7bff:fe87:f879/64 scope link
       valid_lft forever preferred_lft forever
Het dik gedrukte getal met de streep eronder is in dit geval mijn IP adres, bij jou kan het iets anders zijn. Vul dit IP adres in op de navigatie balk van je browser en druk enter. Als het goed is wordt je begroet door het ownCloud installatie scherm. Wanneer je een domeinnaam hebt (gekocht) EN deze wijst al naar je thuis IP adres EN je hebt al een gat in het firewall van je router gemaakt (poort 443 of, zonder SSL poort 80) welke wijst naar het ip adres van je RPi, dan kun je ook surfen naar deze domeinnaam.

In het ownCloud installatie scherm vul je alle gegevens in die je in deze tutorial hebt gebruikt. Je bent vrij om een gebruikersnaam en wachtwoord te kiezen maar de MySQL/MariaDB gebruiker en databasenaam heb je al eerder vastgelegd, hetzelfde geld voor het database wachtwoord. Je kunt in dit overzicht ook nog de "data" map van ownCloud veranderen, dat kan handig zijn (als je wilt dat het bijvoorbeeld een externe USB schijf met veel ruimte is) maar je kunt het later ook nog veranderen. Klik op "Finish setup".

Om het wat veiliger te maken kunnen we optioneel nog even een scriptje draaien om de permissie wat strikter te maken. We geven alle files die de webserver niet hoeft te veranderen aan de root gebruiker zodat er minder kans is op misbruik. De stap is dus echt optioneel. Ga eerst naar je eigen home directory door te typen:
cd
Maak een lege tekst file aan met de naam owncloud-permissions:
nano owncloud-permissions
Plak de volgende tekst in de file:

#!/bin/bash
ocpath='/usr/share/nginx/www/'
htuser='www-data'

find ${ocpath}/ -type f -print0 | xargs -0 chmod 0640
find ${ocpath}/ -type d -print0 | xargs -0 chmod 0750

chown -R root:${htuser} ${ocpath}/
chown -R ${htuser}:${htuser} ${ocpath}/apps/
chown -R ${htuser}:${htuser} ${ocpath}/config/
chown -R ${htuser}:${htuser} ${ocpath}/data/
chown -R ${htuser}:${htuser} ${ocpath}/themes/

chown root:${htuser} ${ocpath}/.htaccess
chown root:${htuser} ${ocpath}/data/.htaccess

chmod 0644 ${ocpath}/.htaccess
chmod 0644 ${ocpath}/data/.htaccess
Sluit nano: ctrl-x, y, enter.
Voer het script uit door te typen:
./owncloud-permissions
Nu zijn alleen de mappen apps, config, data en themes door de webserver schrijfbaar. Overigens, als je een andere data map hebt gekozen tijden de installatie (bijvoorbeeld een externe harde schijf) dan moet je er ook voor zorgen dat de webserver gebruiker (www-data) schrijf toegang heeft tot die map, dat kan met het commando:
chown -R www-data:www-data /pad/naar/externe-schijf

Als je deze tutorial helemaal hebt gevolgd zit er nog een kleine foutmelding in ownCloud 8.1, onder het beheerders menu (geen idee wat dat in het Engels is, mijn installatie staat op Nederlands maar het zit onder je gebruikersnaam bovenin.) Om deze "getenv[PATH]" error weg te krijgen open je de file www.conf:
sudo nano /etc/php5/fpm/pool.d/www.conf
Haal de ";" weg voor de zin: "env[PATH] = /usr/local/bin:/usr/bin:/bin" en sla de file op (ctrl-x, y, enter.) Herstart php5-fpm alsvolgt:
sudo service php5-fpm restart
Een vervelend iets is nu nog dat de maximale file grote die je via de webinterface kunt uploaden maar 513 MB is, via de clients is er geen restrictie. Ik moet zelf nog even uitzoeken hoe ik dat precies verander. Als je Googled vind je al veel hints.

Alles zou nu moeten werken, veel plezier! Ik hoor het graag als er iets niet werkt, in de comments of via het contactformulier.