Eigene Cloud Lösung mit dem Raspberry Pi und ownCloud

Neuerdings verlangt Dropbox den Einsatz von bestimmten Dateisystemen, um den Client nutzen zu können. Dies kollidiert mit meiner durch Ubuntu verschlüsselten home-Partition, warum auch immer, da diese verschlüsselte Partition in Wirklichkeit ein ext4 Dateisystem ist, auf dem der Client eigentlich laufen sollte. Dieser Umstand veranlasste mich dazu, mich nach einer neuen Lösung für meine Filestorage umzusehen. Um meine Abhängigkeit von Google + Co. etwas zu verringern und die teilweise gesalzenen Kosten einzusparen, habe ich mich nach einer einfachen Open Source Lösung für meine privaten 4 Wände umgeschaut und bin dabei über ownCloud gestolpert.
OwnCloud ist eine Platform für Cloud Speicher und bietet, neben einem Web-Interface, auch Unterstützung für native Clients in Linux und Android, was mir für meine Zwecke sehr zugute kommt. Es bietet ebenfalls eine ausgewachsene Benutzerverwaltung, was in meinem Fall zwar nicht von Bedeutung, aber ein nettes Gimmik ist.

Super Sache, nun wo ein OpenSource System für mein FileStorage gefunden ist, brauchte ich natürlich noch eine Hardwaregrundlage. Was könnte hier besser passen, als ein kleines aber feines Raspberry Pi. Dieses kann, mit dem richtigen Case, irgendwo hin gestellt werden, verbraucht wenig Energie und kann deshalb Tag und Nacht im Netzwerk laufen. Gepaart mit einer großen externen Festplatte, kann dieses Pi eine gute Lösung sein. Die Hardware habe ich hier, hier, hier und hier gekauft. Als SD Karte dient eine stinknormale 32GB SDHC Karte von Sandisk.

Nun da wir die Hardware haben, muss noch ein Betriebssystem her. Hier habe ich mich für ein Arch Linux entschieden. Es hat keinen besonderen Grund, außer dass ich selbst noch kein Arch genutzt hatte und ich es bei dieser Gelegenheit ausprobieren will. Die Installation ist ziemlich einfach und durch die Installationsanleitung schon ziemlich gut beschrieben, weswegen ich an dieser Stelle nicht darauf eingehen werde.

Nachdem der Pi im Netzwerk steckt und ein Betriebssystem darauf installiert ist, ist es an der Zeit für einen Web-Stack zu sorgen. Dies ist sehr einfach und durch den in Arch integrierten Package Manager zu bewerkstelligen. Wir brauchen zum Betrieb der ownCloud einen nginx und PHP, sowie eine MySQL Datenbank. All dies lässt sich zunächst durch die Eingabe des folgenden Befehls auf der Kommandozeile des Pi bewerkstelligen.

 

pacman -Sy nginx mariadb

 

Allerdings werden wir PHP nicht aus den Arch Linux Paketquellen installieren, da dort die aktuellste Version 7.3 gezogen wird, womit ownCloud zum jetzigen Zeitpunkt noch nicht kompatibel ist. Wir werden uns deshalb einen Docker Container mit PHP 7.2 basteln und den Webserver veranlassen die Anfragen an diesen zu leiten.

Zunächst installieren wir den Docker Dienst.

 

pacman -Sy docker docker-compose

 

Nach der Installation, starten wir den Docker Dienst

 

systemctl start docker

 

Wenn der Dienst sauber startet, können wir beginnen, eine Docker Compose Konfiguration zu schreiben, um unseren PHP Container aufzusetzen.

Ich habe diese Konfiguration unter /usr/share/docker/php abgelegt, es steht euch jedoch frei diese Konfiguration in einem Ordner eurer Wahl zu hinterlegen.

Die Konfiguration setzt sich aus zwei Dateien zusammen, einmal das Dockerfile und eine docker-compose.yaml.

Zunächst das Dockerfile

 

FROM php:fpm-7.2

RUN apt-get update && apt-get install -y \
                libfreetype6-dev \
                libjpeg62-turbo-dev \
                libpng-dev \
                mysql-client \
                zlib1g-dev \
                libicu-dev \
                g++ \
        && docker-php-ext-install -j$(nproc) iconv \
        && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
        && docker-php-ext-install -j$(nproc) gd \
        && docker-php-ext-install -j$(nproc) mysqli \
        && docker-php-ext-install -j$(nproc) pdo_mysql \
        && docker-php-ext-install -j$(nproc) zip \
        && docker-php-ext-install -j$(nproc) intl

 

Zunächst leiten wir unseren Container vom PHP 7.2 FPM Image ab, um die Grundlegende PHP Installation zu haben. Dann installieren wir diverse Pakete, welche zum Betrieb von ownCloud benötigt werden.

Dieses Dockerfile sorgt dafür, dass unser Container die richtigen Voraussetzungen mitbringt, um die ownCloud ausführen zu können. Theoretisch könnte man diesen Docker Container nun starten und ihm die entsprechenden Ports und Verzeichnisse übergeben. Um dies zu vereinfachen und in einer Datei fest zu halten, erstellen wir die docker-compose.yaml und benutzen docker-compose, um den Container zu starten.

Die docker-compose.yaml enhält folgenden Code

 

version: "3.7"
services:
    php:
        container_name: picloud-ditscheid
        build:
            context: .
            dockerfile: Dockerfile
        restart: always
        ports:
            - 9000:9000
        volumes:
            - /usr/share/nginx/html:/usr/share/nginx/html
        network_mode: "host"

 

In dieser Datei definieren wir zunächst, dass der Name unseres Containers "picloud-ditscheid" lauten soll. Damit können wir den Container später einfach wieder finden, wenn wir Informationen über ihn abfragen wollen. Danach definieren wir den Kontext und das Dockerfile für den build-Prozess. Wir geben an, dass der selbe Ordner, in dem auch die docker-compose.yaml liegt, unser Arbeitsverzeichnis ist und dass das dortige Dockerfile zum Bauen des Containers genutzt werden soll.

Mit restart: always geben wir an, dass der Container nicht nach einmaliger Ausführung beendet wird, sondern weiter existiert.

Die wichtigsten Angaben sind dann die Port-Nummer und die Volumes. PHP FPM nutzt den Port 9000 zur Kommunikation mit dem Webserver und braucht Zugriff auf die Dateien, Woche der Webserver dem PHP Dienst zur Ausführung überreicht. Im Falle von nginx ist das der Ordner /usr/share/nginx/html auf anderen Linux Distributionen kann diese Pfad natürlich anders lauten, zum Beispiel /var/www/html.

Zum Schluss konfigurieren wir den Container so, dass er im Netzwerk des Hosts existiert. Dies machen wir, damit er den MySQL Server auf dem Host erreichen und mit diesem kommunizieren kann.

Das wäre also geschafft, der PHP Container ist konfiguriert und kann mithilfe von docker-compose up gestartet werden.

 

docker-compose up

 

Als nächstes sorgen wir uns um den Webserver. Dieser muss natürlich eine Anfrage an den PHP Container weiter leiten und benötigt entsprechend eine Konfiguration.

Ich habe mir hierfür die Beispielkonfiguration aus der ownCloud Doku genommen und sie um dden fastcgi_pass Parameter erweitert.

 

location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
    ...
    fastcgi_pass 127.0.0.1:9000;
    ...
}

 

Unser PHP Docker Container lauscht nämlich auf Port 9000 auf eingehende Anfragen. Für nginx ist der PHP Container also nicht anders zu behandeln als ein lokales PHP-FPM zum Beispiel.

Fehlt nur noch der Datenbankserver. Dieser muss von innerhalb des PHP Containers erreichbar sein. Um das zu erreichen haben wir uns bereits einen kleinen Trick in die docker-compose YAML Datei gebastelt, indem wir den network_mode auf "host" gestellt haben. Damit ist der Container teil des localhost des Hosts und kann über die ganz normale localhost Adresse 127.0.0.1:3306 auf den Datenbankserver zugreifen.

Wenn wir nun die IP des PI aufrufen, sollte uns die ownCloud begrüßen und wir könnten sie fertig einrichten.

Nun stöpseln wir die externe Festplatte an. Ich persönlich bin ein Fan davon, die Daten auf dieser Festplatte zu verschlüsseln, falls sie mal abhanden kommen sollte.

Dafür habe ich cryptsetup genutzt und verschlüsselte Partitionen erstellt.

 

cryptsetup -y -v luksFormat /dev/xvdc

 

Cryptsetup erstellt uns eine verschlüsselte Partition in /dev/xvdc, wobei xvdc für die Festplatte steht und zum Beispiel auch /dev/sda1 sein könnte. Wichtig ist hier, heraus zu finden, unter welcher Bezeichnung die externe Festplatte von Betriebssystem eingeordnet wurde.

Dieser Artikel hat mir beim Einrichten der verschlüsselten Partition sehr geholfen.

Sobald die verschlüsselte Partition erstellt wurde, müssen wir sie mit

 

cryptsetup luksOpen -v /dev/sda1 usbstorage1

 

öffnen. Die Partition wird unter /dev/mapper/usbstorage1 eingebunden. Wir können dies manuel mittels

 

mount /dev/mapper/usbstorage1 /mnt/usb1

 

nach /mnt/usb1 mounten.

Ich habe dann einfach das data Verzeichnis von ownCloud in usb1 geändert.

 

mount --bind /mnt/usb1 /usr/share/nginx/html/data

 

Nun speichert die ownCloud auf der externen Festplatte anstatt auf dem Raspberry Pi. Der Raspberry ist damit austauschbar geworden. Falls die Speicherkarte abschmieren oder der PI einen Knacks bekommen sollte, kann die externe Festplatte einfach an einen beliebigen Linux Rechner angeschlossen, die Festplatte entsperrt und die Daten gelesen werden.

Das war es schon, mein PI läuft hier im internen Netzwerk und dient als Datenspeicher für alles mögliche. Von außen ist er nicht erreichbar und ich würde keine Grantie dafür übernehmen, dass diese Installation schwer zu knacken ist, aber für private Zwecke reicht es.