Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL/MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban

Nextcloud Logo

Seit dem letzten Ubuntu LTS Release sind schon wieder zwei Jahre vergangen. Im April diesen Jahres ist nun Ubuntu 22.04 LTS („Jammy Jellyfish“) erschienen. Nun ist es daher wieder an der Zeit für einen neuen Artikel zur Installation und Konfiguration von Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL/MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban.

Das ist in diesem Blog fast schon eine Tradition, denn zu diesem Thema gab es bereits mehrere Vorgänger-Artikel. Die letzte Anleitung (Nextcloud auf Ubuntu Server 20.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban) hat dabei auch schon mehr oder weniger dieses Setup beschrieben, basierte jedoch auf Ubuntu 20.04 LTS.

Dieser Artikel beschreibt nun das komplette Nextcloud-Setup unter Ubuntu 22.04 LTS. Es fließen dabei nicht nur die neu gewonnenen Erfahrungen aus den letzten zwei Jahren mit der Installation und Administrierung von Nextcloud-Instanzen ein, sondern erstmals wird der Einsatz von PostgreSQL (als Alternative zu MariaDB) mit aufgenommen.

Und nun viel Spaß mit der 2022er Ausgabe dieses Artikels!

Update-Historie (letztes Update: 24.08.2022)
  • 24.08.2022:
    • Hinweise bzgl. notwendiger individueller Anpassungen in Konfigurations-Dateien hinzugefügt.

Inhalt

Einführung

Zunächst soll eine (möglichst) kurze Einführung folgen. Hier geht es um die Ziele, die ich mit diesem Artikel verfolge, die Voraussetzungen, die für einen Cloud-Betrieb notwendig sind und das allgemeiner Konzept, welches hinter diesem Tutorial steht.

Wie schon die älteren Artikel zu diesem Thema ist auch dieser hier wieder ziemlich lang und umfangreich geworden. Das liegt daran, dass ich ein fundiertes Wissen um die Installation von Nextcloud bieten möchte, wer also ein schnelles „Copy & Paste Tutorial“ sucht, ist hier vermutlich verkehrt. Ich weiß: Diese „wall of text“ kann erst einmal demotivierend sein. Aber das Thema Nextcloud-Hosting ist nicht unbedingt trivial und daher sollte man sich einfach die Zeit nehmen, diesen Artikel hier einmal komplett durch zu arbeiten. Dies ist besonders vor dem Hintergrund wichtig, weil nachher oftmals sensible Daten in der eigenen Cloud gespeichert werden sollen. Hier lohnt es sich meines Erachtens, für den Anfang ein wenig mehr Zeit zu investieren, damit man die dahinter liegenden Konzepte und Konfigurationen versteht. Wenn die Cloud erst einmal seht, dann ist das angeeignete Wissen Gold wert: Falls es mal zu Fehlersituationen kommen sollte, können diese dann meist recht schnell behoben werden, da man ja genau weiß, nach welchen Konzepten die eigene Nextcloud-Instanz installiert und eingerichtet wurde.

Ziele

Die Zielsetzung für diesen Artikel sieht wie folgt aus:

  • Installation der eigenen Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL oder MariaDB und PHP.
  • Konfiguration aller Komponenten mit Fokus auf Sicherheit (PHP-Konfiguration, SSL und Nextcloud-Konfiguration selbst).
  • Verschlüsselte Kommunikation mit der eigenen Cloud mittels HTTPS. Hierzu kommen kostenlose Zertifikate von Let’s Encrypt zum Einsatz (RSA und ECDSA).
  • Nextcloud wird am Ende direkt im Root-Verzeichnis des Webservers laufen und ist z.B. über https://nextcloud.meinedomain.de erreichbar.
  • In der Admin-Oberfläche von Nextcloud sollen keine Fehler oder Warnungen mehr angezeigt werden.
  • Das Datenverzeichnis von Nextcloud (also die Nutzer-Daten) sollen in einem Ordner außerhalb des www-Verzeichnisses liegen.
  • Nutzung von Redis zur Verbesserung der Performance.
  • Absicherung gegen Brute-Force-Angriffe mittels Fail2ban.
  • Einrichtung der (Software-)Firewall ufw.

Abgerundet wird das ganze dann noch durch ein FAQ und einen Troubleshooting-Teil.

Zeitaufwand

Wie schon erwähnt, ist der Artikel recht umfangreich. Für den „Nextcloud-Anfänger“ würde ich empfehlen, den Artikel zumindest erst einmal komplett durchzulesen und sich ein Bild des gesamten Konstrukts und der Zusammenhänge zu machen. Linux-Grundkenntnisse sind hier auf jeden Fall von Vorteil, auch wenn nicht unbedingt erforderlich. Die alten Hasen unter den Nextcloud-Admins wissen ja schon so ziemlich, was auf sie zukommt, diese sollten also direkt loslegen können.

Für das Aufsetzen einer Nextcloud-Instanz nach diesem Artikel schätze ich mit einem Zeitaufwand von 2-3 Stunden.

Änderungen gegenüber älteren Nextcloud-Artikeln

Abgesehen davon, dass Ubuntu Server 22.04 LTS als neuer Unterbau zum Einsatz kommt, hat sich zu den Vorgänger-Artikeln prinzipiell nur wenig geändert.

Hinzugekommen ist in dieser Artikel-Version nun die freie Wahl des Datenbank-Systems: PostgreSQL oder MariaDB. Für jedes Datenbank-System wird es im Verlauf des Artikels immer getrennte Abschnitte für das jeweilige System geben. Daher sollte man sich am Anfang für ein Datenbank-System entscheiden und dann konsequent immer die Abschnitte für das passende System befolgen.
Und keine Sorge, im weiteren Verlauf des Artikels folgt noch eine Beschreibung der Unterschiede zwischen den beiden Datenbank-Systemen, sowie eine kleine Entscheidungshilfe, welches System man nun wählen sollte.

Voraussetzungen

Betriebssystem und Hardware

Die Grundlage bildet Ubuntu 22.04 LTS („Jammy Jellyfish“). Dies ist die aktuellste LTS-Version der Distribution (Long Term Support). LTS-Versionen haben einen verlängerten Support-Zeitraum von 5 Jahren (also bis April 2027). Somit kann ein solches System über einen langen Zeitraum betrieben werden, ohne dass häufige Distributions-Updates durchgeführt werden müssen.
Das Betriebssystem sollte bereits installiert worden sein. Eine genaue Beschreibung der Installation eines Ubuntu Servers wird in diesem Artikel nicht behandelt, unterscheidet sich aber auch nicht von vorherigen Versionen des Ubuntu Servers.

Ubuntu Server hat sich als stabile Plattform zum Hosten einer Nextcloud-Instanz bewährt. Trotzdem können die hier im Artikel gezeigten Schritte auch auf anderen Linux-Distributionen durchgeführt werden (z.B. Debian). Evtl. sind dann einige kleinere Anpassungen notwendig, um Großen und Ganzen verläuft die Installation aber genau so ab.

Zur Hardware: Hier gilt es erst einmal zu unterscheiden, ob man die Cloud auf einem Server in den eigenen vier Wänden hosten möchte (Home-Server – dies ist auch eindeutig der Schwerpunkt dieses Artikels). In diesem Fall benötigt man prinzipiell nur eine Maschine, auf der die neuste Version von Ubuntu läuft. Wenn die Anforderungen nicht besonders hoch sind – beispielsweise für eine kleine „Familien-Cloud“ zu Hause – reicht hier schon ein Raspberry Pi (Affiliate Link). Wer etwas mehr Rechenpower benötigt, weil die Cloud z.B. von einem Verein genutzt werden soll, kann auch zu einem Intel NUC (Affiliate Link) greifen.
Wer nicht selbst hosten möchte, kann die eigene Nextcloud auch auf einem Root– oder virtuellen Server beim Server-Anbieter seines Vertrauens installieren. Ich für meinen Teil habe hier mit Netcup (Affiliate Link) schon gute Erfahrungen sammeln können.

Generell sollte der Nextcloud-Server mindestens vier CPU-Cores und mindestens 4 GB RAM (besser 8 GB) bieten. Für größere Instanzen mit vielen Usern und bei Nutzung von diversen Nextcloud-Apps, die höhere Anforderungen an die Hardware haben (z.B. OnlyOffice, Volltextsuche mit OCR oder Nextcloud Talk), lohnt es sich meistens, eine Maschine mit mehr CPU-Cores und RAM in Betracht zu ziehen.

Entscheidend ist auch der Platzbedarf auf der Festplatte für die Dateien der Nutzer, die in die Cloud hochgeladen werden sollen. Dies hängt sehr von den individuellen Anforderungen ab. Die kleine Familien-Cloud, in der meistens nur Dokumente gespeichert werden, benötigt weniger Platz. Wer hingegen auch die eigene Foto-/Video-Sammlung in der Cloud speichern möchte, sollte den Cloud-Server gleich mit etwas größeren Festplatte(n) planen.

Nextcloud-Version

Ubuntu 22.04 LTS kommt standardmäßig mit PHP in der Version 8.1. Erst Nextcloud 24 ist kompatibel zu PHP 8.1. Daher ist es wichtig, dass die in diesem Artikel beschriebenen Schritte Nextcloud 24 voraussetzen. Eine Installation einer älteren Nextcloud-Version wird nicht ohne größere Nacharbeiten funktionieren!

Zugriff per Konsole/SSH

Ein Ubuntu Server bietet standardmäßig keine grafische Oberfläche, sondern wird rein per Kommandozeile verwaltet. Auch im Home-Server-Bereich wird ein solcher Server meist „headless“ betrieben, d.h. hier wird erst gar kein Monitor angeschlossen. Der Zugriff erfolgt dann remote via SSH. Während der Installation des Ubuntu Server sollte daher gleich der SSH-Server mit installiert werden.

Domain und DynDNS/feste IP-Adresse

Die eigene Nextcloud soll später ja auch aus dem Internet erreichbar sein, daher ist dafür eine Domain notwendig. Im Rahmen dieses Artikel nutze ich als beispielhafte Domain im weiteren Verlauf nextcloud.meinedomaind.de

Wer einen Internet-Anschluss mit einer festen IP-Adresse hat (meistens nur Business-Anschlüsse), oder einen Root-Server mit einer festen IP nutzt, der hat hier sehr wenig Aufwand: In diesem Fall muss dann einfach nur per A-Record (IPv4) bzw. AAAA-Record (IPv6) auf diese feste IP verwiesen werden. Dies erfolgt meistens komfortabel in der Verwaltung des Domain-Anbieters.

Schwieriger wird es mit (privaten) Anschlüssen, da diese meistens keine feste IP-Adresse haben und sich die IP daher jederzeit ändern kann (nach der 24-stündigen Zwangstrennung und Neueinwahl). In diesem Fall bietet DynDNS die Lösung: Ein DynDNS-Dienst sorgt dafür, dass eine Domain immer auf die aktuelle IP-Adresse des eigenen Anschlusses „zeigt“.

DynDNS-Dienste gibt es wie Sand am Meer. Ein paar empfehlenswerte kostenlose Dienste wären dabei:

Kostenlose Dienste bieten aber meistens nur bestimmte Second-Level-Domains an, zu denen man dann eine individuelle Sub-Domain für das eigene Projekt generieren kann. Das funktioniert prinzipiell, aber eine „echte eigene“ (Sub-)Domain ist in vielen Fällen schöner und macht einen professionelleren Eindruck.

Dies bieten meistens nur kostenpflichtige Dienste. Empfehlen kann ich hier z.B. All-Inkl (Affiliate-Link): Bereits im Webhosting-Paket „Privat Plus“ ist ein DynDNS-Dienst enthalten, der mit eigenen Domains genutzt werden kann.

Im Router muss dann noch die DynDNS-Konfiguration erfolgen, indem man die Daten des DynDNS-Dienstes hinterlegt. Das genaue Vorgehen hängt dabei von verwendeten Router ab, daher ist die Dokumentation des Router-Herstellers meistens die erste Anlaufstellen (z.B. AVM). Manche DynDNS-Dienste bieten auch Hilfestellung zur Konfiguration verschiedenster Router-Modelle (z.B. DynDNS Service).

Port-Forwarding

Wenn die eigene Domain auf die aktuelle externe IP des Routers verweist, hilft das erst einmal noch nicht weiter, da die integrierte Firewall im Router sämtliche (eingehenden) Anfragen blockiert. Wir benötigen für unser Vorhaben noch sog. Port-Forwarding: Die Ports 80 (HTTP) und 443 (HTTPS) müssen noch an die Maschine weitergeleitet werden, auf der die Nextcloud dann später laufen soll.
Die genaue Vorgehensweise zur Einrichtung von Port-Weiterleitungen sind leider auch je nach Router-Hersteller unterschiedlich. Daher sollten hier auch die Hilfeseiten des Router-Herstellers konsultiert werden (z.B. bei AVM).

Für Root-Server bei einem Server-Anbieter ist dieser Schritt nicht zu beachten, da hier meistens keine (Hardware-)Firewall vor dem Server steht. Hier nutzen wir später ufw als Software-Firewall, damit der Server nicht komplett „offen“ im Internet steht.

Internet-Anschluss

Im Rahmen des Internet-Anschlusses ist es wichtig, dass eine echte IPv4-Adresse vom Internet-Provider bezogen wird. Dabei darf es sich also nicht um einen Dual-Stack Lite (DSLite) Anschluss handeln, da bei DSLite sämtlicher IPv4-Verkehr über IPv6 getunnelt wird und der Kunde so keine echte/eigene IPv4-Adresse erhält.

Leider setzen viele Internet-Provider bedingt durch die IPv4-Adress-Knappheit häufig auf DSLite. Manchmal kann man eine entsprechende Option für eine echte IPv4-Adresse neben der IPv6-Adresse dazubuchen (das nennt sich dann „Dual Stack“- ohne „Lite“). Im Zweifelsfall sollte man vorher bei Internet-Provider nachfragen, um welchen Anschluss-Typ es sich handelt und ob man ggf. auf Dual Stack umgestellt werden kann.

Für Root-Server spielt dies ebenso keine Rolle. Hier ist mir noch kein Anbieter unter gekommen, der keine echte IPv4-Adresse für Kunden-Server bereit gestellt hat.

Root-Rechte

Die Installation und Konfiguration von Nextcloud und aller Abhängigkeiten werden Root-Rechte (Admin-Rechte) auf dem jeweiligen System benötigt. Unter Ubuntu kann durch das voranstellen von sudo jeder Befehl mit Root-Rechten ausgeführt werden. Damit man nicht immer ein sudo mit eintippen muss, können vor der eigentlichen Installation mit sudo -s für den Rest der Sitzung dauerhaft Root-Rechte erlangt werden.

Hier noch ein Hinweis bzgl. sog. „Webspace“-Angeboten von verschiedenen Anbietern. Diese bieten meistens keinen direkten SSH-Zugang und wenn, dann nur ohne Root-Rechte. Das ist meist vollkommen ausreichend, wenn man darauf eine kleine Website oder ein WordPress-Blog einrichten möchte. Nextcloud hat hier jedoch höhere Anforderungen, so dass ohne Root-Rechte mit erheblichen Einschränkungen zu rechnen ist. Daher eigenen sich Webspace-Angebote nur sehr bedingt für das Betreiben einer eigenen Nextcloud-Instanz.

Konzept

Nach den Voraussetzungen geht es nun ein bisschen in die Theorie. Ich möchte kurz vorstellen, welches Konzept dem hier vorliegenden Artikel zu Grunde liegt.

LEMP-Stack/LEPP-Stack

Nextcloud als PHP-Anwendung wird auf einem ganzen Software-Stack betrieben. Wer sich schon einmal mit dem Hosten von PHP-Anwendungen beschäftigt hat, hat bestimmt schon etwas von einem LAMP-Stack gehört, welcher lange die klassische Grundlage für dynamische Websites war: Linux (Betriebssystem), Apache (Webserver), MySQL (Datenbank) und PHP (Skriptsprache). Durch die Anfangsbuchstaben wird der Begriff LAMP-Stack nun denke ich klar.

In der heutigen Zeit wird aber satt MySQL eher MariaDB eingesetzt. Dieses Datenbank-System ging aus einem Fork aus MySQL hervor, als Oracle MySQL gekauft hat. Ohne nun näher auf Lizenz-Details einzugehen, ist MariaDB das offenere System (in Bezug auf Open Source) und hat daher MySQL in den letzten Jahren den Rang abgelaufen. MariaDB ist dabei binärkompatibel zu MySQL und ist daher ein sog. Drop-In-Replacement zu MySQL. Alle Programm und Tools, die für MySQL entwickelt wurden, sind daher auch mit MariaDB kompatibel. Gerade weil keine Abhängigkeit zu einem großen Software-Anbieter besteht, fällt meine Wahl zwischen diesen beiden Datenbank-Systemen auf MariaDB. Trotzdem spricht man hier noch von einem LAMP-Stack.

Aber halt, in der Überschrift wurde etwas von einem LEMP- bzw. LEPP-Stack erwähnt. Widmen wir uns zunächst dem zweiten Buchstaben. Das „E“ steht dabei für nginx (ausgesprochen „Engine-X“), einem anderen populären Webserver. Warum gebe ich hier nun nginx den Vorzug? Das hat mehrere Gründe:

  • Das erste ist wohl eher Geschmackssache: Ich finde die Konfiguration von nginx (virtuelle Hosts – vHosts) sehr viel strukturierter und leichter lesbar als die Konfigurations-Dateien von Apache. Wer lange Jahre mit Apache gearbeitet hat, wird mir hier sicher widersprechen…
  • nginx arbeitet im Allgemeinen Ressourcen-schonender als Apache: Apache erstellt pro Client-Verbindung neue Threads bzw. Prozesse, um die Requests abzuarbeiten. Deren Erzeugung ist allerdings teuer, da viel Rechenleistung benötigt wird.
    nginx arbeitet dagegen mit einem Thread-Pool: Beim Start des Webservers werden mehrere Threads bereits auf Vorrat erstellt, die dann Webrequests abarbeiten aber danach auch wiederverwendet werden können. Dies spart Ressourcen, macht sich aber in der Praxis erst bei Websites bemerkbar, die sehr viele Requests behandeln müssen. Bei einer privaten Nextcloud-Instanz wird dieser Effekt wohl nicht ins Gewicht fallen.

Um die Verwirrung nun hoffentlich nicht komplett zu machen, bringe ich nun noch PostgreSQL aus alternatives Datenbank-System ins Spiel. Damit erhalten wir dann einen LEPP-Stack (Linux, nginx, PostgreSQL, PHP).

MariaDB oder PostgreSQL?

Die Installation von Nextcloud mit PostgreSQL als Datenbanksystem ist eine Neuerung in diesem Artikel. Da stellt sich natürlich die Frage, für welches Datenbanksystem man sich entscheiden sollte. An MySQL/MariaDB ist zunächst nichts auszusetzen, aber PostgreSQL scheint mittlerweile bei vielen anderen Open Source Projekten (z.B. Matrix Synapse, Mastodon, PeerTube, etc.) die Datenbank der Wahl zu sein. Dies liegt vermutlich daran, dass PostgreSQL einfach das modernere System ist und in einigen Situationen einen Performance-Vorteil gegenüber MySQL/MariaDB hat (v.a. bei sehr vielen parallelen Datenbank-Zugriffen).
Diesen Performance-Vorteil kann PostgreSQL bei Nextcloud aber nur bei sehr großen Instanzen mit mehreren hundert Usern voll ausspielen. Trotzdem ist die „Schwuppdizität“ bei der Verwendung von PostgreSQL um einiges besser. Deshalb setzt auch die offizielle Nextcloud VM bereits auf PostgreSQL (siehe Blog-Beitrag).

Wer daher das modernere Datenbank-System nutzen möchte, oder aber andere Programme auf dem gleichen Server betreiben will, welche PostgreSQL voraussetzen, der sollte eher auf PostgreSQL setzen.

Wer es eher traditionell mag oder Software einsetzen möchte, die nur mit MySQL/MariaDB funktionieren (z.B. WordPress), der sollte auf MariaDB setzen.

Diese Entscheidung ist dann allerdings auch nicht in Stein gemeißelt: Nextcloud unterstützt die Migration von einem Datenbanksystem zum anderen. Hier im Blog wurde dies bereits mit der Migration von MariaDB auf PostgreSQL thematisiert.

Im weiteren Verlauf des Artikels wird es nun immer, wenn es um die Datenbank geht, zwei getrennte Abschnitte – einmal für PostgreSQL und einmal für MariaDB – geben. Dabei sind nur die Schnitte durchzuführen, die zum gewählten Datenbanksystem passen.

Installation des Grundsystems

Nach diesem eher theoretischen Teil geht es nun an die Praxis: Für den Betrieb von Nextcloud ist zunächst einmal der oben erwähnte LEMP/LEPP-Stack zu installieren.

Für einige Schritte muss die (lokale) IP des Servers angegeben werden. Nachfolgend verwende ich dafür die beispielhafte IP 192.168.178.60.

Update Betriebssystem

Als erstes starten wir mit dem Update des Betriebssystems und einem anschließenden Reboot:

apt update && apt upgrade -V && apt autoremove
reboot now

Danach wird die Zeiteinstellung des Systems kontrolliert:

date

Da die Zeit nach einer neuen Installation von Ubuntu meist auf UTC steht, muss man hier manuell die korrekte Zeitzone setzen:

timedatectl set-timezone Europe/Berlin

Programm-Installation

Als nächstes werden alle Programme installiert, die für den Betrieb von Nextcloud notwendig sind.

Ubuntu-Paketquellen, Hersteller-Paketquellen und PPAs

Prinzipiell sind alle benötigten Programme in den Ubuntu-Paketquellen enthalten, so dass diese direkt über apt install … installiert werden könnten. Dabei sind die Maintainer einer Distribution meist bestrebt, möglichst stabile Versionen der Programme in den Paketquellen anzubieten. Die „Nebenwirkung“ dabei ist jedoch, dass die verwendeten Programm-Versionen z.T. schon recht alt sind – je länger ein Distributions-Release „reift“, desto ausgeprägter zeigt sich dieses Problem.

Um nun nicht von Anfang an auf veraltete Software-Versionen zu setzen, kann man neben den Ubuntu-Paketquellen meist auch die Paketquellen der Hersteller der Software im System einbinden, um jeweils die aktuellsten Versionen zu erhalten. Für Software, die häufiger Updates und v.a. Feature-Erweiterungen seitens des Herstellers bekommt, macht es hier durchaus Sinn, nicht die Versionen aus den Ubuntu- sondern aus den Hersteller-Paketquellen zu installieren.
Webserver und Datenbank sind hier die klassischen Kandidaten, weshalb ich im Rahmen des Artikels hier auf die Hersteller-Paketquellen setze.

Daneben gibt es noch sog. PPAs (Personal Package Archive): Dabei handelt es sich um inoffizielle Paketquellen, die oftmals von Privat-Personen (aber auch Unternehmen) betrieben werden. Wenn man immer die brandaktuellsten Versionen bestimmter Software-Pakete nutzen möchte, kommt man fast nicht um PPAs herum. Trotzdem sind diese Quellen inoffiziell, d.h. werden weder von Ubuntu, noch den den Software-Herstellern unterstützt, daher sollte man – wenn man Wert auf Stabilität des Systems Wert legt – nach Möglichkeit auf PPAs verzichten. Im Rahmen des Artikels nutze ich daher keine PPAs.

nginx

Als erstes installieren wir nun den Webserver nginx. Hier verwende ich das Mainline-Repository des Herstellers.

Dazu muss zunächst einmal der Key dieses Repositories auf dem System bekannt gemacht werden, dies ist sozusagen der Fingerabdruck des Repositories. Ohne diesen Schritt würde beim Updaten des Systems eine Warnung kommen und der Update-Prozess gestoppt werden.

Hinweis: Das Vorgehen zum Hinzufügen solcher Repository-Keys hat sich mit Ubuntu 22.04 geändert. Werden Keys nun mit apt-key add hinzugefügt, erhält man nun eine Warnung, dass dieses Vorgehen veraltet ist, um man nach Möglichkeit auf die neue Variante umsteigen sollte. Daher nutze ich im Rahmen des Artikel immer diese neue Variante.

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

Nun können die Paket-Quellen selbst unter Bezug auf den zuvor hinzugefügten Key dem System bekannt gemacht werden:

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | tee /etc/apt/sources.list.d/nginx.list

nginx (aus den Mainline-Paketquellen des Herstellers) kann danach ganz einfach installiert werden.

apt update && apt install nginx

PHP

Weiter geht es mit der Installation von PHP. Diese Pakete installieren wir aus den offiziellen Ubuntu Paketquellen:

apt install php-fpm php-gd php-curl php-xml php-zip php-intl php-mbstring php-bz2 php-json php-apcu php-imagick php-gmp php-bcmath

Es kann sein, dass bestimmte Nextcloud-Apps später noch weitere PHP-Pakete benötigen. Diese können dann bei Bedarf einfach nachinstalliert werden.

Datenbank (PostgreSQL)

Die folgenden Schritte gelten nur für PostgreSQL. Die Anweisungen für MariaDB folgen im nächsten Abschnitt.

Hier verwenden wir wiederum das Hersteller-Repository von PostgreSQL. Dazu muss zunächst wieder der Key des Repositories auf dem System eingerichtet werden:

wget -O- https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-archive-keyring.gpg >/dev/null

Im zweiten Schritt werden die Sourcen dann hinzugefügt:

echo "deb [signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list

Nun kann PostgreSQL zusammen mit dem benötigten PHP-Paket installiert werden:

apt update && apt install postgresql-13 php-pgsql

Datenbank (MariaDB)

Die folgenden Schritte gelten nur, wenn MariaDB als Datenbanksystem zum Einsatz kommen soll.

Auch hier wird das Hersteller-Repository verwendet. Dazu wird im ersten Schritt wieder der Key des Respositories auf dem System bekannt gemacht:

wget -O- https://mariadb.org/mariadb_release_signing_key.asc | gpg --dearmor | sudo tee /usr/share/keyrings/mariadb-keyring.gpg >/dev/null

Und im Anschluss das Repository selbst eingerichtet:

echo "deb [signed-by=/usr/share/keyrings/mariadb-keyring.gpg] https://mirror.kumi.systems/mariadb/repo/10.8/ubuntu $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/mariadb.list

Am Ende kann dann MariaDB mitsamt des benötigten PHP-Moduls installiert werden:

apt install mariadb-server php-mysql

Installation ImageMagick

Nextcloud benötigt zusätzlich noch ImageMagick zur Darstellung von Bildern und Berechnen von Thumbnails:

apt install imagemagick libmagickcore-6.q16-6-extra

Let’s Encrypt/acme.sh

Der Zugriff auf die Nextcloud soll später durch den Einsatz von HTTPS mit TLS-Zertifikaten jederzeit verschlüsselt erfolgen. Hier setzen wir auf den Dienst Let’s Encrypt, der kostenlose TLS-Zertifikate anbietet. Für die Nutzung von Let’s Encrypt wird noch ein entsprechender Client benötigt. Hier setze ich seit einiger Zeit schon auf acme.sh. Dieser Client wurde als reines Bash-Skript implementiert und hat keine weiteren Abhängigkeiten.

acme.sh sollte dabei nicht mit Root-Rechten ausgeführt werden, daher legen wir uns einen speziellen User nur für diesen Zweck an:

adduser letsencrypt

Für diesen User sollte kein Passwort vergeben werden (bei der entsprechenden Frage einfach mehrfach Enter drücken). Ebenso können weitere Angaben (Name, E-Mail-Adresse, etc.) einfach weggelassen werden.

Dieser Nutzer muss noch der Gruppe www-data hinzugefügt werden:

usermod -a -G www-data letsencrypt

Nun braucht dieser User noch die Berechtigungen, den Webserver nginx ohne Root-Rechte neu zu laden:

visudo

Ganz am Ende wird dann einfach folgende Zeile hinzugefügt:

letsencrypt ALL=NOPASSWD: /bin/systemctl reload nginx.service

Nun kann acme.sh installiert werden. Dazu wechseln wir auf den soeben erzeugten User:

su - letsencrypt

Die Installation wir dann einfach mit folgendem Befehl erledigt:

curl https://get.acme.sh | sh

Danach können wir wieder zu unserem normalen User zurück wechseln:

exit

Konfiguration der Programme

Nach der Installation müssen die Programme noch konfiguriert werden, damit Nextcloud nachher optimal läuft.

Konfiguration nginx

Bei der allgemeinen nginx-Konfiguration bedarf es ein paar Anpassungen:

nano /etc/nginx/nginx.conf

Folgende Punkte sind hier wichtig:

  • user: Gibt den Benutzer an, unter dem nginx läuft. Dies muss www-data sein.
    user www-data;
  • worker_processes: Die Anzahl der Threads, die zum Abarbeiten von Requests genutzt werden. auto ist hier meistens die richtige Einstellung, nginx nutzt dann so viele Threads wie CPU-Kerne zur Verfügung stehen.
    worker_processes  auto;
  • server_tokens: Wenn nginx Fehlerseiten anzeigt (z.B. weil eine Website nicht gefunden wurde), wird die nginx-Version auf diesen Seiten mit ausgegeben. Da nicht jeder wissen muss, welchen Webserver in welcher Version wir einsetzen, fügt man einfach folgende Zeile innerhalb des http-Blocks hinzu:
    server_tokens off;

Nun wird noch der virtuelle Host (vHost) deaktiviert, der mit der Installation von nginx mit kam. Dieser ist eh nur eine Art Demo-Seite. Damit die Änderungen greifen, wird der Webserver am Schluss noch neu gestartet:

mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf_disabled 
service nginx restart

Konfiguration PHP

Bei PHP sind die zu setzenden Einstellungen über mehrere Konfigurations-Dateien verstreut.

Wir starten bei der sog. Pool-Konfiguration, mit der der Thread-Pool von PHP konfiguriert wird (PHP verwendet wie schon nginx ebenfalls einen Thread-Pool zum Abarbeiten der Anfragen):

nano /etc/php/8.1/fpm/pool.d/www.conf

Folgende Anpassungen sind die durchzuführen:

  • user/group: Gibt den Benutzer an, unter dem PHP läuft. Dies muss der gleiche User sein, unter dem auch der Webserver läuft, in unserem Fall also www-data.
    user = www-data
    group = www-data
  • listen: Die Kommunikation zwischen Webserver und PHP wird über einen sog. Socket realisiert. Der Pfad, unter dem dieser Socket zur Verfügung steht, wird an dieser Stelle angegeben:
    listen = /run/php/php8.1-fpm.sock
  • Umgebungs-Variablen: Diese Variablen werden bei PHP standardmäßig nicht veräußert, sind aber für den Betrieb von Nextcloud notwendig. In der Datei suchen wir einfach nach dem Ausdruck „Pass environment variables like“ (Hinweis: Suche in nano: STRG + W). Alle Einträge, die nun darunter mit env beginnen, sind auskommentiert. Durch das Entfernen des Semikolons am Anfang jeder dieser Zeilen werden die Umgebungsvariablen über PHP veräußert:
    env[HOSTNAME] = $HOSTNAME
    env[PATH] = /usr/local/bin:/usr/bin:/bin
    env[TMP] = /tmp
    env[TMPDIR] = /tmp
    env[TEMP] = /tmp

Neben der Pool-Konfiguration gibt es noch weitere Einstellungen in der php.ini. Von dieser Datei gibt es zwei Varianten: Einmal die Einstellungen für FPM (FastCGI Process Manager). FPM ist die Technologie, mit der der Webserver nginx mit PHP kommuniziert:

nano /etc/php/8.1/fpm/php.ini
  • cgi.fix_pathinfo: Diese Einstellung sorgt für eine sichere Interpretation von Pfadangaben.
    cgi.fix_pathinfo = 0
  • memory_limit: Gibt den maximalen Speicher an, den ein PHP-Skript während der Abarbeitung belegen darf. Nextcloud benötigt hier mindestens 512 MB. Wenn sehr viel Speicher am Server verfügbar ist, kann dieser Wert auch entsprechend weiter angehoben werden (z.B. auf 1 GB).
    memory_limit = 512M
  • OPcache: PHP OPcache ist ein Caching-Mechanismus, der vorkompilierten Bytecode direkt im Speicher ablegen kann, um damit eine höhere Performance zu erzielen. Zur Optimierung müssen hier folgende Werte gesetzt werden. Die Zeilen dürfen dabei aber nicht auskommentiert sein.
    opcache.enable = 1
    opcache.enable_cli = 1
    opcache.memory_consumption = 128
    opcache.interned_strings_buffer = 8
    opcache.max_accelerated_files = 10000
    opcache.revalidate_freq = 1
    opcache.save_comments = 1

Die zweite php.ini definiert die Einstellungen für den CLI-Zugriff auf PHP (immer, wenn PHP direkt über die Kommandozeile aufgerufen wird, was z.B. von Nextcloud-Cronjob genutzt wird):

nano /etc/php/8.1/cli/php.ini
  • cgi.fix_pathinfo: Wie bereits oben beschrieben:
    cgi.fix_pathinfo = 0
  • apc.enable_cli: Hier muss noch das Caching über APCu explizit aktiviert werden. Diese Variable ist in der php.ini noch nicht vorhanden und muss so ganz am Ende der Datei hinzugefügt werden:
    apc.enable_cli = 1

Zum Abschluss der Konfiguration muss PHP-FPM einmal neu gestartet werden:

service php8.1-fpm restart

Konfiguration PostgreSQL

Dieser Abschnitt ist wieder nur für PostgreSQL relevant, die Konfiguration von MariaDB erfolgt weiter unten.

Eigentlich braucht bei PostgreSQL nicht viel konfiguriert werden. Nach der Installation können aber noch etliche Werte optimiert werden. Dazu empfehle ich die Seite PGTune: Hier gibt man einfach die verwendete Version und einige Kennzahlen des Systems an (RAM, Anzahl der CPU-Kerne, etc.) und die Seite zeigt dann die entsprechenden Werte an, damit PostgreSQL an das System optimal angepasst werden kann.
Diese Werte kann man dann in der Konfiguration von PostgreSQL setzen:

 nano /etc/postgresql/13/main/postgresql.conf

Damit die Optimierungen greifen, wird die Datenbank einmal neu gestartet:

service postgresql restart

Konfiguration MariaDB

Hier folgt nun der Abschnitt für alle, die MariaDB als Datenbank nutzen.

Generell sollte man nach der Installation das System direkt einmal absichern:

mysql_secure_installation

Hier kann man zunächst einmal ein Root-Passwort für MariaDB vergeben. Alle anderen Fragen sind hier mit Ja (y) zu beantworten.

Ab MariaDB 10.6 bedarf es aber noch einer wichtigen Änderung, damit der Schreibzugriff auf Tabellen im Compressed-Format möglich ist – dies wird von Nextcloud benötigt:

nano /etc/mysql/mariadb.conf.d/50-server.cnf

Im Block [mysqld] muss hier noch eine zusätzliche Option mit aufgenommen werden:

innodb_read_only_compressed=OFF

Auch hier muss man die Datenbank neu starten, damit die Änderungen angewendet werden:

service mariadb restart

Konfiguration acme.sh

Das letzte zu konfigurierende Programm ist der Let’s Encrypt Client acme.sh. Dazu wechseln wir zunächst wieder auf den entsprechenden User:

su - letsencrypt

acme.sh nutzt standardmäßig nicht Let’s Encrypt zur Generierung der Zertifikate, sondern den alternativen Anbieter ZeroSSL. Auch wenn prinzipiell nichts gegen diesen Dienst spricht, setze ich der Erfahrung nach lieber auf Let’s Encrypt. Dies kann mittels folgendem Befehl global konfiguriert werden:

acme.sh --set-default-ca --server letsencrypt

Das war es auch schon an dieser Stelle, so dass wir wieder auf den normalen User zurück wechseln können:

exit

Generierung der TLS-Zertifikate für HTTPS

Und schon können die Zertifikate generiert werden.

Vorbereiten der Verzeichnisstruktur

acme.sh platziert die erzeugten Zertifikate standardmäßig im Home-Verzeichnis des entsprechenden Users. Da dies für die Verwaltung etwas umständlich ist, soll acme.sh die Zertifikate in vorher angelegten Verzeichnissen ablegen. Diese legen wir in einem ersten Schritt nun an. Hier sollte das Verzeichnis mit dem Domain-Namen natürlich an die konkret verwendete Domain angepasst werden:

mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
chown -R www-data:www-data /var/www/letsencrypt
chmod -R 775 /var/www/letsencrypt
mkdir -p /etc/letsencrypt/nextcloud.meinedomain.de/rsa
mkdir -p /etc/letsencrypt/nextcloud.meinedomain.de/ecc
chown -R www-data:www-data /etc/letsencrypt
chmod -R 775 /etc/letsencrypt

Der Ordner /var/www/letsencrypt/.well-known/acme-challenge wird später über den Webserver veräußert, so dass Let’s Encrypt hierüber die Domain validieren kann. Über die Let’s Encrypt API wird eine sog. Challenge ausgehandelt (mehr oder weniger eine zufällige Zeichenfolge). Diese wird dem Let’s Encrypt Client mitgeteilt, der diese Zeichenfolge dann in einer Datei in diesem Verzeichnis ablegt. Let’s Encrypt fragt dann diese Challenge ab (über den Webserver) und vergleicht diese Zeichenfolge mit der über die API vorgegebene. Wenn diese beiden Zeichenfolgen zusammen passen, wurde die Domain validiert. Das verhindert, dass man für einen Server Zertifikate generieren kann, auf den man gar keinen Zugriff hat.
Unter /etc/letsencrypt sollen dann die Zertifikate selbst platziert werden. Ich lege hier immer ein Unterverzeichnis pro (Sub-)Domain an und dann getrennte Verzeichnisse für RSA und ECDSA.
Wichtig ist hier noch das Setzen der entsprechenden Rechte, so dass der Webserver-User (oder die entsprechende Gruppe) schreibenden Zugriff auf diese Verzeichnisse hat.

Anlegen des allgemeinen virtuellen Hosts (HTTP-Gateway)

Dies ist der erste virtuelle Host (vHost), den wir für nginx anlegen. Ein vHost definiert einfach nur, welche Verzeichnisse über welche Domain(s)/IP(s) und Ports über einen Webserver bereit gestellt werden.
Sinn und Zweck dieses vHosts ist es nun erst einmal, sämtliche Anfragen über HTTP (Port 80) entgegen zu nehmen. Wenn es sich dabei um eine Let’s Encrypt Challenge handelt, soll dieser vHost diesen Request direkt über HTTP behandeln – und zwar über das zuvor definierte Verzeichnis. Alle anderen Anfragen (z.B. später an die Cloud) sollen automatisch auf HTTPS „umgebogen“ werden. Auf diese Weise erzwingt man, dass alle Anfragen (außer über Let’s Encrypt) ausschließlich über HTTPS ablaufen, also jederzeit verschlüsselt.

Den vHost definieren wir so:

nano /etc/nginx/conf.d/HttpGateway.conf

Der Inhalt der Datei sieht wie folgt aus:

upstream php-handler {
    server unix:/run/php/php8.1-fpm.sock;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name nextcloud.meinedomain.de 192.168.178.60;
 
    root /var/www;

    location ^~ /.well-known/acme-challenge {
        default_type text/plain;
        root /var/www/letsencrypt;
    }

	location / {
		return 301 https://$host$request_uri;
	}
}
  • Ganz oben definieren wir auch gleich die Verbindung zu PHP mittels des oben schon erwähnten Sockets.
  • Der vHost soll auf unsere Domain „hören“ (und zusätzlich noch auf die lokale IP-Adresse). Dies muss natürlich individuell angepasst werden.
  • Die Angabe default_server sorgt dafür, dass nginx alle Requests, die keiner eindeutigen Domain zugeordnet werden können, von diesem vHost abgearbeitet werden.
  • Zugriffe auf .well-known/acme-challenge werden kann direkt von diesem vHost über das oben erzeugte Verzeichnis abgehandelt.
  • Alle anderen Requests werden konsequent auf HTTPS redirected.

Damit der vHost aktiviert wird, muss nginx einmal neu geladen werden:

service nginx reload

Überprüfung der Konfiguration zur Zertifikats-Generierung

Bevor wir nun acme.sh zur Generierung der Zertifikate nutzen, sollte die Konfiguration noch getestet werden. Dieser Schritt ist ziemlich wichtig: Kommt es bei der Generierung der Zertifikate zu Fehlern (Server nicht erreichbar, falsches Port-Forwarding, nicht richtig konfigurierter vHost, etc.) und man versucht es dann ein paar mal hintereinander, dann schlägt bei Let’s Encrypt ein Rate Limiting zu, so dass die angefragte Domain dann für 7 Tage gesperrt ist. Das ist insofern ungünstig, da man dann mit der Installation der Nextcloud 7 Tage warten muss, obwohl man die Cloud am liebsten sofort nutzen möchte.

Für diesen (manuellen) Test legen wir einfach eine Text-Datei an der Stelle ab, an der auch Let’s Encrypt die Challenge-Dateien suchen würde:

echo "Test" >> /var/www/letsencrypt/.well-known/acme-challenge/test.txt

Nun rufen wir diese Datei direkt über den Browser (mittels HTTP) ab. Die genaue URL lautet dabei (hier bitte die echte Domain verwenden): http://nextcloud.meinedomain.de/.well-known/acme-challenge/test.txt
Nun sollte der oben eingetragene Text einfach im Browser erscheinen:

Test des Webservers vor der Generierung der Zertifikate
Test des Webservers vor der Generierung der Zertifikate

Bei Erfolg kann die Text-Datei wieder gelöscht werden:

rm /var/www/letsencrypt/.well-known/acme-challenge/test.txt

Wichtig: Falls dieser Test nicht erfolgreich verlaufen ist und z.B. eine Fehlerseite angezeigt wird, ist die Konfiguration bis hierhin nicht korrekt. In diesem Fall wird die Generierung der Zertifikate über acme.sh ebenfalls fehlschlagen, so dass man dies gar nicht erst probieren sollte. Für die Fehlersuche empfiehlt es sich, zunächst einen Blick in das nginx Fehler-Log zu werfen (/var/log/nginx/error.log). Hier sollte der Request auf jeden Fall zu sehen sein und eine Fehlermeldung, z.B. dass er die angeforderte Datei nicht finden konnte. Wenn hier kein passender Inhalt zu finden ist, ist bereits „weiter vorne“ etwas schief gelaufen. Hier sollte dann nochmal die Einrichtung der DynDNS-Domain und das Port-Forwarding an die entsprechende Maschine geprüft werden.

Generierung der Zertifikate

Der Test war bei euch erfolgreich? Dann kann es ja nun endlich an die Generierung der Zertifikate gehen. Dazu wechseln wir wieder auf den Let’s Encrypt Benutzer:

su - letsencrypt

Für die nächsten Schritte muss die konkret genutzte Domain genutzt werden.

Als erstes Erzeugen wir nun die RSA-Zertifikate:

acme.sh --issue -d nextcloud.meinedomain.de --server letsencrypt --keylength 4096 -w /var/www/letsencrypt --key-file /etc/letsencrypt/nextcloud.meinedomain.de/rsa/key.pem --ca-file /etc/letsencrypt/nextcloud.meinedomain.de/rsa/ca.pem --cert-file /etc/letsencrypt/nextcloud.meinedomain.de/rsa/cert.pem --fullchain-file /etc/letsencrypt/nextcloud.meinedomain.de/rsa/fullchain.pem --reloadcmd "sudo /bin/systemctl reload nginx.service"

Es folgen die ECDSA-Zertifikate:

acme.sh --issue -d nextcloud.meinedomain.de --server letsencrypt --keylength ec-384 -w /var/www/letsencrypt --key-file /etc/letsencrypt/nextcloud.meinedomain.de/ecc/key.pem --ca-file /etc/letsencrypt/nextcloud.meinedomain.de/ecc/ca.pem --cert-file /etc/letsencrypt/nextcloud.meinedomain.de/ecc/cert.pem --fullchain-file /etc/letsencrypt/nextcloud.meinedomain.de/ecc/fullchain.pem --reloadcmd "sudo /bin/systemctl reload nginx.service"

Ich habe hier noch einmal explizit die Nutzung von Let’s Encrypt mit angegeben. Dies ist durch die allgemeine Konfiguration von acme.sh eigentlich nicht mehr notwendig, aber schaden tut es an dieser Stelle auch nicht.

Nach der Validierung der Domain durch Let’s Encrypt und der Ausstellung der Zertifikate sind diese nun unter /etc/letsencrypt/nextcloud.meinedoamin.de/rsa bzw. /etc/letsencrypt/nextcloud.meinedoamin.de/ecc zu finden (einmal RSA und einmal ECDSA):

  • cert.pem: Das öffentliche Zertifikat in Reinform
  • ca.pem: Öffentliches Zertifikat aus der sog. Keychain
  • fullchain.pem: Entspricht cert.pem + chain.pem
  • key.pem: Privates Zertifikat (diese Datei sollte daher niemals weitergegeben werden)

Wir wechseln nun wieder auf den normalen User:

exit

Automatische Erneuerung der Zertifikate

Zertifikate von Let’s Encrypt haben eine Gültigkeit von 90 Tagen und müssen daher vor Ablauf erneuert werden. Dies müsst ihr nun nicht alle 90 Tage manuell erledigen: acme.sh hat dafür einen Cronjob angelegt, der dies vollkommen automatisiert erledigt.

Wichtig ist nur, dass der Server Weiterhin über Port 80/HTTP erreichbar ist. Das entsprechende Port-Forwarding muss dafür dauerhaft bestehen bleiben.

Diffie-Hellman-Parameter

Die Sicherheit der verschlüsselten Kommunikation dann nun noch über den sog. Diffie-Hellman-Schlüsselaustausch erhöht werden. Ohne hier nun zu weit auf die kryptografischen Details einzugehen, ist dies ein Protokoll zur Schlüssel-Vereinbarung zwischen Server und Client.

Dazu benötigen wir noch einen sog. Diffie-Hellman-Parameter, der auf einfache Art und Weise generiert werden kann:

mkdir -p /etc/nginx/dhparams 
openssl dhparam -out /etc/nginx/dhparams/dhparams.pem 4096

Hinweis: Auf schwächerer Hardware (z.B. auf einem Raspberry Pi) kann die Generierung hier sehr lange dauern. Wer hier nicht mehrere Stunden warten möchte, kann auch einen Schlüssel mit 2048 Bit errechnen lassen. Einfach im o.g. Befehl die letzte Zahl durch 2048 ersetzen. Trotzdem wird die Verwendung eines 4096 Bit Schlüssels empfohlen, aber dessen Generierung kann man u.U. auf einen späteren Zeitpunkt verschieben (z.B. über Nacht).

Webserver für Nextcloud vorbereiten

Die Zertifikate wurden nun erzeugt, kann der Webserver nun für die Installation von Nextcloud vorbereitet werden.

SSL-Konfiguration

Mehr oder weniger allgemeingültige Konfigurationen lagere ich bei nginx immer in einzelne Dateien aus, so dass diese Konfigurationen wiederverwendet werden können (z.B. wenn man mehrere Webseiten auf dem gleichen Server betreiben möchte).

Die erste Konfiguration dieser Art sind die Optionen für SSL. Dazu legen wir erst einmal einen Ordner an, in dem solche allgemeinen Konfigurationen gespeichert werden:

mkdir -p /etc/nginx/snippets

Nun legen wir eine Datei für die SSL-Konfiguration an:

nano /etc/nginx/snippets/ssl.conf

Der Inhalt sieht hier folgendermaßen aus:

#
# SSL Configuration
#

# Not using TLSv1 will break:
# Android <= 4.4.40 IE <= 10 IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
ssl_protocols TLSv1.2 TLSv1.3;

# SSL ciphers: RSA + ECDSA
# Two certificate types (ECDSA, RSA) are needed.
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384';

# Diffie-Hellman parameter for DHE ciphersuites, recommended 4096 bits
ssl_dhparam /etc/nginx/dhparams/dhparams.pem;

# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;

# Server should determine the ciphers, not the client
ssl_prefer_server_ciphers on;

# SSL session handling
ssl_session_timeout 1d; 
ssl_session_cache shared:SSL:50m; 
ssl_session_tickets off;

# DNS resolver
resolver 192.168.178.1;

Hier werden zunächst die zu verwendenden TLS-Versionen definiert (TLSv1.0 und 1.1 sollte aus Sicherheitsgründen nicht mehr verwendet werden). Anschließend werden die sog. Cipher Suites festgelegt, dies sind standardisierte kryptografische Verfahren, die beim Schlüsselaustausch zur Anwendung kommen. Daneben wird die Datei mit dem Diffie-Hellman-Parameter eingebunden und noch ein paar weitere Parameter für die SSL-Konfiguration hinterlegt.
Ganz unten wird noch ein Resolver definiert. Dies ist einfach ein DNS-Server und sollte in den meisten Fällen auf euren Router verweisen, der ja auch als DNS-Server fungiert.

Header-Konfiguration

Ganz ähnlich legen wir nun noch eine Datei mit einer allgemeinen Header-Konfiguration an. Diese Header werden später dann mit jedem Web-Request vom Server mit versendet und sorgen u.a. für eine erweiterte Sicherheit (z.B. Verhinderung von Cross-Site-Scripting):

nano /etc/nginx/snippets/headers.conf

Die Datei sollte dabei folgenden Inhalt haben:

#
# Header configuration
#  

# HSTS (ngx_http_headers_module is required) In order to be recoginzed by SSL test, there must be an index.hmtl in the server's root
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload;" always; 
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Robots-Tag none always;
add_header X-Download-Options noopen always;
add_header X-Permitted-Cross-Domain-Policies none always;
add_header Referrer-Policy no-referrer always;
add_header X-Frame-Options "SAMEORIGIN" always;

# Disable FLoC
add_header Permissions-Policy "interest-cohort=()";

# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;

Virtueller Host für Nextcloud

Nun kann auch schon der virtuelle Host für Nextcloud erstellt werden:

nano /etc/nginx/conf.d/nextcloud.meinedomain.de.conf

Der Inhalt dieser Datei ist dabei etwas umfangreicher:

# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name nextcloud.meinedomain.de 192.168.178.60;

    # Path to the root of your installation
    root /var/www/nextcloud;

    # SSL configuration
	# RSA certificates
	ssl_certificate /etc/letsencrypt/nextcloud.meinedomain.de/rsa/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/nextcloud.meinedomain.de/rsa/key.pem;
	# ECC certificates
	ssl_certificate /etc/letsencrypt/nextcloud.meinedomain.de/ecc/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/nextcloud.meinedomain.de/ecc/key.pem;

	# This should be ca.pem (certificate with the additional intermediate certificate)
	# See here: https://certbot.eff.org/docs/using.html
	# ECC
	ssl_trusted_certificate /etc/letsencrypt/nextcloud.meinedomain.de/ecc/ca.pem;
  
  	# Include SSL configuration
	include /etc/nginx/snippets/ssl.conf;

	# Include headers
	include /etc/nginx/snippets/headers.conf;

    # set max upload size and increase upload timeout:
    client_max_body_size 10G;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    # Pagespeed is not supported by Nextcloud, so if your server is built
    # with the `ngx_pagespeed` module, uncomment this line to disable it.
    #pagespeed off;

    # Specify how to handle directories -- specifying `/index.php$request_uri`
    # here as the fallback means that Nginx always exhibits the desired behaviour
    # when a client requests a path that corresponds to a directory that exists
    # on the server. In particular, if that directory contains an index.php file,
    # that file is correctly served; if it doesn't, then the request is passed to
    # the front-end controller. This consistent behaviour means that we don't need
    # to specify custom rules for certain paths (e.g. images and other assets,
    # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
    # `try_files $uri $uri/ /index.php$request_uri`
    # always provides the desired behaviour.
    index index.php index.html /index.php$request_uri;

    # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
    location = / {
        if ( $http_user_agent ~ ^DavClnt ) {
            return 302 /remote.php/webdav/$is_args$args;
        }
    }

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

    # Make a regex exception for `/.well-known` so that clients can still
    # access it despite the existence of the regex rule
    # `location ~ /(\.|autotest|...)` which would otherwise handle requests
    # for `/.well-known`.
    location ^~ /.well-known {
        # The rules in this block are an adaptation of the rules
        # in `.htaccess` that concern `/.well-known`.

        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Rules borrowed from `.htaccess` to hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    # Ensure this block, which passes PHP files to the PHP process, is above the blocks
    # which handle static assets (as seen below). If this block is not declared first,
    # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
    # to the URI, resulting in a HTTP 500 error response.
    location ~ \.php(?:$|/) {
        # Required for legacy support
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;

        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;

        try_files $fastcgi_script_name =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;

        fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
        fastcgi_param front_controller_active true;     # Enable pretty urls
        fastcgi_pass php-handler;

        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

        fastcgi_max_temp_file_size 0;
    
    	fastcgi_read_timeout 600;
		fastcgi_send_timeout 600;
		fastcgi_connect_timeout 600;

		fastcgi_param PHP_VALUE "upload_max_filesize = 10G
			post_max_size = 10G
			max_execution_time = 3600
			output_buffering = off";
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463, $asset_immutable";
        access_log off;     # Optional: Don't log access to assets

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;         # Cache-Control policy borrowed from `.htaccess`
        access_log off;     # Optional: Don't log access to assets
    }

    # Rule borrowed from `.htaccess`
    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }
}

Wie schon beim virtuellen Host für HTTP-Anfragen müssen hier wieder Domain und IP-Adresse an die individuellen Bedürfnisse angepasst werden.

Dieser vHost ist an die vorgeschlagene nginx-Konfiguration im Nextcloud Administration Manual angelehnt, beinhaltet aber ein paar kleine Änderungen:

  • Ein Server für HTTP (Port 80) wird hier nicht definiert, da dieser ja bereits im HTTP-Gateway angelegt wurde.
  • Die Einbindung der Zertifikate erfolgt hier doppelt: Einmal für die RSA- und einmal für die ECDSA-Zertifikate.
  • Die allgemeinen Konfiguration bzgl. SSL und Headern werden hier einfach per include eingebunden.

Wir laden den Webserver neu, damit die geänderte Konfiguration greift:

service nginx reload

Installation Nextcloud

Nachdem die Vorbereitungen nun abgeschlossen wurden, kann die Nextcloud installiert werden.

Download Nextcloud

Als erstes laden wir die aktuellste Version von Nextcloud herunter und entpacken das Archiv in das in das www-Verzeichnis des Webservers:

wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www
rm latest.tar.bz2

Nun werden noch die entsprechenden Rechte gesetzt:

chown -R www-data:www-data /var/www/nextcloud

Anlegen des Datenverzeichnisses

Das Datenverzeichnis (also das Verzeichnis, in dem die Benutzer-Dateien gespeichert werden), sollte außerhalb des Web-Verzeichnisses liegen. Daher legen wir hier ein extra Verzeichnis an und setzen wieder die entsprechenden Rechte:

mkdir -p /var/nextcloud_data 
chown -R www-data:www-data /var/nextcloud_data

Datenbank für Nextcloud anlegen (PostgreSQL)

Nun wird die Datenbank für Nextcloud angelegt. Die folgenden Schritte beziehen sich wieder auf PostgreSQL. Anweisungen für MariaDB folgen weiter unten.

Zunächst melden wir und an der PostgreSQL-Kommandozeile an:

sudo -u postgres psql

Es wird nun ein User (nextcloud_db_user) und anschließend die Datenbank (nextcloud_db) selbst angelegt. Das Passwort für den User sollte hier natürlich durch ein eigenes Passwort ersetzt werden:

CREATE USER nextcloud_db_user WITH PASSWORD 'pAsSw0rD';
CREATE DATABASE nextcloud_db TEMPLATE template0 ENCODING 'UNICODE';
ALTER DATABASE nextcloud_db OWNER TO nextcloud_db_user;
GRANT ALL PRIVILEGES ON DATABASE nextcloud_db TO nextcloud_db_user;

Nun kann die PostgreSQL-Kommandozeile auch schon wieder verlassen werden:

\q

Datenbank für Nextcloud anlegen (MariaDB)

Mit folgenden Schritten wird die Datenbank unter MariaDB angelegt. Auch hier öffnen wir zunächst die MariaDB-Kommandozeile:

mysql -u root -p

Auch hier wird ein entsprechender User und die dazugehörige Datenbank angelegt. Das User-Passwort sollte natürlich angepasst werden:

CREATE USER nextcloud_db_user@localhost IDENTIFIED BY 'pAsSw0rD';
CREATE DATABASE nextcloud_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES on nextcloud_db.* to nextcloud_db_user@localhost;
FLUSH privileges;
exit;

Nextcloud-Setup

Um das Setup von Nextcloud durchzuführen, rufen wir nun einfach die Cloud-Domain im Browser auf (hier beispielhaft https://nextcloud.meinedomain.de). Nun werden folgende Daten verlangt:

  • Benutzer/Passwort (Administrator): Benutzername und Passwort des ersten Users in der Nextcloud. Dieser Benutzer ist automatisch Administrator der Nextcloud-Instanz.
  • Datenverzeichnis: Der Pfad des Datenverzeichnisses. Hier ist das Verzeichnis anzugeben, welches wir schon im Vorfeld erstellt hatten.
  • Datenbank-Verbindung: Benutzer und Passwort des Datenbank-Users für Nextcloud, sowie die Datenbank selbst, die wir im vorherigen Schritt erstellt haben. Je nach Nutzung von PostgreSQL/MariaDB muss hier ggf. die entsprechende Option mit angegeben werden.
Nextcloud Setup
Nextcloud Setup

Nach einer kurzen Wartezeit wird in einem zweiten Schritt die Installation empfohlener Apps angeboten. Wer diese Apps erst einmal nicht benötigt, sollte diesen Schritt mit Abbrechen überspringen. Diese Apps können später über den Nextcloud App Store noch nachträglich installiert werden.

Nextcloud Setup: Empfohlene Apps
Nextcloud Setup: Empfohlene Apps

Am Ende des Setups wird man zu Startseite (Dashboard) von Nextcloud weiter geleitet und das Setup ist damit beendet.

Warnungen im Admin-Bereich

Direkt nach der Installation von Nextcloud sollte man einen Blick in den Admin-Bereich werfen. Dazu oben rechts auf das Symbol des Benutzers klicken und Einstellungen wählen. Anschließend dann Übersicht unter der Kategorie Verwaltung wählen.

Hier werden nach der Installation noch einige Warnungen angezeigt. Dies sind keine Fehler, die Nextcloud funktioniert trotzdem einwandfrei, trotzdem sollte man für einen optimalen Betrieb das System so konfigurieren, dass keine Warnungen mehr angezeigt werden.

Nextcloud: Warnungen im Admin-Bereich
Nextcloud: Warnungen im Admin-Bereich

Der erste Punkt kann in den Grundeinstellungen erledigt werden. Nextcloud benötigt die Daten eines SMTP-Servers, damit das System E-Mails versenden kann (z.B. im Benutzer über geteilte Dateien zu benachrichtigen). Damit nach Eingabe die Mail-Funktion getestet werden kann, muss in den persönlichen Einstellungen des Benutzers noch eine E-Mail-Adresse hinterlegt werden.
Tipp: Am besten nutzt man für das Versenden von Mails über die Cloud eine extra eingerichtete Mail-Adresse.

Für den zweiten Punkt muss die config.php von Nextcloud bearbeitet werden:

nano /var/www/nextcloud/config/config.php

Hier fügen wir am Ende der Datei (aber noch vor der letzten schließenden Klammer) folgende Zeile ein:

'default_phone_region' => 'DE',

Die letzte Warnung bemängelt einen nicht vorhandenen Memory-Cache für PHP. Dies kann auch gleich in der config.php behoben werden. Wiederum ist hier eine zusätzliche Zeile hinzuzufügen:

'memcache.local' => '\OC\Memcache\APCu',

Wenn man nun die Seite im Admin-Bereich neu lädt, sollten alle Warnungen verschwunden sein.

Falls doch noch mehr Warnungen angezeigt werden, bitte nochmal die Schritte dieses Artikels kontrollieren (v.a. die PHP-Konfiguration). Im Nextcloud Administration Manual findet man darüber hinaus eine Übersicht aller Warnungen, die hier aufgelistet werden können, sowie Tipps, die diese Warnungen behoben werden können.

Optimierung der Nextcloud-Konfiguration

Zwei weitere Punkte sollten nun noch in der config.php angepasst werden:

nano /var/www/nextcloud/config/config.php

Zum einen sollte HTTPS als zu verwendendes Protokoll festgelegt werden, damit Nextcloud erst gar nicht versucht, Verbindungen über HTTP (unverschlüsselt) zuzulassen:

'overwriteprotocol' => 'https',

Zum anderen sollte hier auch die richtige Zeitzone mit angegeben werden, ansonsten werden u.U. im Nextcloud-Log falsche Zeitstempel ausgegeben:

'logtimezone' => 'Europe/Berlin',

Cronjob für Nextcloud einrichten

Nextcloud muss in regelmäßigen Zeitabständen Hintergrundaufgaben ausführen (z.B. Bereinigung verwaister Datenbank-Einträge). Standardmäßig werden diese Aufgaben mittels AJAX ausgeführt, d.h. es wird bei jedem Laden einer Seite geprüft, ob Hintergrundaufgaben anstehen und diese werden ggf. ausgeführt. Diese Methode ist aber sehr ineffizient, daher sollte man hierfür einen Cronjob einrichten

Dazu wird der Crontab des Users www-data bearbeitet:

crontab -u www-data -e

Ganz am Ende fügen wir hier folgende Zeile hinzu, damit alle 5 Minuten auf Hintergrundaufgaben geprüft wird und diese ggf. ausgeführt werden:

*/5 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1

Nach einer kurzen Wartezeit (max. 5 Minuten) kann man in den Admin-Einstellungen der Cloud unter Verwaltung > Grundeinstellungen kontrollieren, ob der Cronjob korrekt ausgeführt wurde. Hier sollte die entsprechende Option automatisch aktiviert worden sein:

Nextcloud: Ausführung von Hintergrund-Aufgaben mittels Cron
Nextcloud: Ausführung von Hintergrund-Aufgaben mittels Cron

Rechenintensive Hintergrundaufgaben zu einem definierten Zeitpunkt ausführen

Bei den Hintergrundaufgaben unterscheidet Nextcloud zwischen Aufgaben, die wenig rechenintensiv sind und möglichst schnell abgearbeitet werden sollten und rechenintensiven Aufgaben, die nur einmal täglich ausgeführt werden müssen.

In der config.php kann der Zeitpunkt bestimmt werden, wann solche rechenintensiven Aufgaben durchgeführt werden sollen:

nano /var/www/nextcloud/config/config.php

Hier kann z.B. folgende Zeile hinzugefügt werden:

'maintenance_window_start' => 1,

Achtung: Der Wert bestimmt die Stunde (in UTC), wann solche Aufgaben bearbeitet werden sollen. 01:00 UTC entspricht hier also 03:00 MESZ bzw. 02:00 MEZ. Der Zeitraum für die Abarbeitung dieser Aufgaben erstreckt sich dann max. bis zu 4 Stunden nach dem angegeben Zeitpunkt (in diesem Beispiel also bis max. 05:00 UTC/07:00 MESZ/06:00 MEZ).

Installation und Einrichtung Redis

Eine weitere Optimierung der Cloud ist die Einrichtung von Redis. Nextcloud nutzt hier den Mechanismus des Transactional file locking um z.B. Sperren bei parallelen Zugriffen auf Dateien zu realisieren. Dies wird standardmäßig über die Datenbank realisiert. Um die Performance der Cloud zu erhöhen, kann hier auch Redis genutzt werden. Dies ist eine In-Memory-Datenbank, welche genau für solche Anwendungsgebiete spezialisiert ist.

Um Redis nutzen zu können, wird das Programm und das dazugehörige PHP-Paket benötigt:

apt update && apt install redis-server php-redis

Redis muss daraufhin noch konfiguriert werden:

nano /etc/redis/redis.conf

Wie schon bei PHP sollte Redis über einen Socket angesprochen werden. Dazu werden folgende Werte in der Datei hinterlegt:

port 0 
unixsocket /var/run/redis/redis-server.sock 
unixsocketperm 770

Anschließend muss der Benutzer www-data noch zur Gruppe redis hinzugefügt werden:

usermod -a -G redis www-data

Damit die Änderungen übernommen werden, muss Redis einmal neu gestartet werden:

service redis-server restart

Damit Nextcloud nun auch Redis nutzt, muss dies noch in der config.php aktiviert werden:

nano /var/www/nextcloud/config/config.php

Hier werden am Ende der Datei (aber wie immer vor der letzten schließenden Klammer) folgende Zeilen hinzugefügt:

'filelocking.enabled' => true,
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => array (
     'host' => '/var/run/redis/redis-server.sock',
     'port' => 0,
     'timeout' => 0.0,
      ),

Man wird in der Nextcloud nun direkt keine Veränderungen feststellen können. Aber um zu testen, ob Redis ordnungsgemäß funktioniert, sollte einfach mal eine beliebige Datei in der Cloud geöffnet werden (z.B. das PDF des Benutzerhandbuchs). Wenn sich die Datei ohne Fehlermeldung öffnen lässt, war die Einbindung von Redis korrekt.

Weitere Konfiguration/Erweiterung von Nextcloud durch Apps

Die Grundkonfiguration von Nextcloud ist somit abgeschlossen. Nun kann die Cloud an die eigenen Bedürfnisse angepasst werden.

Zunächst lohnt es sich, sämtliche Einstellungen (persönliche Einstellungen des Benutzers, als auch Admin-Einstellungen) einmal durch zu gehen und die Werte an die eigenen Bedürfnisse anzupassen.

Anschließend kann Nextcloud durch die Installation von weiteren Apps aus dem Nextcloud App Store erweitert werden. Hier gibt es eine große Anzahl an Apps für die unterschiedlichsten Workflows: Von Videokonferenz-Funktionen mittels Nextcloud Talk, über Online-Office bis hinzu Cloud-gestützten Passwort-Managern gibt es hier sehr viele Möglichkeiten.

Optimierung der Server-Umgebung für Nextcloud

Auch wenn die eigene Nextcloud nun schon läuft, sollte die Server-Umgebung jedoch noch an einigen Stellen optimiert werden.

Firewall: ufw

ufw (uncomplicated firewall) ist eine einfache Software-Firewall die bereits auf einem Ubuntu-Server installiert ist. Im Heimbereich übernimmt normalerweise der Router die Aufgaben einer Firewall, daher ist hier die Einrichtung von ufw optional. Einem Root-Server ist aber im Normalfall keine Firewall vorgeschaltet, daher sollte ufw hier auf jeden Fall eingerichtet werden.

Dabei sollte die Firewall bis auf einige Ausnahmen sämtlichen Traffic blockieren:

  • SSH (Port 22): Damit der Zugriff über SSH weiterhin möglich ist. Im Heimnetz-Bereich kann hier eine weitere Einschränkung definiert werden, bei der der Zugriff nur aus dem lokalen Netz möglich ist.
  • HTTP/HTTPS (Ports 80 und 443): Dies ist für den Zugriff auf dem Webserver notwendig.

Mit folgenden Befehlen können diese Regeln definiert werden:

ufw default deny
ufw allow 80
ufw allow 443

Auf einem Root-Server lässt man nun alle Verbindungen über Port 22 zu (falls der eigene Anschluss keine feste IP-Adresse hat):

ufw allow 22

Im Heimnetz mit lokal beschränktem Zugriff kann die Regel für Port 22 folgendermaßen definiert werden. Hier haben dann nur Rechner mit den lokalen IP-Adressen 192.168.178.1 – 192.168.178.254 Zugriff (das Netz muss hier ggf. noch an die eigenen Netzwerk-Einstellungen angepasst werden):

ufw allow proto tcp from 192.168.178.0/24 to any port 22

Nun kann die Firewall scharf geschaltet werden:

ufw enable

Die aktiven Regeln können nun noch angezeigt werden:

ufw status

Hinweis: Wenn auf dem System noch weitere Anwendungen installiert sind oder ein abweichender Port für SSH hinterlegt ist, sind diese Firewall-Regeln natürlich anzupassen. Vor dem Aktivieren der Firewall lieber noch einmal genau kontrollieren, was für Regeln hinterlegt wurden, ansonsten kann man sich ganz leicht vom System ausschließend (z.B. wenn man die Freigabe für SSH vergisst).

Fail2ban

Nextcloud kommt seit einigen Version schon mit einem Brute Force Schutz daher. Dieser sorgt dafür, dass Login-Versuche (künstlich) immer weiter verzögert werden, wenn die Anmelde-Daten eines Benutzers nicht korrekt sind. Bei mehreren ungültigen Anmeldungen wird der Login dabei maximal um 25 Sekunden verzögert.

In der Praxis hat sich Fail2ban als Alternative (bzw. umfangreichere Lösung) bewährt. Hier können auch mehrere unabhängige Dienste (wie z.B. zusätzlich noch SSH) gegen Brute-Force-Attacken abgesichert werden, was auf jeden Fall Sinn macht. Ebenso werden IPs, von denen ungültige Logins ausgehen nach einer zu konfigurierenden Anzahl an Logins für einen gewissen Zeitraum gebannt, so dass der Server (für die entsprechenden IPs) gar nicht mehr erreichbar ist. Dies ist meist effizienter als eine künstliche Verzögerung von Login-Versuchen.

Deaktivierung der Nextcloud Brute Force Protection

Mit dem Einsatz von Fail2ban ist die in Nextcloud integrierte Brute Force Protection überflüssig und kann daher in der config.php deaktiviert werden:

nano /var/www/nextcloud/config/config.php

Mit folgendem Eintrag wird der Dienst deaktiviert:

'auth.bruteforce.protection.enabled' => false,

An dieser Stelle sollte auch gleich nochmal kontrolliert werden, ob die Zeitzone in der config.php korrekt gesetzt wurde:

'logtimezone' => 'Europe/Berlin',

Dies ist für den ordnungsgemäßen Betrieb von Fail2ban äußerst wichtig, da anhand der Zeitstempel der Log-Einträge ungültige Login-Versuche erkannt werden. Wenn diese Zeitstempel nicht passen (da z.B. eine andere Zeitzone eingestellt ist), wird Fail2ban nicht wie erwartet funktionieren.

Installation und Konfiguration Fail2ban

Fail2ban kann ganz einfach installiert werden. Das Paket rsyslog wird bei der Minimal-Installation von Ubuntu 22.04 LTS ebenfalls benötigt:

apt update && apt install fail2ban rsyslog

Im Anschluss wird ein sog. Filter für Nextcloud definiert:

nano /etc/fail2ban/filter.d/nextcloud.local

Dieser Filter definiert einen regulären Ausdruck, der einen ungültigen Login-Versuch beschreibt. Mit Hilfe dieses regulären Ausdrucks wird später die Log-Datei von Nextcloud durchsucht, um ungültige Login-Versuche zu erkennen:

[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
            ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

Damit der Filter zum Einsatz kommt, muss bei Fail2ban noch ein sog. Jail definiert werden:

nano /etc/fail2ban/jail.local

Ein Jail definiert hauptsächlich die Verbindung zwischen Log-Datei und Filter:

[DEFAULT]
maxretry=3
bantime=1800

[nextcloud]
enabled=true
port=80,443
protocol=tcp
filter=nextcloud
logpath=/var/nextcloud_data/nextcloud.log

[nginx-http-auth]
enabled = true

Der Block [DEFAULT] beinhaltet allgemeine Einstellungen, die für alles Jails gelten:

  • maxretry: Anzahl der fehlgeschlagenen Login-Versuche, bevor Fail2ban greift und aktiv bannt.
  • bantime: Der Zeitraum (in Sekunden), für die eine IP gebannt werden soll. Durch einen Wert von -1 werden IPs dauerhaft gebannt.

Der nächste Block [nextcloud] definiert ein neues Jail für Nextcloud:

  • enabled: Aktivierung des Jails. Wenn ein Jail (temporär) nicht aktiv sein soll, kann es an dieser Stelle ausgeschaltet werden.
  • port: Port, hier 80 (HTTP) und 443 (HTTPS).
  • protocol: Das verwendete Protokoll, hier TCP.
  • filter: Name des Filters anzuwendenden Filters. Dieser ergibt sich auch dem Dateinamen unter /etc/fail2ban/filter.d (in unserem Fall also einfach „nextcloud“).
  • logpath: Gibt die Log-Datei an, die Fail2ban mit Hilfe des Filters untersuchen soll.
  • Ebenso könnten in diesem Block noch vom Standard abweichende Werte für maxretry und bantime angegeben werden. Dies wird hier ausgelassen, da die Standard-Werte genutzt werden sollen.

Wie man gut sehen kann, wird gleich noch ein zusätzliches Jail mit aktiviert ([nginx-http-auth]): Dieses sorgt dafür, dass zusätzlich noch das nginx Log bzgl. ungültigen Anmeldeversuchen (HTTP-Basic-Authentifizierung) überwacht wird. Dies ist hier zwar nicht unbedingt notwendig, da Nextcloud die ungültigen Logins selbst logt, schadet aber auf keinen Fall (z.B. wenn man weitere Webanwendungen auf dem gleichen Server hosten will). Hier sind dabei keine weiteren Parameter anzugeben, da es sich hier um ein „Standard-Jail“ handelt, welches mit Fail2ban automatisch mitkommt (/etc/fail2ban/jail.conf), daher reicht hier einfach die Aktivierung.

Ebenso wird bei der Installation von Fail2ban automatisch das Jail für SSH aktiviert. Dies ist besonders für Root-Server besonders wichtig, da hier häufiger mal durch die „Bad Guys“ ungültige Anmeldeversuche festgestellt werden. Dies ist mitunter ein Hauptgrund, warum Fail2ban auf jeden Fall installiert werden sollte.

Die Änderungen werden mit einem Neustart von Fail2ban übernommen:

service fail2ban restart

Optional: E-Mail-Versand durch Fail2ban

Fail2ban ist nun scharf geschaltet und bannt nun bereits nach der konfigurierten Anzahl an ungültigen Anmeldungen. Damit man nun aktiv per E-Mail benachrichtigt wird, wenn Fail2ban „zugeschlagen“ hat, sind noch einige zusätzliche Schritte durchzuführen. Dieser Schritt ist optional, aber dennoch sinnvoll, damit man etwas im Auge behalten kann, was auf dem Server gerade so passiert.

Voraussetzung dafür ist, dass das System bereits E-Mails versenden kann. Dazu kann beispielsweise msmtp genutzt werden. Wie dieses Programm installiert und eingerichtet werden kann, wurde bereits im Artikel Linux: Einfach E-Mails versenden mit msmtp beschrieben.

Fail2ban ist dabei schon auf den Versand von E-Mails vorbereitet, deshalb reichen hier kleinere Anpassungen, wenn msmtp bereits einsatzfähig ist:

nano /etc/fail2ban/jail.local

In der Default-Sektion werden dazu ein paar weitere Parameter mit angegeben:

[DEFAULT]
maxretry=3
bantime=1800

# Destination email address used solely for the interpolations in
# jail.{conf,local,d/*} configuration files.
destemail = meineemail@provider.de

# Sender email address used solely for some actions
sender = absenderadresse@provider.de

# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
# mailing. Change mta configuration parameter to mail if you want to
# revert to conventional 'mail'.
mta = mail
action = %(action_mwl)s

Folgende Dinge sind hier relevant:

  • destemail: Die E-Mail-Adresse, an die die Benachrichtigungen verschickt werden sollen (Empfänger).
  • sender: Die Absender-Mail-Adresse.
  • Durch die letzte Zeile (action = %(action_mwl)s) wird letzten Endes der E-Mail-Versand über Fail2ban aktiviert.

Nun würde mal aber für sehr viele Aktionen eine E-Mail zugesendet bekommen (z.B. auch bei einem einfachen Neustart eines Dienstes auf dem System). Wer die o.g. Konfiguration mal mit einem Neustart des Dienstes übernommen hat, wird sich über das hohe „Spam-Aufkommen“ wundern.

Wir wollen Fail2ban daher nun so einrichten, dass ausschließlich E-Mails versendet werden, wenn eine IP durch ein beliebiges Jail gebannt wurde. Dazu sind einige Dateien im Verzeichnis /etc/fail2ban/action.d anzulegen. Der Inhalt sieht dabei immer gleich aus:

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart =

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop =

Dieser Inhalt muss in folgenden Dateien im o.g. Verzeichnis übernommen werden:

  • mail-buffered.local
  • mail.local
  • mail-whois-lines.local
  • mail-whois.local
  • sendmail-buffered.local
  • sendmail-common.local

Tipp: Am besten die erste Datei mit den Inhalt anlegen und dann einfach mit den anderen Dateinamen kopieren, z.B.:

cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail.local

Dies dann solange wiederholen, bis alle Dateien angelegt wurden.

Anschließend ist Fail2ban einmal neu zu starten:

service fail2ban restart

Fail2ban: Test der Funktion

Ob nun alles geklappt hat, kann man nun ganz einfach testen: Man sperrt sich selber mal aus dem System aus. Dieser Test ist insofern sinnvoll, dass man sich selbst wieder entbannen kann, wenn man mal das Passwort zu oft falsch eingegeben hat (soll ja vorkommen…).

Dazu einfach bei der eigenen Cloud abmelden und anschließend drei mal mit z.B. einem nicht existierenden User (oder einfach falschem Passwort) anmelden. Ihr solltet daraufhin sofort eine E-Mail von Fail2ban erhalten und ein erneuter Login-Versuch wird schon deshalb scheitern, weil der Server anscheinend gar nicht mehr reagiert (da die Verbindung von vorn herein blockiert wird). Hier hat dann das Jail von Nextcloud zugeschlagen.

Um euch nun die gebannte(n) IP(s) des Nextcloud-Jails anzeigen zu lassen, könnt ihr folgenden Befehl verwenden:

fail2ban-client status nextcloud

Hier sollte nun eure IP gelistet werden. Entbannen könnt ihr euch dann wieder mit:

fail2ban-client set nextcloud unbanip 45.135.54.12

Anschließend kann man dann wieder wie gewohnt auf Nextcloud zugreifen (hoffentlich mit dem richtigen Passwort).

Überprüfung der Sicherheit

Die Sicherheit der eigenen Cloud war ja von Anfang an erklärtes Ziel des Artikels. Hier gilt nun wie so oft: „Vertrauen ist gut, Kontrolle ist besser“. Glücklicherweise gibt es einige Tools im Web, mit der bestimmte Sicherheits-Parameter überprüft werden können.

Wichtig: Keine Software ist frei von Fehlern! Daher spreche ich auch explizit von „einigen Sicherheits-Parametern“. Auch wenn diese Test erfolgreich ablaufen, dann es aber immer in einer neueren Version von Nextcloud zu Bugs, etc. kommen, die eine Sicherheits-Lücke aufreißen. Hier kann ich euch aber beruhigen: In den vergangenen Jahren ist es hier (nach meinem Wissensstand) noch nie zu kritischen Sicherheits-Lücken gekommen, bei der z.B. das ganze System übernommen werden konnte. Trotzdem sollte man immer im Hinterkopf behalten, dass es die absolute Sicherheit nicht geben kann!

Allen folgenden Security-Checks ist gemein, dass diese nur die öffentlich zugänglichen Daten des Webservers bzw. der Nextcloud prüfen. Kein Dienst kann dabei z.B. eure in der Cloud gespeicherten Daten sehen oder herunter laden.

Qualys SSL Labs

Die Firma Qualys bietet schon seit geraumer Zeit die Webanwendung SSL Server Test an: Damit kann v.a. die Verschlüsselung mittels HTTPS geprüft werden, also die Zertifikate von Let’s Encrypt und ob diese korrekt im Webserver eingebunden wurden. Wenn ihr auf dieser Website eure Server-URL eingebt (beispielsweise https://nextcloud.meinedomain.de) und ab besten auch die Option Do not show the results on the boards aktiviert (nicht jeder muss ja eure Cloud-Domain kennen), dann sollte beim Test ein A+ Rating erscheinen:

Qualys SSL Server Test
Qualys SSL Server Test

Mozilla Observatory

Ein weiterer Test ist Mozilla Observatory. Dieser Test zielt v.a. auf die vom Webserver gesetzten Header ab und gibt ggf. noch Tipps, um die Sicherheit noch weiter zu erhöhen. Hier auch am besten wieder die Option „Don’t include my site in the public results“ aktivieren, damit die eigene Domain nicht in den öffentlichen Resultaten landet.
Auch hier sollte wieder ein A+ Rating angezeigt werden.

Mozilla Observatory
Mozilla Observatory

Nextcloud Security Scan

Der Nextcloud Security Scan prüft die (öffentlich zugänglichen) Informationen zur eigenen Cloud-Instanz und kann ggf. Schwachstellen aufzeigen, beispielsweise, wenn eine veraltete Version von Nextcloud zum Einsatz kommt. Hier sollte man aber auch wieder im einem A+ Rating belohnt werden.

Nextcloud Security Scan
Nextcloud Security Scan

FAQ

An dieser Stelle sollen die häufigsten Fragen zu diesem Artikel beantwortet werden

Ich habe bereits eine Nextcloud-Installation unter Ubuntu Server 20.04 LTS laufen. Soll ich diese nun möglichst schnell auf Ubuntu Server 22.04 LTS updaten?

Ubuntu 20.04 LTS wird noch bis April 2025 unterstützt. Daher ist ein sofortiges Update nicht zwingend erforderlich, die alte Version wird noch lange genug supportet. Da Ubuntu 22.04 LTS gerade erst erschienen ist, würde ich mit einem Update auf jeden Fall noch abwarten, bis Version 22.04.1 von Ubuntu erschienen ist.
Wenn man allerdings eine komplett neue (Erst-)Installation vornimmt, würde ich heute schon auf Ubuntu 22.04 LTS setzen.

Macht es bei einer bestehenden Nextcloud-Instanz mit MariaDB als Datenbank Sinn, auf PostgreSQL zu wechseln?

Die Wahl des Datenbank-Systems ist nicht pauschal zu beantworten. Wenn die Nextcloud-Instanz mit MariaDB einwandfrei läuft, würde ich auch dabei bleiben. Auch wenn PostgreSQL in der Theorie etwas mehr Performance bieten sollte, wird man dies in den meisten Fällen in der Praxis überhaupt nicht bemerken.
Wer doch auf PostgreSQL wechseln möchte, kann sich an den Artikel Nextcloud: Migration der Datenbank von MySQL/MariaDB auf PostgreSQL halten. Auf jeden Fall sollte aber vorher ein Backup der Nextcloud-Instanz gemacht werden.

Wie kann ich ein Backup meiner Nextcloud anfertigen?

Ein komplettes Backup besteht immer aus dem Dateiverzeichnis (/var/www/nextcloud), dem Datenverzeichnis (/var/nextcloud_data) und der Datenbank (Dump). Aus diesen drei Bausteinen lässt sich eine Nextcloud wieder komplett herstellen. Wie man ein Backup der Nextcloud erstellen und dieses Backup auch wiederherstellen kann, ist im Artikel Nextcloud: Backups erstellen und wiederherstellen – manuell oder per Skript beschrieben.
Wer das Backup nicht manuell durchführen will, kann auch die bewährten Nextcloud Backup/Restore Skripte nutzen. Wie man diese verwendet und was es dabei zu beachten gilt, ist in der Readme des Codeberg-Repositories beschrieben.

Nextcloud gibt es doch auch als Docker-Image. Warum sollte ich also den Aufwand betreiben, alles manuell zu installieren?

Nextcloud bietet ein offizielles Docker-Image an. Dies beinhaltet zunächst nur eine absolute Basis-Installation von Nextcloud. So wird standardmäßig z.B. als Datenbank SQLite verwendet. Diese Datenbank sollte allerdings nicht für eine produktive Instanz genutzt werden. Also benötigt man dann einen weiteren Docker-Container mit PostgreSQL oder MariaDB. Ebenso fehlt beim Nextcloud-Docker-Image die Transportverschlüsselung mittels HTTPS. Hier braucht man also (mindestens) noch einen zusätzlichen Container, mit dem dann Zertifikate generiert werden können und der ggf. dann als Reverse Proxy für die SSL-Terminierung zuständig ist. Wenn man in der Nextcloud dann auch noch Apps installieren möchte, die ein Backend benötigen (z.B. die Volltextsuche), wird wieder ein zusätzlicher Container benötigt.
Ihr seht schon: Wenn man etwas höhere Anforderungen an die eigene Nextcloud hat, wird das Setup mittels Docker schnell ziemlich kompliziert, da man zig Container benötigt. Aus diesem Grund setze ich immer auf eine Installation ohne Docker, weil sich dann eine solche Instanz auch schnell und einfach an die eigenen Bedürfnisse anpassen und erweitern lässt.

Kann ich Nextcloud auch auf meinem NAS installieren?

Nextcloud kann natürlich auch auf einem NAS betrieben werden. Die erste Möglichkeit wäre der Einsatz von Docker. Davon würde ich aber aus o.g. Gründen eher abraten. Besser ist hier das Aufsetzen einer virtuellen Maschine (VM) für Nextcloud. Diese verhält sich dann genau so wie ein Hardware-Rechner und man kann alle Schritte dieses Tutorials auch auch dieser VM umsetzen.
Man sollte jedoch bedenken, dass die meisten (Consumer-)NAS-Systeme eher wenig Rechenleistung bieten. Daher eignet sich eine Nextcloud-Instanz auf einem NAS nur für kleinere Cloud-Systeme mit wenigen Benutzern. Auch von einer Installation von Apps, die spezielle Backend nutzen (z.B. Volltextsuche oder OnlyOffice) muss eher abgeraten werden.

Ich möchte meine Nextcloud nicht im Root der Domain, sondern in einem Unterverzeichnis betreiben. Wie kann dies umgesetzt werden?

Der Artikel zeigt, wie man Nextcloud im Root der (Sub-)Domain betreibt (z.B. https://nextcloud.meinedomain.de). Man kann die Cloud aber auch in einem Unterverzeichnis laufen lassen, also beispielsweise https://meinedomain.de/nextcloud. Hier sind dann hauptsächlich Änderungen am Webserver (vHost für Nextcloud) umzusetzen. Wie ein solcher vHost dann aussehen kann, ist im Nextcloud Administration Manual beschrieben.

Ich möchte neben der Nextcloud noch andere Webanwendungen auf dem gleichen Server betreiben. Wie muss ich hier vorgehen?

Da Nextcloud nicht exklusiv auf dem Server laufen muss, können selbstverständlich auch noch weitere Webanwendungen auf dem gleichen Server installiert werden. Hier ist dann v.a. die Webserver-Konfiguration (vHosts) entscheidend. Der Artikel Webserver-Konfiguration (nginx): Mehrere Webanwendungen auf einem Server hosten zeigt hier verschiedene Lösungs-Ansätze.

Troubleshooting

Auch wenn ich versucht habe, alle Schritte zum Betrieb der eigenen Nextcloud möglichst detailliert zu beschreiben, kann es dennoch vorkommen, dass es nicht auf Anhieb klappt. An dieser Stelle daher ein paar Tipps für die Fehlersuche:

  • Wurden alle Schritte korrekt ausgeführt?
    Die Installation von Nextcloud ist schon recht umfangreich und erfordert viele einzelne Schritte. Hier kann es vorkommen, dass man einen kleinen Schritt übersieht und dann das „große Ganze“ nicht mehr mehr funktioniert. Daher ist es im Fehlerfall immer sinnvoll, nochmals alle Schritte durchzugehen und zu kontrollieren, ob diese korrekt ausgeführt wurden, oder ob es z.B. bei einem Schritt zu einem Fehler bekommen ist, den man vielleicht nicht bemerkt hat.
  • Kontrolle der Logs:
    Oftmals hilft auch ein Blick in die Log-Dateien der einzelnen Programme. Daher würde ich immer „von innen nach außen“ vorgehen:
    • nginx (/var/log/nginx/error.log): Der Webserver listet hier Fehler und Warnungen auf, z.B. wenn eine angeforderte Datei nicht gefunden werden kann. Meistens liefern die Einträge in diesem Log schon erste Hinweise auf den Fehler (z.B. falsches Webserver-Verzeichnis). Dies ist meist die erste Anlaufstelle, wenn es zu Webserver-Fehlermeldungen kommt (also man gar nicht bis zur Nextcloud durchkommt).
    • Nextcloud (/var/nextcloud_data/nextcloud.log): In dieser Datei sind Fehler und Warnungen von Nextcloud selbst enthalten. Diese Logs können auch direkt über die Admin-Oberfläche der Cloud eingesehen werden. Diese Logs sind v.a. dann interessant, wenn die Cloud prinzipiell schon aufgerufen werden kann – also der Webserver vermutlich korrekt konfiguriert ist – aber es bei der Nutzung der Nextcloud zu Problemen kommt.
      Hinweis: Dieses Log ist im Allgemeinen sehr geschwätzig. Wichtig ist hier, dass nicht jeder Fehler euch ein „echter Fehler“ ist. Erst, wenn Nextcloud nicht richtig funktioniert, kann man hier von einem Fehler ausgehen.
  • Developer-Konsole im Browser:
    Wenn in den Logs keine sinnvollen Hinweise auf den Fehler gefunden werden können, lohnt oftmals auch ein Blick in die Browser-Konsole (bei den meisten Browsern kann man diese mit F12 öffnen). Hier wird dann aufgelistet, was bei einem Aufruf der Webseite passiert. Oftmals kann dies dann auch einen Hinweis auf den Fehler geben.

Fazit

Hat man sich bis zum Ende des Artikels durchgearbeitet, ist man mit der eigenen Cloud wieder Herr über der eigenen Daten und nicht mehr abhängig von irgendwelchen (externen) Cloud-Anbietern. Besser noch: Weil man alles selbst installiert und eingerichtet hat, kann man im Fehlerfall das Problem meist recht schnell selbst analysieren und beheben.

Denn eines muss auch klar sein: Wer seine eigene Cloud betreibt, ist auch für diese verantwortlich. So muss der Administrator beispielsweise dafür Sorge tragen, dass das System stets auf dem neusten Stand ist. Trotzdem sollte sich der Aufwand hierfür in Grenzen halten.

Ich hoffe, dass der Artikel wieder mal hilfreich war und euch hoffentlich etwas Zeit und Nerven bei der Einrichtung der eigenen Nextcloud erspart hat. Konstruktive Kritik und Verbesserungsvorschläge sind dabei wie immer willkommen, hinterlasst mir dazu doch einfach einen Kommentar.

In diesem Sinne: Viel Spaß mit eurer eigenen Nextcloud!

Weiterführende Artikel

Links

93 Kommentare zu „Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL/MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban“

  1. Danke für die tolle und ausführliche Beschreibung.

    Du gehst in den FAQ auf die Installation als Docker-Image ein. Gilt das gleiche auch für die Installation per Snap oder gibt des andere Vor-/Nachteile?

    Hast Du Erfahrungen mit der Nextcloud-News-App?
    Ich würde diese gerne nutzen. Von Zeit zu Zeit versuche ich es auch, dann kommt es aber zu Problemen und ich wechsel doch wieder zurück zu meiner FreshRSS-Installation.
    Fresh-RSS funktioniert gut, hat für mich aber eigentlich zu viele Funktionen. Die News-App der Nextcloud hat für mich den Vorteil, dass sie eben in die Nextcloud integriert ist. Das gefällt mir einfach besser. Ich bevorzuge einfach die einheitliche Oberfläche.
    Zu den Problemen:
    Ich habe über die Jahre recht viele RSS-Feeds abonniert (250-300). Manchmal habe ich den Eindruck, das ist zu viel für die Nextcloud-News-App. Sie scheint sich zu „verschlucken“. Manche Feeds werden dann nicht zuverlässig aktualisiert.
    Nach einem Reboot des Server dauert es manchmal Stunden bis eine Aktualisierung des Feeds erfolgt. Wenn überhaupt. Manchmal ist das auch nach Tagen noch nicht geschehen. Das ist dann dann der Zeitpunkt, wo ich wieder zurück zu Freshh-RSS wechsel;)
    Falls Du dazu etwas sagen kannst, wäre ich Dir sehr verbunden?!

    Danke nochmals für den Artikel und das gesamte Blog!

    1. Hi,

      Snap verhält sich in dieser Beziehung ähnlich wie die Installation per Docker. Hier kommt zwar schon MySQL als „richtiges“ Datenbank-System mit, trotzdem muss man sehr viel „drum herum bauen“, wenn man eine Nextcloud-Installation mit allem drum und dran haben möchte. Von daher würde ich sagen, dass es sich ähnlich wie mit Docker verhält.

      Zur News-App: Nutze ich selbst in meiner privaten Cloud, habe hier jedoch nur 50-75 Feeds abonniert. Mit diesen Abos habe ich hier noch nie ein Problem feststellen können.
      Du könntest höchstens mal das Nextcloud-Log nach Fehlermeldungen der News-App durchforsten: Hier ist mir aufgefallen, dass es manchmal zu Meldungen kommt, dass ein Feed nicht abgerufen werden kann (wenn es einen Blog o.ä. zwischenzeitlich gar nicht mehr gibt). Hier weiß ich nicht, ob die App aus dem Tritt kommt, wenn dies mit mit sehr vielen Feeds auftritt, bzw. wie oft die News-App versucht, genau diese Feeds abzuholen.
      Hier würde ich an deiner Stelle mal einen Issue im entsprechenden GitHub-Repo aufmachen, die Entwickler können hier bestimmt besser unterstützen.

      Gruß,
      Jan

  2. Hallo Jan,

    ist es von Dir angedacht, das Thema „Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL/MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban“ auch auf Basis von Proxmox (insbesondere mit weiteren Servern aka WordPress oder Mail) abzuhandeln?

    1. Hi Ingo,

      bei Proxmox ist ja erst einmal die Grundkonfiguration entscheidend. Daraufhin installiert man hier eine virtuelle Maschine oder einen LXC-Container. Die VM oder der LXC-Container verhält sich dann ja wie ein normaler Rechner. Hier ist die Installation von Nextcloud ja genau gleich.
      Bzgl. der weiteren Webanwendungen: Hier habe ich dazu auch mal was geschrieben.
      Im Gesamt-Kontext spielt es dabei keine Rolle, wo die einzelnen Webanwendungen/Webserver installiert sind (auf einer Maschine oder auf getrennten (virtuellen) Maschinen).

      Von daher sollten die „Bausteine“ bereits bekannt sein. Lediglich die Konfiguration des Webservers/des „Backends“ pro Webanwendung ist hier leider sehr individuell, daher kann ich hier leider kein Patent-Rezept abliefern.
      Oder fehlt dir irgend etwas, um diese Bausteine noch zusammen zu setzen? Wenn ja, wo hakt es denn? Vielleicht wäre dies ja einen Artikel wert, dazu muss das ganze aber schon recht konkret sein.

      Gruß,
      Jan

      1. Hallo Jan,
        ich benutze den Nginx Proxy Manager (über Docker installiert).
        Wie verhält es sich dort mit den Einstellungen?
        Ist eine Nginx Installation direkt auf Ubuntu Server dann noch nötig?

        Habe auch Proxmox mit mehreren Containern. Glaube so was meinte jan über dir.
        Gruß
        Stefan

        1. Hi Stefan,

          der nginx Proxy Manager ist ja nur der Reverse Proxy (NPM), der dann auch die „echte“ SSL-Terminierung vornimmt (also mit validen Zertifikaten).
          Am Nextcloud-Backend (z.B. auf einer anderen Maschine) benötigst du dann aber ebenfalls einen nginx, da der ja die genaue Konfiguration für Nextcloud bereit stellt.
          Wichtig ist hier nur, dass die Header nicht doppelt gesetzt werden (einmal am NPM, einmal am nginx). Ich würde diese vermutlich weiter vorne – als am NPM – setzen.

          Gruß,
          Jan

          1. Hallo Jan,
            leider hat er eben meine Antwort nicht angenommen, hoffe die kommt jetzt nicht doppelt.
            Ja okai leider bin ich was das angeht noch nicht auf Stand, bzw. lerne noch. Denke man sollte sich da zwar mehr auskennen, wenn man so sagen alle installiert, aber ja :-)

            Jedenfalls könntest du genauer erläutern was es auf sich hat mit den doppelten Header?
            Oder gibt es dazu eine Quelle die das genau erklärt?

            Ich sehe ja nur das du nginx und letsencrypt auf der „nextcloud Maschine“ installierst. Ich habe diese sachen ja auf einer weiteren „Maschine“ also Proxmox Container installiert, also ist das für mich doppelt!? Daher meine Fragestellung dazu, doppelt gemoppelt ist ja eher semi gut. Und leider fehlt mir da die Erfahrung bzw. noch das Verständnis wie man dies dann behandelt.

            Gruß
            Stefan

            und vielen Dank für die ganzen Infos die du hier raus haust.

          2. Hi Stefan,

            angenommen du hast einmal nginx auf der ersten Maschine, wo auch die „echten“ Zertifikate sind. Von hier aus gibt’s dann eine Weiterleitung auf die zweite Maschine, wo ebenfalls ein nginx und die NC selbst installiert sind. Ein Request durchläuft dann beide nginx-Instanzen. Die Header dürfen aber nur an einer Instanz gesetzt werden (vorzugsweise beim „äußeren“ nginx, also dort, wo auch die echten Zertifikate liegen).
            Wird das nun etwas klarer?

            Gruß,
            Jan

          3. Hallo Jan,
            :-)

            jaein sag ich mal vorab.
            wenn ich dem NPM nur eine Weiterleitung ohne SSL Generierung vorgebe auf meinen NC Container, kann ich dann die Aufgaben der Verschlüsselung etc. einfach so abarbeiten lassen wie oben in der Anleitung beschrieben?
            Ich gestehe einfach mal das mit das Wissen noch fehlt, was sich für mich ändern muss in deiner Anleitung um die Installation fertig zu stellen mit einen 2ten NPM der vor dem eigentlichen NC Server ist.

            Gruß
            Stefan

          4. Hi Stefan,

            um es „richtig“ zu machen, d.h. dass die Verbindung bis zum letzten „Hop“ verschlüsselt abläuft, bräuchtest du folgendes Konstrukt:
            Server „Proxy“: NPM + Zertifikate (valide, als von Let’s Encrypt). Weiterleitung an die NC-Maschine (mittels HTTPS!).
            Server „NC“: nginx genau so wie im Artikel beschrieben (ok, den Gateway-Host und alles, was zu Let’s Encrypt gehört, kann man weglassen). Jedoch hier keine Let’s Encrypt Zertifikate, sondern selbst signierte Zertifikate nutzen (z.B. hier beschrieben)

            Auf der NC-Maschine wäre auch das Weglassen der Zertifikate möglich, dann würde die Verbindung NPM -> nginx/NC (also der interne Netzwerk-Verkehr) unverschlüsselt ablaufen. Klingt erst einmal nach der einfacheren Variante, es sind hier aber eiige Änderungen am vHost von NC notwendig, die die Sache dann schon wieder komplizierter machen würden. Von daher meine Empfehlung mit den selbst signierten Zertifikaten.

            Gruß,
            Jan

          5. Hallo Jan,
            vielen vielen Dank für die schnellen Antworten.
            Ich schaue mal was ich jetzt mache, muss mich da dann erstmal schön rein „fummeln“ ;-)
            aber so was macht ja auch Spass.

            vielen Dank noch mal.
            Stefan

  3. Hallo Jan,
    ist dir was bekannt NC 24 (Ubuntu Server 22.04 LTS) in Verbindung mit dem Verschlüsselungsmodul ?

    OCP\Files\NotFoundException: No mount for path /files_encryption/OC_DEFAULT_MODULE/pubShare_74946a8a.publicKey existing mounts:

    Vielen Dank

    Gruß Hans

    1. Hi Hans,

      ja, es gibt dazu wohl einen Bug-Report, leider aber ohne Feedback der Entwickler o.ä.
      Ich selbst bin darüber noch nicht gestolpert, aber ich setze die Server-seitige Verschlüsselung auch nicht ein, da diese nur in ganz speziellen Konstellationen Sinn macht (und die Sache ansonsten nur verkompliziert bzw. dafür sorgt, dass viele Apps nicht verwendet werden können).

      Aber mal sehen, ob sich bei dem Bug Report noch etwas tut.

      Gruß,
      Jan

      1. Hallo Jan.
        vielen Dank, den Report habe ich auch schon gesehen.
        Diese spezielle Konstellation habe ich leider bei einem Bekannten.

        Dann bleibt mir keine Wahl als das Standard-Verschlüsselungs-Modul und die Verschlüsselung der Benutzerverzeichnisse zu deaktivieren.
        Unter NC 23.05 gabe es hier keine großen Probleme in Verbindung mit den Standardanwendungen.

        Gruß Hans

  4. Hallo Jan
    erst einmal vielen Dank für den neuen Artikeln. Wie immer sehr gut geschrieben und toll erklärt, ein Grund warum ich immer wieder auf die Seite komme.
    Wie du schon in den FAQ geschrieben hast, hat man etwas höhere Anforderungen an die eigene Nextcloud, wird es mit Docker schnell kompliziert. Das habe ich nach einiger Zeit mit dem Nextcloud Container auch immer wieder festgestellt. Als Unraid Nutzer hat man ja zum glück alle Option, als fix eine VM erstellt, decatec.de geöffnet und Jan‘s neuen Artikel durchgearbeitet. 😊 Alles top aber beim Reverse Proxy und Nextcloud bin ich dann stecken geblieben.
    Würdest du deinen Artikel vielleicht um ein Reverse Proxy Teil erweitern oder mir sagen, wie die vHost Konfiguration im Nginx für die Nextcloud aussehen muss? Im Nginx Proxy Manager habe ich nur die Carddav und Caldav locations unter Custom hinzugefügt.

    Viele Dank noch mal für den Artikel und mach weiter so.
    Marzel

    1. Hi Marzel,

      den vHost der Nextcloud selbst würde ich so lassen, hier muss man dann aber auf selbst signierte Zertifikate setzen. Die „echte“ SSL-Terminierung übernimmt dann der nginx Proxy Manager (NPM).
      In der config.php musst du dann vermutlich den NPM als „trusted proxy“ eintragen.
      Ich habe allerdings noch nie mit dem NPM gearbeitet, daher kann ich dir leider keine konkrete Konfiguration nennen. Aber schau z.B. mal hier vorbei, vielleicht hilft das ja weiter.

      Gruß,
      Jan

      1. Hallo Jan
        Danke für den Tipp mit den selbst signierten Zertifikaten! Da hätte ich auch mal draufkommen können, anstatt mich die ganze Zeit mit der vhost config rumzuärgern. Jetzt läuft alles, Nextcloud Security Scan A+, Mozilla Observatory A+, Qualys SSL Labs auch A+ aber nur 90 bei Key Exchange und nicht 100 wie bei dir. Ich denke das liegt an den selbst signierten Zertifikaten, ich habe auch nicht die Info „DNS Certification Authority Authorization (CAA) Policy found for this Domain.“ bekommen.

        Eine Info noch, bei mir hat Redis erst nach einem nginx und php Neustart funktioniert, vorher hatte ich immer eine Fehlermeldung von Nextcloud beim neu laden der Seite. Gibt es eigentlich einen Grund warum du beim memcache.local auf APCu bleibe und dort nicht auch zu Redis wechselst?

        Viele Dank noch mal für die Hilfe und den großartigen Artikel.
        Marzel

        1. Hi Marzel,

          den Key-Exchange sollte man bei dir auch auf 100 bekommen, da Qualys hier nur die Let’s Encrypt Zertifikate „sieht“. Dass das „Backend“ mit selbst signierten Zertifikaten angebunden ist, spielt hier keine Rolle.

          Redis nutze ich nur fürs Transactional File Locking. Fürs Caching dann APCu. Ist mehr oder weniger die offizielle Empfehlung. Caching über Redis wird dann erst bei größeren Instanzen interessant, wo es mehrere Frontends auf mehreren Servern gibt, die dann einen gemeinsamen Cache nutzen sollen.

          Gruß,
          Jan

  5. Hallo Jan,

    mal ne Frage in Sachen 2 Faktor Authentifizierung. Unter Ubuntu 20.04 konnte ich noch TOTP aus den Apps installieren aber jetzt unter 22.04 geht’s nicht. Die App ist nicht mal mehr vorhanden. Gibt es ne Möglichkeit die App manuell zu installieren? OpenOTP lässt sich zwar installieren funktioniert aber trotz installiertem PHP-LDAP nicht. Ach und danke für diese super Anleitung. Sehr einfach erklärt (:

    Gruss Christian

    1. Hi Christian,

      ich denke, die App ist noch nicht mit PHP 8.1 kompatibel, siehe hier.
      Einzige Möglichkeit dürfte daher sein, PHP 8.0 via PPA zu installieren. Oder einfach ein wenig abwarten, bis die Entwickler hier nachgelegt haben.

      Gruß,
      Jan

  6. Danke für die umfangreichen Erklärungen. Nach einigen Installationen auf einem Raspi & Nextcloudpi konnte ich mich an Hand dieser Beschreibung am Server ausprobieren. Das hat soweit super funktioniert (habe deutlich mehr verstanden was ich da tue) bis auf….die Einbindung von Redis in der config.php.

    Dies hat bei mir erst durch den Zusatz
    ‚memcache.local‘ => ‚\OC\MEMCACHE\Redis‘,
    funktioniert und dafür gesorgt, dass die Fehlermeldung aus der Übersicht „Sicherheits- & Einrichtungswarnungen“ bzgl. des PHP Cache verschwand.

    Gerne würde ich verstehen, warum das erst dann funktioniert. Ggf. habe ich auch etwas übersehen.
    Ich nutze Ubuntu 20.04.4 LTS & Nextcloud 24.0.1.

    Gruß Andreas

    1. Hi Andreas,

      das ist der lokale Cache. Hierfür nehme ich der Einfachheit halber immer APCu: 'memcache.local' => '\OC\Memcache\APCu',
      Hier kann man auch Redis nutzen, hier sehe ich aber keinen großen Vorteil. Erst bei distributed Caching (wenn man z.B. mehrere Nextcloud-„Frontends“ inkl. Webserver hat), lohnt es sich hier auf Redis umzusteigen (distributed nicht local).
      Fehlte bei dir evtl. noch die Einbindung von APCu als lokaler Cache?

      Gruß,
      Jan

  7. Hi Jan,
    langsam ist mir das alles sehr Peinlich aber habe eigentlich alles schon versucht das Problem zu lösen.
    Nextcloud bereits 2-mal installiert incl. Ubuntu 22.04 LTS aber komme nicht weiter.

    Mein Problem ist, ich würde gerne per Mail informiert werden, wenn fail2ban eine IP-Sperrt, ohne Mailzusatz klappt es auch, aber wenn ich das so wie in der Anleitung beschrieben wurde mit Mail und den dazugehörigen Dateien mache passiert Folgendes:

    Wenn ich einen Neustart mache und dann Status von Fail2ban anschauen möchte, erhalte ich folgende Meldung:
    2022-06-21 19:35:31,040 fail2ban [1184]: ERROR Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?

    Was auch bedeutet, dass die Sperrung nicht erfolgt und man kann munter weiter versuchen sich einzuloggen.

    Gebe ich nun „service fail2ban restart“ über SSH Zugriff ein wird nun auf einmal die IP gesperrt und ich sehe auch welche IP gesperrt wurde und die Mail wird jetzt auch gesendet.

    Deshalb müsste ich, um nicht auf fail2ban zu verzichten, auf die Mailinformation verzichten. Hat jemand eine Idee woran das liegen kann.

    1. Hi Thomas,

      die Fehlermeldung klingt echt so, als wenn fail2ban abschmieren würde. Kontrollier mal den Status mittels „service fail2ban status“, wenn das Problem nochmal auftritt.
      Das Paket „rsyslog“ hast du installiert, das ist eine beliebte Fehlerquelle.

      Gruß,
      Jan

      1. Hi Jan,

        also das Paket rsyslog habe ich nicht installiert, oder müsste ich das installieren?
        Ich erhalte bei der Eingabe „service fail2ban status“ nach jedem Neustart folgende FM:

        Fail2ban.service – Fail2ban Service
        Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; ventor present: enabled)

        Active: inactive (dead)
        Docs: man:fail2ban (1)

        Vielleicht ist es ein Problem das es als VM im Proxmox läuft da ich diese Probleme bei der vorherigen Installation unter Ubuntu und Exsi nicht hatte.

        Habe mir erst mal so geholfen als Workaround:
        crontab -e
        @reboot service fail2ban restart

        Dann funktioniert es wenigstens aber so ganz verstehen kann ich es nicht.

        Gruß

        Thomas

        1. Hi Thomas,

          ja, rsyslog sollte auf dem System drauf sein. Wenn du Ubuntu 22.04 aber „minimal“ installiert hast, dann fehlt das Paket u.U., was dann dafür sorgt, dass fail2ban nicht so recht mag (aber keine passende Fehlermeldung ausgibt).
          Installier mal das Paket und teste das dann nochmal.

          Gruß,
          Jan

          1. Hi Jan,

            root@Home:~# rsyslogd
            rsyslogd: pidfile ‚/run/rsyslogd.pid‘ and pid 2475 already exist.
            If you want to run multiple instances of rsyslog, you need to specify
            different pid files for them (-i option).
            rsyslogd: run failed with error -3000 (see rsyslog.h or try https://www.rsyslog.com/e/3000 to learn what that number means)

            habe ich gemacht, aber die Fail2ban FM blieb gleich.

            Noch eine Idee…. :-(

          2. Hi Thomas,

            nur noch eines: Er sagt beim fail2ban status „(/lib/systemd/system/fail2ban.service; disabled“
            Versuchs doch mal mit einem systemctl enable fail2ban. Dann sollte er auch nach einem Neustart fail2ban automatisch starten.

            Gruß,
            Jan

          3. Hi Jan,

            Super es geht !!!!!
            Aber keine Ahnung warum es auf Disable stand ich habe die Anleitung 2-mal Schritt für Schritt so ausgeführt wie es auf Deiner Seite beschreiben hast.
            Es ist ja nicht das erste mal das ich die Nextcloud eingerichtet habe und es hat immer der Standard funktioniert nur bei Backup usw. hatte ich meine Probleme. Aber wie gut das Du und die anderen im Forum helfen.

            Vielen Dank und Sorry das ich manchmal mit so was um die Ecke komme.

            Gruß

            Thomas

          4. Hi Thomas,

            ja, fail2ban ist im Normalfall nach der Installation gleich so eingerichtet, dass es bei Systemstart automatisch mitgestartet wird. Warum das bei dir nun anders war ist etwas seltsam. Aber zumindest konnten wir das Problem nun finden und beheben.
            Danke für die Rückmeldung!

            Gruß,
            Jan

  8. Hi Jan,
    Danke für die super Anleitungen die Du uns immer zukommen lässt. Bin jetzt ein halbes Jahr mit dem ganzen Thema Nextcloud beschäftigt und es funktioniert alles perfekt. Da der Server „noch“ auf Version 20.04 läuft, sollte ich ihn „einfach“ updaten oder komplett neu aufsetzen, oder warten?

    Gibt es da eine Einfache Update Anleitung von Dir….in naher Zukunft.

    1. Hi Jens,

      da Ubuntu 20.04 noch lange genug supported wird, besteht hier zunächst einmal kein zwingender Bedarf, das System nun sofort auf 22.04 zu heben.
      Eine komplette Neuinstallation ist hier nicht notwendig. Einfach den normalen (Ubuntu-) Update-Prozess durchlaufen (vorher natürlich Backups machen). Danach wird Nextcloud erst einmal nicht mehr laufen, hier sind dann einige Stellen anzupassen (z.B. heißt der PHP-FPM-Socket nun anders, da unter Ubuntu 22.04 ja PHP 8.1 mit kommt).
      Zumindest hatte ich beim Update von 18.04 auf 22.04 nie Probleme, daher denke ich mal, dass das auch beim Update auf 22.04 so problemlos laufen wird.

      Gruß,
      Jan

  9. Hallo Jan,
    nur eine kurze Frage:
    gibt es eine einfache Möglichkeit, das Datenverzeichnis auf eine neue/andere Festplatte zu verschieben?
    Vielen Dank,
    Jochen

    1. Hi Jochen,

      offiziell wird dies von Nextcloud nicht unterstützt, funktioniert dennoch: NC in den Maintenance-Mode versetzen und Webserver sicherheitshalber stoppen. Dann das Datenverzeichnis umziehen und die entsprechenden Rechte setzen. config.php anpassen und Cloud wieder aus dem Maintenance-Mode heraus holen. Danach sollte dann ein kompletter File-Scan per OCC erfolgen.

      Zuvor würde ich ein Komplett-Backup der Cloud empfehlen.

      Gruß,
      Jan

      1. Achtung, die Tabelle oc.storages enthält danach mehr als einen „local::/“ – Eintrag.
        Das sollte korrigiert werden, um bestehende Links etc. aufrecht zu erhalten!
        Grüße, Carsten

        1. Vielen Dank für eure raschen Antworten!
          Da ich in dem Thema doch noch eher Anfänger bin scheint mir das doch etwas zu komplex zu sein und ich werde es vorläufig lassen…
          Vielleicht bin ich mal eingelesen genug, dass ich das hin bekomme und probiere es dann. ;-)

  10. Kurt Haferl

    Hallo,

    kann ich diese Anleitung auch für ein aktuelles OMV6 als Grundsystem verwenden?

    Würde gerne diese Anleitung verwenden inkl. der Anleitung „Nextcloud Talk mit eigenem Signaling-Server (High Performance Backend)“ damit auch Nextcloud Talk mit mehr als 5 Personen funktioniert!

    1. Hallo Kurt,

      mit OVM kenne ich mich nicht sonderlich aus, aber es basiert ja auf Debian. Also sollte auch die Installation des High Performance Backend funktionieren.

      Gruß,
      Jan

  11. Hi Jan gerade erst diese Super Seite entdeckt,
    Danke für die Anleitung. Es hat direkt alles einwandfrei funktioniert. Wird es auch eine Anleitung für einen Reverse Proxy geben? Ich würde nämlich gerne auch noch eine Searx Instanz in einem Proxmox LXC hosten.

    Viele Grüße

    Momo

    1. Hi Momo,

      schau dir mal am besten diesen Artikel an, hier werden mehrere Möglichkeiten gezeigt, wie man weitere Web-Anwendungen neben NC hosten kann. Lieder ist dies auch immer von der speziellen Web-Anwendung abhängig, wie ein solcher Reverse Proxy auszusehen hat, daher ist der Artikel eher allgemein gehalten.

      Ansonsten gibt es noch diesen (schon recht alten) Artikel, der aber vielleicht auch noch hilfreich sein kann.

      Gruß,
      Jan

  12. Hi Jan,
    vielen Dank für die echt gut gemachten Anleitungen. Diese haben auch mir als erfahrenen ITler oft geholfen und eine Menge Zeit eingespart. Top!
    Was mich jetzt interessieren würde, wören Deine grundsätzlichen Erfahrungen mit Performance und Fein-Tuning maßnahmen. Ich betreibe derzeit meine NC Instanzen auf zwei unterschiedlichen VPS mit einmal 6 CPU/16GB/400MBit und 8CPU/30GB/600MBit. Der High Performance Backend Signaling Server läuft mit Turn/Janus etc. auf dem erstgenannten.
    Dennoch habe ich bei Talk Sessions mit mehr als 6 Teilnehmern immer mal Probleme mit einzelnen Verbindungen. Dann ist hier mal ein Teilnehmer nicht von allen zu hören, ein anderes Mal dauert die Verbindungsaufnahme zum Signaling zu lang. Regelmäßig bekommen alle mal angezeigt, dass die Verbindung zu langsam ist und vermutlich nicht alle Bild/Ton sehen bzw. hören können (damit ist diese Standardmeldung in der NC gemeint). Die Server selbst idlen aber eigentlich nur rum.
    Die eigentlichen php-fpm modifikationen habe ich schon eingestellt. Die NC selbst reagiert zügig, selbst wenn Meetings laufen. Problematisch sind nur die Meetings selbst.
    Macht es vielleicht doch eher Sinn, das HPB mit coturn etc auf demselben VPS laufen zu lassen um die Latenz bei der serververbindung untereinander zu sparen? Hast Du da andere Erfahrungen gemacht?
    Gruß
    Hoschie

    1. Hi,

      ich denke, dass man hier Performance-technisch nicht viele Stellschrauben hat.
      Den coturn lässt man idealerweise eh auf einer separaten Maschine laufen, damit dieser über Port 443 erreichbar ist (wichtig, wenn Clients hinter restriktiven Firewalls sitzen, die nur Traffic auf Port 443 zulassen).

      Wenn beide Server beim gleichen Anbieter stehen, macht es u.U. Sinn, beide in ein VLAN zu packen, dass der Traffic zwischen den Servern dann nicht mehr „über das Internet geht“.

      Ich habe das was anderes in Verdacht: NC Talk arbeitet als MCU, d.h. alle Streams werden vom Server gesammelt und an alle Clients ausgeliefert (mehr Infos dazu gibt es z.B. hier). Das hat u.U. zur Folge, dass wenn ein Client mit einer schlechten Verbindung in eine Konferenz kommt, die ganze Konferenz runter ziehen kann. Hier vielleicht mal darauf achten, ob es immer mit den gleichen Clients zu Problemen kommt.

      Gruß,
      Jan

  13. Hallo Jan,

    gibt es eine ander Webseite als pgtune.leopard.in.ua um die entsprechenden Werte für die Konfiguration von PostgreSQL generieren zu lassen? Ich kann die Webseite nicht aufrufen und as liegt wohl an der Sperrung der TLD aus der Ukraine (.ua) welche ich vorsorglich hinterlgt habe.
    Ich brauche eigentlich nur die Werte für mein System und es hat letzendlich 4 CPU und 8GB RAM.

    Vielen Dank vorab
    Grüße aus Berlin
    Paul

    1. Hi Paul,

      ich habe dir mal die Werte ermittelt:
      # DB Version: 14
      # OS Type: linux
      # DB Type: web
      # Total Memory (RAM): 6 GB
      # CPUs num: 2
      # Data Storage: ssd

      max_connections = 200
      shared_buffers = 1536MB
      effective_cache_size = 4608MB
      maintenance_work_mem = 384MB
      checkpoint_completion_target = 0.9
      wal_buffers = 16MB
      default_statistics_target = 100
      random_page_cost = 1.1
      effective_io_concurrency = 200
      work_mem = 7864kB
      min_wal_size = 1GB
      max_wal_size = 4GB
      max_worker_processes = 2
      max_parallel_workers_per_gather = 1
      max_parallel_workers = 2
      max_parallel_maintenance_workers = 1

      Warum hast du Seiten aus der Ukraine geblockt? In solchen Fällen kannst du aber sicherlich über den Tor-Browser gehen, der kann solche Sperren ganz leicht umgehen.

      Gruß,
      Jan

  14. Hallo Jan,
    ich habe versucht einen Kommentar zu schreiben in der Anleitung für WordPress zu. Der ging aber nicht durch. Ist da vielleicht irgendwo ein Fehler drin?
    Grüße
    Udo

  15. Salue, super Anleitung, mir fehlt nur eines:
    Konfigurationdes Nextcloud High Performance Backend für Dateien (App in Nextcloud)

    1. Hi,

      hier gibt es bereits eine. separate Anleitung, siehe hier.
      Das habe ich bewusst nicht in den allgemeinen Installations-Artikel mit aufgenommen, da sich dieses Backend erst bei größeren Cloud-Instanzen positiv bemerkbar macht. Bei der typischen privaten Cloud wirst du hier keine Performance-Verbesserungen feststellen können.

      Gruß,
      Jan

  16. …und sollte der fail2ban service nicht ueber die syctl enabled werden, damit er nach einem reboot auch wieder da ist?

    1. Hi,

      nach der Installation von fail2ban ist der Service im Normalfall automatisch schon so eingerichtet, dass dieser nach einem Neustasrt des Systems mit startet. War dies bei dir nicht der Fall? Gab es hier evtl. während der Installation einen Fehler, so dass die Installation vielleicht nicht vollständig beendet wurde?

      Gruß,
      Jan

  17. Servus Jan,

    danke für die prima Anleitung. Ich habe die Nextcloud im wesentlichen so aufgesetzt wie in deinem Beispiel beschrieben.
    Bei mir ist aber ein nginx Proxy vorgeschaltet. Macht es dann eigentlich Sinn, Fail2Ban einzurichten? Weil Fail2Ban ja quasi dann meinen Proxy bannen würde und sich dann keiner mehr anmelden könnte.

    Viele Grüße
    Jörg

    PS: Dein BackupScript is ja mal richtig geil. Danke auch dafür!

    1. Hi Jörg,

      wenn fail2ban auf der NC-Maschine installiert werden soll, musst du dafür sorgen, dass er die richtige IP nimmt (die externe IP des Users, nicht die des Proxies). Dafür gibt es z.B. hier eine Anleitung.

      Alternativ kannst du fail2ban auch auf dem Proxy einrichten, damit dieser „an vorderster Front“ bannt. Dieser braucht dann jedoch Zugriff auf das NC-Log. Dies kann man z.B. mit einer NFS-Freigabe regeln, in dem dann das NC-Log geschrieben wird.

      Gruß,
      Jan

  18. Hallo,
    vielen Dank für diese super Anleitung.
    Ich habe allerdings folgendes Problem. Ich erhalte beim Synchronisieren meiner Dateien bei manchen die Fehlermeldung, 403 Forbidden Put: ….
    Ich synchronisiere die Datei mithilfe das Nextcloud Clients.

    Woran kann das liegen?
    Es tritt tatsächlich nur bei manchen Dateien (Fotos und Videos) auf.

    Ich danke dir vielmals.

    1. Hi Luca,

      das ist seltsam, wenn dies nur bei manchen Dateien passiert. Hier würde ich mal das Nextcloud-Log genauer unter die Lupe nehmen, ob hier noch irgendwelche sinnvollen Infos enthalten sind.
      Auch kann ein Blick in die nginx-Logs helfen, vielleicht sind hier ja die Upload-Größen noch zu klein.

      Gruß,
      Jan

      1. Hi Jan,
        vielen Dank für schnelle Rückmeldung. Dann suche ich mal die Log-Dateien durch. Wonach muss ich da Ausschau halten?
        für die nextcloud logs verwende ich:
        nano /var/log/nextcloud/nextcloud.log
        Wie rufe ich die nginx logs ab?

        An der Dateigröße kann es eigentlich nicht liegen. Da teilweise Videos hochgeladen ist, aber keine Fotos.

        Es erscheint über den nextcloud client folgende Fehlermeldung:
        Datei.mp4: Server hat „403 Forbidden“ auf „PUT https://…/remote.php/dav/uploads/…/…/0000000000000002″ geantwortet.
        Danke für deine Mithilfe.

          1. Hi Jan,

            ich habe nun die nginx-Log ausgelesen und da tauchen einige Fehlermeldungen auf.
            Hier ein kleiner Auszug davon:
            2022/08/08 17:10:46 [error] 2546534#2546534: *2550 Request body limit is marked to reject the request, client: XXX, server: XXX, request:<"PUT /remote.php/dav/uploads/benutzer/159876481/0000000000000001 HTTP/1.1", host: "XXX"
            2022/08/08 17:11:05 [error] 2546534#2546534: *2836 connect() failed (111: Connection refused) while connecting to upstream, client: XXX, server: XXX, request: "GET /push/ws HTTP/1.1", upstream: "http://127.0.0.1:7867/ws&quot;, host: "XXX"

            Ich habe auch versucht die Dateien übers Handy mittels Foldersync zu synchronisieren und erhalte folgende Fehlermeldung:
            2022/08/08 17:18:30 [error] 2546534#2546534: *2888 Request body limit is marked to reject the request, client: XXX, server: XXX, request: "PUT / /remote.php/dav/files/XXX/Pfad/Fotos/IMG.jpg HTTP/2.0", host: "XXX"
            2022/08/08 17:18:34 [warn] 2546534#2546534: *2888 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0037149590, client: XXX request: "PUT /remote.php/dav/files/benutzer/Pfad/IMG.jpg HTTP/2.0", host: "XXX"

            Kannst du etwas mit diesen Fehlermeldungen anfangen?

            Ich weiß auch nicht, warum dieser Link so aussieht. Ich habe nichts besonderes eingestellt. Also keinen anonymen Upload Ordner.

            Ich freue mich wieder auf deine Rückmeldung und bin gespannt, was du dazu sagst.

            Viele Grüße

            Luca

          2. Hi Luca,

            übersetzt heißt die Meldung, dass die hochzuladende Datei zu groß war. Hier einfach mal die max. Upload-Größen checken, die per nginx konfiguriert sind.

            Es kann aber auch an der Client-Anwendung liegen, das legt zumindest die Formulierung der Fehlermeldung nahe. Kannst du dies verifizieren, d.h. treten solche Fehler mit allen Clients auf, oder nur mit FolderSync?

            Gruß,
            Jan

          3. Hallo Jan,

            wie checke ich denn die Upload Größen im nginx?
            Ich kenne nur die Upload Größen im PHP. Und da betragen die 10 GB.

            Es treten die Fehler mit dem nextcloud client auf dem PC und mit Foldersync auf.
            und immer wieder erhalte ich die oben beschriebenen Fehlermeldungen. Oder gibt es eine Liste im nginx, wo fehlerhafte Dateien landen?
            So ganz kann ich mir das auch noch nicht erklären.

            oder könnte man den nginx einmal zurücksetzen?

            Ich danke dir ganz herzlich für deine Mithilfe.

  19. Hallo, Tut mir leid, aber mir der Anleitung hat es nicht geklappt. Viele Stunden vergeudet für nichts. Bitte überdenken Sie mal einige Schritte diese verständlicher/nachvollziehbarer darzustellen… für Newbies nicht zu empfehlen

    1. Hallo,

      danke für das Feedback.
      Welche Teile des Artikels sind denn hier nicht gut verständlich und/oder nachvollziehbar? Wenn es hier konkrete Punkte gibt, dann kann ich diese evtl. im Artikel noch etwas verbessern oder leichter verständlich formulieren.

      Gruß,
      Jan

    2. Hallo RISK, mir hat diese Anleitung schon mehrfach gute Dienste geleistet, daher kann ich deine Kritik, vor allem in dieser pauschalen Form, in keiner Weise nachvollziehen. Bitte gib doch konkrete Fehlerbeschreibungen und nenne die Schritte, die für dich nicht verständlich waren.

  20. Hallo,
    super Anleitung! Habe mir Teile ausgeliehen und auf mein Netzwerk angepasst.

    Ich habe eine Frage zu Fail2Ban:
    Ich nutze Opnsense mit Haproxy & HTTPS Offloading und leider wird bei Fail2Ban nicht die IP des Clients, sondern der Opnsense blockiert. Das führt dazu, dass ALLE User ausgesperrt werden…
    Hat jemand eine Idee, woran das liegen kann? Evtl. die „Overwrite“-Parameter in der NC-Config?

    1. Hi,

      die OpnSense bzw. der Proxy müssen die echte IP des Clients an die NC-Maschine weitergeben. Ich habe dazu hier eine Anleitung gefunden, wie man dies realisieren kann. Ist zwar schon etwas älter, sollte aber im Grunde noch funktionieren.

      Gruß,
      Jan

    2. Erstmal Danke an Jan für die tolle Anleitung.

      Ich nutze Nextcloud in einem docker-compose Set-Up.
      Als erstes muss man zuschauen, dass die REMOTE_IPs in der nextcloud.log erscheinen und nicht die IP des Proxy. Ansonsten wird der Proxy gebannt und damit alle User. Hier mal nach trusted_domains und trusted_proxies in der Nextcloud Doku schauen/googeln für die PHP config.php. In trusted_domains habe ich meine Nextcloud Domäne angegeben (cloud.mydomain.tld) und in trusted_proxies die IP des Proxy, die den Traffic entgegen nimmt und weiterleitet.
      Dies habe ich schon geschafft und die korrekten IPs werden angezeigt und gebannt. Jedoch kann ich mich dann trotzdem noch anmelden. Ich denke, ich muss hier eine gesonderte action.conf anlegen müssen.
      Gestern habe ich das gleiche Szenario mit Mailu (Mailu und Nextcloud hinter dem selben Proxy) erfolgreich umgesetzt. Ggf. probiere ich mal diese action auf für Nextcloud.
      /etc/fail2ban/action.d/docker-action.conf (https://mailu.io/1.9/faq.html#do-you-support-fail2ban). Ggf. hilft Dir dies auch weiter.

      Für mich eine kleine Frage: Welche action wird denn hier in dieser Beschreibung verwendet? Hier ist ja keine explizit angegeben.

      1. Also bei mir funktioniert es nun :-)
        config.php:

        ‚trusted_domains‘ =>
        array (
        0 => ‚cloud.mydomain.tld‘,
        ),
        ‚trusted_proxies‘ =>
        array (
        0 => ‚MY_PROXY_IP‘,
        ),
        ‚overwriteprotocol‘ => ‚https‘,
        ‚logtimezone‘ => ‚Europe/Berlin‘,
        ‚forwarded_for_headers‘ =>
        array (
        0 => ‚HTTP_X_FORWARDED_FOR‘,
        ),

        Fail2ban nach Anleitung wie hier von Jan.
        Zudem „/etc/fail2ban/action.d/docker-action.conf“ anlegen wie hier https://mailu.io/1.9/faq.html#do-you-support-fail2ban dokumentiert.
        Und Eintrag in /etc/fail2ban/jail.local in section [nextcloud] :
        logpath…
        action = docker-action

        Dann hat es auf Anhieb funktioniert.

  21. Hallöchen,
    seit ein paar Tagen scheinen die Bowser keine selbstsignierten Zertifikate von Letsencrypt mehr anzuerkennen.

    Habt ihr das selbe Problem?
    Browser-Meldung (getestet auf InternetExplorer, Mozilla, Chrome)
    „xxx.spdns.org verwendet ein ungültiges Sicherheitszertifikat.
    Dem Zertifikat wird nicht vertraut, weil es vom Aussteller selbst signiert wurde.
    Fehlercode: MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT

    Eine Erneuerung der Zertis mit acme.sh … –force bringt nichts.

    1. Hi,

      also mir sind da keine Probleme bekannt. Wenn ich auf die Website gehe, die du angegeben hast, dann ist das Zertifikat auch gültig (oder ist hier eine andere Domain betroffen)?

      Gruß,
      Jan

  22. Hallo,

    erstmal vielen Dank für Deine lehrreiche Anleitung.
    Hier wird mir bei der Installation einiges klarer.

    Ich habe allerdings ein Problem.
    Ich komme nur bis zum Punkt:
    Nextcloud-Setup
    Ich kann also nicht die Cloud-Domain im Browser aufrufen, um mit der Konfiguration fortzufahren.

    Ich frage mich, was ich übersehen habe?
    Gibt es klassische Fehler, die gemacht werden?

    Ich muss dazu sagen, dass ich ein ds-lite Opfer bin :-)
    Diesen Missstand habe ich aber immer mit einem reverse-SSH-Tunnel zu einem gemieteten vServer mit fester IPv4 Adresse beheben können.

    Bisher habe ich Nextcloud immer auf Debian-Basis installiert.
    Dabei bin ich der Anleitung von c-rieger.de gefolgt. Das klappt mit besagtem Tunnel auch problemlos.
    Oder gibt es bei Ubuntu ein Sicherheitsfeature, das solche Tunnel nicht zulässt bzw. blockiert?
    (Liegt vielleicht hier das Problem?)

    Ich möchte nun einmal Deine Anleitung probieren, da es wohl Probleme gibt im Zusammenhang mit MariaDB und einer Proxmox VM hinsichtlich der backups; siehe:
    https://jira.mariadb.org/browse/MDEV-27196

    Vor allem deswegen will ich die Variante PostgreSQL nutzen.

    Für einen Tipp wäre ich dankbar.

  23. Hallo,

    nach einem wiederholten Installationsversuch ist die Installation und Konfiguration nach Deiner Anleitung gelungen – auch mit der „reverse-SSH-Tunnel-Krücke“ (wegen ds-lite).
    Einige Flüchtigkeitsfehler hatten sich doch bei mir vorher eingeschlichen; z.B. im Punkt 4.3:

    nano /etc/nginx/conf.d/nextcloud.meinedomain.de.conf

    Klar, beim Anlegen dieser Datei muss die eigene URL angeben werden.
    Wenn man aber einmal im „copy&paste-Trott“ ist, kann man dies leicht übersehen :-)

    Nichtsdestotrotz ist die Anleitung natürlich super!
    Vielleicht kann man die individuellen Anpassungen, die vorgenommen werden müssen farblich hervorheben?

    Vielen Dank nochmals tolle Anleitung!

    1. Hi,

      ok, dann konntest du das Problem ja inzwischen lösen.
      Ich habe mal Hinweise bzgl. des anzupassenden Domain-Names und der IP-Adresse in den Artikel an den jeweiligen Stellen mit aufgenommen. Danke für den Hinweis!

      Gruß,
      Jan

      1. Super, vielen Dank :-)
        Kann man die anzupassenden Einträge vielleicht farbig (z.B. rot) hervorheben?
        Dann ist es wirklich idiotensicher :-D
        (oder wäre das zu aufwendig?)

        Ich weiß es aus eigener Erfahrung.
        Was einem selber völlig klar und selbstverständlich ist, muss einem anderen überhaupt nicht einleuchten ;)

        Auf der anderen Seite: Wenn man einmal Deine Anleitung erfolgreich durchgeführt hat, kennt man die Stellen, auf die man achten und anpassen muss.

        1. Hi,

          ich hallte in alten Artikeln Dinge in Code-Abschnitten zeilenweise markiert. Jedoch ändern sich diese Code-Abschnitte hin und wieder (v.a. vHosts, weil NC beispielsweise weitere Anforderungen an den vHost hinzugefügt hat). In diesem Fall „verrutschen“ die markierten Zeilen dann schnell mal, was dann wieder verwirrender ist.
          Daher habe ich das mal im Fließtext geschrieben.

          Gruß,
          Jan

  24. Hallo, hat jemand Erfahrung mit Netcup in Verbindung mit All-Inkl.
    Domain bei All-Inkl (Record A) und Root Server bei Netcup.

    Gibt es hier Probleme?
    Vielen Dank
    Gruß Hans

    1. Hi Hans,

      generell ist es kein Problem, wenn A-Record und das „Ziel“ bei unterschiedlichen Anbietern liegt.
      All-Inkl auf Netcup machen ich aber selbst auch, also: ja.

      Gruß,
      Jan

  25. Ich habe ganz gute Erfahrungen mit ionos.de gemacht.
    Die sind ganz günstig. Für meinen vServer mit fester IPv4 Adresse zahle ich dauerhaft 1,-€ pro Monat (mittlerweile haben die auf 2,-€ erhöht).
    Damit habe ich als ds-lite Opfer und reverse SSH-Tunnel eine feste IPv4.

      1. Falls es für jemanden interessant ist, hier steht, wie es geht mit dem reverse-SSH-Tunnel:
        https://www.heise.de/select/ct/2018/2/1515452696423264
        c’t 2/2018 S. 138

        Und das ist die Kurzanleitung in Stichpunkten:

        Auf dem vServer
        • # nano /etc/ssh/sshd_config
        > ### relevante Einträge
        PermitRootLogin without-password # hier darf nicht no stehen
        GatewayPorts yes
        ClientAliveInterval 10
        ClientAliveCountMax 3

        dann:
        # cd /root/
        [# mkdir .ssh] # existiert hier bereits
        # ssh-keygen -t ed25519 -N „“ -f /root/.ssh/example-root
        # cd /root/.ssh
        # cp example-root.pub authorized_keys
        # nano /root/.ssh/authorized_keys
        > ### ganz am Anfang der Schlüsselzeile, also als erstes:
        command=“/bin/false“ ssh-ed…
        # chmod 600 /root/.ssh/authorized_keys

        – Die Datei /root/.ssh/example-root muss zum Heimserver über die IPv6 Adresse kopiert
        werden;
        – auf dem Router muss der Zugang zum Gerät frei gegeben werden:
        # ip a #mittlere inet 6 Adresse, also die Adresse vor: […] scope global dynamic mngtmpaddr
        – ufw dazu deaktivieren (falls aktiviert): sudo ufw disable

        # scp -P xxxx /root/.ssh/example-root user@[2a00:aaaa:bbbb:cccc:dddd:eeee:ffff:ggg]:/home/user/
        – xxxxx = Port, falls man einen anderen ssh Port gewählt hat als 22
        – 2a00:aaaa:bbbb:cccc:dddd:eeee:ffff:ggg = IPv6-Adresse des Heimservers

        Auf dem Heimserver
        • # mv /home/user/example-root /home/user/.ssh/
        • # chmod 600 /home/user/.ssh/example-root

        Auf dem Heimserver > Aufbau des Tunnels:
        temporärer Versuch:
        – xxxxx = Port, falls man einen anderen ssh Port gewählt hat als 22
        – aa.bbb.ccc.ddd = feste IP-Adresse des vServers

        vServer neu starten
        Auf Heimserver einloggen

        Die Ports links (443) müssen auf dem vServer frei gegeben werden (firewall).
        • # ssh -R 443:hostname:443 -i /home/user/.ssh/example-root -N ‚root@aa.bbb.ccc.ddd‘ ‚-p xxxx‘
        – Den einzutragenden hostname bekommt heraus mit dem Befehl: # hostname -f

        Den Tunnel automatisch starten:
        Auf dem Heimserver
        # apt install autossh
        # nano /etc/systemd/system/sshtunnel.service
        >
        [Unit]
        Description=Keeps a sshtunnel open
        After=network-online.target ssh.service

        [Service]
        User=root
        Environment=“AUTOSSH_PORT=0″
        Environment=“AUTOSSH_GATETIME=0″
        RestartSec=30
        Restart=always
        ExecStart=/usr/bin/autossh -M 0 -R 80:hostname:80 -R 443:hostname:443 -i /home/user/.ssh/example-root -o ServerAliveInterval=12 -o ServerAliveCountMax=3 -N ‚root@aa.bbb.ccc.ddd‘ ‚-p xxxxx‘
        ExecStop=killall -s KILL autossh
        TimeoutStopSec=10

        [Install]
        WantedBy=multi-user.target

        # sudo systemctl start sshtunnel.service
        # sudo systemctl status sshtunnel.service
        # sudo systemctl enable sshtunnel.service

        Wenn alles geklappt hat, dann hat der Heimserver trotz ds-lite eine feste IPv4 Adresse für wenige Euro im Monat. Einen teuren Business-Zugang kann man sich dann sparen, wenn das der einzige Anwendungsgrund ist. Wobei der natürlich immer besser ist (aber eben auch viel teurer)

          1. Ja, sieht kompliziert aus, ist aber schnell eingrichtet.
            Ich sehe gerade nur beim Durchlesen, dass sich kleine Kopierfehler eingeschlichen haben. Die Anführungsteichen (auch die mit einem Strich), sind immer oben :-)

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht.