DecaTec https://decatec.de Home-Server | Linux | Nextcloud | Raspberry Pi | Programmierung | Fotografie Tue, 28 Jul 2020 09:55:31 +0000 de-DE hourly 1 Nextcloud Zwei-Faktor-Authentifizierung mit Nitrokey FIDO2 https://decatec.de/home-server/nextcloud-zwei-faktor-authentifizierung-mit-nitrokey-fido2/ https://decatec.de/home-server/nextcloud-zwei-faktor-authentifizierung-mit-nitrokey-fido2/#comments Wed, 22 Jul 2020 15:14:28 +0000 https://decatec.de/?p=6867 Nextcloud Nitrokey Logo

Für die eigene Nextcloud spielt das Thema Sicherheit eine große Rolle, da in einer Cloud meistens auch sensible Daten gespeichert sind. Dass man für solche Dienste stets sichere Passwörter nutzen sollte, versteht sich von selbst. Dennoch kann ein Passwort noch so sicher sein, es bleibt der einzige „Faktor“ bei der Authentifizierung. Sollte dieses Passwort abhanden kommen, ist der Zugang zur Cloud nicht mehr als sicher zu betrachten.

Hier kommt das Konzept der Zwei-Faktor-Authentifizierung zum tragen: Neben Benutzername/Passwort wird hier ein zweiter Faktor für die Anmeldung benötigt. Nextcloud unterstützt mittlerweile viele Varianten der Zwei-Faktor-Authentifizierung. Das bekannteste Verfahren ist hier sicherlich TOTP – dabei wird z.B. auf dem Smartphone lediglich eine TOTP-App (beispielsweise andOTP) benötigt. Dies macht die Anmeldung schon einmal sicherer, aber dennoch handelt es sich beim Smartphone um ein Gerät, welches ebenfalls kompromittiert werden kann.

Am sichersten ist hier ein Gerät, welches ausschließlich für die Zwei-Faktor-Authentifizierung genutzt wird. Ich habe mir daher mal die Authentifizierung mittels des Nitrokey FIDO2 näher angeschaut.

Nitrokey FIDO2 – Hardware

Beim Nitrokey FIDO2 handelt es sich um ein USB-Device (USB Typ A), welches für die Zwei-Faktor-Authentifizierung genutzt werden kann. Auch wenn das Aussehen an einen USB-Stick erinnert, können jedoch keine Daten auf dem Nitrokey gespeichert werden.

Nitrokey FIDO2

Nitrokey FIDO2

Nitrokey FIDO2 als zweiten Faktor bei Nextcloud hinzufügen

Für die Nutzung eines Hardware-Devices als zweiten Faktor benötigt man zunächst einmal zwei zusätzliche PHP-Pakete, die auf dem Nextcloud-Server installiert sein sollten. Wenn dies noch nicht geschehen ist, holen wir dies nun nach:

apt update && apt install php-gmp php-bcmath

Als nächstes muss nun in der Nextcloud die App Two-Factor Webauthn aus dem Nextcloud App Store heruntergeladen und aktiviert werden. Hiermit kann als zweiter Faktor WebAuthn genutzt werden.

Die App Two-Factor Webauthn im Nextcloud App Store

Die App Two-Factor Webauthn im Nextcloud App Store

Anschließend gibt es in den persönlichen Einstellungen unter Sicherheit eine weitere Option Webauthn Devices. Hier einfach auf den Button Add Webauthn device klicken, den Nitrokey einstecken und einen Namen für das Gerät vergeben.

Nitrokey als WebAuthn Device hinzufügen

Nitrokey als WebAuthn Device hinzufügen

Zum Test nun einfach einmal von der Cloud ab- und nochmal neu anmelden. Hier sollte dann nach Eingabe von User/Passwort die entsprechende Option für den zweiten Faktor angeboten werden.

Nextcloud: Login mit Nitrokey/WebAuthn

Nextcloud: Login mit Nitrokey/WebAuthn

Hier wieder den Nitrokey einstecken, kurz berühren und der Login sollte damit erfolgreich abgeschlossen sein.

Das ganze funktioniert auch analog mit der App Two-Factor U2F. Damit kann als zweiter Faktor U2F verwendet werden. WebAuthn ist allerdings das modernere Verfahren, daher gebe ich WebAuthn den Vorrang.

Hinweis: Wenn die Zwei-Faktor-Authentifizierung aktiviert wurde, ist es für viele Clients (z.B. Nextcloud Desktop-Client) keine direkte Anmeldung per Benutzername/Passwort möglich. In diesem Fall muss man hier sog. App-Passwörter generieren, die dann bei der Anmeldung der Clients genutzt werden können. Dies erledigt man in den persönlichen Einstellungen unter Sicherheit (Geräte & Sitzungen).

Ab Nextcloud 19: Passwortlose Anmeldung

Nextcloud unterstützt ab Version 19 auch eine rein passwortlose Authentifizierung. Diese wird ebenfalls unter den persönlichen Einstellungen im Bereich Sicherheit aktiviert. Der Ablauf zum Hinzufügen des Nitrokeys ist dabei prinzipiell der gleiche wie bei der Zwei-Faktor-Authentifizierung.

Nitrokey für passwortlose Authentifizierung hinzufügen

Nitrokey für passwortlose Authentifizierung hinzufügen

Nach der Einrichtung kann im Anmeldebildschirm der Cloud neben der klassischen Eingabe von Benutzername und Passwort die Option Mit einem Gerät anmelden gewählt werden.

Nextcloud: Anmeldung mit einem Gerät

Nextcloud: Anmeldung mit einem Gerät

Hier reicht dann die Eingabe des Benutzernamens und das anschließende Bestätigen des Logins mittels des Nitrokeys.

Zusätzlich kann natürlich noch ein beliebiger zweiter Faktor für die Authentifizierung genutzt werden.

Nitrokey FIDO2 unter Linux

Unter Linux kann es passieren, dass der Nitrokey nicht sofort erkannt wird – beim Einstecken passiert hier einfach nichts. In diesem Fall muss nur ein kleiner Schritt durchgeführt werden, damit der Nitrokey auch unter Linux verwendet werden kann:

wget https://www.nitrokey.com/sites/default/files/41-nitrokey.rules
sudo mv 41-nitrokey.rules /etc/udev/rules.d/

Anschließend sollte der Nitrokey einwandfrei funktionieren.

Firmware-Updates

Der Nitrokey FIDO2 unterstützt ebenfalls Firmware-Updates. Dazu muss der Stick lediglich eingesteckt werden und die Firmware-Update-Seite mit einem Browser aufgerufen werden. Nun einfach den Anweisungen folgen, falls ein Firmware-Update verfügbar ist, wird dieses automatisch heruntergeladen und installiert.

Nitrokey FIDO2: Firmware-Update im Browser

Nitrokey FIDO2: Firmware-Update im Browser

Weitere Einsatzgebiete

Neben der Anmeldung an Nextcloud kann der Nitrokey auch für weitere Anmeldungen genutzt werden. Viele Webdienste unterstützen mittlerweile die Anmeldung per WebAuthn. Dazu gehören u.a.:

Auf dongleauth.info gibt es eine gute Zusammenstellung, welche Dienste bereits mit dem Nitrokey verwendet werden können.

Fazit

Der Nitrokey FIDO2 ist in ein paar Minuten in Nextcloud als zweiter Faktor bei der Authentifizierung eingerichtet und kann anschließend auf jedem Gerät genutzt werden – und ja: sogar am Smartphone.

Links

]]>
https://decatec.de/home-server/nextcloud-zwei-faktor-authentifizierung-mit-nitrokey-fido2/feed/ 4
Nextcloud Talk mit eigenem Signaling-Server (High Performance Backend) https://decatec.de/home-server/nextcloud-talk-mit-eigenem-signaling-server-high-performance-backend/ https://decatec.de/home-server/nextcloud-talk-mit-eigenem-signaling-server-high-performance-backend/#comments Mon, 06 Jul 2020 14:03:49 +0000 https://decatec.de/?p=6817 Nextcloud Talk Logo

Nextcloud unterstützt mit Nextcloud Talk schon seit längerem Video-Konferenzen. Zu diesem Thema gab es hier im Blog bereits einen Artikel, wie man Nextcloud Talk mit eigenem TURN-Server (coturn) aufsetzen kann: Nextcloud Talk mit eigenem TURN-Server (coturn).

Leider hatte die Lösung einen Haken: Video-Chats mit mehr als vier bis fünf Personen waren hier nicht möglich. Nextcloud hat hier immer ab einer gewissen Teilnehmerzahl eine Warnung ausgegeben und man konnte darauf warten, dass die Verbindung irgendwann abbricht.

Dennoch gab es hier Potential nach oben: Mit dem sog. High Performance Backend für Nextcloud sind Video-Konferenzen mit sehr viel mehr Teilnehmern möglich. Hier benötigte man jedoch immer eine Nextcloud Enterprise-Subscription, die sich aber für die eigene Familien-Cloud preislich nicht gelohnt hat.

Nun hat sich Nextcloud mit seinem Partner Struktur AG dazu entschlossen, diese Vorteile an die Community weiterzugeben. Ab sofort ist der Teil des High Performance Backends, welche für Talk interessant ist, als Open Source verfügbar (siehe Nextcloud Blog). Genauer gesagt handelt es sich dabei um den sog. Signaling Server.

Die Installation ist aber nicht gerade trivial, so dass es hier bisher noch sehr wenige Anleitungen gibt. Daher soll dieser Artikel nun die Installation und Konfiguration des Signaling Servers und dessen Einbindung in Nextcloud beschreiben.

Update-Historie (letztes Update: 28.07.2020)
  • 28.07.2020:
    • Empfehlung für Ubuntu Server 20.04, Hinweise für ältere Versionen ergänzt.
  • 14.07.2020:
    • STUN-Server zur Janus-Konfiguration hinzugefügt.

Voraussetzungen

Für die Installation eines eigenen Signaling Server gelten folgende Voraussetzungen:

Server

Die Hardware, auf dem der Signaling Server betrieben wird, sollte folgende Voraussetzungen erfüllen:

  • 4 CPU Cores
  • 16 GB RAM
  • 1 GBit/s Netzwerk (Up und Down)

Auf schwächerer Hardware lässt sich der Signaling Server auch betreiben, hier kann es allerdings zu Einbußen bzgl. Performance und Teilnehmerzahl kommen.

Betriebssystem/Distribution

Ich verwende für diesen Artikel Ubuntu Server 20.04 LTS. Für ältere Versionen der Distribution (z.B. 18.04) ist das gezeigte Vorgehen so nicht umsetzbar, da die in den Paketquellen enthaltene Version von Janus zu alt ist. Hier muss man u.U. auf Backports von Janus aufsetzen.

Daher empfehle ich für einen Signaling Sever den einsatz vom Ubtuntu Server 20.04 LTS.

Software/Webserver/Domain

Für diesen Artikel setze ich ebenfalls folgendes Voraus:

Beispielhaft nutze ich in diesem Artikel die Domain signaling.meinedomain.de für den Signaling Server. Der verwendete TURN-Server (coturn) ist unter turn.meinedomain.de erreichbar. Nextcloud selbst hat die fiktive URL nextcloud.meinedomain.de.

Installation des Signaling Servers

Der Signaling Server (bzw. das sog. High Performance Backend für Nextcloud) besteht aus mehreren Komponenten:

Keys erzeugen

Für die Einrichtung der verschiedenen Komponenten werden unterschiedliche Keys benötigt, die wir hier im Vorfeld generieren können:

  • Janus API-Key:
    openssl rand -base64 16
  • Hash-Key:
    openssl rand -hex 16
  • Block-Key:
    openssl rand -hex 16
  • Nextcloud Secret Key:
    openssl rand -hex 16

Am besten man erstellt diese Keys und speichert sich diese irgendwo sicher ab.

Im weiteren Verlauf dieses Artikels wird auf diese Keys immer in spitzen Klammern verwiesen (z.B. <Janus API-Key>).

Daneben wird noch der Turn-Server-Key benötigt, der bei der Einrichtung von coturn vergeben wird (Variable static-auth-secret in der Datei /etc/turnserver.conf). Diesen sollte man nun auch nochmal raus suchen und mit den anderen Keys notieren.

libSRTP

Janus benötigt eine recht aktuelle Version des Pakets libsrtp2-1. Die in den Ubuntu Paketquellen enthaltene Version ist hier leider zu alt, so dass man hier eine manuelle Installation per DEB-Datei (aus dem kommenden Ubuntu-Release) vornehmen muss:

cd /tmp
wget http://de.archive.ubuntu.com/ubuntu/pool/universe/libs/libsrtp2/libsrtp2-1_2.3.0-4_amd64.deb
apt install /tmp/libsrtp2-1_2.3.0-4_amd64.deb
rm libsrtp2-1_2.3.0-4_amd64.deb

Unter Debian kann man hier eine aktuelle Version des Paketes herunter laden: http://ftp.de.debian.org/debian/pool/main/libs/libsrtp2/libsrtp2-1_2.3.0-4_amd64.deb

Signaling Server

Als nächstes kann ich schon der Signaling Server installiert werden. Hier gibt es keine fertigen Pakete, so dass man sich die Software selbst bauen muss:

apt install golang-go
cd /etc/
git clone https://github.com/strukturag/nextcloud-spreed-signaling.git
cd /etc/nextcloud-spreed-signaling
make build

Nach ein paar Augenblicken sollte der Build durchgelaufen sein.

Anschließend muss die Konfigurations-Datei angepasst werden:

cd /etc/nextcloud-spreed-signaling
cp server.conf.in server.conf
nano server.conf

Die Datei ist in verschiedene Sektionen aufgeteilt:

  • Sektion „http“:
    • Hier wird die IP und der Port angegeben (diese Zeile muss daher einfach einkommentiert werden):
      listen = 127.0.0.1:8080
  • Sektion „sessions“:
    • Angabe des Hash-Keys (s.o.):
      hashkey = <Hash-Key>
    • Angabe des Block-Keys (s.o.):
      blockkey = <Block-Key>
  • Sektion „backend“:
    • Hier wird die URL der Cloud-Instanz angegeben, so dass nur diese auf den Signaling Server zugreifen kann:
      allowed = nextcloud.meinedomain.de
    • Der Secret-Key für Nextcloud wird hier ebenfalls angegeben (s.o.):
      secret = <Nextcloud Secret Key>
  • Sektion „mcu“:
    • Hier wird die Verbindung zum Websocket von Janus festgelegt:
      url = ws://127.0.0.1:8188
  • Sektion „turn“:
    • Hinzufügen des Janus API-Keys:
      apikey = <Janus API-Key>
    • Hinzufügen des Secret Keys vom TURN-Server (coturn):
      secret = <Turn-Server-Key>
    • Angabe der TURN-Server-URL:
      servers = turn:turn.meinedomain.de:5349?transport=udp,turn:turn.meinedomain.de:5349?transport=tcp

bevor wir den Signaling Server nun starten können, müssen die restlichen Programme installiert werden.

Janus

Die Installation erfolgt hier über einen Befehl:

apt install janus

Anschließend müssen hier ebenfalls die Konfigurations-Dateien bearbeitet werden:

nano /etc/janus/janus.jcfg

Hier konfigurieren wir den STUN-Server (coturn), aktivieren die Option „Full Trickle“ und tragen den API-Key ein:

# ...
stun_server = "turn.meinedomain.de"
stun_port = 5349
# ...
full_trickle = true
# ...
turn_rest_api_key = "<Janus API-Key>"
# ...

Anschließend wird Janus so konfiguriert, dass es nur lokal (d.h. nicht über das Netzwerk) angesprochen werden kann:

nano /etc/janus/janus.transport.http.jcfg

Das Interface wird dabei auf „lo“ gesetzt:

# ...
interface = "lo" 
# ...

Das gleiche wird auch für den Websocket gemacht:

nano /etc/janus/janus.transport.websockets.jcfg

# ...
ws_interface = "lo"
# ...

NATS

Ebenfalls benötigt wird ein NATS-Server. Diesen Installieren wir der Einfachheit halber mittels Docker:

docker pull nats:latest
docker run --name=NATSSERVER -d -p 4222:4222 -ti --restart=always nats:latest

Hier muss weiter nichts konfiguriert werden, der Docker-Cointainer wird nur so angelegt, dass dieser beim Systemstart automatisch mit gestartet wird.

nginx

Nun muss nich dafür gesorgt werden, dass der Signaling Server durch nginx (oder einen anderen Webserver) erreichbar ist. Hierzu bearbeiten wir den virtuellen Host, der die Signaling-Domain bedient:

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

Hier werden nun der Upstream zu Signaling Server selbst und zwei location-Blöcke hinzugefügt. Die erweiterte Konfiguration des vHosts (z.B. SSL- bzw. Header-Konfiguration) wird an dieser Stelle nicht weiter behandelt.

upstream signaling {
    server 127.0.0.1:8080;
}

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

        # SSL and header configuration omitted

        location /standalone-signaling/ {
                proxy_pass http://signaling/;
                proxy_http_version 1.1;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /standalone-signaling/spreed {
                proxy_pass http://signaling/spreed;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Nach einem Neustart von nginx ist dieser Teil auch abgeschlossen:

service nginx restart

Starten des Signaling Servers

Nun kommt der spannende Teil: Wir starten zum ersten mal den Signaling Server!
Dazu wird erst einmal der Janus-Dienst neu gestartet:

service janus restart

Anschließend wird das Programm für einen ersten Test im Vordergrund aufgerufen:

cd /etc/nextcloud-spreed-signaling
./bin/signaling --config server.conf

Hier wird u.U. sehr viel Output erzeugt, aber es sollten keine Fehler darunter zu finden sein.

Signaling Server als Systemdienst

Damit der Signaling Server nicht jedes Mal über die Konsole im Vordergrund gestartet werden muss, sollte dieser als Systemdienst installiert werden. Dazu stoppen wir erst einmal die Konsolen-Instanz.

Zunächst legen wir uns einen speziellen User für den Signaling Server an:

groupadd signaling
useradd --system --gid signaling --shell /usr/sbin/nologin --comment "Standalone signaling server for Nextcloud Talk." signaling

Anschließend wird die Konfigurationsdatei des Servers noch an einen anderen Ort kopiert (damit diese z.B. bei Update nicht überschrieben wird). Ebenso werden die entsprechenden Berechtigungen gesetzt:

mkdir -p /etc/signaling
cp server.conf /etc/signaling/server.conf
chmod 600 /etc/signaling/server.conf
chown signaling: /etc/signaling/server.conf

Nun editieren wir noch die Datei für den Systemdienst:

nano dist/init/systemd/signaling.service

Folgendes ist hier einzutragen:

[Unit]
Description=Nextcloud Talk signaling server

[Service]
ExecStart=/etc/nextcloud-spreed-signaling/bin/signaling --config /etc/signaling/server.conf
User=signaling
Group=signaling
Restart=on-failure

[Install]
WantedBy=multi-user.target

Der Dienst wird im System registriert und aktiviert:

cp dist/init/systemd/signaling.service /etc/systemd/system/signaling.service
systemctl enable signaling.service
systemctl start signaling.service

Anschließend wir der Signaling Server immer beim Systemstart mit geladen.

Einbinden des Signaling Servers in Nextcloud

Die Konsole packen wir erst einmal bei Seite und hinterlegen den neuen Signaling Server in der Nextcloud-Instanz. Dies geschieht unter Einstellungen > Talk. Ganz unten wird nun ein Signaling Server mit dem Plus-Zeichen hinzugefügt. Die Domain lautet hierfür https://signaling.meinedomain.de/standalone-signaling. Unter Gemeinsames Geheimnis wird nun der Nextcloud Secret Key hinterlegt, den wir ganz am Anfang erzeugt haben:

Hinterlegen des Signaling Servers in der Nextcloud Talk Konfiguration

Hinterlegen des Signaling Servers in der Nextcloud Talk Konfiguration

Die Option SSL Zertifikat überprüfen sollte hier aktiviert werden, wenn der Signaling Server über ein valides Zertifikat verfügt (z.B. Let’s Encrypt).

Anschließend sollte man Talk mit einer Videokonferenz testen. Dazu fragt man am besten einen anderen Cloud-User um Hilfe, oder testet dies einfach über eine Talk-Konferenz mit mehreren Endgeräten (z.B. PC, Notebook, Handy, etc.). Wenn hier Chat- und Videofunktionen gegeben sind, läuft der Signaling Server korrekt.

Benchmark/Test

Für den Signaling Server gibt es ebenfalls einen mitgelieferten Client, mit dem man den Server testen bzw. einen Benchmark ausführen kann.

Dazu muss der Client erst einmal gebaut werden:

cd /etc/nextcloud-spreed-signaling
make client

Als nächstes muss die Server-Konfiguration noch geändert werden, damit Verbindungen mit den Client möglich sind:

nano /etc/signaling/server.conf

Hier muss in der Backend-Sektion die Variable allowall auf true gesetzt werden, damit keine Einschränkung auf bestimmte Domains besteht.

[backend]
# ...
allowall = true
# ...

Der Service ist dann noch neu zu starten:

service signaling restart

Nun kann mit den Client ein Benchmark durchgeführt werden:

cd /etc/nextcloud-spreed-signaling
./bin/client -addr localhost:8080

Der Client baut daraufhin 100 Verbindungen zum Server auf und zeigt den Durchsatz an.

Benchmark des Signaling Servers

Benchmark des Signaling Servers

Wichtig ist hier v.a., dass sämtliche Verbindungen zu Stande kommen („All connections established“). Im Hintergrund sieht man, dass das System CPU-seitig ordentlich unter Last gesetzt wird.

Wichtig: Aus Sicherheitsgründen sollte die Variable allowall in der server.conf nach dem Test wieder auf false gesetzt werden (Neustart des Services nicht vergessen).

Fazit

Mit einem eigenen Signaling Server ist es nun mit Nextcloud Talk endlich möglich, Konferenzen mit mehr als vier bis fünf Teilnehmern zu realisieren. Die Installation ist durchaus etwas aufwendiger, aber man hat anschließend eine gute (Video-)Chat-Lösung für die eigene Cloud.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-talk-mit-eigenem-signaling-server-high-performance-backend/feed/ 26
Webserver-Konfiguration (nginx): Mehrere Webanwendungen auf einem Server hosten https://decatec.de/home-server/webserver-konfiguration-nginx-mehrere-webanwendungen-auf-einem-server-hosten/ https://decatec.de/home-server/webserver-konfiguration-nginx-mehrere-webanwendungen-auf-einem-server-hosten/#comments Tue, 23 Jun 2020 14:39:51 +0000 https://decatec.de/?p=5593 nginx Logo

Dieser Blog beschäftigt sich ja mit etlichen Themen rund um selbst gehostete (Web-)Anwendungen. Die eigene Cloud mit Nextcloud ist hierbei wohl das größte Themengebiet, aber es wurden auch andere Lösungen gezeigt, wie z.B. der eigene Firefox Sync Server.

Spätestens, wenn mehrere Webanwendungen auf einem (Home-)Server gehostet werden sollen, braucht man ein Konzept, um diese Anwendungen voneinander zu trennen. Über lange Zeit habe ich in diesem Blog immer die Variante bevorzugt, mehrere Webanwendungen einfach in verschiedenen Unterverzeichnissen des Webservers laufen zu lassen, wie bei diesem älteren Artikel über Nextcloud. In Zukunft werde ich diese Trennung eher über unterschiedliche (Sub)-Domains realisieren, siehe dazu der aktuelle Artikel zu Nextcloud. Darüber hinaus besteht noch eine dritte Möglichkeit, die Trennung durch die Verwendung unterschiedlicher Ports umzusetzen.

In diesem Artikel möchte ich daher nun genauer auf diese Varianten eingehen, Vor- als auch Nachteile beschreiben und die möglichen Webserver-Konfigurationen skizzieren. Die Ausführen sollen dabei eher allgemein gehalten und nicht an einer speziellen Webanwendung festgemacht werden.

Auch wenn in diesem Artikel nginx als Webserver verwendet wird, so sind die Konzepte auch auch andere Webserver (z.B. Apache) übertragbar.

Basics: Domains, Webserver und virtuelle Hosts

Zunächst soll kurz skizziert werden, was zum Hosten einer Webanwendung benötigt wird.

Domain

Erst einmal wird eine Domain benötigt, über die die Webanwendung später erreichbar sein soll. Im Heim-Bereich kommt hier oftmals eine DynDNS-Domain zum Einsatz, da ein privater Internet-Anschluss keine feste IP-Adresse hat. Einfach ausgedrückt mappt ein DynDNS-Dienst immer die Domain auf die aktuelle IP-Adresse.

Es gibt eine große Auswahl an DynDNS-Diensten. Aus Gründen des Datenschutzes sollte man dabei einen Anbieter wählen, dessen Server-Standort in Deutschland liegt. Einige empfohlene Anbieter sind z.B.:

Im Business-Bereich werden meist feste IP-Adressen verwendet, daher ist hier kein DynDNS-Dienst notwendig. Hier reicht es dann aus, einen A-Record (IPv4) bzw. einen AAAA-Record (IPv6) für die Domain zu setzen. Dies wird meist in der DNS-Verwaltung des Domain-Providers konfiguriert. Da sind das Vorgehen von Anbieter zu Anbieter unterscheidet, kann an dieser Stelle leider keine allgemeingültige Anleitung erfolgen.

Router-/Netzwerk-Konfiguration

Damit die später zu erstellende Webanwendung dann später auch im Internet erreichbar ist, müssen im Router noch Port-Forwardings definiert werden. Wichtig sind dabei die Ports 80 (HTTP) und 443 (HTTPS). Anfragen, wie über diese Ports eingehen, müssen auf den Server weitergeleitet werden, auf dem der Webserver (nginx) läuft.

Auch hier unterscheidet sich das Vorgehen je nach Router-Hersteller. Wie dies z.B. bei einer FritzBox eingerichtet werden kann, wird auf den AVM-Hilfeseiten erklärt.

Auf dem folgenden Screenshot sieht man die Einrichtung eines Port-Forwardings für Port 80. Analog ist dann mit dem Port 443 zu verfahren.

Portfreigabe in der FritzBox einrichten

Portfreigabe in der FritzBox einrichten

Bei Bedarf können hier auch andere Ports freigeschaltet werden. Dies muss dann später bei der Konfiguration der virtuellen Hosts beachtet werden.

Webserver

Als Webserver kommt im Rahmen des Artikels nginx zum Einsatz. Damit dieser eine Website ausliefern kann, wird mindestens ein virtueller Host (vHost) benötigt. Bei nginx wird ein vHost durch einen Server-Block definiert.

Im folgenden Beispiel werden zwei sehr einfache virtuelle Hosts definiert – einer für HTTP (Port 80) und einer für Port 443 (HTTPS). Beide bedienen die gleiche Domain und es wird einfach nur statischer Content (z.B. HTML) ausgeliefert, welcher im Verzeichnis /var/www/meinedomain.de liegt:

server {
    # Virtual host 1:
    # - Listens on port 80 (HTTP) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain.de" and IP address 192.168.178.60 (local IP of server).
    # - Forwards all requests to the second vHost (HTTPS).
	listen 80 default_server;
    listen [::]:80 default_server;
	server_name meinedomain.de 192.168.178.60;
 
	root /var/www/meinedomain.de;

	location / {
	# Enforce HTTPS
	return 301 https://$server_name$request_uri;
    }		
}

server {
    # Virtual host 2:
    # - Listens on port 443 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain.de" and IP address 192.168.178.60 (local IP of server).
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain.de 192.168.178.60;

    # Certificates used
    ssl_certificate /etc/letsencrypt/meinedomain1.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain1.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain1.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/meinedomain.de;	
}

Hinweis: Die für einen HTTPS-vHost notwendige SSL-Konfiguration wird hier nicht genauer behandelt (bis auf die Einbindung der TLS-Zertifikate), da dies den Rahmen des Artikels sprengen würde. Daher wird diese Konfiguration den vHosts hier nur beispielhaft per „include“ hinzugefügt. Mehr Informationen zu Zertifikaten und der SSL-Paramter kann folgenden Artikeln entnommen werden:

Die virtuellen Hosts werden normalerweise im Verzeichnis /etc/nginx/conf.d gespeichert (mit der Dateiendung .conf), so dass nginx diese beim Starten automatisch anzieht. Zur besseren Übersichtlichkeit wird meist eine Datei pro vHosts angelegt. Wenn – wie in diesem Beispiel – der virtuelle Host für HTTP lediglich für eine generelle Weiterleitung auf HTTPS gedacht ist, dann können beide vHosts auch in einer einzelnen Datei aufgeführt werden (z.B. unter /etc/nginx/conf.d/meinedomain.de.conf). Der Name dieser Datei ist prinzipiell egal, wichtig ist nur, dass die Dateiendung .conf lautet, sonst wird diese von nginx nicht geladen.

Die oben aufgeführte Konfiguration der virtuellen Hosts wäre eine Standard-Definition, wenn eben nur eine Webanwendung über eine Domain mit den Standard-Ports (80/443) betrieben werden soll.

Webanwendung

Die Webanwendung wird durch den Webserver gehostet (z.B. Nextcloud, Firefox Sync, etc.). Da sich dieser Artikel mit den verschiedenen Möglichkeiten des Hostings beschäftigt und keine zusätzliche Komplexität durch die Webanwendung selbst hinzugefügt werden soll, wird hier nur von einer einfachen statischen HTML-Website ausgegangen.

Mehrere Webanwendungen parallel hosten

Was passiert nun aber, wenn mehrere Webanwendungen parallel auf den gleichen Server gehostet werden sollen? Hier muss der Webserver auf Grund eines Requests eine Unterscheidung vornehmen können, welche Webanwendung ausgeliefert werden soll. Dazu müssen sich weitere virtuelle Hosts in mindestens einem Aspekt unterscheiden:

  • Unterschiedliche Ports.
  • Unterschiedliche Domains.
  • Unterschiedlicher Pfade auf dem Webserver.

Daraus resultieren für das Vorhaben nun drei Möglichkeiten.

Ein virtueller Host pro Webanwendung (unterschiedliche Ports)

Die einfachste Möglichkeit besteht nun darin, dass man für jede Webanwendung einfach andere Ports verwendet.

Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Ports)

Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Ports)

Ein Beispiel mit zwei virtuellen Hosts für zwei Webanwendungen könnte dann wie folgt aussehen (der Einfachheit halber werden hier die vHosts für HTTP weggelassen und nur die vHosts für HTTPS gezeigt):

server {
    # Virtual host 1/web application 1:
    # - Listens on port 443 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain.de" and IP address 192.168.178.60 (local IP of server).
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain.de 192.168.178.60;

    ssl_certificate /etc/letsencrypt/meinedomain1.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain1.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain1.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/webapplication1;	
}

server {
    # Virtual host 2/web application 2:
    # - Listens on port 444 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain.de:444" and IP address 192.168.178.60:444 (local IP of server).
	listen 444 ssl http2;
	listen [::]:444 ssl http2;
	server_name meinedomain.de 192.168.178.60;

    ssl_certificate /etc/letsencrypt/meinedomain1.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain1.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain1.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/webapplication2;	
}

Beide vHosts „hören“ auf den Namen meinedomain.de, unterscheiden sich allerdings im verwendeten Port. Die relevanten Zeilen sind im obigen Beispiel markiert. Für Anwendung 1 ist dies der Standard-Port 443, für Anwendung 2 der Port 444 (dieser Port muss dann auch „offen“ sein, d.h. man benötigt ein weiteres Port-Forwarding).

Da sich die Domains hier nicht unterscheiden, kann aber das gleiche TLS-Zertikat zum Einsatz kommen.

Folglich landet man bei Webanwendung 1, wenn man im Browser nun https://meindomain.de aufruft. Die Angabe des Ports 443 ist hier nicht notwendig, da dies der Standard-Port für HTTPS ist und der Browser diesen automatisch nutzt.

Um Webanwendung 2 aufzurufen, muss der alternative Port 444 im Browser spezifiziert werden: https://meinedomain.de:444

Vorteile

  • Einfache Trennung der einzelnen Webanwendungen mittels unterschiedlicher Ports.
  • Keine zweite Domain benötigt: Beide Webanwendungen laufen über die gleiche Domain.
  • Es wird nur ein TLS-Zertifikat benötigt.
  • Anleitungen/Tutorials zu bestimmten Webanwendungen unter nginx können meistens einfach übernommen werden – hier muss dann lediglich der Port angepasst werden.

Nachteile

  • Wenig komfortabel: Beim Aufruf der zweiten Webanwendung muss in sämtlichen Clients (z.B. Browser, Apps, etc.) immer der abweichende Port (444) mit angegeben werden. Falls hier z.B. eine App keinen alternativen Port zulässt, kann damit auch nicht auf die zweite Webanwendung zugegriffen werden.
  • Weiteres Port-Forwarding benötigt: Für die zusätzlichen Port müssen weitere Port-Forwardings eingerichtet werden. Das widerspricht dem Konzept, dass man möglichst wenige Port-Forwardings konfigurieren sollte.

Ein virtueller Host pro Webanwendung (unterschiedliche Domains)

Wenn man nun keine vom Standard abweichenden Ports verwenden möchte, muss man ein anderes Kriterium nutzen, um eine saubere Trennung zu realisieren. Der zweite Lösungsansatz besteht nun darin, unterschiedliche Domains zu verwenden.

Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Domains)

Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Domains)

In unserem Beispiel könnte dies dann wie folgt aussehen. Es werden wieder nur die vHosts für HTTPS gezeigt:

server {
    # Virtual host 1/web application 1:
    # - Listens on port 443 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain1.de" and IP address 192.168.178.60 (local IP of server).
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain1.de 192.168.178.60;

    # IMPORTANT: You need a specific TLS certificate for meinedomain1.de
    ssl_certificate /etc/letsencrypt/meinedomain1.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain1.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain1.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/webapplication1;	
}

server {
    # Virtual host 2/web application 2:
    # - Listens on port 443 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain2.de".
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain2.de;

    # IMPORTANT: You need a specific TLS certificate for meinedomain2.de
    ssl_certificate /etc/letsencrypt/meinedomain2.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain2.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain2.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/webapplication2;	
}

Für beide Webanwendungen wird nun der gleiche Port (443) verwendet, jedoch unterschiedliche Domains: meinedomain1.de für Anwendung 1, meinedomain2.de für Anwendung 2. In den virtuellen Hosts wird dies über die Anweisung server_name angegeben (oben wieder markiert).

Eine Nebenwirkung hat dieses Konzept allerdings: Nur Webanwendung 1 ist nun noch über die lokale IP-Adresse des Servers erreichbar. Dies ist notwendig, da ja ansonsten wieder beide vHosts auf die gleiche IP-Adresse und den gleichen Port konfiguriert wären.

Im Browser kann man dann https://meinedomain1.de für Anwendung 1, https://meinedomain2.de für Anwendung 2 aufrufen.

Die Besonderheit dieser Lösung liegt nun in der Domain-Konfiguration: Beide Domains müssen auf die (Internet-)IP des Webservers auflösen. Bei statischen IP-Adressen kann dies einfach in der Verwaltung des Domain-Providers angegeben werden. Meistens gibt es hier einen Punkt zur DNS-Verwaltung von Domains. Hier müssen die sog. A-Records (für IPv4) und AAAA-Records (für IPv6) auf die entsprechenden IPs des Servers gesetzt werden.

Für diese Lösung werden übrigens nicht zwingend mehrere Second-Level-Domains (wie z.B. meinedomain1.de und meinedomain2.de) benötigt. Hier reicht auch eine Second-Level-Domain (meinedomain.de), zu der dann mehrere Sub-Domains erstellt werden (bielspielsweise app1.meinedomain.de und app2.meinedomain.de).

Im Heimbereich kommt darüber hinaus meist DnyDNS zum Einsatz. Hier wird die Konfiguration etwas umständlicher, da meistens nur eine einzige DynDNS-Domain im Router hinterlegt werden kann (z.B. bei einer FritzBox). Damit die zweite Domain nun ebenfalls „daheim am Router ankommt“, kann für die zweite Domain ein sog. CNAME-Record gesetzt werden (dies geschieht ebenfalls in der Domain-Verwaltung des Providers). Da sich das Vorgehen von Provider zu Provider unterscheidet, kann hierfür leider keine genaue Anleitung erfolgen. Der folgende Screenshot zeigt beispielhaft die Einrichtung eines CNAME-Records für eine Subdomain beim Provider All-Inkl (Affiliate-Link):

All-Inkl.com: CNAME-Eintrag für Subdomain erstellen

All-Inkl.com: CNAME-Eintrag für Subdomain erstellen

Vorteile

  • Einfache Trennung der Webanwendungen auf Grund unterschiedlicher Domains.
  • Keine zusätzlichen Port-Forwardings benötigt.
  • Anleitungen/Tutorials zu bestimmten Webanwendungen unter nginx können meistens einfach 1:1 übernommen werden.

Nachteile

  • Ggf. etwas kompliziertere Domain-Konfiguration erforderlich (v.a. bei der Verwendung von DynDNS).
  • Es werden mehrere TLS-Zertifikate benötigt (eines pro Domain).
  • Nur eine Webanwendung kann so konfiguriert werden, dass diese auf die lokale IP des Servers reagiert.

Webanwendungen in Unterverzeichnissen (mit Gateway-Host)

Wenn beide zuvor genannten Lösungen nicht umzusetzen sind, beispielsweise wenn nicht mehrere Domains zur Verfügung stehen und man keine zusätzlichen Ports freigeben möchte, kann man mehrere Webanwendungen auch in Unterverzeichnisses des Webservers hosten.

In diesem Fall wird die Webserver-Konfiguration etwas komplizierter, da man einen vorgeschalteten virtuellen Host („Gateway-Host“) benötigt, der alle Requests auf die Domain abfängt und diese anschließend an Hand des Verzeichnisses an weitere vHosts weiterleitet.

Schematische Darstellung: Gateway-Host und einzelne vHosts pro Webanwendung

Schematische Darstellung: Gateway-Host und einzelne vHosts pro Webanwendung

Eine solche Konfiguration könnte dabei wie folgt aussehen:

server {
    # Gateway host handling all the requests.
    # - Listens on port 443 (HTTPS) - IPv4 and IPv6.
    # - Is capable of serving requests for domain "meinedomain.de" and IP address 192.168.178.60 (local IP of server).
	# - Handles all SSL related stuff.
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain.de 192.168.178.60;

    ssl_certificate /etc/letsencrypt/meinedomain1.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/meinedomain1.de/key.pem;
    ssl_trusted_certificate /etc/letsencrypt/meinedomain1.de/ca.pem;

    # Include headers and SSL specific stuff.
    include /etc/nginx/snippets/ssl.conf;
    include /etc/nginx/snippets/headers.conf;

    root /var/www/	
	
	# Disable access to the web root.
	location = / {
		deny all;
	}
	
	# Subdirectory for app 1 (https://meinedomain.de/app1)
	location ^~ /app1 {
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto https;
		proxy_pass http://127.0.0.1:81;
		proxy_redirect off;
	}
	
	# Subdirectory for app 2 (https://meinedomain.de/app2)
	location ^~ /app2 {
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto https;
		proxy_pass http://127.0.0.1:82;
		proxy_redirect off;
	}
}

server {
    # Virtual host for web application 1:
	# - Only local (127.0.0.1), cannot be addressed directly (without gateway host).
    # - Listens on port 81 (HTTP) - IPv4 and IPv6.
    # - Is capable of serving requests for local IP address 127.0.0.1.
	listen 81;
	server_name 127.0.0.1;

	location ^~ /app1 {
		root /var/www/webapplication1;	
	}
}

server {
    # Virtual host for web application 2:
	# - Only local (127.0.0.1), cannot be addressed directly (without gateway host).
    # - Listens on port 82 (HTTP - different port as for vHost serving web application 1) - IPv4 and IPv6.
    # - Is capable of serving requests for local IP address 127.0.0.1.
	listen 82;
	server_name 127.0.0.1;

	location ^~ /app2 {
		root /var/www/webapplication2;	
	}
}

Der Gateway-Host nimmt hier alle Requests auf die Domain (oder lokale IP-Adresse des Servers) auf dem Standard-Port 443 (HTTPS) entgegen und ist für das SSL-Handling zuständig. Die Unterscheidung, welche Webanwendung nun gemeint ist, wird durch das Unterverzeichnis definiert (also https://meinedomain.de/app1 bzw. https://meinedomain.de/app2). Entsprechende Requests werden dann an die vHosts der jeweiligen Anwendung weitergeleitet (proxy_pass).

Die einzelnen Webanwendungen werden durch jeweils einen vitruellen Host abgebildet. Diese Hosts laufen rein lokal (127.0.0.1) auf unterschiedlichen Ports. Daher können diese vHosts nicht „von außen“ angesprochen werden, es muss immer erst der Gateway-Host passiert werden.

Vorteile

  • Nur eine Domain notwendig.
  • Es müssen keine zusätzlichen Port-Forwardings konfiguriert werden.
  • Es wird lediglich ein TLS-Zertifikat für den Gatway-Host benötigt.

Nachteile

  • Kompliziertere Konfiguration, da immer ein Routing vom Gateway-Host an die Anwendungs-vHosts implementiert werden muss.
  • Anleitungen/Tutorials zu bestimmten Webanwendungen unter nginx können nicht einfach übernommen werden. Hier muss zunächst immer eine Lösung implementiert werden, die das Konzept des Gateway-Hosts berücksichtigt.

Empfehlung: Welche Lösung ist die beste?

Eine eindeutige Empfehlung kann an dieser Stelle nicht erfolgen, da dies auch immer von den individuellen Gegebenheiten/Bedürfnissen abhängt.

Dennoch ist meine bevorzugte Lösung die Trennung der einzelnen Webanwendungen durch unterschiedliche (Sub-)Domains. Auf diese Weise laufen alle Anwendungen auf den Standard-Ports 80 (HTTP) und 443 (HTTPS) und man spart sich einiges an Komplexität, die man mit einem Gateway-Host beachten müsste. Dadurch wird die gesamte Webserver-Konfiguration um einiges einfacher.

Überführung der Lösungen/Mischbetrieb

Abschließend noch der Hinweis, dass eine einmal umgesetzte Lösung nicht in Stein gemeißelt ist. Es ist jederzeit möglich, eineLösung in eine andere zu überführen. Normalerweise geschieht das dann einzig und allein über die Webserver-Konfiguration (vHosts) – die Konfiguration der Webanwendung muss meistens gar nicht geändert werden.

Die im Artikel gezeigten Beispiele für die einzelnen virtuellen Hosts von nginx können bei der Überführung der Lösungen hilfreich sein. Falls nach einer Änderung der Konfiguration die Webanwendung nicht mehr funktioniert, sollte auf jeden Fall ein Blick in das nginx Error-Log (/var/log/nginx/error.log) helfen. Meistens ist das Problem dann auf eine falsche Verzeichnisstruktur zurück zu führen – entweder die loakle Verzeichnisstruktur, oder aber die Stuktur, die in den virtuellen Hosts konfiguriert wurde.

Man muss sich darüber hinaus auch nicht auf eine Lösung festlegen: Es ist genau so möglich, mehrere Lösungen parallel auf einem Server zu betreiben. So wäre es beispielsweise denkbar, dass zwei Webanwendungen unter den Domains meinedomain1.de/app1 und meinedomain1.de/app2 verfügbar sind und eine dritte Anwendung über meinedomain3.de erreichbar ist.

Fazit

Der Artikel hat drei Lösungsansätze aufgezeigt, wie unter nginx mehrere Webanwendungen parallel gehostet werden können und welche Vor- bzw. Nachteile die einzelnen Lösungen bieten. Wie immer gibt es hier nicht die eine richtige Lösung, da dies immer von den jeweiligen Anforderungen abhängt.

Welchen Ansatz bevorzugt ihr? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/webserver-konfiguration-nginx-mehrere-webanwendungen-auf-einem-server-hosten/feed/ 10
Nextcloud auf Ubuntu Server 20.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban https://decatec.de/home-server/nextcloud-auf-ubuntu-server-20-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/ https://decatec.de/home-server/nextcloud-auf-ubuntu-server-20-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/#comments Mon, 11 May 2020 16:09:47 +0000 https://decatec.de/?p=6601 Nextcloud Logo

In diesem Artikel wird die Installation und Konfiguration von Nextcloud auf Ubuntu Server 20.04 LTS („Focal Fossa“) mit nginx, MariaDB, PHP und Let’s Encrypt beschrieben. Ebenfalls kommen Redis, Fail2ban und ufw zur Verbesserung der Sicherheit und Performance zum Einsatz.

Zum Thema Nextcloud auf Ubuntu Server gab es in diesem Blog bereits zahlreiche Artikel. Die letzte Anleitung Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban hat bereits ein ähnliches Setup beschrieben, basierte jedoch auf der Ubuntu-Version 18.04 LTS. Nach gut zwei Jahren ist nun eine neue LTS-Version von Ubuntu erschienen, so dass diese Artikel-Serie mit der neusten Version der Distribution fortgeführt wird.

Daneben bietet dieses Tutorial einen ganz neuen Ansatz: In vorherigen Artikeln zu diesem Thema wurde Nextcloud immer in einem Unterverzeichnis des Webservers installiert. Hier stieg allerdings die Nachfrage nach einem Setup, bei dem Nextcloud direkt im Root-Verzeichnis einer Domain installiert werden kann. Als positiver Nebeneffekt wird damit auch die Webserver-Konfiguration im einiges einfacher. Daher wird die eigene Cloud in diesem Artikel direkt im Web-Root der Domain installiert und nicht mehr in einem Unterverzeichnis.

Update-Historie (letztes Update: 22.06.2020)
  • 22.06.2020:
    • MariaDB wird nun in Version 10.4 verwendet.
    • Für MariaDB werden nun die Paketquellen von MariaDB eingebunden (Channel: „Stable“).
    • Das Paket php-bcmath wird von Nextcloud 19 vorausgesetzt, daher wird dieses nun bei der Installation von PHP berücksichtigt.
  • 14.05.2020:
    • FAQs: Anleitung zum Hosten weiterer Webanwendungen hinzugefügt.

Motivation, Voraussetzungen und Konzept

Dieser Artikel wird sicherlich wieder lang und umfangreich werden. Wie immer möchte ich hier kein „Copy & Paste Tutorial“ bereit stellen, in dem einfach nur eine Reihe von (Kommandozeilen-)Befehlen aufgeführt wird. Das hauptsächliche Ziel des Artikels ist es daher wieder, Wissen zu vermitteln: Dem Leser soll ein solides Grundlagenwissen vermittelt werden, so dass er sich zu jeder Zeit bewusst ist, warum die Dinge wie hier im Artikel skizziert umgesetzt wurden. Das Wissen um Zusammenhänge und Hintergründe ist ebenfalls bei auftretenden Problemen sehr wichtig. Denn wer eine eigene Cloud betreibt (und hier evtl. noch eigene Anforderungen umsetzen möchte), der wird froh sein, wenn auftretende Probleme eigenständig analysiert und gelöst werden können.

Ziele

Mit diesem Tutorial werden konkret folgende Ziele verfolgt:

  • Installation der eigenen Nextcloud auf Ubuntu Server 20.04 LTS mit nginx, MariaDB und PHP (LEMP-Stack).
  • Erhöhte Sicherheit der Cloud (PHP-Konfiguration, SSL, Nextcloud-Konfiguration laut Nextcloud Administation Manual).
  • Verschlüsselte Verbindung zur eigenen Cloud mittels HTTPS. Dazu kommt ein Zertifikat von Let’s Encrypt zum Einsatz (ECDSA- und RSA-Zertifikate im Hybrid-Betrieb mit TLSv1.3).
  • Nextcloud soll in einem Root-Verzeichnis des Webservers laufen und direkt über die URL https://nextcloud.meinedomain.de erreichbar sein.
  • In der Admin-Oberfläche von Nextcloud sollen keine Warnungen angezeigt werden.
  • Das Datenverzeichnis von Nextcloud soll außerhalb des www-Verzeichnisses liegen.
  • Verbesserung der Performance durch Verwendung von Redis für das Transactional File Locking.
  • Absicherung gegen Brute-Force-Attacken mit Fail2ban.
  • Einrichtung der Firewall ufw.

Zeitaufwand und Programm-Versionen

Zeitaufwand: ca. 3 Stunden

Eingesetzte Programm-Versionen:

  • Ubuntu Server 20.04 LTS („Focal Fossa“)
  • Nextcloud 18.0.3
  • nginx 1.17
  • MariaDB 10.4
  • PHP 7.4
  • Redis 5.0.7
  • Fail2ban 0.11.1
  • OpenSSL 1.1.1f

Änderungen gegenüber älteren Nextcloud-Artikeln

In diesem Blog gab es bereits einige Artikel zur Installation von Nextcloud auf Ubuntu Server. Im aktuellen Tutorial gibt es nun allerdings einige Änderungen, die das gesamte Setup betreffen – natürlich abgesehen, dass eine neue Verison von Ubuntu Server zum Einsatz kommt.

Folgende Punkte wurden nun im Vergleich zu den vorherigen Nextcloud-Artikeln geändert:

  • Nextcloud wird nun nicht mehr in einem Unterverzeichnis, sondern direkt im Root-Verzeichnis von nginx installiert:
    Dies macht die komplette Webserver-Konfiguration wesentlich einfacher, da kein Gateway-Host mehr benötigt wird, der alle Requests entgegen nehmen und weiterleiten muss. Dies verhindert allerdings nicht die Installation weiterer Webanwendungen. Diese benötigen im hier gezeigten Setup jedoch jeweils eigene (Sub-)Domains.
  • Verzicht auf die Konfiguration von open_basedir.
    Mittels open_basedir kann in einer PHP-Umgebung der Zugriff von PHP auf bestimmte Verzeichnisse beschränkt werden. In der Praxis sorgte diese Einschränkung doch immer wieder für Fehler/Probleme. Da dieses Thema in der heutigen Zeit nicht mehr so relevant für die Sicherheit ist, wird die Konfiguration von open_basedir nun ausgelassen.
  • Die Generierung der HTTPS-Zertifikate setzt nun konsequent auf acme.sh mit TLSv1.2 und TLSv1.3 im Hybrid-Betrieb (RSA- und ECDSA-Zertifikate parallel).
    Die älteren Artikel hatten dieses Konzept nicht so konsequent umgesetzt, so dass man die Informationen zu dem Thema ggf. aus weiteren Artikeln zusammen suchen musste. Das Vorgehen dazu wird nun hier direkt im Arikel ausführlich behandelt.

Neben diesen offensichtlichen Änderungen sind aber ebenfalls noch viele kleine Verbesserungen in diesen Artikel eingeflossen.

Voraussetzungen

Betriebssystem und Hardware

Als Betriebssystem kommt Ubuntu Server 20.04 LTS („Focal Fossa“) zum Einsatz. Generell ist hier der Einsatz einer LTS-Version (Long Term Support) zu empfehlen, da durch den verlängerten Support-Zeitraum (in diesem Fall fünf Jahre – bis April 2025) ein solches System über eine lange Zeit betrieben werden kann, ohne dass ein Distributions-Update zwingend erforderlich ist.

Das Betriebssystem sollte bereits installiert sein. Eine genaue Anleitung der Betriebssystem-Installation würde sicherlich den Rahmen des Artikels sprengen.

Alle gezeigten Schritte können allerdings auch mit anderen Linux-Distributionen (z.B Debian) umgesetzt werden. Evtl. sind hier dann kleinere Anpassungen an einigen wenigen Schritten notwendig.

Als Hardware braucht man prinzipiell nur eine Maschine, auf der Linux läuft. Wenn die Anforderungen nicht besonders hoch sind, kann das Tutorial auch auf einem Kleinstrechner wie dem  Raspberry Pi (Affiliate-Link) umgesetzt werden. Wird mehr Leistung benötigt, bietet sich z.B. auch eine Intel NUC (Affiliate Link) an. Die Cloud muss allerdings auch nicht zwingend in den eigenen vier Wänden betrieben werden: Wer einen eigenen Root-Server gemietet hat, kann sich ebenfalls an diesem Artikel orientieren.

Zugriff Per SSH

Ein Server läuft normalerweise „headless“, d.h. ohne angeschlossenen Monitor, Maus und Tastatur. Der Zugriff findet dann in der Regel über SSH statt. Daher sollte man im Rahmen des Ubuntu-Setups gleich einen SSH-Server mit installieren.

Domain und DynDNS/feste IP

Die eigene Cloud soll später ja auch aus dem Internet aus erreichbar sein. Daher ist zunächst eine Domain erforderlich. Im Rahmen des Artikels nutze ich die beispielhafte (Sub-)Domain nextcloud.meinedomain.de.

Diese Domain muss zunächst auf den eigenen Internet-Anschluss verweisen. Wer einen Anschluss mit fester IP hat (meistens Business-Anschlüsse), tut sich hier sehr leicht. In diesem Fall reicht es aus, den A-Record (IPv4) und AAAA-Record (IPv6) von der Domain auf die IPs des Anschlusses zu setzen. Dies wird normalerweise in den Einstellungen beim Domain-Provider erledigt.

Wenn keine feste IP-Adresse vorhanden ist – was bei den meisten privaten Internet-Anschlüssen der Fall ist – muss man auf DynDNS  setzen. Dies sorgt dafür, dass die (öffentliche) IP des Servers/Routers immer auf eine DynDNS-Domain gemappt wird. Dies ist notwendig, da die meisten Provider nach der 24-stündigen Zwangstrennung dem Kunden einen neue IP-Adresse zuweisen.
Ebenfalls benötigt man schon für die Erzeugung der SSL-Zertifikate zwingend eine Domain, da Zertifikate nicht auf IP-Adressen ausgestellt werden können.

Hierzu benötigt man einen sog. DynDNS-Dienst. Hier gibt es zahlreiche kostenlose Anbieter. Ein paar empfehlenswerte Dienste wären dabei:

Trotzdem kann es – gerade bei kostenlosen Diensten – immer mal wieder zu Problemen kommen. Eine meist bessere Alternative ist daher der Einsatz eines bezahlten Angebots, welches dann meistens zuverlässiger ist. Dazu bieten viele Webhoster auch DynDNS-Dienste an. Empfehlen kann ich hier den Hoster All-Inkl.com (Affiliate Link): Hier ist ein DynDNS-Dienst bereits um Webhosting-Paket „Privat Plus“ enthalten.

Im Router muss dann diese DynDNS-Domain noch konfiguriert werden, damit sich dieser korrekt am DynDNS-Dienst anmeldet. Erst nach diesem Schritt ist das eigene Netzwerk per DynDNS-Domain erreichbar. Das Vorgehen zum konfigurieren vom DynDNS hängt vom verwendeten Router-Modell, aber auch vom DynDNS-Dienst ab. Eine Informationsquelle sind hier die Hersteller-Seiten des Routers (z.B. AVM), aber auch die Websites der jeweiligen DynDNS-Dienste (z.B. ddnss.de) bieten meistens Hinweise zu verschiedenen Router-Modellen.

Port-Forwarding

Damit der (lokale) Webserver später auch aus dem Internet erreichbar ist, muss ein sog. Port-Forwarding im Router für die Ports 80 (HTTP) und 443 (HTTPS) für die IP-Adresse des Servers (in diesem Beispiel: 192.168.178.60) konfiguriert werden. Da sich das Vorgehen dazu wieder von Router zu Router unterscheidet, kann hier ebenfalls keine konkrete Anleitung erfolgen. Oftmals beschreiben die Hersteller das genaue Vorgehen auf ihren Internet-Seiten. Beispielsweise findet man die Vorgehensweise für die Einrichtung von Port-Forwardings für eine FritzBox auf den Hilfeseiten vom AVM.

Internet-Anschluss

Der Internet-Anschluss muss auch gewisse Voraussetzungen erfüllen. Hierbei darf es sich nicht um einen Dual-Stack Lite (DS-Lite) Anschluss handeln. Dies ist eine Technik, bei der der Endkunde keine „echte“ IPv4 Adresse bekommt, sondern nur eine IPv6-Adresse. Verbindungen die über IPv4 laufen, werden dann über IPv6 getunnelt. Leider setzen durch die gegebene Knappheit an IPv4-Adressen immer mehr Provider auf DS-Lite.

Mit einem DS-Lite-Anschluss ist der Betrieb eines selbstgehosteten Webdienstes leider nicht direkt möglich.

Daher wird zum Hosten einer eigenen Nextcloud zwingend ein „echter“ IPv4-Anschluss benötigt. Mit einem DS-Lite-Anschluss ist es nicht möglich, mit der hier gezeigten Vorgehensweise eine eigene Cloud aufzusetzen.

Wer doch nur einen DS-Lite-Anschluss hat, kann evtl. eine Zusatz-Option für einen echten IPv4-Anschluss beim Provider dazu buchen. Falls der Provider eine solche Option nicht direkt anbietet, kann es oftmals auch helfen, beim Provider anzurufen und nach einer solchen Option zu fragen, die dann evtl. manuell gebucht werden kann.

Falls dies nicht möglich ist, kann man nur einen Umweg über einen sog. Portmapper gehen. Diese Lösung ist allerdings sehr aufwendig und verursacht zusätzliche Kosten.

Root-Rechte

Für die Installation und die Konfiguration der benötigten Programmen sind unter Linux meist Root-Rechte erforderlich. Unter Ubuntu kann jeder Befehl durch das Voranstellen von „sudo“ mit Root-Rechten ausgeführt werden. Damit dieses „sudo“ nicht immer mit angegeben werden muss, ist es für die Installation empfehlenswert, sich am Anfang der Installation/Konfiguration einmalig Root-Rechte mit dem Befehl sudo -s zu verschaffen.

Konzept

Der folgende Abschnitt erklärt das Konzept, welches diesem Tutorial zugrunde liegt.

LEMP-Stack

Wer sich im Bereich Webhosting ein wenig auskennt, hat sicher schon mal etwas vom sog. LAMP-Stack gehört. Darunter versteht man eine Reihe an Programmen, die oftmals zusammen eingesetzt werden, wenn es um das Hosten dynamischer Webseiten geht: Linux (Betriebssystem), Apache (Webserver), MySQL (Datenbank) und PHP (Skriptsprache). Setzt man die Anfangsbuchstaben dieser Programme zusammen, versteht man, warum dies als LAMP-Stack bezeichnet wird.

Ich setze im Rahmen des Artikels jedoch auf einen sog. LEMP-Stack: Dies eine eine weitere Variante dieses Software-Pakets, bei der zunächst ebenfalls Linux als Grundlage zum Einsatz kommt. Allerdings nutzt man nun keinen Apache, sondern nginx als Webserver. Ebenso setze ich auf MariaDB als Datenbanksystem (statt MySQL). Was gleich bleibt ist der Einsatz von PHP. Die Bezeichnung LEMP-Stack ergibt sich wieder aus dem Anfangsbuchstaben der Programme (das „E“ kommt von der Aussprache von nginx: „Engine-X“).

Warum nutze ich nun abweichend vom Standard einen anderen Webserver und ein anderes Datenbanksystem? Dies bringt meiner Meinung nach folgende Vorteile:

  • Der Webserver nginx ist im Allgemeinen etwas ressourcenschonende als Apache. Letzterer erstellt pro (Client-)Verbindung neue Threads bzw. Prozesse, über die die einzelnen Webrequest abgearbeitet werden. Die Erzeugung neuer Threads/Prozesse ist allerdings teuer, da vergleichsweise viel Rechenleistung benötigt wird.
    nginx dagegen arbeitet mit einem sog. Thread-Pool: Hier werden beim Start des Webservers bereits mehrere Threads angelegt. Diese arbeiten dann die Webrequests ab, können aber im weiteren Verlauf wieder verwendet werden. Dies benötigt im Allgemeinen nicht so viele Ressourcen.
    Darüber hinaus finde ich die Konfiguration von nginx einfacher als die von Apache. Dies ist allerdings meine persönliche Meinung und mit Sicherheit Geschmackssache.
  • Das Datenbanksystem MariaDB ging aus einem Fork von MySQL hervor und ist zu diesem binärkompatibel. MariaDB ist daher ein sog. Drop-In-Replacement für MySQL (sozusagen ein 1:1 Ersatz). Deshalb spielt es für eine Anwendung keine Rolle, ob das dahinter liegende Datenbanksystem nun MySQL oder MariaDB ist. Ebenfalls sind alle Tools und Programme, die für MySQL entwickelt wurde auch automatisch mit MariaDB kompatibel.
    Für unser Vorhaben spielt es daher keine große Rolle, ob nun MySQL oder MariaDB zum Einsatz kommt. Im Gegensatz zu MySQL steht hinter MariaDB jedoch kein großes Unternehmen (bei MySQL ist dies Oracle), sondern es handelt sich dabei um „echte“ Open-Source-Software. Das ist auch der Grund, warum mittlerweile viele Linux-Distributionen MariaDB als Standard-Datenbanksystem einsetzen.
    Da mir dieses System zukunftssicherer erscheint, nutze ich daher im Rahmen des Artikels MariaDB als Datenbanksystem.

Virtuelle Hosts und Konfigurations-Dateien von nginx

Bevor es losgeht, noch ein paar Anmerkungen zu den Konfigurationsdateien bei nginx. Der Webserver verwendet sog. virtuelle Hosts (vHosts). Dies sind zunächst einmal reine Textdateien, die die Konfiguration für genau eine Website oder Anwendung beschreibt. Folgende Dateien/Verzeichnisse sind dabei wichtig:

  • /etc/nginx/nginx.conf: Dies ist die globale Konfiguration von nginx. Hier werden alle globalen Einstellungen definiert, die für alle Websites gelten sollen.
  • /etc/nginx/conf.d: In diesem Verzeichnis erwartet nginx die virtuellen Hosts und lädt diese beim Start. vHosts müssen in diesem Verzeichnis liegen und mit der Dateiendung *.conf gespeichert werden. Andere Dateien, die nicht mit .conf enden, werden beim Start des Webservers ignoriert.
  • Andere Verzeichnisse/Includes: Neben dieses fest definierten Verzeichnissen können aber auch andere Konfigurations-Dateien zum Einsatz kommen. Diese können irgendwo gespeichert sein und in jeder nginx-Konfiguration/vHost eingebunden werden. Ich nutze für solche „Snippets“ immer das Verzeichnis /etc/nginx/snippets. Was es damit auf sich hat und wie die Dateien inkludiert werden, wird im weiteren Verlauf des Artikels deutlich.

Hinweis bei abweichender Verzeichnisstruktur bei nginx

Es kann vorkommen, dass je nach verwendeter nginx-Version die Verzeichnisstruktur etwas anders ist. Nach der Installation sollte daher schnell überprüft werden, wo der default-vHost zu finden ist. Wenn dieses das oben genannten Verzeichnis ist (/etc/nginx/conf.d), kann dieser hier Abschnitt übersprungen werden.

Wenn der default-vHost allerdings nicht in in diesem Verzeichnis zu finden ist, dann liegt dieser meist unter /etc/nginx/sites-enabled. In diesem Fall kommt eine alternative Verzeichnisstruktur bei nginx zum Einsatz. Hier werden die virtuellen Hosts dann folgendermaßen verarbeitet:

  • /etc/nginx/sites-available: In diesem Verzeichnis sind die verfügbaren virtuellen Hosts enthalten, d.h. vHosts, die beim Start von nginx nicht automatisch geladen werden. Die Dateiendung für vHosts ist hier egal und man lässt diese für gewöhnlich einfach weg.
  • /etc/nginx/sites-enabled: Hier sind die virtuellen Hosts gespeichert, die der Webserver beim Starten lädt, die „aktiven vHosts“.
  • Um einen virtuellen Host zu aktivieren, muss sich dieser also im Verzeichnis sites-enabled befinden. Um nun nicht zwei Dateien verwalten zu müssen (unter sites-available und sites-enabled), kann einfach eine symbolische Verknüpfung für einen virtuellen Host angelegt werden. Ein Beispiel: Wenn ein (deaktivierter) vHost /etc/nginx/sitesavailable/meinedomain.de aktiviert werden soll, dann wird mit folgendem Befehl eine entsprechende Verknüpfung angelegt:
ln -s /etc/nginx/sites-available/meinedomain.de /etc/nginx/sites-enabled/
Wenn diese alternative Verzeichnisstruktur bei nginx zum Einsatz kommt, dann ist im weiteren Verlauf des Artikels darauf zu achten, die Dateien der virtuellen Hosts an der richtigen Stelle zu platzieren.

Installation und Konfiguration benötigter Programme

Genug der Vorrede, nun geht es an die Praxis!

Ubuntu Server 20.04 LTS ist bereits installiert? Gut.
Das System sollte dabei eine statische IP im LAN zugeteilt bekommen haben. Ich nutze im Folgenden die beispielhafte IP 192.168.178.60.

Update des Betriebssystems

Zunächst bringen wir das System auf den neusten Stand und starten den Server anschließend einmal neu:

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

Programm-Installation

Bevor Nextcloud installiert werden kann, müssen zunächst einmal alle Programme installiert werden, die zum Betrieb der Cloud notwendig sind.

Exkurs: Ubuntu-Paketquellen und Hersteller-Paketquellen

Die meisten benötigten Programme sind bereits in den offiziellen Ubuntu-Paketquellen enthalten. Diese könnte man nun ohne Umwege direkt über apt installieren. Jedoch legt die Distribution Wert auf die Stabilität der Programme, die in den offiziellen Paketquellen enthalten sind. Leider sind diese Programm-Versionen oftmals ziemlich alt und erhalten keine größeren Updates mehr. Daher altert ein solches System recht schnell und man kann keine Features der Programme nutzen, die in neueren Versionen hinzugefügt werden.

Die Hersteller der Programme bieten darüber hinaus auch meistens eigene Paketquellen (Repositories) an. Die hier enthaltenen Versionen sind meistens wesentlich aktueller und werden auch zukünftig mit (Feature-)Updates versorgt. Oftmals unterscheiden die Hersteller dabei nochmals zwischen zwei (oder sogar mehr) Entwicklungs-Branches: Meist gibt es einen Stable-Branch, dessen Programm-Versionen möglichst stabil gehalten werden. Daher sind auch hier meistens keine größeren Updates mehr zu erwarten und neue Features werden erst nach z.T. langer Zeit in diesen Branch mit aufgenommen. Daneben gibt es meist noch einen Mainline-Branch, der zwar auch als stabil betrachtet werden kann, aber zeitnah mit Updates und neuen Features versorgt wird.

Daher muss man nun für sich selbst entscheiden, welche Programm-Versionen/Repositories zum Einsatz kommen:

  • Wenn Stabilität das absolut Wichtigste ist, dann sollten die offiziellen Ubuntu-Paketquellen verwendet werden.
  • Wenn man eine LTS-Version von Ubuntu gewählt hat, bleibt man oftmals sehr lange auf dieser einen Betriebssystem-Version. Hier ist Stabilität ein wichtiger Faktor. Wenn darüber hinaus trotzdem einigermaßen aktuelle Software eingesetzt werden soll, dann ist der Stable-Branch der Hersteller zu empfehlen.
  • Wer von neuen Features aktueller Programm-Versionen profitieren und die Programme auf einem möglichst aktuellen Stand halten möchte, sollte den Mainline-Branch der Software-Hersteller nutzen.

Meiner Erfahrung nach sind die Mainline-Branches der Hersteller allerdings ausreichend stabil, so dass auch der Einsatz in produktiven Umgebungen empfohlen werden kann. Daher nutze ich in diesem Artikel meist die Mainline-Branches aus den Paketquellen der Software-Hersteller.

Wer auf andere Versionen/Branches setzt, muss evtl. die im Artikel gezeigten Schritte geringfügig anpassen, da z.B. einige Programm-Features nicht verfügbar sind.

Hinweis für Raspberry Pi Benutzer: Oftmals verzichten die Software-Hersteller darauf, in ihren Paketquellen Programm-Versionen für die ARM-Architektur bereit zu stellen. In diesem Fall würde ein Hinzufügen der Hersteller-Repositories zu einem Fehler bei der Programm-Installation führen. In diesem Fall muss man auf die Paketquellen von Raspbian/Debian zurückgreifen und kann keine Hersteller-Repositories einbinden.

nginx

Zuerst wird der Webserver installiert. Da ich hier das Mainline-Repository von nginx verwende, muss diese Paketquelle zunächst auf dem System eingebunden werden.

Als erstes fügen wir den Key des Repositories hinzu, da es ansonsten später bei der Installation zu einer Fehlermeldung kommt:

wget -O - http://nginx.org/keys/nginx_signing.key | apt-key add -

Nun kann die Paketquelle selbst hinzugefügt werden. Dazu legen wir eine entsprechende Datei an:

nano /etc/apt/sources.list.d/nginx.list

Diese wird mit folgendem Inhalt gefüllt:

# Nginx (Mainline)
deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ focal nginx
deb-src [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ focal nginx

Die Installation des Webservers erfolgt nun über diesen Befehl:

apt update && apt install nginx

Direkt nach der Installation kann man die Funktionsweise des Webservers im Browser testen (einfach durch Aufruf der IP des Servers):

Der Webserver läuft

Der Webserver läuft

MariaDB

Weiter geht es mit dem Datenbanksystem. Wie schon bei nginx pflegt der Hersteller hier seine eigenen Repositories. Hier gibt es die beiden Branches „Stable“ und „Development“ – hier ist auf jeden Fall der „Stable“ Release vorzuziehen. Mehr Informationen zu den Releases von MariaDB gibt es in der MariaDB-Knowledgebase.

Wie schon bei nginx, muss erst einmal der Repository-Key auf dem System bekannt gemacht werden:

sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'

Die MariaDB-Paketquellen werden kann wieder in einer einzelnen Datei hinzugefügt:

nano /etc/apt/sources.list.d/MariaDB.list

# MariaDB 10.4 repository list
# http://downloads.mariadb.org/mariadb/repositories/
deb [arch=amd64] http://mirror.netcologne.de/mariadb/repo/10.4/ubuntu focal main
deb-src http://mirror.netcologne.de/mariadb/repo/10.4/ubuntu focal main

Die Installation von MariaDB wird dann mit folgendem Befehl durchgeführt:

apt update && apt install mariadb-server

PHP

Als nächstes werden die benötigten PHP-Pakete installiert:

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

Werden später weitere PHP-Pakete benötigt (z.B. für einige Nextcloud Apps), so können diese zu einem späteren Zeitpunkt nachinstalliert werden.

Let’s Encrypt/acme.sh

Zur Generierung der Zertifikate für HTTPS ist noch ein Let’s Encrypt Client notwendig. Ich empfehle hier den Client acme.sh, da es sich hierbei um ein reines Bash-Skript handelt. Auf diese Weise ist man nicht abhängig von einer „echten“ Programm-Installation, welche zu einem Problem werden kann, wenn die Version in den Paketquellen zu alt ist.

acme.sh sollte dabei nicht mit Root-Rechten (also auch ohne sudo) ausgeführt werden. Daher wird extra für acme.sh ein spezieller User angelegt:

adduser letsencrypt

Für diesen User muss kein Passwort vergeben werden (einfach leer lassen). Ebenso können die weiteren Angaben zum User (Name, E-Mail, etc.) weggelassen werden.

Dieser User wird dann noch der Gruppe www-data hinzugefügt:

usermod -a -G www-data letsencrypt

Der User letsencrypt braucht anschließend noch die Rechte, nginx ohne Eingabe eines Root-Passworts neu zu laden. Dies wird mit folgendem Befehl konfiguriert:

visudo

Ganz am Ende der Datei wird nun folgende Zeile hinzugefügt:

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

Nun kann auch schon acme.sh installiert werden. Dazu wechseln wir zunächst zum User letsencrypt:

su - letsencrypt

Die Installation wird dann mit folgendem Befehl gestartet:

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

Nach einem kurzen Augenblick ist die Installation abgeschlossen und wir wechseln wieder zum normalen User:

exit

Konfiguration der Programme

Die Installation aller benötigten Programme ist nun abgeschlossen. Nun müssen diese allerdings noch konfiguriert werden, bevor die Nextcloud-Installation beginnen kann.

Konfiguration nginx

Hier bedarf es ein paar kleineren Anpassungen an der globalen nginx-Konfiguration:

nano /etc/nginx/nginx.conf

Hier sollten folgende Punkte angepasst/kontrolliert werden:

  • user: Gibt den Benutzer an, unter dem der Webserver läuft. Dies sollte immer www-data sein.
  • worker_processes: Die Anzahl der Threads, die nginx dazu verwendet, Client-Requests abzuarbeiten. Die optimale Einstellung ist hier auto, da nginx dann pro CPU-Kern einen Thread verwendet.
  • server_tokens: Mit der Angabe off sorgt man dafür, dass nginx keine Versions-Informationen preisgibt (z.B. auf Fehlerseiten). Wenn diese Variable nicht vorhanden ist, muss man diese im HTTP-Block der Datei einfügen: server_tokens off;

Nun deaktivieren wir gleich noch die Default-Seite von nginx, da dies sowieso nur eine Art Demo-Seite ist:

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

Am Schluss wird nginx noch neu gestartet, damit die Änderungen übernommen werden.

Konfiguration MariaDB

Bei der Datenbank muss nicht viel konfiguriert werden, allerdings sollte die Installation auf maximale Sicherheit getrimmt werden:

mysql_secure_installation

An dieser Stelle kann gleich ein Root-Passwort für MariaDB gesetzt werden. Alle weiteren Fragen des Assistenten sollten mit „Ja“ (y) beantwortet werden.

Konfiguration PHP

Bei PHP muss einiges mehr konfiguriert werden, da sich die Einstellungen über mehrere Dateien verteilen.

PHP wird bei nginx über FPM (FastCGI Process Manager) betrieben. Dies ist eine performante Möglichkeit der Kommunikation zwischen PHP und dem Webserver. FPM definiert einen sog. Thread-Pool, der die Anfragen abarbeitet (ähnlich wie schon bei nginx). Die Konfiguration ist dazu in folgender Datei zu finden:

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

Folgende Anpassungen sollten hier durchgeführt/kontrolliert werden:

  • user/group: Benutzer unter dem PHP ausgeführt wird. Dies ist wieder der Webserver-User www-data:
    user = www-data
    group = www-data
  • listen: Die Kommunikation zwischen dem Webserver und PHP findet über einen sog. Socket ab. Der Pfad des Sockets wird hier angegeben:
    listen = /run/php/php7.4-fpm.sock
  • Umgebungs-Variablen: Umgebungs-Variablen werden von PHP in der Standard-Einstellung nicht veräußert. Für den Betrieb von Nextcloud ist dies jedoch erforderlich. Daher suchen wir nach Pass environment variables like LD_LIBRARY_PATH. ALL $VARIABLES are taken from the current environment (Shortcut für die Suche in nano: STRG + W). Alle Einträge, die mit env beginnen sind hier auskommentiert. Durch das Entfernen des Semikolons am Zeilenanfang wird die Weitergabe der Umgebungs-Variablen aktiviert:
    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 zwei weitere Dateien, die allgemeine Einstellungen zu PHP beinhalten. Die erste ist die php.ini für FPM:

nano /etc/php/7.4/fpm/php.ini

  • cgi.fix_pathinfo: Sorgt für eine sichere Interpretation von Pfadangaben:

    cgi.fix_pathinfo = 0

  • memory_limit: Dieser Wert gibt an, wie viel Speicher ein PHP-Skript nutzen darf. Nextcloud benötigt mindestens 512 MB als Memory Limit:

    memory_limit = 512M

  • OPcache: PHP OPcache erhöht bessere Performance durch das Ablegen vorkompilierten Bytecodes in den Arbeitsspeicher. Diese Einträge dazu sollten in der php.ini bereits vorhanden sein (allerdings auskommentiert). Eine Suche in der Datei sollte einiges an Tipparbeit sparen. Folgende Werte sind hier anzugeben:

    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

Es gibt noch eine weitere Datei mit dem Namen php.ini. Diese enthält Einstellungen für PHP-CLI (PHP-Aufrufe direkt über die Kommandozeile):

nano /etc/php/7.4/cli/php.ini

  • cgi.fix_pathinfo: Wie oben beschrieben:

    cgi.fix_pathinfo = 0

Nach einem Neustart von PHP werden alle Änderungen übernommen

service php7.4-fpm restart

Generierung der Zertifikate für HTTPS

Nachdem alle Vorbereitungen getroffen worden sind, kann es nun an die Generierung der HTTPS-Zertifikate gehen.

Vorbereiten der Verzeichnisstruktur

Zunächst legen wir ein paar Verzeichnisse an und weisen diesen die entsprechenden Rechte zu:

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

Das erste Verzeichnis (/var/www/letsencrypt/.well-known/acme-challenge) wird später vom Webserver bereit gestellt. Darüber kann Let’s Encrypt die Domain verifizieren.
Unter /etc/letsencrypt werden die eigentlichen Zertifikate gespeichert. Ich lege hier immer ein Unterverzeichnis pro Domain an. Darunter dann getrennte Verzeichnisse für RSA- und ECDSA-Zertifikate. Damit bleibt es auch übersichtlich, wenn später mehrere Domains durch den Webserver bereit gestellt werden sollen.

Wichtig ist hier noch die Zuweisung der Rechte (chmod -R 775), damit der User für Let’s Encrpyt auch die erforderlichen Schreinrechte hat (dieser ist Mitglied der Gruppe www-data).

Anlegen des ersten virtuellen Hosts (HTTP-Gateway)

Als nächsten braucht man nun den virtuellen Host, der für die Zertifikats-Generierung benötigt wird. Ich nenne diesen Host hier einfach „HTTP-Gateway“, da dieser die gesamte Kommunikation über HTTP (Port 80) behandelt. Auch wenn dieser zunächst einmal für nur eine Domain gilt, kann dieser später ebenfalls erweitert werden, wenn weitere Domains gehostet werden sollen.

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

Folgender Inhalt wird hier eingefügt:

upstream php-handler {
    server unix:/run/php/php7.4-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;
	}
}

Anzumerken sind hier noch folgende Dinge:

  • Ganz oben wird ein sog. Upstream für PHP definiert. Durch die Anlage im HTTP-Gateway ist dieser immer verfügbar (und wird später für Nextcloud benötigt).
  • Weiter unten sieht man, wie sämtlicher Traffic, der nichts mit der Generierung der HTTPS-Zertifikate zu tun hat, an HTTPS weitergeleitet wird. Dadurch findet immer eine „Zwangs-Umleitung“ auf HTTPS statt, damit sämtliche Verbindungen stets verschlüsselt sind. Nur für die Zertifikats-Generierung über Let’s Encrypt muss der Traffic unverschlüsselt über Port 80 (HTTP) erfolgen.

Damit die Änderungen übernommen werden, muss der Webserver noch neu gestartet werden.

service nginx restart

Überprüfung des Webserver vor der Zeritikats-Generierung

Bevor man sich nun an der Generierung der Zertifikate macht, sollte die korrekte Konfiguration des Webservers (und der DynDNS-Domain/des Port-Forwardings) erfolgen. Hintergrund ist eine Einschränkung von Let’s Encrypt: Wenn die Generierung fehlschlägt (z.B. weil der Webserver einfach nicht über die DynDNS-Domain erreichbar ist), ist man meistens gewillt, den Befehl zum Generieren der Zertifikate mehrfach hintereinander auszuprobieren. Irgendwann stößt man hier an ein „Rate Limit“, nachdem Let’s Encrypt die Zertifikats-Generierung für 7 Tage sperrt. In diesem Fall muss man mit der Installation der Cloud für eine Woche warten und dies sorgt meist für Frust.

Dazu legen wir eine einfache Text-Datei an der Stelle ab, an der Let’s Encrypt die Verifizierung der Domain vornimmt:

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

Nun erfolgt ein einfacher Aufruf dieser Datei im Browser: http://nextcloud.meinedomain.de/.well-known/acme-challenge/test.txt. Wichtig ist hier die Angabe von HTTP (nicht HTTPS). Hier sollte dann der Inhalt der zuvor angelegten Datei angezeigt werden.

Test des Webservers vor der Generierung der Zertifikate

Test des Webservers vor der Generierung der Zertifikate

Am Schluss kann die Text-Datei wieder gelöscht werden:

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

Wichtig: Die Generierung der Zertifikate sollte erst nach einem erfolgreichen Test durchgeführt werden.
Wenn der Test nicht erfolgreich ist (und die Datei nicht angezeigt wird), sollte ein Blick in das Log von nginx erfolgen (/var/log/nginx/error.log). Hier sollte ersichtlich werden, an welcher Stelle der die Datei test.txt (erfolglos) sucht. Wenn hier keine passenden Inhalte im Log zu finden sind, liegt das Problem vermutlich an der DynDNS-Domain bzw. dem Port-Forwarding, so dass der Request gar nicht am Webserver ankommt.

Generierung der Zertifikate

Nun können endlich die Zertifikate erzeugt werden. Dazu wechseln wir zunächst wieder auf den User letsencrypt:

su - letsencrypt

Nun werden zunächst die RSA-Zertifikate erzeugt:

acme.sh --issue -d nextcloud.meinedomain.de --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"

Wenn dies erfolgreich war, können noch die ECDSA-Zertifikate generiert werden:

acme.sh --issue -d nextcloud.meinedomain.de --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"

Im Anschluss findet man die Zertifikat-Dateien im Verzeichnis /etc/letsencrypt/nextcloud.meinedoamin.de/rsa bzw. /etc/letsencrypt/nextcloud.meinedoamin.de/ecc:

  • 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 man daher niemals weitergeben)

Im Anschluss wechseln wir wieder auf den normalen User:

exit

Erneuerung der Zertifikate

Die Zertifikate von Let’s Encrypt haben eine Gültigkeit von 90 Tagen und müssen vor Ablauf dieses Zeitraums erneuert werden.

Um diese Erneuerung muss man sich allerdings nicht mehr kümmern, da im Rahmen der Zertifikats-Generierung für den User letsencrypt ein Cronjob eingerichtet wurde, der in regelmäßigen Abständen prüft, ob die Zertifikate bald ablaufen und diese ggf. automatisch erneuert.

Diffie-Hellman-Parameter

Die Sicherheit des Kommunikation mittels HTTPS kann noch durch den Einsatz sog. Diffie-Hellman-Parameter weiter erhöht werden. Mittels dieser Parameter kann einfach gesagt der Schlüsselaustausch beim Verbindungsaufbau weiter abgesichert werden. Da die Generierung eines dafür benötigten Schlüssels recht einfach ist, sollte dieser Schritt auf jeden Fall durchgeführt werden.

Achtung: Auf schwächerer Hardware – z.B. bei einem älteren Raspberry Pi – kann die Generierung des Schlüssels sehr lange dauern (bis zu einigen Stunden). Wer nicht so lange warten möchte, der kann auch einen Schlüssel mit „nur“ 2048 Bit errechnen lassen (die Zahl des zweiten Befehls gibt hierbei die Länge des Schlüssels in Bit an).

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

Webserver für Nextcloud vorbereiten

Nachdem wir nun gültige Zertifikate haben, kann der Webserver für die Installation von Nextcloud vorbereitet werden.

SSL-Konfiguration

Die allgemeine Konfiguration für SSL lagere ich immer in eine spezielle Datei aus. Diese kann dann später einfach in einen vHost eingebunden werden. Durch diese Modularität bleibt man bei der Konfiguration der virtuellen Hosts flexibler. Beispielsweise kann diese allgemeine SSL-Konfiguration später auch in anderen vHosts eingebunden werden, wenn später mehrere Webanwendungen gehostet werden sollen.

Dazu legen wir zunächst ein Verzeichnis für solche Snippets an:

mkdir -p /etc/nginx/snippets

Nun wird eine Datei für die allgemeine SSL-Konfiguration angelegt:

nano /etc/nginx/snippets/ssl.conf

Der Inhalt dieser Datei sieht folgendermaßen aus:

#
# Configure SSL
#

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

# 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';

# 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;

# SSL stapling has to be done seperately, becuase it will not work with self signed certs
# OCSP Stapling fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# DNS resolver
resolver 192.168.178.1;

Wichtig ist hier die Angabe des richtigen „Resolvers“: Dies ist der lokale DNS-Server, mittels dessen der Webserver Domain-Namen auflösen kann. In den meisten Fällen ist dies einfach die IP des Routers (in diesem Beispiel 192.168.178.1), der einen DNS-Server im lokalen Netzwerk bereit stellt. Alternativ kann hier ein beliebiger DNS-Server angegeben werden. Hier sollte man am besten nicht auf DNS-Server von Google oder Cloudflare setzen, sondern besser auf einen Server, der nicht protokolliert und nicht zensiert. Eine Liste mit empfehlenswerten Servern gibt es z.B. hier.

Header-Konfiguration

Bei jeder Webanwendung sollten vom Webserver gewisse Header gesetzt werden. Diese lagern wir wieder in eine spezielle Datei aus, damit diese später wieder in virtuelle Hosts eingebunden werden kann.

nano /etc/nginx/snippets/headers.conf

Diese Datei wird mit folgendem Inhalt gefüllt:

#
# Add headers to serve security related headers
#  
# HSTS (ngx_http_headers_module is required)
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;

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

Virtueller Host für Nextcloud

Nun setzen wir alle Puzzleteile zusammen und erstellen den vHost für Nextcloud selbst. Diesen benenne ich hier einfach nach dem verwendeten Domain-Namen:

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

Der Inhalt ist diesmal etwas umfangreicher:

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

	# 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;

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

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

	# The following 2 rules are only needed for the user_webfinger app. Uncomment it if you're planning to use this app. 
	#rewrite ^/.well-known/host-meta /public.php?service=host-meta last; 
	#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

	# Well-known URL for CardDAV
	location = /.well-known/carddav {
		return 301 $scheme://$host/remote.php/dav;
	}

	# Well-known URL for CalDAV
	location = /.well-known/caldav {
		return 301 $scheme://$host/remote.php/dav;
	}
	
	# Well-known URL for Webfinger
	# Regardless of this rule, you'll get a warning in the admin UI when the social app is not installed
	location = /.well-known/webfinger {
		return 301 $scheme://$host/public.php?service=webfinger;
	}

	# set max upload size
	client_max_body_size 10G;
	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/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;

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

	location / {
		rewrite ^ /index.php;
	}

	location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
		deny all;
	 }
	
	location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
		deny all;
	}

	location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
        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 $fastcgi_path_info;
		fastcgi_param HTTPS on;
		#Avoid sending the security headers twice
		fastcgi_param modHeadersAvailable true;
		fastcgi_param front_controller_active true;
		fastcgi_pass php-handler;
		fastcgi_intercept_errors on;
		fastcgi_request_buffering off;
		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 ~ ^\/(?:updater|ocs-provider|ocm-provider)(?:$|\/) {
		try_files $uri/ =404;
		index index.php;
	}

	# Adding the cache control header for js and css files
	# Make sure it is BELOW the PHP block
	location ~ \.(?:css|js|woff2?|svg|gif)$ {
		try_files $uri /index.php$request_uri;
		add_header Cache-Control "public, max-age=15778463";
		# Add headers to serve security related headers (It is intended to
		# have those duplicated to the ones above)
		# Before enabling Strict-Transport-Security headers please read into
		# this topic first.
		add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload;" always; 
		
		# WARNING: Only add the preload option once you read about
		# the consequences in https://hstspreload.org/. This option
		# will add the domain to a hardcoded list that is shipped
		# in all major browsers and getting removed from this list
		# could take several months
		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;

		# Optional: Don't log access to assets
		access_log off;
	}

	location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
		try_files $uri /index.php$request_uri;	
		# Optional: Don't log access to other assets
		access_log off;
	}
}

Diese Konfiguration ist an die vorgeschlagene nginx-Konfiguration im Nextcloud Administation Manual angelehnt. Zu beachten ist hier folgendes:

  • Es wird nur ein server für HTTPS (nicht HTTP) definiert. Dies reicht aus, da die Kommunikation mit der Nextcloud ausschließlich verschlüsselt (über HTTPS) ablaufen soll. Der zuvor angelegte HTTP-Gateway nimmt alle Verbindungen über HTTP entgegen und leitet diese an den HTTPS-vHost weiter.
  • Die Let’s Encrypt Zertifikate werden hier in doppelter Ausführung (einmal RSA, einmal ECDSA) angegeben. Beim Verbindungsaufbau wird dann das ECDSA-Zertifikat verwendet, wenn der Client dies unterstützt. Wenn nicht, findet ein „Fallback“ auf das RSA-Zertifikat statt.
  • Die bereits angelegten Dateien für die allgemeine SSL-Konfiguration und die Header werden hier einfach per include eingebunden.

Bitte auch die Kommentare in dieser Datei beachten und ggf. an die eigenen Bedürfnisse anpassen.

Nach diesen Änderung muss der Webserver natürlich noch neu gestartet werden:

service nginx restart

Installation Nextcloud

Endlich sind nun alle Vorbereitungen getroffen worden, damit kann es an die Installation von Nextcloud gehen.

Download

Zunächst laden wir die aktuellste Version von Nextcloud herunter und entpacken diese 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

Im Anschluss müssen noch die Berechtigungen für den Webserver-User gesetzt werden:

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

Anlegen des Datenverzeichnisses

Das Datenverzeichnis von Nextcloud sollte aus Sicherheitsgründen nicht innerhalb des www-Verzeichnisses liegen. Daher legen wir ein eigenes Verzeichnis dafür an und setzen hier ebenfalls die entsprechenden Berechtigungen:

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

Datenbank für Nextcloud anlegen

Vor dem Nextcloud-Setup muss noch eine Datenbank für Nextcloud angelegt werden. Dazu melden wir uns einfach an den MySQL-Kommandozeile an:

mysql -u root -p

Nach der Eingabe des Root-Passworts für MariaDB wird zunächst ein spezieller Datenbank-User für Nextcloud angelegt. Anschließend wird eine Datenbank angelegt und dem Nextcloud-Datenbank-User die entsprechenden Rechte zugewiesen. Die Angabe localhost sorgt dafür, dass der Zugriff auf die Datenbank nur auf dem lokalen System erfolgen kann. Ein Remote-Zugriff über das Netzwerk (auf diese Datenbank) ist damit aus Sicherheitsgründen nicht möglich. Die Befehle auf der MySQL-Kommandozeile müssen mit einem Semikolon abgeschlossen werden:

CREATE USER nextcloud_db_user@localhost IDENTIFIED BY 'MeInPasSw0rT';
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;

Hier sollte natürlich ein eigenes Passwort für den Nextcloud-DB-User gewählt werden. Beim Anlegen der Datenbank ist auch die Angabe von CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci wichtig, damit die Nextcloud-Datenbank mit 4-Byte-Support erstellt wird.

Nextcloud-Setup

Nun kann das Nextcloud-Setup gestartet werden. Dazu wird einfach die URL der Cloud im Browser aufgerufen (https://nextcloud.meinedomain.de). Hier werden nun folgende Informationen angegeben:

  • Benutzer/Passwort (Administrator): Im Rahmen des Setups wird ein erster Benutzer angelegt, der automatisch Administrator-Rechte für die Cloud besitzt. Der Benutzername ist dabei frei wählbar. Achten sollte man hier auf ein starkes Passwort, da die Cloud ja später öffentlich im Internet erreichbar ist.
  • Datenverzeichnis: Ebenso wird hier nun der Pfad des Datenverzeichnisses angegeben. Standardmäßig will das Setup diesen Datenpfad innerhalb des www-Verzeichnisses erstellen. Allerdings wird aus Gründen der Sicherheit empfohlen, dass das Datenverzeichnis außerhalb des Verzeichnisses /var/www liegen sollte. Daher sollte man hier genau darauf achten, dass hier das richtige Verzeichnis angegeben wird, welches wir zuvor für das Datenverzeichnis von Nextcloud erstellt hatten (/var/nextcloud_data).
  • Datenbank-Verbindung: Hier sind die Zugangsdaten für die soeben angelegte Datenbank anzugeben.
  • Empfohlene Apps: Ganz unten wird noch eine Option angeboten, dass empfohlene Apps gleich im Rahmen des Nextcloud-Setups aktiviert werden („Install recommend apps“). Dabei handelt es sich dann um die Apps Calender, Contacts, Talk, Mail und OnlyOffice. Da für diese Apps aber z.T. weitere Voraussetzungen erfüllt werden müssen, empfehle ich, diese Option im Nextcloud-Setup zu deaktivieren und diese Apps dann bei Bedarf zu einem späteren Zeitpunkt zu installieren.
Nextcloud Setup

Nextcloud Setup

Nach einem Klick auf Installation abschließen wird das Setup ausgeführt. Nach einem kurzen Augenblick wird man dann zur eigenen Cloud weitergeleitet.

Warnungen im Admin-Bereich

Nach der Installation sollte man gleich einen Blick in den Admin-Bereich der Cloud werfen (oben rechts auf das Symbol für den Benutzer Klicken und dann Einstellungen wählen). Weil der erste angelegte Benutzer Admin-Rechte hat, findet man nun auf der linken Seite unter Übersicht eine Zusammenfassung über die Cloud.

Hier werden nach einer frischen Installation mehrere Warnungen angezeigt:

Warnungen im Admin-Bereich nach dem Nextcloud Setup

Warnungen im Admin-Bereich nach dem Nextcloud Setup

Die erste Warnung bemängelt das Fehlen eines Memory-Caches für PHP. Dies ist dabei nicht als Fehler zu verstehen, sondern eher als Hinweis, dass die Performance der Cloud durch einen Memory-Cache verbessert werden kann. Dazu muss einfach nur eine Zeile in der Nextcloud-Konfiguration geändert werden:

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

Hier wird einfach am Ende folgende Zeile ergänzt:

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

Die beiden anderen Meldungen beziehen sich auf die Datenbank (fehlende Indizes und fehlende Konvertierung in „big int“ für einige Tabellen). Um diese Warnungen zu beseitigen müssen zwei OCC-Befehle (Kommandozeilen-Interface für Nextcloud) ausgeführt werden:

cd /var/www/nextcloud
sudo -u www-data php occ db:add-missing-indices
sudo -u www-data php occ db:convert-filecache-bigint

Beim zweiten Befehl wird zwar ein Hinweis angezeigt, dass die Konvertierung sehr lange dauern kann, dies ist bei einer komplett neuen Nextcloud-Installation nicht gegeben.

Wenn die Admin-Übersicht in der Nextcloud nun neu geladen wird, sollten alle Warnungen verschwunden sein.

Nach der Bearbeitung der Hinwiese werden keine Warnungen mehr angezeigt

Nach der Bearbeitung der Hinwiese werden keine Warnungen mehr angezeigt

Wenn mehr Warnungen im Admin-Bereich angezeigt werden: Wenn hier immer noch Warnungen zu sehen sein sollten, dann bitte nochmals alle Schritte dieses Tutorials überprüfen, ob nicht ein kleines Detail ausgelassen wurde (besonders die PHP-Konfiguration). Im Nextcloud Administration Manual findet man auch eine Übersicht aller Warnungen, die hier im Admin-Bereich angezeigt werden könnten und entsprechende Lösungsansätze.

Optimieren der Nextcloud-Konfiguration

Die Konfiguration von Nextcloud sollte über die Datei config.php noch weiter optimiert werden:

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

Hier sollten nun folgende Anweisungen eingefügt/kontrolliert werden:

  • HTTPS als Standard definierten: Um alle Verbindungen zur Nextcloud strikt per HTTPS zu behandeln, wird die Verbindung nur über https:// zu forcieren, sollte hier folgende Variable gesetzt werden:
    'overwriteprotocol' => 'https',
  • Zeitzone für Log-Einträge: Die richtige Zeitzone (z.B. für die Zeitangaben der Log-Einträge) wird durch diese Variable konfiguriert:
    'logtimezone' => 'Europe/Berlin',

Installation/Einrichtung Redis

Eine weitere Optimierung, die nun gleich durchgeführt werden sollte, ist die Einrichtung von Redis für Nextcloud. Die Cloud nutzt sog. Transactional File Locking, um Sperren bei parallelem Zugriff auf Dateien zu realisieren. Dateien, die gerade im Zugriff sind, werden dadurch „gelockt“, damit es bei parallelen Zugriffen nicht zu Datenverlusten kommen kann. Ansonsten würde hier immer die letzte Änderung „gewinnen“ und alle parallel durchgeführten Änderungen überschreiben.

Diese Sperren werden standardmäßig in der Datenbank von Nextcloud verwaltet. Um hier Last von der Datenbank zu nehmen und die generelle Performance zu erhöhen, kann hier auch Redis genutzt werden. Diese In-Memory-Datenbank ist genau für solche Aufgaben optimiert, wodurch sich die Performance-Verbesserung ergibt.
Hier sollte man allerdings nicht zu viel erwarten: In kleineren Cloud-Instanzen mit nur wenigen Benutzern wird man hier kaum messbare Änderungen erzielen. Trotzdem empfehle ich den generellen Einsatz von Redis, da die Einrichtung auch nicht besonders aufwändig ist.

Installation und Konfiguration Redis

Zunächst wird Redis und das dazugehörige PHP-Modul installiert:

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

Nun erfolgt die Konfiguration der In-Memory-Datenbank:

nano /etc/redis/redis.conf

Analog zur Konfiguration von PHP sollte auch Redis über einen Socket angesprochen werden. Dazu müssen in dieser Konfigurations-Datei folgende Einstellungen gesetzt werden.

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

Hiermit wird folgendes konfiguriert:

  • port: Redis lauscht standardmäßig auf dem Port 6379. Wie gesagt wollen wir aber einen Socket nutzen, daher wird das Lauschen auf einem Port deaktiviert.
  • unixsocket: Hiermit wird der eigentliche Socket definiert.
  • unixsocketperm: Berechtigungen für diesen Socket.

Nun muss der Redis-Benutzer noch der Gruppe www-data hinzugefügt werden:

usermod -a -G redis www-data

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

service redis-server restart

Einbinden von Redis in Nextcloud

Damit die eigene Cloud nun auch Redis nutzt, muss dieses noch in der Nextcloud-Konfiguration angepasst werden:

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

Am Ende der Datei wird nun folgende Konfiguration hinzugefügt:

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

Anschließend nutzt Nextcloud nun das Transactional File Locking.

Cronjob für Nextcloud einrichten

Nextcloud benötigt für den einwandfreien Betrieb die regelmäßige Ausführung von Hintergrundaufgaben (z.B. Bereinigung verwaister Datenbank-Einträge, etc.). Diese Aufgaben werden direkt nach der Installation per AJAX ausgeführt: Immer, wenn eine Seite der Cloud aufgerufen wird, wird beim Laden einer Seite geprüft, ob Hintergrundaufgaben anstehen und diese ggf. ausgeführt. Diese Methode hat jedoch zwei Nachteile: Es wird erstens immer ein angemeldeter Benutzer benötigt, denn nur durch diesen können die Hintergrundaufgaben beim Laden der Seite angestoßen werden. Wenn die Cloud nun lange ohne Benutzeranmeldung läuft, dann werden u.U. über einen längeren Zeitraum keine Hintergrund-Jobs ausgeführt. Zum anderen ist die Lösung über AJAX wenig performant.

Daher sollte die Hintergrundaufgaben besser per Cron ausgeführt werden. Hier prüft ein Hintergrund-Dienst in regelmäßigen Abständen, ob Hintergrundaufgaben ausgeführt werden sollten. Besonders auf schwächerer Hardware ist diese Methode deutlich effizienter.

Dazu wird einfach ein Cronjob unter dem Webserver-Benutzer angelegt:

crontab -u www-data -e

Am Ende der Datei wird anschließend folgende Zeile eingefügt:

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

Nach dem Speichern der Datei wird dieser Cronjob alle 5 Minuten automatisch ausgeführt. Theoretisch könnte hier auch eine andere Zeitspanne genutzt werden, allerdings ist die allgemeine Empfehlung 5 Minuten (siehe Nextcloud Admin-Manual).

Nach fünf Minuten kann nun in der Admin-Oberfläche (unter den Grundeinstellungen) der Cloud geprüft werden, ob der Cronjob ausgeführt wurde: Die entsprechende Option sollte nun auf Cron stehen. Ebenso sollte nach jeder Ausführung des Cronjobs unter Letzte Aufgabe ausgeführt folgendes stehen: Gerade eben.

Nextcloud: Ausführung von Hintergrund-Aufgaben per Cron

Nextcloud: Ausführung von Hintergrund-Aufgaben per Cron

Weitere Konfiguration Nextcloud

Damit ist die die grundsätzliche Konfiguration von Nextcloud soweit abgeschlossen. Nun ist es an der Zeit, die Cloud an die eigenen Bedürfnisse anzupassen.

Nextcloud kann nun durch eine große Auswahl an Apps erweitert werden: siehe Nextcloud App Store.

Generell ist bei der erweiterten Konfiguration von Nextcloud ein Blick ins Nextcloud Administration Manual empfehlenswert.

Optimierung der Server-Umgebung für Nextcloud

Die eigene Nextcloud ist nun soweit fertig eingerichtet und kann bereits genutzt werden. Dennoch kann die Server-Umgebung noch weiter optimiert werden.

ufw

ufw (uncomplicated firewall) ist eine Software-Firewall, die auf einer Ubuntu-Installation standardmäßig bereits installiert ist. Im Heim-Bereich übernimmt normalerweise der Router schon die Aufgaben einer Firewall, daher ist die Einrichtung von hier ufw optional. Auf einem Root-Server ist aber in der Regel keine Firewall vor den Server geschaltet, daher sollte die Einrichtung von ufw hier in jedem Fall erfolgen.

Falls ufw noch nicht installiert sein sollte, kann man dies mit folgendem Befehl nachholen:

apt update && apt install ufw

Die Firewall soll sämtlichen eingehenden Traffic blockieren, mit einigen Ausnahmen:

  • SSH (Port 22): Hier soll der Zugriff nur aus dem Heimnetzwerk erlaubt sein.
  • HTTP/HTTPS (Ports 80/443): Da der Zugriff aus dem Web erforderlich ist, muss hier auch eine Ausnahme hinzugefügt werden.

Mit folgenden Befehlen werden diese Regeln umgesetzt:

ufw default deny
ufw allow proto tcp from 192.168.178.0/24 to any port 22
ufw allow 80
ufw allow 443
ufw enable

Nach dem Aktivieren der Firewall können die Regeln nochmal überprüft werden:

ufw status

Wichtig: Wenn auf dem Server weitere Anwendungen installiert sind, die andere Ports nutzen oder z.B. ein abweichender Port für SSH genutzt wird, ist dies natürlich bei der Erstellung der Firewall-Regeln zu beachten. Man sollte also immer im Hinterkopf behalten, dass eine Firewall auf dem System aktiv ist und das diese ggf. angepasst werden muss.

Fail2ban

Nextcloud wird standardmäßig mit einem Brute-Force-Schutz ausgeliefert. Dieser sorgt bei fehlgeschlagenen Logins für eine Verzögerung von Login-Versuchen aus dem betroffenen Subnetz. Bei Brute-Force-Attacken führt dies zu maximal zu einer Verzögerung um 30 Sekunden zwischen Login-Versuchen. Allerdings werden keine IPs gebannt.
Daher ist für eine Absicherung der Cloud der Einsatz von Fail2ban sinnvoll. Gegenüber dem Brute-Force-Schutz der Nextcloud bietet Fail2ban folgende Vorteile:

  • Mit Fail2ban können IPs automatisch gebannt werden. Nach einem solchen Ban kann die betroffene IP nicht mehr auf die Nextcloud-Instanz zugreifen, es wird lediglich eine Fehlermeldung des Browsers angezeigt.
  • Fail2ban arbeitet IP-basiert: Es wird nur die betroffene IP blockiert, von der aus zu viele fehlgeschlagene Login-Versuche unternommen wurden. Andere Nutzer mit abweichenden IP-Adressen aus dem gleichen Netzwerk (Subnet) werden dabei nicht gebannt.
  • Das Einsatzgebiet von Fail2ban ist sehr weit gefächert: Man kann hier nicht nur die Nextcloud-Installation, sondern auch weitere Anwendungen auf dem Server absichern (z.B. Webserver und SSH).

Konfigurations-Dateien von Fail2ban

Vor der Installation noch ein paar Worte zu den Konfigurations-Dateien von Fail2ban: Das Programm unterscheidet zwischen zwei Arten von Konfigurations-Dateien: *.conf und *.local. Die conf-Dateien kommen bei der Installation mit und sind die „Standard-Einstellungen“. Diese Dateien sollten aber nie direkt bearbeitet werden, da diese bei einem Update von Fail2ban überschrieben werden können. Daher nutzt man für individuelle Änderungen Dateien mit gleichem Namen, aber mit der Dateiendung .local. Diese local-Dateien überschreiben dann die Standard-Einstellungen der conf-Dateien. Auf diese Weise geht eine individuelle Konfiguration bei einem Update von Fail2ban nicht verloren.

Deaktivieren des Nextcloud Brute-Force-Schnutzes

Wenn Fail2ban zum Einsatz kommt, dann der integrierte Brute-Force-Schutz von Nextcloud deaktiviert werden. Dazu bearbeiten wir die Konfigurations-Datei von Nextcloud:

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

Der Schutz wird durch die Eingabe folgender Zeile deaktiviert:

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

Hier sollte auch gleich noch kontrolliert werden, ob Nextcloud die richtige Zeitzone für die Einträge im Log nutzt, da es für Fail2ban essentiell ist, dass hier korrekte Zeiten geloggt werden:

'logtimezone' => 'Europe/Berlin',

Installation und Konfiguration Fail2ban

Nun kann Fail2ban installiert werden:

apt update && apt install fail2ban

Anschließend muss ein sog. „Filter“ für Nextcloud definiert werden:

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

In dieser Filter-Datei wird nun ein regulärer Ausdruck hinterlegt. Dieser definiert das Format, welches einen fehlgeschlagenen Login-Versuch im Nextcloud-Log identifiziert:

[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
            ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
            ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: .* \(Remote IP: <HOST>\).*}$

Damit dieser Filter zum Einsatz kommt, wird dieser Fail2ban noch bekannt gemacht:

nano /etc/fail2ban/jail.local

Hier fügen wir folgenden Inhalt ein:

[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 Teil unter [DEFAULT] gilt dabei für alle Regel-Sets (Jails). Hier werden die allgemeinen Einstellungen für Bans hinterlegt:

  • maxretry: Anzahl der Fehlversuche, bevor Fail2ban eine IP sperrt.
  • bantime: Zeitraum (in Sekunden), für den eine IP gesperrt werden soll. Durch die Eingabe von -1 werden betroffene IPs dauerhaft gebannt.

Unter [nextcloud] wird dann neues Jail für Nextcloud definiert:

  • enabled: Aktivierung dieser Regel. Falls das Jail später (temporär) deaktiviert werden soll, kann dies einfach durch diese Option erfolgen.
  • port: Port, hier 80 (HTTP) und 443 (HTTPS).
  • protocol: Das verwendete Protokoll, in unserem Fall TCP.
  • filter: Name des Filters aus gleichnamiger Datei unter /etc/fail2ban/filter.d. Der Filter für Nextcloud wurde ja schon im vorherigen Schritt angelegt.
  • logpath: Log-Datei, die Fail2ban für dieses Jail beobachten soll. Auf diese Datei wird der oben definierte Filter angewendet.
  • Hier könnten auch noch Werte für maxretry und bantime hinterlegt werden, die dann sie Standard-Werte überschreiben und nur für das Nextcloud-Jail gelten.

Wir aktivieren hier unter [nginx-http-auth] auch gleich noch die Überwachung der Logs des Webservers. Dieses Jail ist bereits in den Standard-Jails (/etc/fail2ban/jail.conf) definiert und wird an dieser Stelle lediglich „scharf geschaltet“. Dies sorgt für eine Überwachung bei anderen Webanwendungen, bei den eine HTTP-Basic-Authentifizierung zum Einsatz kommt. Die Ban-Optionen (maxretry und bantime) werden hier nicht angegeben, daher gelten die Standard-Werte, die in der Sektion [DEFAULT] angegeben wurden.

Nun fehlt nur noch ein Neustart des Dienstes:

service fail2ban restart

Optional: E-Mail-Versand durch Fail2ban

Fail2ban arbeitet nun „lautlos“ im Hintergrund. Nur ein Administrator kann den aktuellen Status von Fail2ban über die Kommandozeile prüfen.

Sinnvoll ist nun noch eine Erweiterung, damit Fail2ban im Falle eines Bans eine E-Mail an den Server-Administrator verschickt. Die Voraussetzung ist dabei, dass das Linux-System bereits Mails versenden kann. Dies kann ohne großen Aufwand über msmtp realisiert werden. Die Installation und Einrichtung des Programms wurde bereits im Artikel Linux: Einfach E-Mails senden mit msmtp ausführlich erklärt.

Bei Fail2ban ist bereits der Versand von E-Mails vorgesehen, daher reichen hier kleinere Anpassungen, wenn msmtp bereits installiert wurde:

nano /etc/fail2ban/jail.local

Am Anfang werden nun in der Default-Sektion folgende Zeilen eingefügt (hier markiert):

[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 Optionen werden damit gesetzt:

  • destemail ist die Mail-Adresse, an die Benachrichtigungen verschickt werden.
  • sender ist die Adresse, von der die E-Mail gesendet werden (Absender).
  • Wichtig ist insbesondere die Zeile action = %(action_mwl)s: Hierdurch werden E-Mails standardmäßig versendet.

Nun würde man bei jeder Aktion von Fail2ban eine E-Mail erhalten, also auch wenn der Dienst z.B. neu gestartet wurde. Wenn Fail2ban ausschließlich beim Bannen einer IP eine Mail versenden soll, müssen noch ein paar Änderungen vorgenommen werden. Die Konfiguration dazu wird wieder über local-Dateien im Verzeichnis /etc/fail2ban/action.d realisiert. Folgende Dateien müssen dafür angelegt werden:

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

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 =

Am Ende noch Fail2ban neu starten:

service fail2ban restart

Test der Funktionalität

Am Schluss sollte noch die Funktionalität von Fail2ban getestet werden. Dies ist insbesondere sinnvoll, damit man auch mal das Entbannen einer IP durchgeführt hat – es könnte ja mal sein, dass man sich selbst „aussperrt“.

Dazu meldet man sich einfach drei mal mit einem nicht vorhandenen Benutzer an der eigenen Cloud an. Beim vierten Versuch sollte wie Webseite dann gar nicht mehr aufrufbar sein. Zeitgleich sollte man eine E-Mail erhalten, die über den Ban informiert. Auf der Kommandozeile kann man sich diesen Ban nun anzeigen lassen:

fail2ban-client status nextcloud

Hier sollte nun die gebannte IP aufgeführt werden. Um den Ban aufzuheben, geben wir nun folgenden Befehl ein:

fail2ban-client set nextcloud unbanip 45.135.54.12

Anschließend sollte man wieder wie gewohnt auf Nextcloud zugreifen können.

Überprüfung der Sicherheit

Die Sicherheit der eigenen Cloud war ja von Anfang an ein wichtiges Ziel dieses Artikels. Nach der Einrichtung von Nextcloud gibt es einige Tools, mit denen dies nochmal kontrolliert werden kann.

Qualys SSL Labs

Mit dem SSL Server Test von Qualys SSL Labs kann die HTTPS-Verschlüsselung auf einfache Weise überprüft werden. Getestet wird hier sowohl die Einbindung der Let’s Encrypt Zertifikate, als auch die SSL-Einstellungen des Webservers.
Wenn alles richtig konfiguriert wurde, sollte hier eine Bewertung von A+ angezeigt werden:

Qualys SSL Server Test

Qualys SSL Server Test

Mozilla Observatory

Ebenfalls ein guter Test ist Mozilla Observatory. Hier sollte ebenso ein Rating von A+ erzielt werden können.

Mozilla Observatory

Mozilla Observatory

Nextcloud Security Scan

Ein weiterer Test ist der Nextcloud Security Scan. Dieses Tool prüft die öffentlich verfügbaren Informationen der Nextcloud-Instanz und kann eventuelle Schwachstellen aufzeigen. Auch hier sollte ein Rating von A+ angezeigt 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 18.04 LTS am laufen. Soll ich diese nun möglichst schnell auf Ubuntu Server 20.04 LTS updaten?

Ubuntu 18.04 LTS wird noch bis April 2023 unterstützt. Daher ist beim Update auf Ubuntu Server 20.04 LTS keine Eile geboten. Im Gegenteil: Wenn das System ansonsten keine Probleme bereitet, würde ich mit dem Update noch etwas abwarten – zumindest bis zur Version 20.04.1.
Bei komplett neuen Installationen macht es dagegen durchaus Sinn, direkt auf Ubuntu Server 20.04 LTS aufzusetzen.

Der Artikel zeigt, wie man Nextcloud direkt im Root-Verzeichnis des Webservers installiert. Ich möchte die Nextcloud allerdings in einem Unterverzeichnis des Webservers laufen lassen. Was muss ich dazu beachten?

Durch die vereinfachte Webserver-Konfiguration empfehle ich mittlerweile die Installation der eigenen Cloud direkt im Web-Root (z.B. https://nextcloud.meinedomain.de). Wer Nextcloud dennoch in einem Unterverzeichnis des Webservers laufen lassen will (z.B. https://meinedomain.de/nextcloud), der kann sich dazu am vorherigen Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban orientieren.

Ich möchte eine weitere Webanwendung auf dem gleichen Server installieren. Wie muss ich dazu vorgehen?

Angenommen, man möchte neben Nextcloud (nextcloud.meinedomain.de) noch eine WordPress-Instanz unter (blog.meinedomain.de) aufsetzen. In diesem Fall muss zunächst einmal sicher gestellt sein, dass die zweite Domain auch auf die eigene IP-Adresse verweist. Hier reichen wieder A- bzw. AAAA-Records bei der zweiten Domain aus, wenn es sich um eine fest IP handelt. Falls nicht, muss ein sog. CNAME-Eintrag für die Domain blog.meinedomain.de erstellt werden, der auf die DynDNS-Adresse verweist (in diesem Fall nextcloud.meinedomain.de). Dies ist notwendig, weil die meisten Router nicht die gleichzeitige Verwendung mehrerer DynDNS-Konfigurationen erlauben.

Anschließend muss der HTTP-Gateway erweitert werden, so dass dieser auch auf die neue Domain reagiert:

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

Hier fügen wir die neue Domain unter server_name ein:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name nextcloud.meinedomain.de blog.meinedomain.de 192.168.178.60;
    
    #...
}

Nach einem Neustart können nun für die zweite Domain Zertifikate bei Let’s Encrypt beantragt werden. Dies geschieht analog wie im Artikel für die Domain nextcloud.meinedomain.de gezeigt.

Nun kann ein weiterer virtueller Host für die zweite Domain erstellt werden:

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

Hier werden dann die soeben ausgestellten Zertifikate eingebunden. Dank er Modularisierung mit den „Snippets“ für die allgemeine SSL-Konfiguration und den Headern, können diese Bausteine wiederverwendet werden:

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name blog.meinedomain.de;
 
	# SSL configuration
	# RSA certificates
	ssl_certificate /etc/letsencrypt/blog.meinedomain.de/rsa/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/blog.meinedomain.de/rsa/key.pem;
	# ECC certificates
	ssl_certificate /etc/letsencrypt/blog.meinedomain.de/ecc/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/blog.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/blog.meinedomain.de/ecc/ca.pem;
 
    # Include SSL configuration
	include /etc/nginx/snippets/ssl.conf;
 
	# Include headers
    include /etc/nginx/snippets/headers.conf;
    
    #...
}

Die weitere Konfiguration des vHosts für blog.meinedomain.de ist abhängig von der jeweiligen Webanwendung, die installiert werden soll. Für WordPress findet man z.B. hier eine Konfiguration, die man als Grundlage verwenden kann.

Auf diese Weise hat man die Konfigurationen zu den einzelnen Webseiten durch den Einsatz von zwei separaten vHosts gut getrennt.

Troubleshooting

Das hier gezeigte Setup ist durchaus umfangreich. Daher kann es passieren, dass nicht alles auf Anhieb klappt. Für diese Fälle hier noch ein paar Tipps und Tricks für die Fehlersuche:

  • Wurden alle Schritte korrekt ausgeführt?
    Die Installation der eigenen Cloud erfordert viele Schritte, die aufeinander aufbauen. Hier kann es leicht vorkommen, dass man einen kleinen Schritt übersieht, oder es während der Ausführung des Schrittes zu einem Fehler gekommen ist, den man aber nicht bemerkt hat. Auch wenn der Schritt noch so unbedeutend aussehen mag: Die kleinste Abweichung kann dazu führen, dass „das große Ganze“ nicht mehr funktioniert. Als ersten Punkt für die Fehlersuche empfehle ich daher immer nochmal die genaue Kontrolle der einzelnen Schritte.
  • Kontrolle der Logs
    Wenn irgend etwas nicht auf Anhieb klappen mag, hilft oftmals ein Blick in die entsprechenden Log-Dateien:

    • nginx (/var/log/nginx/error.log): Der Webserver führt hier alle Warnungen und Fehler auf. Dies sollte immer die erste Anlaufstelle sein, wenn sich Nextcloud gar nicht aufrufen lässt bzw. Links nicht richtig funktionieren.
    • Nextcloud (/var/nextcloud_data/nextcloud.log): Hier sind Fehler/Warnungen von Nextcloud selbst enthalten. Die Logs können auch direkt über die Admin-Oberfläche von Nextcloud untersucht werden. Die Einträge im Nextcloud-Log sind v.a. dann interessant, wenn die eigene Cloud prinzipiell aufgerufen werden kann (und der Webserver vermutlich korrekt eingerichtet wurde), es aber bei der Benutzung von Nextcloud zu Problemen kommt.
  • Developer-Console im Browser
    Wenn die Kontrolle der Logs zu keinen Erkenntnissen führen, dann es sinnvoll sein, einen Request mit geöffneter Developer-Console im Browser (meist zu öffnen mit F12) auszuführen. Hier wird detailliert aufgelistet, was bei einem Aufruf des Clients passiert. Die Bedienung der Console läuft in jedem Browser etwas anders ab, daher hilft ein Blick in die entsprechende Dokumentation:

Falls ihr also Probleme bei der Einrichtung von Nextcloud haben solltet, bitte erst einmal diese Punkte überprüfen. Oftmals findet man dann relativ schnell die Ursache. Wenn alles nicht hilft, dann könnt ihr hier natürlich einen Kommentar hinterlassen, vielleicht kann euch schnell weitergeholfen werden.

Falls sich bestimmte Probleme häufen sollte, werde ich den Artikel ggf. anpassen und/oder erweitern.

Nextcloud: Ein sicherer Ort für all deine Daten

Dies ist der bekannte Slogan von Nextcloud und dieser trifft es auch ziemlich genau: Auch wenn der Aufwand zum Aufsetzen der eigenen Cloud nicht zu unterschätzen ist, ist man nach getaner Arbeit jedoch unabhängig von einem (externen) Cloud-Anbieter. Dadurch bleibt man jederzeit Herr über die eigenen Daten, die sicher und einfach in der eigenen Cloud gespeichert werden können.

Jedoch sollte man sich auch im Klaren darüber sein, dass man nun auch für den Betrieb der Cloud verantwortlich ist. Dies erfordert nach dem Aufsetzen von Nextcloud auch einen gewissen administrativen Aufwand. So ist der Cloud-Admin dafür verantwortlich, dass die Cloud und das Betriebssystem auf dem aktuellen Stand gehalten werden. Dennoch sollte sich der Aufwand hierfür in Grenzen halten.

Ich hoffe, dass dieser Artikel hilfreich war und ich einigen unter euch etwas Zeit (und Nerven) bei der Einrichtung der eigenen Cloud ersparen konnte. Für konstruktive Kritik und Verbesserungsvorschläge bin ich immer offen, daher hinterlasst mir doch gern einen Kommentar.

In diesem Sinne heißt es wie immer: Viel Spaß mit eurer eigenen Nextcloud!

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-auf-ubuntu-server-20-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/feed/ 181
Jitsi Meet: Videokonferenz-System unter Ubuntu Server mit nginx https://decatec.de/home-server/jitsi-meet-videokonferenz-system-unter-ubuntu-server-mit-nginx/ https://decatec.de/home-server/jitsi-meet-videokonferenz-system-unter-ubuntu-server-mit-nginx/#comments Sat, 21 Mar 2020 14:09:21 +0000 https://decatec.de/?p=6465 Jitsi Logo

Videokonferenzen werden heutzutage immer wichtiger. Im geschäftlichen Umfeld kommen hier meist proprietäre Lösungen wie z.B. Skype zum Einsatz. In Sachen Datenschutz und Privatsphäre sind diese Lösungen natürlich bedenklich.

Die bessere Alternative kann hier Jitsi Meet sein. Dies ist eine quelloffene Software, mit der Videokonferenzen mit mehreren Teilnehmern durchgeführt werden können.

Der folgende Artikel zeigt die Installation und Konfiguration von Jitsi Meet unter Ubuntu Server mit nginx als Webserver. Ebenso kommt coturn als eigener TURN-/STUN-Server zum Einsatz.

Update-Historie (letztes Update: 02.05.2020)
  • 02.05.2020:
    • Einbindung eines eigenen coturn-Servers verbessert (useStunTurn).
    • Hinweis zum Deaktivieren der Verbindungen zu externen Diensten ergänzt.
  • 05.04.2020:
    • Artikel nochmals auf die aktuellste Jitsi Meet Version angepasst.
    • coturn wird nun als TURN-/STUN-Server für Jitsi Meet integriert.
  • 03.04.2020:
    • Artikel überarbeitet, da sich nach dem letzten Update von Jitsi Meet einiges geändert hat.
  • 28.03.2020:
    • Weitere Hinweise zur Verwendung eines eigenen STUN-Servers (coturn) hinzugefügt.

Voraussetzungen/Ziele

Zum Thema Jitsi Meet gibt es bereits unzählige Tutorials im Netz. Diese beziehen sich aber meist nur auf die Standard-Installation und es wird meist auch nicht explizit auf die Webserver-Konfiguration eingegangen. Das Augenmerk auf die (sichere) Webserver-Konfiguration ist meiner Meinung allerdings sehr wichtig, v.a. wenn auf dem Server bereits andere Anwendungen gehostet werden.

Darüber hinaus schlägt die Installation unter Ubuntu Server 18.04 u.U. manchmal fehl. Hier gilt es dann einige Besonderheiten zu beachten.

Dabei kommen folgende Programm-Versionen zum Einsatz:

  • Ubuntu Server 18.04 LTS („Bionic Beaver“).
  • nginx 1.17.9 (aktuelle Mainline-Version).
  • coturn 4.5.0.7.

Dieses Tutorial konzentriert sich dabei v.a. auf Jitsi Meet. Eine komplette Beschreibung der Webserver-Konfiguration (nginx, Let’s Encrypt/acme.sh) würde sicherlich den Rahmen des Artikel sprengen.

Wichtig: nginx muss vor der Installation von Jitsi Meet bereits auf dem System vorhanden sein, da das Jitsi-Setup darauf aufbaut und virtuelle Hosts anlegt.

Ich gehe im folgenden davon aus, dass auf dem System nginx bereits installiert und eingerichtet ist. Ebenfalls sollte alles vorbereitet sein, dass TLS-Zertifikate über Let’s Encrypt ausgestellt werden können.

Wie eine entsprechende Konfiguration (nginx/Let’s Encrypt) aussehen kann wird in folgenden Artikel näher beschrieben:

Ebenso wird eine bereits laufende Instanz von coturn (TURN-/STUN-Server) vorausgesetzt. Die dies umgesetzt werden kann, ist im Artikel Nextcloud Talk mit eigenem TURN-Server (coturn) beschrieben.

Im Rahmen des Tutorials nutze ich folgende beispielhafte Domains:

  • meet.meinedomain.de für die Jitsi Meet Installation.
  • turn.meinedomain.de für die coturn-Instanz.

Systemvoraussetzungen

Jitsi Meet hat moderate Systemvoraussetzungen, was CPU/RAM angeht. Logischerweise sind die Anforderungen bzgl. der Bandbreite (Up- bzw. Download) für eine Videokonferenz-Lösung recht hoch. Dies hängt allerdings stark von der erwarteten Nutzung (= Anzahl der parallel zugreifenden Teilnehmer) des Jitsi Meet Servers ab.
Trotzdem sollte man sich an einem privaten Internet-Anschluss nicht all zu viele Hoffnungen machen. Auch bei einer guten Bandbreite des Internet-Anschlusses wird man hier bei einer selbstgehosteten Lösung in den eigenen vier Wänden nur Konferenzen mit wenigen Teilnehmern durchführen können. Im Allgemeinen ist daher die Empfehlung, Jitsi Meet auf einem eigenen Root-Server zu betreiben. Aus eigener Erfahrung kann ich hier einen Server von Netcup (Affiliate-Link) empfehlen.

Vor der Installation zu beachten

Jitsi Meet besteht aus einer Reihe von Komponenten, die im Rahmen des Setups installiert werden.

Wenn auf dem Server bereits Teile dieser Komponenten installiert sind, besteht die Gefahr, dass bereits laufende Systeme unbrauchbar werden, da Jitsi Meet einfach die bestehenden Komponenten/Konfiguration überschreibt.

Dies betrifft zum einen coturn, als auch Prosody.
Die Beschreibungen in diesem Artikel sorgen dafür, dass ein vorhandener coturn Server nicht überschrieben wird.

Allerdings sollte das Jitsi Meet Setup nicht ausgeführt werden, wenn bereits ein Prosody/XMPP Server auf dem System betrieben wird.

Vorbereitungen

Nun kann es auch schon an die Installation gehen.

Betriebssystem-Updates

Vor der eigentlichen Installation wird das System zunächst auf den neusten Stand gebracht:

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

Anpassungen nginx

Wichtig: nginx ist meistens so konfiguriert, dass die virtuellen Hosts unter /etc/nginx/conf.d geladen werden. Das Setup von Jitsi Meet geht allerdings davon aus, dass die virtuellen Hosts unter /etc/nginx/sites-available bzw. /etc/nginx/sites-enabled zu finden sind. Daher müssen diese Verzeichnisse manuell angelegt werden, falls diese noch nicht vorhanden sind (dies betrifft darüber hinaus auch noch ein drittes Verzeichnis):

mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled
mkdir -p /etc/nginx/modules-enabled

Wird dieser Schritt nicht ausgeführt, schlägt das Setup von Jitsi Meet später fehl!

Domain/TLS-Zertifikate

Wie bereits erwähnt, nutzen wir für den Artikel die fiktive (Sub-)Domain meet.meinedomain.de.

Für diese Domain sollten vor dem Jitsi-Setup bereits Zertifikate über Let’s Encrypt beantragt werden. Folgende Artikel sollten dazu einen guten Anhaltspunkt geben:

Die folgende Konfiguration wird RSA- und ECDSA-Zertifikate (Hybrid-Betrieb) mit TLSv1.2/TLSv1.3 nutzen.

Auflösung der Domain auf localhost

Auf dem Server, auf dem Jitsi Meet installiert werden soll, muss die verwendete Domain auf localhost auflösen. Dies wird in der Hosts-Datei konfiguriert:

nano /etc/hosts

Ganz unten wird nun folgender Eintrag hinzugefügt:

127.0.0.1 meet.meinedomain.de

Installation Jitsi Meet

Als nächstes kann es an die eigentliche Installation von Jitsi Meet gehen.

Jitsi Meet – Setup

Da das Programm (noch) nicht in den offiziellen Ubuntu Paketquellen enthalten ist, müssen wir das Repository zunächst einbinden.

Dazu wird als erstes der Repository-Key im System importiert:

wget -qO -  https://download.jitsi.org/jitsi-key.gpg.key | apt-key add -

Anschließend kann das Repository eingebunden werden:

echo 'deb https://download.jitsi.org stable/' >> /etc/apt/sources.list.d/jitsi-stable.list

Nun werden die Paketquellen noch aktualisiert:

apt update

Es folgt die eigentliche Installation.
Wichtig ist hierbei die Angabe von no-install-recommends, da ansonsten u.a. die Konfiguration von coturn überschrieben wird.

apt install --no-install-recommends jitsi-meet

Während der Installation wird man zuerst nach der Domain gefragt, unter der Jitsi Meet gehostet werden soll. Dies ist die Domain, für das vorher schon das TLS-Zertifikat ausgestellt wurde – in diesem Beispiel also meet.meinedomain.de.

Jitsi Meet Setup: Eingabe der Domain

Jitsi Meet Setup: Eingabe der Domain

Als nächstes wird noch nach dem Zertifikat gefragt: Hier muss die zweite Option gewählt werden (I want to use my own certificate), da wir die Zertifikate selbst verwalten wollen (siehe oben).

Jitsi Meet Setup: Verwendung eigener Zertifikate

Jitsi Meet Setup: Verwendung eigener Zertifikate

Nun wird man noch nach dem Speicherort der Zertifikats-Dateien gefragt. Diese beiden Dialoge (einmal für die *.key und einmal für die *crt-Datei) kann einfach mit OK bestätigt werden. Die Zertifikate werden im Anschluss manuell im virtuellen Host von nginx hinzugefügt.

Jitsi Meet Setup: Pfad zu den Zertifikats-Dateien

Jitsi Meet Setup: Verwendung eigener Zertifikate

Das Setup sollte anschließend ohne Probleme durchlaufen.

Jitsi Meet – Anpassen des virtuellen Hosts (nginx)

Das Setup hat nun im Verzeichnis /etc/nginx/sites-available einen neuen virtuellen Host erstellt und einen symbolischen Link in /etc/nginx/sites-enabled hinzugefügt. Da wir an dieser Stelle die Verzeichnisse sites-availabe und sites-enabled nicht verwenden, wird die Datei hier entfernt und in das passende Verzeichnis verschoben:

rm /etc/nginx/sites-enabled/meet.meinedomain.de.conf
mv /etc/nginx/sites-available/meet.meinedomain.de.conf /etc/nginx/conf.d/meet.meinedomain.de.conf

Den Webserver noch nicht neu starten, erst bedarf es noch Anpassungen am vHost für Jitsi Meet.

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

Diese Datei wird nun folgendermaßen bearbeitet (alle Änderungen sind hier markiert):

server_names_hash_bucket_size 64;

#server {
#    listen 80;
#    server_name meet.meinedomain.de;
#    return 301 https://$host$request_uri;
#}

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

    #
    # SSL configuration
    # 

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

    # This should be ca.pem (certificate with the additional intermediate certifica$
    # See here: https://certbot.eff.org/docs/using.html
    # ECC
    ssl_trusted_certificate /etc/letsencrypt/meet.meinedomain.de/ecc/ca.pem;

    # SSL stapling has to be done seperately, becuase it will not work with self signed certs
    # OCSP Stapling fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

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

    # 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';
    
    # Use multiple curves.
    ssl_ecdh_curve secp521r1:secp384r1;

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

    # Add your DNS resolver here
    resolver 192.168.178.1;

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


    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    #ssl_prefer_server_ciphers on;
    #ssl_ciphers ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED";
    #add_header Strict-Transport-Security "max-age=31536000";
    #ssl_certificate /etc/jitsi/meet/meet.meinedomain.de.crt;
    #ssl_certificate_key /etc/jitsi/meet/meet.meinedomain.de.key;

    # 
    # Headers
    #

    # 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;

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


    root /usr/share/jitsi-meet;
    ssi on;
    index index.html index.htm;
    error_page 404 /static/404.html;

    location = /config.js {
        alias /etc/jitsi/meet/meet.meinedomain.de-config.js;
    }

    location = /external_api.js {
        alias /usr/share/jitsi-meet/libs/external_api.min.js;
    }

    #ensure all static content can always be found first
    location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
    {
        add_header 'Access-Control-Allow-Origin' '*';
        alias /usr/share/jitsi-meet/$1/$2;
    }

    # BOSH
    location = /http-bind {
        proxy_pass      http://localhost:5280/http-bind;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $http_host;
    }

    # external_api.js must be accessible from the root of the
    # installation for the electron version of Jitsi Meet to work
    # https://github.com/jitsi/jitsi-meet-electron
    location /external_api.js {
        alias /usr/share/jitsi-meet/libs/external_api.min.js;
    }

    location ~ ^/([^/?&:'"]+)$ {
        try_files $uri @root_path;
    }

    location @root_path {
        rewrite ^/(.*)$ / break;
    }
}

Erklärungen zu den einzelnen Änderungen:

  • Zunächst wird der virtuelle Host für HTTP (Port 80) deaktiviert/auskommentiert. Dieser wird nicht benötigt, da dieser schon in einer anderen Datei vorhanden ist (sonst hätte ja die Erzeugung der TLS-Zertifikate über Let’s Encrypt vorher nicht geklappt).
  • Es folgen die Einstellungen für SSL. Die vom Jitsi Meet Setup eingefügten Zeilen wurden hier wieder auskommentiert und durch eigene optimierte Anweisungen ersetzt (RSA- und ECDSA-Zertifikate im Hybrid-Betrieb).
  • Wichtig ist hier noch die Angabe eines (DNS-)Resolvers (resolver 192.168.178.1). Hier ist die IP-Adresse eines DNS-Servers anzugeben (in diesem Beispiel die IP-Adresse des Routers, da dieser als DNS-Server fungiert).
  • Anschließend werden noch Header gesetzt, die für eine sichere Webserver-Konfiguration empfohlen sind.
  • Weiter unten wurde noch ein weiterer location-Block hinzugefügt. Dieser sorgt dafür, dass die externe API von Jitsi Meet verfügbar ist. Dies wird zur Nutzung der Desktop-Clients/mobilen Apps von Jitsi Meet benötigt.

Nun wird der Webserver neu gestartet:

service nginx restart

Zum Schluss müssen ein paar benötigte Ports in der Firewall freigeschaltet werden (in diesem Beispiel nutze ich die Firewall ufw):

ufw allow http
ufw allow https
ufw allow in 10000/udp

Falls eine andere Firewall genutzt wird, ist diese entsprechend zu konfigurieren. Denkt auch daran, dass das Port-Forwarding ggf. auch im Router konfiguriert werden muss (Ports 80, 443, 4443, Protokoll: TCP und Port 10000, Protokoll: UDP).

Diese Ports müssen übrigens auch bei den Clients geöffnet sein (nur für ausgehenden Traffic!).

Konfiguration Jitsi Meet

Nach der Installation müssen noch einige Dinge an der Installation angepasst werden.

coturn als TURN-/STUN-Server

Jitsi Meet benötigt für einen stabilen Betrieb sowohl einen TURN-Server, als auch STUN-Server. Dies ist eine Technologie, die Verbindungen durch Router/Firewalls ermöglicht.

Als TURN-/STUN-Server nutze ich hier die quelloffene Implementierung coturn. Wie ein coturn-Server aufgesetzt werden kann, wurde bereits im Artikel Nextcloud Talk mit eigenem TURN-Server (coturn) beleuchtet.

Zunächst hinterlegen wir die Daten für TURN:

nano /etc/prosody/conf.d/meet.meinedomain.de.cfg.lua

Hier wird ziemlich weit oben der zu verwendende TURN-Server angegeben. Diese Konfiguration wird nun so abgeändert, dass die eigene coturn-Instanz genutzt wird:

turncredentials_secret = "my-secret";

turncredentials = {
  { type = "stun", host = "turn.meinedomain.de", port = "5349" },
  { type = "turn", host = "turn.meinedomain.de", port = "5349", transport = "udp" },
  { type = "turns", host = "turn.meinedomain.de", port = "5349", transport = "tcp" }
};

Wichtig ist hier v.a. das sog. „Secret“, als auch die zu nutzenden Ports. Diese Konfiguration liegt jedoch nicht bei Jitsi Meet, sondern bei coturn selbst. Die Konfiguration von coturn befindet sich dabei hier: /etc/turnserver.conf (tls-listening-port und static-auth-secret).

Für STUN nutzt Jitsi in der Standard-Konfiguration einen eigenen Server (meet-jit-si-turnrelay.jitsi.net:443). Hier können aber auch beliebige andere STUN-Server genutzt werden.

Dazu wird einfach die entsprechende Konfiguration geöffnet:

nano /etc/jitsi/meet/meet.meinedomain.de-config.js

Hier sucht man nun nach der Stelle, an der die STUN-Server hinterlegt sind:

stunServers: [
   { urls: 'meet-jit-si-turnrelay.jitsi.net:443' }
],

Hier können nun andere STUN-Server hinterlegt werden. Eine Liste mit öffentlichen STUN-Servern findet man z.B. hier.

Wir nutzen hier allerdings ebenfalls die eigene coturn-Instanz:

stunServers: [
            { urls: 'stun:stun.meinedomain.de:5349' }
        ],

Damit nur noch der eigene TURN-/STUN-Server genutzt wird, sind noch zwei Variablen (useStunTurn) in dieser Konfigurations-Datei zu ändern:

useStunTurn: true,
# ...
p2p: {
   # ...
   useStunTurn: true,
   # ...

Nun werden alle Dienste nochmal neu gestartet, damit die Änderungen übernommen werden:

service prosody restart
service jicofo restart
service jitsi-videobridge2 restart

Test des eigenen STUN-Servers: Um den eigenen STUN-Server zu testen, kann diese Seite gnutzt werden. Unter STUN or TURN URI wir dann folgendes eingegeben: stun:stun.meinedomain.de:5349

Nach einem Klick auf Gather candidates sollte das Ergebnis dann in etwa so aussehen:

Ergebnisse des STUN-Server Tests

Ergebnisse des STUN-Server Tests

Wichtig sind dabei, dass die Einträge vom Typ „srflx“ angezeigt werden.

Öffentlichen Zugang unterbinden („Secure Domain“)

Jitsi Meet ist nun so konfiguriert, dass jeder, der die URL des Servers kennt, beliebig viele Konferenz-Räume erstellen kann. Dies ist u.U. nicht gewünscht, da man den Server z.B. nur privat verwenden möchte. In diesem Fall kann man Jitsi Meet so konfigurieren, dass neue Konferenz-Räume nur mit einem Benutzernamen und Passwort erstellt werden können.

Wer seine Instanz öffentlich betreiben möchte, muss die folgenden Schritt nicht ausführen.

Dazu ist zunächst eine Anpassungen in folgender Datei nötig:

nano /etc/prosody/conf.avail/meet.meinedomain.de.cfg.lua

Hier werden sog. virtuelle Hosts definiert (nicht zu verwechseln mit den virtuellen Hosts von nginx). Der erste virtuelle Host wird nun so eingestellt, dass eine Authentifizierung erforderlich ist:

VirtualHost "meet.meinedomain.de"
    authentication = "internal_plain"

Am Ende der Datei wird dann ein weiterer virtueller Host hinzugefügt:

VirtualHost "guest.meet.meinedomain.de"
    authentication = "anonymous"
    c2s_require_encryption = false

Als nächstes wird der neue virtuelle Host der Jitsi Meet Installation bekannt gemacht:

nano /etc/jitsi/meet/meet.meinedomain.de-config.js

Unter der Angabe der eigentlichen Domain wird nun die Domain des zuvor angelegten virtuellen Hosts als „anonyme Domain“ hinterlegt:

hosts: {
        // XMPP domain.
        domain: 'meet.meinedomain.de',

        // When using authentication, domain for guest users.
        anonymousdomain: 'guest.meet.meinedomain.de',

Nun muss noch eine weitere Datei bearbeitet werden:

nano /etc/jitsi/jicofo/sip-communicator.properties

Hier fügen wir einfach nur eine Zeile ein:

org.jitsi.jicofo.auth.URL=XMPP:meet.meinedomain.de

Nun folgt noch ein wichtiger Punkt: Das Hinzufügen von Benutzername und Passwort zum Erstellen neuer Konferenz-Räume. Dazu einfach folgenden Befehl direkt in die Kommandozeile eingeben:

prosodyctl register JitsiAdmin meet.meinedomain.de 'mEinPAssw0rt'

JitsiAdmin ist in diesem Beispiel der Benutzername, mEinPAssw0rt das dazugehörige Passwort.

Nach den Änderungen an der Konfiguration von Jitsi Meet sind nun noch die entsprechenden Services neu zu starten:

service prosody restart
service jicofo restart
service jitsi-videobridge2 restart

Verbindungen zu externen Diensten verhindern

Jitsi Meet nutzt einige externe Dienste, wie z.B. Gravatar zum Anzeigen von Benutzer-Icons, wenn die User eine E-Mail-Adresse in den Einstellungen hinterlegt haben und einen Gravatar-Account haben.
Aus Sicht des Datenschutzes ist dies natürlich bedenklich. Wer also auf etwas Komfort verzichten kann, dafür aber Wert auf Datenschutz legt, kann diese Verbindungen zu externen Diensten in Jitsi Meet deaktivieren.

Die Einstellung dazu kann in folgender Datei gesetzt werden:

nano /etc/jitsi/meet/meet.meinedomain.de-config.js

Hier ändern wir nun die entsprechende Variable:

// If third party requests are disabled, no other server will be contacted.
// This means avatars will be locally generated and callstats integration
// will not function.
disableThirdPartyRequests: true,

Zum Übernehmen der Änderungen werden alle Dienste noch einmal neu gestartet:

service prosody restart
service jicofo restart
service jitsi-videobridge2 restart

Nutzung von Jitsi Meet

Die eigene Instanz kann nun einfach im Browser genutzt werden: https://meet.meinedomain.de.

Hinweis: Es gibt momentan wohl noch kleinere Probleme mit neueren Versionen von Firefox. Daher wird offiziell die Verwendung von Chrome/Chromium empfohlen.

Jitsi Meet im Browser

Jitsi Meet im Browser

Als erstes sollte eine Blick in die Einstellungen geworfen werden (Zahnrad oben rechts).
Unter Profil kann ein Name und eine E-Mail-Adresse hinterlegt werden. Der Name wird dann in den Konferenzen angezeigt. An Hand der E-Mail-Adresse wird versucht, per Gravatar ein Avatar für den Benutzer anzuzeigen.

Einstellungen Jitsi Meet

Einstellungen Jitsi Meet

Ebenso kann hier die Sprache der Oberfläche angepasst werden. Nach einem Klick auf OK werden die Einstellungen gespeichert.

Ein Konferenzraum kann nun durch Eingabe des Names für das Meeting und einen Klick auf Los gestartet werden. Der Browser fragt dann, ob man Zugriff auf Mikrofon/Kamera erlauben möchte. Dies sollte man bestätigen, ansonsten macht es ja für Video-Konferenzen wenig Sinn.

Der Konferenz-Raum wird dann noch nicht sofort erstellt, sondern es erscheint eine Meldung mit der Frage nach dem Organisator (dieser Schritt belibt aus, wenn ihr nicht die „Secure Domain“ konfiguriert habt, s.o.):

Jitsi Meet fragt nach dem Organisator

Jitsi Meet fragt nach dem Organisator

Erst nach einem Klick auf „Ich bin der Organisator“ und der Eingabe von Benutzername und Passwort, welches wir weiter oben konfiguriert haben, wird der Raum eröffnet.

Nun präsentiert sich Jitsi Meet mit einer aufgeräumten Oberfläche. Der folgende Screenshot zeigt dabei alle wichtigen Elemente.

Die Oberfläche von Jitsi Meet

Die Oberfläche von Jitsi Meet

Damit andere Leute nun an der Konferenz teilnehmen können, wird einfach der Link auf die Konferenz benötigt (Schaltfläche unten rechts). Ein konkreter Link könnte dann so aussehen: https://meet.meinedomain.de/MeinMeeting

Hier kann auch gleich ein Passwort für die Konferenz eingetragen werden, damit nicht jeder anonyme Benutzer der Konferenz beitreten kann.

Die Benutzung via Browser stellt vermutlich die einfachste Möglichkeit dar. Allerdings gibt es auch Clients für die unterschiedlichsten Plattformen, siehe Jitsi Download-Seite.

Hinweise für Remote Control: Für die Fernsteuerung von Rechnern (ähnlich Teamviewer), muss ein spezieller Desktop-Client („Jitsi Meet Electron“) auf dem fernzusteuernden Rechner genutzt werden. Dieser kann bei GitHub herunter geladen werden. Der Teilnehmer, der die Bedienung remote übernehmen möchte, kann allerdings auch per Browser an der Konferenz teilnehmen.

Fazit

Die eigene Videokonferenz-Lösung aufzusetzen ist mit Jitsi Meet gar nicht so schwer und innerhalb von kürzester Zeit erledigt. Lediglich die individuellen Anpassungen/Absicherungen gehen ein wenig mehr ins Detail.

Man bekommt dafür eine Lösung für Videokonferenzen, die aus Sicht von Privatsphäre und Datenschutz um einiges besser ist als proprietäre Konferenz-Software eines Unternehmens.

Wie steht es bei euch? Nutzt ihr regelmäßig Audio-/Video-Konferenzen? Habt ihr vielleicht schon eure eigene Jitsi Meet Instanz aufgesetzt? Was sind eure Erfahrungen?
Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/jitsi-meet-videokonferenz-system-unter-ubuntu-server-mit-nginx/feed/ 114
Windows Server Advanced Power Management: Version 1.6.2 https://decatec.de/software/windows-server-advanced-power-management/windows-server-advanced-power-management-version-1-6-2/ https://decatec.de/software/windows-server-advanced-power-management/windows-server-advanced-power-management-version-1-6-2/#respond Sun, 15 Mar 2020 15:12:53 +0000 https://decatec.de/?p=6462 Windows Server Advanced Power Management Logo

Windows Server Advanced Power Management v1.6.2 steht ab sofort zum Download bereit.

Dieses Update behebt einen kleinen Fehler, der beim Importieren von Einstellungen auftreten konnte.

Änderungen in Version 1.5.4

  • BUGFIX: Beim Importieren von Einstellung mit geplanten Aufwach-Zeiten konnte es u.U. zu einem Fehler kommen, so dass die Einstellungen nicht richtig geladen werden konnten.
  • Update-Check verbessert.
  • .NET Framework 4.6.2 (oder neuer) muss installiert sein.
  • Update der verwendeten Software-Pakete.
  • Die folgenden Windows-Versionen werden offiziell nicht mehr unterstützt: Windows XP, Windows 7, Windows Server 2003, Windows Server 2008, Windows Home Server 2011

Update

Am einfachsten wird das Update über die integrierte Update-Funktion im Programm heruntergeladen und installiert.
Hinweis: Es kann sein, das bei alten Versionen des Programms hier eine Fehlermeldung erscheint. In diesem Fall muss das Update einfach manuell installiert werden.

Die neue Version kann alternativ auch einfach über eine bestehende Version installiert werden. Die Einstellungen bleiben dabei erhalten.

Weitere Informationen, Download und Benutzerhandbuch:
Windows Server Advanced Power Management

Links

]]>
https://decatec.de/software/windows-server-advanced-power-management/windows-server-advanced-power-management-version-1-6-2/feed/ 0
Backup-Strategie für Linux-Server mit Borg Backup https://decatec.de/linux/backup-strategie-fuer-linux-server-mit-borg-backup/ https://decatec.de/linux/backup-strategie-fuer-linux-server-mit-borg-backup/#comments Fri, 29 Nov 2019 08:31:28 +0000 https://decatec.de/?p=6094 Logo Backup

Wer einen eigenen (Home-)Server betreibt, sollte sich auf jeden Fall Gedanken über Backups machen. Spätestens, wenn wichtige Dateien mal unbeabsichtigt gelöscht wurden, kann man froh sein, wenn man auf Backups zurück greifen kann.

Deshalb möchte ich an dieser Stelle meine Backup-Strategie für Linux-Server vorstellen. Diese basiert hauptsächlich auf dem Programm Borg Backup und wird ergänzt durch eigene Backup-Skripte.

Als Betriebssystem kommt hier Ubuntu Server 18.04 zum Einsatz, das Gezeigte kann allerdings auch auf anderen Distributionen umgesetzt werden.

Die Inspiration zu dieser Tutorial stammt aus einem Artikel von Thomas Leister: Borg Backup für Serversicherungen. Ich habe diese Strategie jedoch an meine Bedürfnisse angepasst.
Genau dies solltet ihr übrigens auch machen: Jeder hat hier individuelle Anforderungen, daher wird es nicht die eine Lösung geben. Daher könnt ihr die hier gezeigte Lösung/Skripte als Vorlage nehmen, die ihr dann an eure eigenen Bedürfnisse anpasst.

Borg Backup

Den größten Teil der Arbeit übernimmt das Programm Borg Backup. Dies ist ein Backup-Programm, welches einige Vorteile bietet:

  • Kompression: Die Backups werden komprimiert.
  • Verschlüsselung: Die Backups können verschlüsselt werden.
  • Deduplizierung: Bei mehreren aufeinander folgenden Backups werden nur die inkrementellen Änderungen gesichert. Wenn mit dem ersten Backup beispielsweise 1 GB Daten gespeichert wurden und es ändern sich darauf hin nur 100 MB, dann werden im folgenden Backup nur diese 100 MB an Daten gesichert.

Durch die Verschlüsselung ist die Sicherheit der Backups gewährleistet, so dass man diese auch z.B. auf einem FTP-Server im Internet sichern könnte.
Durch die Verschlüsselung und Deduplizierung sind die Backups recht kompakt und werden schnell angefertigt.

Um Borg Backup zu installieren, bringen wir das System erst einmal auf den aktuellen Stand:

apt update && apt upgrade -V && apt dist-upgrade && apt autoremove

Anschließend kann Borg Backup installiert werden:

apt install borgbackup

Nun kann es schon an die Einrichtung des Backups gehen.

Backup einrichten

Übersicht

Zunächst ein paar Worte zum grundsätzlichen Vorgehen.

Ziel ist ein Backup-Skript, welches alle wichtigen Teile des Systems sichert:

  • Wichtige Dateien und Verzeichnisse.
  • Komplette Anwendungen.

Unter kompletten Anwendungen verstehe ich hier ein komplettes Backup einer Anwendung, welches grundsätzlich auch erst mal für sich allein angefertigt werden kann. Als Beispiel für eine solche Anwendung dient im Rahmen dieses Artikels Nextcloud, eine selbst gehostete Cloud-Lösung. Wie ein Backup von Nextcloud angefertigt werden kann, habe ich bereits im Artikel Nextcloud: Backups erstellen und wiederherstellen – manuell oder per Skript beschrieben. Das Skript, welches im Rahmen dieses Artikels erstellt wurde, kann nun für das komplette Backup des Servers wiederverwendet werden.

Jedoch kann auch jede beliebige andere Anwendung mittels des Server-Backup-Skripts gesichert werden: Weitere Beispiele wären hier z.B. FHEM, oder auch ein Firefox Sync-Server.

Das grundsätzliche Vorgehen sieht nun so aus, dass zunächst alle zu sichernden Anwendungen einzeln auf einen temporären Speicherort gesichert werden. Anschließend werden diese einzelnen Backups zusammen mit den zu sichernden Verzeichnissen des Systems an Borg Backup für die Gesamt-Sicherung übergeben. Anschließend werden die temporären Backups der Anwendungen wieder gelöscht.

In diesem Zusammenhang ist es nur wichtig, dass keine Teile des Systems doppelt gesichert werden. Wenn z.B. das Web-Verzeichnis (meist unter /var/www zu finden) gesichert werden soll, ist bei der Übergabe an Borg Backup das Nextcloud-Verzeichnis (unter /var/www/nextcloud) vom Backup auszuschließen, da dies ja schon durch die Nextcloud-Sicherung gespeichert wurde.

Individuelle Sicherung von Anwendungen

Zunächst beschäftigen wir uns mit dem Backup einzelner Anwendungen. Wie bereits erwähnt, dient hier Nextcloud als Beispiel-Anwendung, die es nun zu sichern gilt. Dieses Thema wurde hier bereits im Blog mit dem Artikel Nextcloud: Backups erstellen und wiederherstellen – manuell oder per Skript behandelt. Aus diesem Grund sei hier auf das dazugehörige Bash-Skript verwiesen, welches auf Codeberg verfügbar ist: Nextcloud Backup Restore

Wenn andere Anwendungen gesichert werden sollen, empfiehlt es sich, hier ebenfalls ein gesondertes Skript anzufertigen. Als weiteres Beispiel sei an dieser Stelle WordPress erwähnt (WordPress: Backups erstellen und wiederherstellen – manuell oder per Skript). Das dazugehörige Bash-Skript ist ebenfalls auf Codeberg verfügbar: WordPress Backup Restore

Borg Repository einrichten

Vor der Erstellung des Backup-Skripts muss noch das sog. Borg-Repository angelegt werden. In diesem Beispiel erfolgt dies auf einer zweiten internen HDD (/media/hdd2). Es kann aber auch ein beliebiges anderes Verzeichnis sein (z.B. ein per fstab gemountetes NAS). Das Repository wird dabei mit folgenden Befehlen angelegt:

mkdir -p /media/hdd2/server_backup/borg
borg init -e repokey-blake2 /media/hdd2/server_backup/borg

Beim Angelgen wird nach einem Passwort gefragt. Dieses sollte ein ausreichend sicheres Passwort sein. Dieses Passwort sollte man sich auch gut merken, denn ohne das Passwort kann kein Zugriff auf die Backups erfolgen. Am besten speichert es man sich gleich in einem Passwort-Safe (wie z.B. KeePass ab).

Der Befehl zum Initialisieren eines Repositories bietet noch weitere Optionen. So ist es auch möglich, die Verschlüsselung mittels einer Schlüssel-Datei zu realisieren. Eine genaue Beschreibung zum Initialisieren von Borg-Repositories ist in der offiziellen Dokumentation zu finden.

Auch wenn es möglich ist, ein Repository ohne Verschlüsselung anzulegen, rate ich davon ab. Die Verschlüsselung sollte beim Initialisieren immer verwendet werden.

Backup-Skript erstellen

Wie sämtliche Skripte speichere ich auch die Backup-Skripte im Verzeichnis /home/<user>/scripts. Hier wird erst einmal das Skript selbst erstellt:

nano /home/user/scripts/server_backup.sh

Der Inhalt sieht dann wie folgt aus:

#!/bin/bash

#
# Backup Script for Linux servers
#
# This script needs to be customized to fit your needs. Most important are the folder and applications which should be part of the backup.
# The folders to backup are specified in the variable $borgBackupDirs (see below)
# Besides these folders, Nextcloud (https://nextcloud.com/) is taken as example for an additional web application which should be included in the backup. 
#
# Required software and scripts:
# 	- Borg Backup (https://www.borgbackup.org/)
# 	- When Nextcloud backup should be included: Nextcloud Backup/Restore scrips (https://codeberg.org/DecaTec/Nextcloud-Backup-Restore)
#
# Remarks
# 	- The borg repository has to be set up before the script is called.
#
# IMPORTANT
# You have to customize this script (directories, users, etc.) for your actual environment.
# All entries which need to be customized are tagged with "TODO".
#
#
# Calling via cron:
#  	- crontab -e: Every night at 02:05
#		m h  dom mon dow   command
#	  	5 2 * * * /home/user/scripts/server_backup.sh > /dev/null 2>&1
#

#
# Environment variables
#

# TODO: The borg repository's password
export BORG_PASSPHRASE='passw0rd'
# This has to be set when the repository has been created by user and the script is called by cron
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
# For "Warning: The repository at location ... was previously located at ..."
export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes

#
# Variables
#

startTime=$(date +%s)
currentDate=$(date --date @"$startTime" +"%Y%m%d_%H%M%S")
currentDateReadable=$(date --date @"$startTime" +"%d.%m.%Y - %H:%M:%S")

# TODO: Customize according to your needs
logDirectory="/home/user/backup_logs/server_backup"
logFile="${logDirectory}/server-backup-${currentDate}.log"

# TODO: This is the local backup dir where the local backups (e.g. Nextcloud) are stored before being backuped by borg backup.
localBackupDir="/media/hdd1/backups_local_temp"

# TODO: Mount point of the backup destination folder
backupDiskMount="/media/hdd2"

# TODO: This is the dir where the borg respository is stored
borgRepository="${backupDiskMount}/server_backup/borg"

# TODO: List of (local) dirs borg should backup
borgBackupDirs="/var/www/ /etc/ /home/user/ /media/hdd1/NetworkShares/ $localBackupDir/"

# Nextcloud
localNextcloudBackupDir="${localBackupDir}/nextcloud"
# TODO: To be excluded by borg (the Nextcloud web directory)
nextcloudDirBorgExclude="/var/www/nextcloud"

#
# Create log dir if it does not exist already
#
if [ ! -d "${logDirectory}" ]
then
	mkdir -p "${logDirectory}"
fi

# Function for error messages
errorecho() { cat <<< "$@" 1>&2; }

#
# Write output to logfile. Comment following lines in order to see output on terminal.
#
exec > >(tee -i "${logFile}")
exec 2>&1

#
# Preparation
#

# Check for root
if [ "$(id -u)" != "0" ]
then
	errorecho "ERROR: This script has to be run as root!"
	exit 1
fi

#
# Check if directories already exist
#

# Local backup directory
if [ ! -d "${localBackupDir}" ]
then
	mkdir -p "${localBackupDir}"
fi

# Nextcloud
if [ ! -d "${localNextcloudBackupDir}" ]
then
	mkdir -p "${localNextcloudBackupDir}"
fi

echo -e "\n###### Starting server backup on ${currentDateReadable} ######\n"

#
# Create a list with installed software
#
echo -e "\n######"
echo -e "\nCreate a list with installed software"
dpkg --get-selections > "${localBackupDir}/software.list"
echo -e "\nDone\n"
echo -e "######\n"

#
# Backup Nextcloud
#
# TODO: Storage location of the script
echo -e "\n######"
echo -e "\nBackup Nextcloud"
/bin/bash /home/user/scripts/NextcloudBackup.sh ${localNextcloudBackupDir}
echo -e "\nDone\n"
echo -e "######\n"

#
# Backup with borg
#
echo -e "\n######"
echo -e "\nBackup with Borg"

# The backup is created with two main parts:
# 	- The backups created separately (in this example Nextcloud)
# 	- Backup of the important directories of the system.
#
# Remarks
# 	- Do not add "--progress" when calling the script by cron!
borg create --stats \
    $borgRepository::"${currentDate}" \
	$borgBackupDirs \
	--exclude $nextcloudDirBorgExclude 

echo -e "\nDone\n"
echo -e "######\n"

#
# Cleanup
#

echo -e "\n\n###### Cleanup backup ######"

# All local backups are deleted again, as they were saved by borg backup

# Delete list of installed software
echo -e "\n######"
echo -e "\nDelete list of installed software"
rm "${localBackupDir}"/software.list
echo -e "\nDone\n"
echo -e "######\n"

# Delete local Nextcloud backup
echo -e "\n######"
echo -e "\nDelete local Nextcloud backup"
rm -r "${localNextcloudBackupDir:?}"/*
echo -e "\nDone\n"
echo -e "######\n"

# Borg prune
echo -e "\n######"
echo -e "\nCleanup borg backups"

# TODO: Borg should keep backups from the last 7 days (one week), 4 weekly backups (one month) and 6 monthly backups (half a year)
borg prune --progress --stats $borgRepository \
--keep-within=7d \
--keep-weekly=4 \
--keep-monthly=6

echo -e "\nDone\n"
echo -e "######\n"

#
# Misc
#

# Duration of backup
endTime=$(date +%s)
endDateReadable=$(date --date @"$endTime" +"%d.%m.%Y - %H:%M:%S")
duration=$((endTime-startTime))
durationSec=$((duration % 60))
durationMin=$(((duration / 60) % 60))
durationHour=$((duration / 3600))
durationReadable=$(printf "%02d hours %02d minutes %02d seconds" $durationHour $durationMin $durationSec)
echo -e "\n\n###### Server backup finished on ${endDateReadable} (${durationReadable}) ######\n"

# Free space on backup disk
echo -e "\nDisk usage:\n"
df -h ${backupDiskMount}

#
# Send mail to admin
#
# Important: An MTA has to be installed for sending mails.
# TODO: Add your own e-mail address here.
mail -s "Server backup finished" my@email.address < "${logFile}"

Das komplette Skript ist auch als Git-Repository auf Codeberg verfügbar: Linux-Server-Backup @ Codeberg

Bevor man das Skript also mühselig kopiert und einfügt, kann einfach das Repository gecloned werden:

mkdir -p /home/user/scripts/
git clone https://codeberg.org/DecaTec/Linux-Server-Backup.git

Wichtig: In diesem Skript sind alle Stellen, die individuell angepasst werden müssen mit einem TODO im Kommentar gekennzeichnet (die betrifft v.a. Verzeichnis-Angaben). Daher das Skript bitte nicht einfach übernehmen, sondern immer auf die eigenen Bedürfnisse anpassen.

Erläuterungen zum den einzelnen Schritten des Backup-Skripts (bitte auch die Kommentare im Skript selbst beachten):

  • Als erstes werden Variablen zum Bedienen des Borg-Repositories gesetzt. Die betrifft v.a. das vergebene Passwort (Variable BORG_PASSPHRASE).
  • Mit der Variable logDirectory wird das Verzeichnis festgelegt, in das pro Backup ein Log-File geschrieben wird.
  • Mit localBackupDir wird das Verzeichnis angegeben, in das die lokalen Backups gespeichert werden – also in diesem Fall das gesondert angefertigte Nextcloud-Backup. Nach dem Aufruf von Borg werden die Inhalte dieses Verzeichnisses wieder gelöscht.
  • Anschließend wird das Verzeichnis des Borg-Repositories angegeben (borgRepository) und die Verzeichnisse definiert, die später von Borg direkt gesichert werden sollen (borgBackupDirs).
  • Es folgen die Verzeichnis-Angaben für das separate Nextcloud-Backup. Da /var/www ja schon direkt per Borg gesichert wird, ist das Web-Verzeichnis von Nextcloud später vom Backup auszuschließen (nextcloudDirBorgExclude).
  • Anschließend erfolgt bei der Ausführung des Skripts die Überprüfung, ob dieses auch mit Root-Rechten ausgeführt wird.
  • Nun beginnt die eigentliche Ausführung des Skripts: Es wird eine Liste der installierten Pakete im lokalen Backup-Verzeichnis gespeichert (sinnvoll, wenn das Backup auf einem anderen System wiederhergestellt werden sollte).
  • Das Nextcloud-Backup wird dann einfach durch das Aufrufen des Nextcloud-Backup-Skripts erstellt.
  • Es folgt der eigentliche Aufruf von Borg Backup.
  • Anschließend werden die (temporären) lokalen Backups wieder gelöscht.
  • Nun wird das Borg-Repository bereinigt. In diesem Beispiel sollen Backups der letzten 7 Tage, 4 wöchentliche Backups und 6 monatliche Backups behalten werden. Backup-Sets, die nicht mehr diesem Muster entsprechen, werden aus dem Respository gelöscht und dieses wird konsolidiert.
  • Ganz am Ende des Skripts wird noch eine E-Mail versendet. Damit dies funktionieren kann, muss auf dem System ein MTA installiert sein (siehe Linux: Einfach E-Mails versenden mit msmtp).

Ist das Skript erstellt, werden die Zugriffsrechte noch eingeschränkt (hier ist ja das Passwort des Borg-Repositories gespeichert) und das Skript wird als ausführbar gekennzeichnet:

chmod 600 /home/user/scripts/server_backup.sh
chmod +x /home/user/scripts/server_backup.sh

Das Backup-Skript kann nun für einen ersten Lauf manuell ausgeführt werden:

./home/user/scripts/server_backup.sh

Die erste Ausführung dauert in der Regel etwas länger, da alle zu sichernden Verzeichnisse und lokalen Backups gesichert werden müssen. Weitere Ausführungen des Skripts sollten dann aber deutlich schneller ablaufen.

Backups automatisieren

Das Anfertigen der Backups kann nun mittels Cron einfach automatisiert werden. Dazu muss lediglich für den Root-User ein Cronjob eingerichtet werden:

crontab -e

Hier fügen wir nun ganz unten z.B. folgende Zeile hinzu:

0 2 * * * /home/user/scripts/server_backup.sh > /dev/null 2>&1

Nun wird das Backup-Skript jede Nacht um 02:00 aufgerufen.

Hinweis: Der Pfad zum Skript muss in der Crontab immer absolut (also mit dem kompletten Verzeichnis-Pfad) angegeben werden.

Wenn das Skript zu einem anderen Zeitpunkt ausgeführt werden soll, kann ich die Seite contab guru empfehlen: Dies ist eine Seite zum einfachen Erstellen von Crontab Zeitplänen. Hiermit wird es einfacher, die Syntax für den Zeitplan eines Cronjobs zu erzeugen.

Off-Shore Backups

Das Backup kann mit diesem Skript an jeden beliebigen Ort gespeichert werden, der auf der lokalen Maschine verfügbar ist (z.B. eine zweite interne Festplatte, ein NAS, etc.). Nun kann man sich Gedanken über ein „Offshore-Backup“ machen: Dies bedeutet, dass man ein weiteres Backup anfertigt, welches jedoch örtlich getrennt vom ersten Backup ist. Im einfachsten Fall ist dies ein Backup auf einer externen Festplatte, welche bei Freunden/Verwandten gelagert wird, oder auch ein Backup in eine Cloud. Sinn und Zweck hierbei ist die Datensicherheit im Katastrophenfall (z.B. bei Hausbrand, Überschwemmung, Diebstahl, etc.).

Das Borg-Repository kann dazu in seiner Gesamtheit an einen beliebigen Ort kopiert werden und schon hat man ein zweites identisches Backup. Durch die Verschlüsselung des Backups muss man sich hierbei auch keine Gedanken um unbefugten Zugriff machen: Selbst, wenn die externe Festplatte in die falschen Hände gerät, kann ein Dritter keinen Zugriff auf die Daten des Backups erlangen.

Um das Borg-Repository (/media/hdd2/server_backup) beispielsweise auf eine externe Festplatte (hier z.B. gemountet unter /media/hdd_ext) zu kopieren, kann einfach rsync verwendet werden:

rsync -ahP --delete --stats /media/hdd2/server_backup /mnt/hdd_ext

Das zweite Backup ist dann eine identische Kopie des ersten Backups und kann genau so zur Wiederherstellung verwendet werden.

Dies kann dann auch auf einem anderen Rechner geschehen. Die einzige Voraussetzung ist eine Installation von Borg Backup und das Passwort des Original-Repositories.

Backups wiederherstellen

Ein Backup anzufertigen ist die eine Sache. Bevor man im Problemfall darauf angewiesen ist, sollte man sich auf jeden Fall damit vertraut machen, wie man die Daten aus dem Backup wiederherstellen kann.

Für die Wiederherstellung von Dateien und Verzeichnissen gibt es z.B. den Befehl borg extract (siehe Borg Dokumentation).

Ich gehe hier aber meistens einen anderen Weg, da dies für mich persönlich komfortabler ist. Zunächst kann man sich eine Liste an „Backup-Sets“ anzeigen lassen:

borg list /media/hdd2/server_backup/borg/

Nach der Eingabe des Passworts werden alle verfügbaren Backup-Sets aufgelistet (hier rot markiert):

Borg: Auflistung der Backup-Sets

Borg: Auflistung der Backup-Sets

Ein Backup-Set kann nun einfach in das Dateisystem gemountet werden:

mkdir -p /mnt/borg
borg mount /media/hdd2/server_backup/borg::20191006_020001 /mnt/borg

Wieder wird nach dem Passwort gefragt und anschließend ist das komplette Backup (mitsamt Unterverzeichnissen) unter /mnt/borg gemountet und man kann mit normalen Dateioperationen darauf zugreifen.

Um nun beispielsweise eine einzelne Datei auf dem Backup zu extrahieren, kann ganz einfach cp verwendet werden:

cp /mnt/borg/etc/nginx/conf.d/HTTP-Gateway.conf /etc/nginx/conf.d/HTTP-Gateway.conf

Nach dem Extrahieren der benötigten Dateien aus dem Backup kann das Backup-Set wieder ausgehängt werden:

borg umount /mnt/borg

Wenn nun keine einzelnen Dateien, sondern das Backup einer kompletten Applikation wiederhergestellt werden muss, wird das Backup der Anwendung aus dem Borg-Repository extrahiert. Anschließend wird dies separat wiederhergestellt. Siehe beispielsweise die Restore-Anweisungen für Nextcloud.

Troubleshooting

Das hier gezeigte Skript ist natürlich nur ein Beispiel und kann beliebig erweitert werden. Damit kann das Skript auch durchaus umfangreich werden. Wenn das Skript dann nicht richtig funktionieren sollte, ist der erste Schritt immer die Kontrolle der Logs, die durch das Skript angelegt werden. Sollte dies nicht zur Lösung des Problems führen, sollten die einzelnen Schritte, die im Skript enthalten sind, einzeln und in genau der Reihenfolge auf der Kommandozeile ausgeführt werden. Hier sollte dann zumindest der Schritt identifiziert werden können, ab dem das Skript „aus dem Ruder läuft“. Wenn das Problem gefunden wurde, sollte anschließend das Skript dementsprechend angepasst werden.

Fazit

Dieser Artikel hat eine einfache und effiziente Möglichkeit skizziert, wie ein Linux-System gesichert werden kann. Das bereit gestellt Skript kann als Ausgangspunkt für eigene Backup-Strategien verwendet werden.

Wenn das System erst einmal eingerichtet wurde (und das Wiederherstellen der angefertigten Backups getestet wurde!), können die Backups automatisiert werden, so dass man hier in Zukunft nicht mehr viel Zeit investieren muss. Im Problemfall kann man dann ganz einfach auf die erstellten Backups zurückgreifen.

Habt ihr euch für euren Server auch schon eine Backup-Strategie ausgedacht? Wie sieht diese im Detail aus? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/linux/backup-strategie-fuer-linux-server-mit-borg-backup/feed/ 16
Metasuchmaschine searx auf eigenem Server installieren (mit Docker und nginx) https://decatec.de/home-server/metasuchmaschine-searx-auf-eigenem-server-installieren-mit-docker-und-nginx/ https://decatec.de/home-server/metasuchmaschine-searx-auf-eigenem-server-installieren-mit-docker-und-nginx/#comments Sun, 20 Oct 2019 09:53:15 +0000 https://decatec.de/?p=6151 searx Logo

Eine Suchmaschine ist eine der wichtigsten Tools im Internet. Google ist hier der unangefochtenen Platzhirsch: Die Marktmacht von Google lässt sich allein schon an der Tatsache erahnen, dass das Wort „googeln“ schon 2004 im Duden aufgenommen wurde.
Wer nun aber Wert auf Privatsphäre und Datenschutz im Internet legt, für den ist Google sicherlich nicht die beste Wahl.

Hier gilt es also, sich nach Alternativen umzusehen. Auf dem Markt gibt es zum Glück einige Suchmaschinen, die in Bezug auf Privatsphäre und Datenschutz besser dastehen als Google. Einfach eine andere Suchmaschine zu benutzen ist jedoch auch keine optimale Lösung – mehr dazu später.

Der folgende Artikel soll daher zeigen, wie man searx als eigene Metasuchmaschine mit Docker und nginx betreiben kann. Damit bleibt man auch bei der Suche im Internet Herr seiner eigenen Daten.

Update-Historie (letztes Update: 05.02.2020)
  • 05.02.2020:
    • Update für searx v0.16.0: Der Docker-Container nutzt nun den Port 8080.
  • 15.12.2019:
    • Befehl zum Starten des Docker-Containers angepasst, so dass keine Docker-Logs geschrieben werden (–log-driver none).
  • 13.11.2019:
    • Allgemeine Hinweise zum Betrieb einer eigenen searx-Instanz hinzugefügt (kleiner Nutzerkreis).
  • 21.10.2019:
    • Hinweis auf die von mir betriebene searx-Instanz searx.decatec.de hinzugefügt.
    • Hinweis auf das Anpassen der Standard-Einstellungen (/opt/searx/searx/settings.yml) hinzugefügt.

Warum eine eigene Suchmaschine betreiben?

Sehen wir uns den Markt der Suchmaschinen mal näher an:

Hier gibt es zum einen Suchmaschinen, die von den jeweiligen Anbietern betrieben werden, z.B. Google, Bing, Yahoo, etc. Nur diese großen Anbieter haben die Kapazitäten, eigene Suchindizes aufzubauen. Und wer hier investiert, der möchte mit dem Produkt natürlich auch Geld verdienen. Dies sind jedoch nicht die Suchmaschinen selbst, sondern das Produkt sind dabei die Benutzer (bzw. deren Daten). Die Benutzer-Daten können gesammelt und ausgewertet werden, um daraufhin z.B. personalisierte Werbung zu schalten.

Daneben gibt es die sog. Metasuchmaschinen. Dies sind Suchmaschinen, die keine eigenen Suchindizes verwalten, sondern Suchanfragen an andere Suchmaschinen (wie z.B. Google) weiterleiten. Der große Vorteil dabei ist, dass dadurch Suchanfragen anonymisiert werden können, da z.B. Google einen User nicht mehr eindeutig tracken kann. Der einzige Nachteil an einer Metasuchmaschine ist, dass die Suchergebnisse nicht mehr personalisiert werden. Daher hat man immer das Gefühl, dass die Suchergebnisse von Google direkt etwas besser ausfallen, als die Ergebnisse einer Metasuchmaschine. Google schafft dies allerdings nur, weil die User getrackt werden, und das wollen wir ja gerade verhindern.

Lange Zeit habe ich Startpage als Metasuchmaschine genutzt und empfohlen. Jedoch hat Startpage ab Oktober diesen Jahres mit System1 LLC einen neuen Anteilseigner (Quellen: hier bzw. hier). Dessen Geschäftsmodell basiert allerdings genau auf dem Sammeln und Auswerten von Daten. Dies passt meiner Meinung nach nicht zu den Grundsätzen von Startpage (lt. eigener Aussage „die diskreteste Suchmaschine der Welt“). Mit dieser Meinung stehe ich sicherlich nicht allein da, siehe Startpage and System1 Abuse Your Privacy Under the Guise of ‘Privacy One Group’.

Eine Alternative wäre hier z.B. DuckDuckGo (ebenfalls eine Metasuchmaschine). Allerdings wird diese von einem amerikanischen Anbieter betrieben, der lt. Gesetzt dazu verpflichtet ist, mit den US-Behörden zusammen zu arbeiten. Also kann man im Zweifelsfall auch davon ausgehen, dass hier Daten gespeichert und ausgewertet/weitergegeben werden.

Mit searx gibt es allerdings auch eine Metasuchmaschine, die auf einem eigenen Server betrieben werden kann. Ziel dieses Open Source Projektes ist der Schutz der Privatsphäre der Benutzer, indem keine IP-Adressen an die dahinter liegenden Suchmaschinen weitergegeben werden und deren Tracking-Cookies geblockt werden.

Voraussetzungen und Installationsvarianten

searx kann auf jedem Linux-System installiert werden, welches Python-Programme ausführen kann. Dies ist auf so gut wie allen Distributionen gegeben.

Dabei gibt es mehrere Installationsvarianten:

  • Die klassische Installation.
  • Das Bauen eines Docker-Images aus dem offiziellen Repositories und der Betrieb als Docker-Container.
  • Die Nutzung eines vorgefertigten Docker-Images (z.B. wonderfall/serx bei Docker Hub).
  • Die Nutzung des Docker-Images aus dem Projekt searx-docker.

Ich empfehle hier die zweite Variante, indem das Docker-Image aus dem offiziellen Repository gebaut wird. Genau diese Variante wird daher auch in diesem Artikel gezeigt.

Daher ist der Betrieb von Docker ebenfalls eine Installations-Voraussetzung. Eine Einführung zu Docker mit Installationsanweisungen kann dem Artikel Docker auf Ubuntu Server entnommen werden.

Wichtig ist hier auch, dass die Suchmaschine per HTTPS erreichbar ist, damit die Verbindung stets verschlüsselt ist. Hier wird nginx als Webserver verwendet, der die Anfragen an die Suchmaschine an den Docker-Container weiterleitet. Der Webserver ist hierbei für die Verschlüsselung per HTTPS zuständig. Wie man die entsprechenden TLS-Zertifikate mittels acme.sh erzeugen kann, ist im Artikel RSA und ECDSA-Zertifikate mit nginx (Hybrid-Lösung) zu finden.

Am einfachsten ist der Betrieb der Suchmaschine über eine eigene (Sub-)Domain. Wenn DynDNS verwendet wird, dann empfiehlt sich das Anlegen eines CNAME-Eintrags. Details dazu findet man im Artikel Nextcloud: Online-Office mit ONLYOFFICE (mit eigener Subdomain). Im folgenden gehe ich davon aus, dass die Suchmaschine unter der Domain searx.meinedomain.de betrieben wird.

Allgemeine Hinweise zum Betrieb einer eigenen searx-Instanz

Der Artikel zeigt, wie man schnell eine eigene searx-Instanz in Betrieb nehmen kann. Jedoch sollte man sich im Vorfeld Gedanken über den Nutzerkreis der Instanz machen.

Google, Bing & Co „sehen“ nur die IP-Adresse des searx-Servers. Wenn die eigene Suchmaschine nur von sehr wenigen Usern benutzt wird (im Extremfall von nur einem Benutzer), nutzt die Verschleierung der IP-Adressen der Clients durch searx hier wenig. Die Suchmaschinen können dann ebenso einfach ein Profiling vornehmen, als wenn man die diese direkt (d.h. ohne searx) verwenden würde – da die IP pro Nutzer immer die gleiche ist.

Daher sollte man eine searx-Instanz besser nicht mit sehr wenigen/einem einzelnen Benutzer betreiben. Je mehr Benutzer die Instanz verwenden, desto weniger können die Suchmaschinen ein Profiling vornehmen.

Wenn der Nutzerkreis der eigenen searx-Instanz vermutlich sehr klein ausfallen wird, ist es vielleicht eine Überlegung wert, statt einer privaten searx-Instanz auf eine der öffentlich verfügbaren searx-Instanzen auszuweichen.

searx installieren

Zunächst bringen wir das System auf den neusten Stand:

apt update && apt upgrade -V && apt dist-upgrade && apt autoremove

Anschließend wird das Git-Repository gecloned:

cd /opt
git clone https://github.com/asciimoo/searx.git
cd searx

In den meisten Anleitungen wird das Docker-Image direkt aus dem Main-Branch des Projekts gebaut (Entwicklungsversion). Ich empfehle hier jedoch das Bauen des neusten Releases. Dazu listet man zunächst einmal die Releases des Projekts auf:

git tag -l

Auflisten der searx-Releases

Auflisten der searx-Releases

Momentan ist die Version v0.16.0 aktuell, daher rufen wir im Folgenden diesen Release ab:

git checkout tags/v0.16.0

Die Warnung („Detached Head“) kann hier ruhig ignoriert werden.

Auch wenn searx recht gute Standard-Einstellungen mitbringt (z.B. die zu verwendenden Suchmaschinen, die Standard-Sprache der Suche, das Theme, etc.), können diese Einstellungen individuell angepasst werden. Dazu wird vor dem Bauen des Docker-Images folgende Datei bearbeitet:

nano /opt/searx/searx/settings.yml

Die Inhalte dieser Datei sind eigentlich selbsterklärend und würden den Rahmen des Artikels sprengen. Daher wird an dieser Stelle nur auf die Möglichkeit hingewiesen, die Einstellungen der searx-Instanz individuell anzupassen.
Auch wenn alle Einstellungen auf Standard belassen werden, können die Benutzer der Suchmaschine später ihre individuellen Einstellungen vornehmen. Diese werden dann Client-seitig mittels eines Cookies gespeichert.

Das einzige, was ihr in der Datei settings.yml ändern solltet, ist der sog. secret_key: Dies kann mit folgendem Befehl schnell durchgeführt werden:

sed -i -e "s/ultrasecretkey/`openssl rand -hex 32`/g" /opt/searx/searx/settings.yml

Das Docker-Image wird nun mit folgendem Befehl gebaut:

docker build -t searx .

Nun kann man sich erst mal einen Kaffee holen, da dieser Vorgang durchaus ein paar Minuten dauert.

Anschließend kann der Container auch schon gestartet werden:

docker run -d --name searx -p 8080:8080 --restart=always --log-driver none -e IMAGE_PROXY=True -e BASE_URL=https://searx.meindomain.de searx

Die Parameter haben dabei die folgende Bedeutung:

  • -p 8080:8080
    : Der Port 8080 (Standard-Port von searx) wird vom Host-System an den Docker-Conatiner weitergeleitet.
    Hinweis: Dies hat sich mit der Version v0.16.0 von searx geändert, bis searx v0.15.0 war dies der Port 8888. Dieser ist weiterhin auch im Settings-File (settings.yml) von searx angegeben, wird aber nicht wirklich verwendet, da der Docker-Container nur den Port 8080 nutzt.
  • --restart=always
    : Der Container soll bei jedem Systemstart automatisch gestartet werden.
  • --log-driver none
    : Sorgt dafür, dass keine Logs geschrieben werden. Ohne diesem Parameter könnten die Logs später mit dem Befehl docker logs searx abgerufen werden.
    Wichtig:
    Dieser Parameter sollte unbedingt gesetzt werden, wenn durch die searx-Instanz absolut keine Daten geloggt werden sollen.
  • -e IMAGE_PROXY=True
    : Aktiviert die Proxy-Funktion für Bilder, d.h. Bilder werden nicht direkt durch den Client-Browser abgerufen, sondern durch searx selbst.
  • -e BASE_URL=https://searx.meindomain.de
    : Hiermit wird die URL angegeben, unter der searx erreichbar sein soll. Hier muss auch das Protokoll (http/https) mit angegeben werden.

Der letzte Schritt ist nun das Hinzufügen eines virtuellen Hosts für nginx:

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

Beispielhaft kann die Konfiguration hier folgendermaßen aussehen:

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

        # Include SSL configuration
        include /etc/nginx/snippets/ssl.conf;

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

        # Important: Disable error and access log, so that no IPs get logged
        access_log  off;
        error_log off;

        #
        # Configuration for Searx
        #

        location / {
                proxy_pass http://localhost:8080;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Remote-Port $remote_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_redirect off;
        }
}

Das Setzen der Settings für SSL und der Standard-Header des Webservers erfolgt hier über das Einbinden über includes. Interessant ist hier hauptsächlich der location-Block, mit dem die Anfrage an den Docker-Container von searx weitergeleitet wird (Port 8080). Diese Kommunikation erfolgt unverschlüsselt über HTTP, da diese nur Maschinen-intern stattfindet.

Wichtig: Damit absolut keine Daten gesammelt werden, sollten Access- und Error-Log für diesen virtuellen Host deaktiviert werden (access_log off bzw. error_log off). Wenn diese nicht deaktiviert werden, werden die IPs der Aufrufer automatisch über nginx geloggt!

Zu guter Letzt muss der Webserver noch neu gestartet werden:

service nginx restart

Nun kann die Suchmaschine schon über den Browser aufgerufen werden: https://searx.meinedomain.de

searx in Firefox

searx in Firefox

Damit searx als Standard-Suchmaschine genutzt werden kann, muss diese Suchmaschine noch im Browser hinzugefügt werden. Bei Firefox kann dies über das Menü mit den drei Punkten in der Adress-Leiste erledigt werden.

searx als Suchmaschine in Firefox hinzufügen

searx als Suchmaschine in Firefox hinzufügen

Anschließend kann die Standard-Suchmaschine in den Einstellungen des Browsers gesetzt werden.

Die Nutzung von searx

Nachdem searx nun fertig installiert ist, können die Optionen der Suchmaschine über einen Klick auf Einstellungen (oben rechts) gesetzt werden (z.B. welche Suchmaschinen verwendet werden). Die wichtigste Einstellung ist hier vermutlich die Suchsprache, welche auf Deutsch – de gesetzt werden sollte, da ansonsten nur englische Suchergebnisse angezeigt werden:

Die Suchsprache in searx festlegen

Die Suchsprache in searx festlegen

Diese Einstellungen werden übrigens nicht bei searx gespeichert, sondern ausschließlich per Cookie auf dem Client.

Nun lohnt sich noch ein Blick auf die Such-Syntax. Hiermit können z.B. die Ergebnisse auf eine Suchmaschine begrenzt werden. Soll z.B. nur bei Wikipedia nach dem Suchbegriff „Nürnberg“ gesucht werden, sieht die Syntax folgendermaßen aus: !wp Nürnberg
Ebenso kann explizit nach Suchergebnissen einer bestimmten Sprache gesucht werden (z.B. Englisch): :en Nürnberg

searx updaten

Wenn eine neue Version von searx verfügbar ist, wird das alte Image entfernt und das GitHub-Repository einfach neu abgerufen, wie schon bei der initialen Installation:

docker stop searx
docker rm searx
docker rmi searx
cd /opt
rm -r searx
git clone https://github.com/asciimoo/searx.git
cd searx
git tag -l
git checkout tags/v0.16.0
docker build -t searx .
docker run -d --name searx -p 8080:8080 --restart=always -e IMAGE_PROXY=True -e BASE_URL=https://searx.meindomain.de searx

searx-Instanz von decatec.de

Meine eigene Instanz ist übrigens unter searx.decatec.de zu erreichen. Diese wurde nach den Vorgaben dieses Artikels umgesetzt und es werden keine Daten gespeichert/gesammelt/ausgewertet.

Die Verbindung ist darüber hinaus dank HTTPS stets verschlüsselt, siehe Qualys SSL Labs und Mozilla Observatory.

Wenn ihr keine eigene searx-Instanz aufbauen wollt und einfach nur eine öffentliche Instanz sucht, dann lade ich euch ein, über searx.decatec.de zu suchen.

Fazit

Mittels Docker ist die eigene searx-Instanz schnell aufgesetzt. Durch das Hosten der Metasuchmaschine auf eigener Hardware und der Tatsache, dass keine IPs oder Suchanfragen geloggt werden, ist dies eine gute Lösung bzgl. Datenschutz und Privatsphäre.

Neben der Nutzung einer komplett eigenen Instanz kann auch eine öffentliche Instanz von searx genutzt werden. Eine Liste von öffentlichen Instanzen ist im Wiki des GitHub-Repositories zu finden: Searx instances

Bei der Verwendung einer öffentlichen Instanz muss man jedoch dem Administrator der Instanz vertraut werden (siehe Why use a private instance?). Von außen ist nämlich nicht ersichtlich, ob hier vielleicht doch Daten gesammelt/ausgewertet/weitergegeben werden. Absolut sicher gehen kann man hier nur durch eine eigene/persönliche Instanz von searx.

Welche Suchmaschine nutzt ihr? Ist euch hier Privatsphäre und Datenschutz wichtig, oder geht es euch mehr um den Komfort beim Suchen? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/metasuchmaschine-searx-auf-eigenem-server-installieren-mit-docker-und-nginx/feed/ 80
TLSv1.3 unter Ubuntu Server 18.04 LTS mit nginx https://decatec.de/home-server/tlsv1-3-unter-ubuntu-server-18-04-lts-mit-nginx/ https://decatec.de/home-server/tlsv1-3-unter-ubuntu-server-18-04-lts-mit-nginx/#respond Wed, 24 Jul 2019 13:45:35 +0000 https://decatec.de/?p=5974 Let's Encrypt Logo

Moderne Webserver und Browser nutzen TLS (Transport Layer Security) für die verschlüsselte Datenübertragung (z.B. mittels HTTPS). Bereits im August 2018 wurde hier der neue Standard TLSv1.3 verabschiedet. TLSv1.3 bietet viele Vorteile bzw. Sicherheit und Performance: Es kommen moderne Krypto-Algorithmen zum Einsatz, ältere (und als unsicher geltende Algorithmen werden nicht mehr unterstützt). Ebenfalls kann der Verbindungsaufbau durch einen effizienteren Handshake schneller durchgeführt werden.

Allerdings war TLSv1.3 unter Ubuntu Server 18.04 LTS (mit nginx) lange Zeit nicht nutzbar. Dies lag zum einen daran, dass unter Ubuntu 18.04 mit OpenSSL 1.1.0 ausgeliefert wurde. Die Unterstützung für TLSv1.3 wurde allerdings erst in OpenSSL 1.1.1 hinzugefügt. Dieses Update auf Version 1.1.1 wurde allerdings zu einem späteren Zeitpunkt nachgeliefert. Zum anderen wird der Webserver nginx gegen eine bestimmte Version von OpenSSL gebaut. Erst mit dem Update vom 23.07.2019 (nginx 1.17.2 – Mainline-Version) kommt nun auch hier unter Ubuntu 18.04 OpenSSL 1.1.1 zum Einsatz.

Vor diesen Updates kursierten im Internet zahlreiche Anleitungen, wie man OpenSSL und nginx für die Unterstützung von TLSv1.3 selbst kompilieren und installieren konnte. Allerdings sollte man auf solche Aktionen gerade auf Produktiv-Systemen verzichten.

Mit den nun verfügbaren Updates kann nun auch endlich TLSv1.3 unter nginx auf Ubuntu Server 18.04 LTS genutzt werden. Dieser Artikel zeigt, was dabei zu beachten ist.

Update-Historie (letztes Update: 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.

 

Updates durchführen

Falls noch nicht geschehen, sollte das System zunächst einmal auf den aktuellen Stand gebracht werden:

apt-get update && apt-get upgrade -V && apt-get dist-upgrade && apt-get autoremove

Anschließend kann die Version von OpenSSL und nginx überprüft werden. Die Befehle dazu lauten wie folgt:

openssl version
nginx -V

Hier sollte in beiden Fällen OpenSSL 1.1.1 angezeigt werden:

Informationen zu OpenSSL/nginx

In diesem Fall ist das System bereit für TLSv1.3.

TLSv1.3 in nginx aktivieren

Die Konfiguration für TLSv1.3 muss anschließend in den virtuellen Hosts von nginx aktiviert werden.

Hinweis: Ich gehe im Folgenden davon aus, dass der Webserver bereits für HTTPS mit Zertifikaten von Let’s Encrypt konfiguriert ist. Ebenfalls kommen sowohl ECDSA-, als auch RSA-Zertifikate im Hybrid-Betrieb zum Einsatz. Details dazu sind dem Artikel RSA und ECDSA-Zertifikate mit nginx (Hybrid-Lösung) zu entnehmen.

Die Konfiguration für SSL kann dabei direkt in den virtuellen Hosts erfolgen (meist zu finden unter /etc/nginx/conf.d). Für eine bessere Übersicht und die Möglichkeit, SSL-Konfigurationen für mehrere vHosts wiederzuverwenden, nutze ich hier allerdings eine eigene Konfigurations-Datei, welche anschließend in die virtuellen Hosts eingebunden wird (/etc/nginx/snippets/ssl.conf).

Für TLSv1.3 sind hier mehrere Dinge wichtig:

  • ssl_protocols TLSv1.2 TLSv1.3: Hiermit wird die Unterstützung für TLSv1.2 und TLSv1.3 aktiviert. Wichtig: TLSv1.0 und TLSv1.1 sollten an dieser Stelle nicht mit aufgelistet werden, weil diese nicht mehr als sicher gelten.
  • 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‘: Definiert die sog. Cipher Suites. Diese müssen für TLSv1.3 entsprechend angepasst werden (die ersten beiden in der Liste sind speziell für TLSv1.3). Danaben wird hier ECDSA vor RSA bevorzugt.
  • ssl_ecdh_curve secp521r1:secp384r1: Spezifiziert die „Kurve“ für ECDHE-Algorithmen. Hier sollte prime256v1 nicht mehr gelistet werden.

Alle anderen Einstellungen müssen nicht weiter angepasst werden, so dass die SSL-Konfiguration zusammenfassend so aussehen kann:

# Certificates used
# RSA
ssl_certificate /etc/letsencrypt/DOMAIN.de/rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/DOMAIN.de/rsa/key.pem;

# ECC
ssl_certificate /etc/letsencrypt/DOMAIN.de/ecc/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/DOMAIN.de/ecc/key.pem;

# This should be ca.pem (certificate with the additional intermediate certificate)
# See here: https://certbot.eff.org/docs/using.html
ssl_trusted_certificate /etc/letsencrypt/DOMAIN.de/ecc/ca.pem;

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

# Not using TLSv1 will break:
#	Android <= 4.4.40
#	IE <= 10
#	IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
# TLSv1.3 is not supported by most clients, but it should be enabled.
ssl_protocols TLSv1.2 TLSv1.3;

# Prefer the SSL ciphers for ECDSA:
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';


# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;

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

# OCSP Stapling
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# This is the IP if yout DNS-Server (in most cases: your router's IP)
resolver 192.168.178.1;

# SSL session handling
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

Am Schluss muss der Webserver noch neu gestartet werden, damit die Änderungen greifen.

service nginx restart

Falls es hier zu Fehler kommen sollte, kann die genaue Stelle des Fehlers mit folgendem Befehl ermittelt werden:

nginx -t

Kontrolle der Änderungen

Nun kann man die Website im Browser aufrufen und sich die detaillierten Informationen zu der Seite anzeigen lassen. Unter Firefox geht dies beispielsweise, indem man auf das Schloss-Symbol in der Adressleiste klickt. Unter den Details zur Verbindung (Pfeil nach rechts) findet man unten die Schaltfläche Weitere Informationen. Hier sollte dann unter Technische Details ersichtlich werden, dass TLSv1.3 genutzt wird:

Firefox nutzt nun automatisch TLSv1.3

Firefox nutzt nun automatisch TLSv1.3

Eine weitere Anlaufstelle zum Testen von Websites und deren Sicherheit ist der SSL Server Test von Qualys. Beim Test der eigenen Website sollte hier ein A+ Rating und ein Hinweis auf die Unterstützung von TLSv1.3 angezeigt werden:

Beim Qualys SSL Server Test sollte man ein A+ Rating erzielen können

Beim Qualys SSL Server Test sollte man ein A+ Rating erzielen können

Hinweis: In der Kategorie Cipher Strength kann man hier momentan nur eine Wertung von 90% erzielen, auch wenn hier vorher (TLSv1.2) eine 100% Wertung aufgelistet wurde. Dies liegt darin begründet, dass der TLSv1.3-Standard eine Cipher Suite vorgibt, die nur auf 128 Bit basiert (TLS_AES_128_GCM_SHA256). Diese ist bei OpenSSL fest verdrahtet und kann nicht deaktiviert werden. Qualys wertet hier nur mit 100%, wenn alle Cipher Suites mindestens 256 Bit haben. Dies kann momentan nur umgangen werden, indem man OpenSSL selbst kompiliert und installiert. Auf einem Produktiv-System ist dies jedoch nicht zu empfehlen. Mehr Informationen zu diesem Problem findet man auf GitHub.

Wichtig beim SSL Server Tests ist aber ausschließlich das Rating von A+. Auch wenn eine Kategorie nicht mit 100% bewertet ist, stellt dies kein Sicherheits-Risiko dar.

Fazit

Mit dem Update von nginx auf v1.17.2 ist es nun auch endlich möglich, unter Ubuntu Server 18.04 LTS TLSv1.3 zu nutzen. Dies funktioniert ab sofort auch „out-of-the-box“, ohne dass man den Webserver oder OpenSSL selbst bauen und installieren muss.

TLSv1.3 bietet Vorteile bei der Sicherheit und Performance. Daher sollte man seinen Webserver auf jeden Fall für diesem modernen Standard konfigurieren.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/tlsv1-3-unter-ubuntu-server-18-04-lts-mit-nginx/feed/ 0
Verschlüsselte Festplatte (LUKS) mit USB-Stick bei Systemstart entschlüsseln https://decatec.de/linux/verschluesselte-festplatte-luks-mit-usb-stick-bei-systemstart-entschluesseln/ https://decatec.de/linux/verschluesselte-festplatte-luks-mit-usb-stick-bei-systemstart-entschluesseln/#comments Sun, 14 Jul 2019 10:28:32 +0000 https://decatec.de/?p=5914

Oftmals werden auf dem PC oder Home-Server sensible Daten gespeichert. Hier sollte man immer überlegen, ob eine Verschlüsselung der Datenträger lohnt. Wenn der Server zu Hause steht, hat prinzipiell kein Dritter physischen Zugriff auf das System. Aber was passiert, wenn der Home-Server bei einem Einbruch gestohlen wird?. Auch wenn es der Dieb eher auf die Hardware abgesehen hat, bleibt ein ungutes Gefühl, wenn die Daten auf dem Server unverschlüsselt gespeichert wurden. In der Theorie haben dann Dritte Zugriff auf das System und alle darauf gespeicherten Daten.

Die Verschlüsselung von Datenträgern ist unter Linux schnell eingerichtet. Das Mittel der Wahl ist dabei meistens LUKS („Linux Unified Key Setup“). Hier kommt dann meist ein Passwort, oder auch ein sog. Key-File (Dateien mit beliebigem Inhalt – am besten eine zufällige Byte-Folge) zum Einsatz, mit dem eine Festplatte entschlüsselt werden kann.

Die Sicherheit erkauft man sich dann allerdings durch einen Mangel an Komfort: Nach dem Start des Systems müssen verschlüsselte Festplatten erst einmal mittels Passwort/Key-File entschlüsselt und anschließend gemountet werden. Das bedeutet nach jedem (Neu-)Start des Systems Handarbeit.

Um diese Einschränkungen zu umgehen, zeigt dieser Artikel, wie ein USB-Stick zum Entschlüsseln von Datenträgern beim Systemstart genutzt werden kann. Der Clou an der Sache: Wir speichern das Key-File nicht einfach auf dem USB-Stick selbst, sondern noch vor der ersten Partition. Auf diese Weise kann der Stick noch normal verwendet (und auch formatiert) werden. Ebenfalls ist es nicht ersichtlich, dass ein Key-File auf dem Stick enthalten ist, sollte dieser mal in falsche Hände geraten.

Update-Historie (letztes Update: 11.08.2019)
  • 11.08.2019:
    • Korrektur: Beim Erzeugen der Schlüssel-Datei wurden nur 8 statt 16 Sektoren genutzt.

Voraussetzungen

Der Artikel basiert auf Ubuntu Server 18.04 LTS, sollte allerdings auch auf andere Distributionen übertragbar sein.

Es wird nur ein beliebiger USB-Stick benötigt – die Speichergröße ist hierbei egal. Ich verwende beispielsweise einen USB-Stick von SanDisk (Affiliate-Link).

Die zu verschlüsselnde Festplatte ist in diesem Artikel beispielhaft eine zweite interne Festplatte (also nicht die System-Partition). Dadurch kann der ganze Workflow vom Verschlüsseln der Festplatte selbst, bis zum Entschlüsseln mittels USB-Stick bei Systemstart gezeigt werden.

Wichtig: Beim Verschlüsseln der Festplatte gehen dabei alle Daten verloren. Sind bereits Daten auf der Festplatte vorhanden, müssen diese vorher gesichert und nach dem Prozess wieder zurück gespielt werden.
Ebenfalls ist darauf zu achten, bei sämtlichen Befehlen die richtige Festplatte/Partition auszuwählen/anzugeben. Wird eine falsches Gerät adressiert, kann man schnell das komplette System lahm legen (weil z.B. die Daten der System-Partition überschrieben/gelöscht werden). Daher bitte die Befehle nicht einfach kopieren, sondern manuell in der Kommandozeile eingeben und am besten vor dem Ausführen nochmals kontrollieren.

Generell empfiehlt es sich, ein Backup des Systems anzufertigen, bevor die Schritte des Artikels durchgeführt werden.

Festplatte mit LUKS verschlüsseln

Ich gehe im folgenden davon aus, dass die zweite Festplatte im System unter /dev/sdb erkannt wird. Ebenfalls kommt im Setup weder LVM, noch RAID zum Einsatz. Bei LUKS in Verbindung mit LVM bzw. RAID gibt es einige zusätzliche Dinge zu beachten (siehe LUKS FAQ).

Bei der Verschlüsselung mittels LUKS hat man die Wahl, ob man die Festplatte direkt („Raw Device“), oder eine auf der Festplatte zuvor angelegte Partition verschlüsseln möchte. In diesem Beispiel wird die Festplatte (ohne Partition) verschlüsselt, da ich keine Aufteilung in unterschiedliche Partitionen benötige. Wer lieber eine Partition verschlüsseln möchte, muss dies in den entsprechenden Befehlen beachten. Hier ist dann nicht das Device an sich (/dev/sdb), sondern die Partition anzugeben (z.B. /dev/sdb1).

Zunächst wird die benötigte Software installiert:

apt-get update && apt-get install crypsteup dosfstools

Mit folgendem Befehl wird kontrolliert, ob die Festplatte richtig angeschlossen ist und ob die Gerätedatei (/dev/sdb) auch korrekt ist:

fdisk -l

Am besten achtet man hier auf die Größenangaben der Festplatte. Der Output des Programms sieht dann für /dev/sdb beispielhaft so aus:

Disk /dev/sdb: 2,7 TiB, 3000592982016 bytes, 5860533168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Wenn es sich um eine Festplatte handelt, die bereits vorher in Benutzung war, sollte diese vor der Verschlüsselung nochmals mit zufälligen Daten überschrieben werden. Dies macht die Verschlüsselung dann etwas sicherer, da keine unverschlüsselten Daten mehr auf der Festplatte vorliegen.

dd if=/dev/urandom of=/dev/sdb

Achtung: Dieser Vorgang kann gerade bei größeren Festplatten sehr lange dauern!

Anschließend wird ein evtl. vorhandenes Dateisystem auf der Festplatte gelöscht:

wipefs -a /dev/sdb

Nun kann auch schon das interaktive Setup von LUKS aufgerufen werden:

cryptsetup luksFormat /dev/sdb

Hier ist ein Passwort einzugeben, mit dem das Laufwerk entschlüsselt werden kann. Das Passwort sollte dabei eine ausreichende Länge haben.

Tipp: Ein Passwort-Manager (z.B. KeePassXC) hilft nicht nur dabei, Passwörter sicher aufzubewahren, sondern kann auch bei der Generierung sicherer Passwörter helfen.

Um anschließend Zugriff auf die Festplatte zu erlangen, muss diese durch einen Device-Mapper als Geräte-Datei bereit gestellt werden:

cryptsetup luksOpen /dev/sdb crypt_hdd1

crypt_hdd1 ist anschließend der Name der entschlüsselten Festplatte. Diese kann nun wie eine normale Festplatte gemountet werden:

mkdir -p /media/hdd1
mount /dev/mapper/crypt_hdd1 /media/hdd1

Der Zugriff auf die Festplatte erfolgt in diesem Beispiel dann über den Ordner /media/hdd1.

Nun kann auf der Festplatte ein Dateisystem erzeugt werden (in diesem Fall ext4):

mkfs.ext4 /dev/mapper/crypt_hdd1

Zusammenfassend nochmals die Befehle zum Einhängen/Aushängen der verschlüsselten Festplatte.

Einhängen/Mounten:

cryptsetup luksOpen /dev/sdb crypt_hdd1
mount /dev/mapper/crypt_hdd1 /media/hdd1

Hier wird man nach dem ersten Befehl nach dem Passwort gefragt. Ohne dieses lässt sich die Platte nicht mehr entschlüsseln.

Aushängen/Unmounten:

umount /mnt/crypt_hdd1
cryptsetup luksClose crypt_hdd1

Durch luksClose wird die Verschlüsselung der Festplatte wieder aktiv, so dass ohne vorheriges Entschlüsseln/Mounten kein Zugriff mehr erfolgen kann.

USB-Stick zum Entschlüsseln einrichten

Als nächstes wird der USB-Stick vorbereitet, so dass dieser zum Entschlüsseln der Festplatte genutzt werden kann.

Achtung: Auch hier gehen wieder alle Daten verloren, die auf dem USB-Stick gespeichert sind. Wie schon zuvor ist darauf zu achten, dass man das richtige Gerät wählt. In diesem Beispiel erfolgt der Zugriff auf den USB-Stick über /dev/sdc.

Zum Einrichten des USB-Sticks benutzen wir wieder fdisk:

fdisk /dev/sdc

Mit folgenden Eingaben wird der Stick vorbereitet:

  • d: Bestehende Partition löschen.
  • o: Partitionstabelle neu erstellen.
  • n: Neue Partition erstellen. Dies sollte eine primäre Partition sein (p). Beginn der Partition sollte Sektor 2048 sein, dies ist die Standard-Einstellung.
  • w: Speichern und beenden.

Der USB-Stick wird mittels fdisk vorbereitet

Nun kann auf dem USB-Stick ein Dateisystem angelegt werden. Ich nehme hier ein FAT32-Dateisystem, damit der Stick sowohl unter Linux, als auch unter Windows verwendet werden kann. Wenn der Stick ausschließlich unter Linux verwendet werden soll, kann natürlich auch ein ext2/3/4-Dateisystem verwendet werden.

sudo mkfs.vfat -F 32 /dev/sdc1

Nun wird auf dem USB-Stick vor der ersten Partition (also in den ersten 2048 Sektoren) eine zufällige Byte-Folge erzeugt, die nachher als Schlüssel für die verschlüsselte Festplatte dienen wird:

dd if=/dev/urandom of=/dev/sdc bs=512 seek=1 count=2046

Schlüssel zur verschlüsselten Festplatte hinzufügen

Als nächstes speichern wir den soeben erzeugten Schlüssel in einer Datei ab:

dd if=/dev/sdc bs=512 skip=1 count=16 > tempKeyFile.bin

Hier nehmen wir die ersten 16 Sektoren des USB-Sticks, somit haben wir hier eine Schlüssellänge 8192 Bytes.

Diese (temporär) erzeugte Datei wird nun über LUKS als neuer Key der Festplatte hinzugefügt:

cryptsetup luksAddKey /dev/sdb tempKeyFile.bin

Anschließend kann die Festplatte auf zwei verschiedene Weisen entschlüsselt werden:

  • Mit dem Passwort, welches bei der Verschlüsselung der Festplatte angegeben wurde.
  • Mit dem soeben erzeugten Key-File, welches auch auf dem Stick vor der ersten Partition gespeichert ist.

Das Key-File (tempKeyFile.bin) wird anschließend nicht mehr benötigt. Jedoch sollte man dies ebenfalls sicher verwahren, falls man z.B. zukünftig einen anderen USB-Stick zum entschlüsseln verwenden möchte. Das Key-File kann z.B. neben dem Passwort zum Entschlüsseln ebenfalls in einem Passwort-Manager (als Anhang) gespeichert werden.

Anschließend wird das Key-File vom System entfernt:

rm tempKeyFile.bin

Festplatte automatisch bei Systemstart entschlüsseln

Nun fehlt nur noch ein entscheidender Bestandteil der Lösung: Wir wollen die Festplatte nicht per Passwort oder Key-File, sondern mit dem Schlüssel entschlüsseln, der auf dem USB-Stick hinterlegt ist. Das ganze soll auch transparent bei Systemstart ohne weiteres Zutun den Users passieren.

UUIDs der Geräte ermitteln

Damit dies umgesetzt werden kann, müssen die UUIDs der entsprechenden Geräte ermittelt werden.
Für den USB-Stick kann dies durch folgenden Befehl geschehen:

ls /dev/disk/by-id/

Hier sollte der USB-Stick mit zwei Einträgen gelistet werden.

usb-SanDisk_Ultra_4C530000100xxxxxxxxx-0:0
usb-SanDisk_Ultra_4C530000100xxxxxxxxx-0:0-part1

Hier brauchen wir die UUID des Sticks selbst und nicht jene von der ersten Partition (zu erkennen an -part1 am Ende). Die gesuchte UUID ist in diesem Beispiel also 4C530000100xxxxxxxxx-0:0.

Nun brauchen wir nur noch die UUID der LUKS-verschlüsselten Festplatte. Hier hilft folgender Befehl:

blkid

Hier sollte man nun folgende Zeile finden (die verschlüsselte Festplatte ist ja unter /dev/sdb zu erreichen):

/dev/sdb: UUID=“10fc8291-daf2-4962-xxxx-xxxxxxxxxxxx“ TYPE=“crypto_LUKS“

Die UUID ist hier dementsprechend 10fc8291-daf2-4962-xxxx-xxxxxxxxxxxx.

crypttab/fstab editieren

Damit die Festplatte bei Systemstart entschlüsselt wird, wird nun die crypttab (Anweisungen zum Einhängen verschlüsselter Geräte) bearbeitet:

nano /etc/crypttab

Hier fügen wir am Ende folgende Zeile ein:

crypt_hdd1 UUID=10fc8291-daf2-4962-xxxx-xxxxxxxxxxxx /dev/disk/by-id/usb-SanDisk_Ultra_4C530000100xxxxxxxxx-0:0 luks,tries=3,keyfile-size=8192,keyfile-offset=512

Bei der UUID handelt es sich um jene der verschlüsselten Festplatte. Daraufhin folgen Angaben zum USB-Stick, der zum entschlüsseln verwendet werden soll. Am Schluss wird angegeben, wo der entsprechende Schlüssel zu finden ist.

Damit wird die Festplatte beim Systemstart entschlüsselt. Was nun noch fehlt ist das Einhängen der entschlüsselten Festplatte, so dass diese nach dem Systemstart sofort zur Verfügung steht. Dazu wird noch die fstab editiert:

nano /etc/fstab

Am Ende fügen wir folgende Zeile hinzu:

/dev/mapper/crypt_hdd1       /media/hdd1     ext4    defaults        0       2

Beim Systemstart werden nun erst einmal die Inhalte der crypttab abgearbeitet. Damit wird die Festplatte entschlüsselt und steht per Mapper (/dev/mapper/crypt_hdd1) zur Verfügung. Erst im Anschluss werden die Laufwerke per fstab gemountet. Hier wird der Mapper dann unter /media/hdd1 eingehängt.

Nach einem Neustart des Systems (mit angeschlossenem USB-Stick) sollte die Festplatte nun direkt unter /media/hdd1 zur Verfügung stehen. Es wird kein Passwort mehr benötigt und das Key-File ist auch nicht mehr manuell anzugeben.

Fazit

Die Einrichtung von verschlüsselten Festplatten, die beim Systemstart automatisch per USB-Stick entschlüsselt werden, ist mit einigem Aufwand verbunden. Jedoch muss man sich nach der Konfiguration nicht weiter um die Ver-/Entschlüsselung der Festplatte sorgen, da dies nun vollkommen transparent geschieht

Wichtig ist ab nun nur, dass man den USB-Stick einstecken muss, wenn die Maschine (neu) gestartet werden soll. Sollte man dies vergessen, bleibt das System schon beim Booten hängen, da die Anweisungen in der crypttab nicht abgearbeitet werden können und der Mount per fstab fehlschlägt.

Ebenso benötigt es etwas Disziplin: Wenn die Maschine erst einmal läuft, sollte der USB-Stick auf jeden Fall entfernt und sicher aufbewahrt werden (z.B. am Schlüsselbund). Im Falle eines Diebstahls der Hardware ist es nun praktisch gesehen unmöglich, auf die Daten des Systems zuzugreifen, wenn man nicht den passenden USB-Stick zur Hand hat.

Links

]]>
https://decatec.de/linux/verschluesselte-festplatte-luks-mit-usb-stick-bei-systemstart-entschluesseln/feed/ 16
WordPress: Backups erstellen und wiederherstellen – manuell oder per Skript https://decatec.de/home-server/wordpress-backups-erstellen-und-wiederherstellen-manuell-oder-per-skript/ https://decatec.de/home-server/wordpress-backups-erstellen-und-wiederherstellen-manuell-oder-per-skript/#comments Sat, 08 Jun 2019 09:02:18 +0000 https://decatec.de/?p=5817 Wordpress Logo

WordPress erfreut sich bei Bloggern nach wie vor großer Beliebtheit. Wenn man einen eigenen WordPress-Blog betreibt, sollte man sich auch um das Thema Backup kümmern.

Wird der Blog bei einem Webhosting-Provider gehostet, dann werden meist von diesem automatisch Backups des kompletten Webspace durchgeführt. Damit wird dann auch ein vorhandener WordPress-Blog mit gesichert.

Anders sieht die Sache bei selbstgehosteten Blogs aus. Hier ist der Administrator selbst für Backups des Servers und der Webseiten verantwortlich.

Voraussetzungen

Dieser Artikel richtet sich an Administratoren, die WordPress auf einem eigenen (Home-)Server betreiben.

Als Grundlage dient ein WordPress-Blog, der auf einem Ubuntu Server 18.04 LTS installiert ist. Als Webserver dient hier nginx, als Datenbank kommt MariaDB zum Einsatz.
Eine beispielhafte Konfiguration wurde bereits im Artikel Zweite Web-Anwendung neben ownCloud/Nextcloud einrichten (am Beispiel WordPress) gezeigt.

Allerdings lassen sich die gezeigten Schritte auch auf andere Umgebungen (andere Distributionen, andere Webserver, etc.) anwenden.

Grundlagen

Ein Backup von WordPress besteht immer aus zwei Teilen:

  • Dem WordPress Dateiverzeichnis: Dies sind alle Dateien, die zum Betrieb von WordPress benötigt werden (z.B. php, oder auch css-Dateien). Dies ist normalerweise unter /var/www/wordpress zu finden.
  • Der WordPress-Datenbank: WordPress benötigt eine MySQL/MariaDB-Datenbank. Diese muss ebenfalls in die Sicherung einfließen.

Sollen Backups des eigenen Blogs eingerichtet werden, müssen immer diese beiden Teile berücksichtigt werden.

Im Vorfeld sollte man sich Gedanken darüber machen, wo die Backups gespeichert werden sollen. Im Rahmen dieses Artikels nutze ich beispielhaft das Verzeichnis /media/hdd/wordpress_backup als Backup-Ziel. Dies kann in der Praxis eine zweite (externe) Festplatte oder ein NAS sein, welches im Netzwerk zur Verfügung steht.

Backup erstellen

Um ein Backup zu erstellen, stoppen wir zunächst den Webserver:

service nginx stop

Dies verhindert, dass während des Backups aktive Zugriffe auf den Blog stattfinden.

Als nächstes wird das Dateiverzeichnis von WordPress gesichert. Hier ist dies beispielhaft das Verzeichnis /var/www/wordpress. Bitte den Punkt am Ende des Befehls beachten.

tar -cpzf "/media/hdd/wordpress_backup/wordpress-filedir_`date +"%Y%m%d"`.tar.gz" -C "/var/www/wordpress" .

Als nächstes wird die Datenbank gesichert. Nach dem Absetzen des Befehls ist noch das Passwort des WordPress-Datenbank-Users einzugeben:

mysqldump --single-transaction -h localhost -u wordpress_db_user -p wordpress_db > /media/hdd/wordpress_backup/wordpress-db_`date +"%Y%m%d"`.sql

Das Backup ist damit schon komplett und der Webserver kann neu gestartet werden:

service nginx start

Backup wiederherstellen

Das Anfertigen von Backups ist aber nur der erste Schritt. Ebenso wichtig ist es, dass diese Backups auch wiederhergestellt werden können.

Dies sollte man nach dem ersten Anfertigen eines Backups auch mindestens einmal ausprobieren.

Zunächst wird der Webserver gestoppt:

service nginx stop

Anschließend wird das Dateiverzeichnis von WordPress gelöscht und neu angelegt (allerdings leer):

rm -r /var/www/wordpress/
mkdir -p /var/www/wordpress

Als nächstes werden die Inhalte des Verzeichnisses aus dem Backup wiederhergestellt. Zu beachten ist hier der richtige Dateiname (da abhängig vom Datum):

tar -xpzf /media/hdd/wordpress_backup/wordpress-filedir_20190530.tar.gz -C /var/www/wordpress/

Nun werden noch die passenden Rechte gesetzt:

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

Nun muss nur noch die Datenbank wiederhergestellt werden. Dazu wird die alte Datenbank zunächst einmal entfernt und neu angelegt:

mysql -h localhost -u wordpress_db_user -p -e "DROP DATABASE wordpress_db"
mysql -h localhost -u wordpress_db_user -p -e "CREATE DATABASE wordpress_db"

Nun wird der DB-Dump aus dem Backup wieder eingespielt:

mysql -h localhost -u wordpress_db_user -p wordpress_db < /media/hdd/wordpress_backup/wordpress-db_20190530.sql

Am Schluss wird der Webserver wieder gestartet:

service nginx start

Backup/Restore mit Bash-Skript

Ein Backup kann mit diesen einfachen Schritten erstellt werden. Allerdings sind dazu immer manuelle Schritte erforderlich. Komfortabler wird die Sache, wenn man alle Schritte mit einem Bash-Skript zusammenfasst. Dieses kann dann einfach ausgeführt werden und es wird automatisch ein Backup erstellt.

Zu diesem Zweck habe ich zwei Bash-Skripte auf Codeberg zur Verfügung gestellt:

WordPress-Backup-Restore @ Codeberg

Hinweis: Ich habe die Skript-Dateien als Open Source auf Codeberg zur Verfügung gestellt. Damit sind diese frei verfügbar und können auch von jedermann angepasst und verbessert werden. Ich übernehme allerdings keinerlei Haftung für den Einsatz dieser Skripte. Diese sollen lediglich als Basis für die Erstellung eigener Backup-/Restore-Skripte für eure WordPress-Instanzen dienen.

Das Repository kann einfach über Git gecloned werden:

cd ~
git clone https://codeberg.org/DecaTec/Wordpress-Backup-Restore.git
cd Wordpress-Backup-Restore

Wichtig: Die Skripte müssen auf jeden Fall noch an die konkrete Umgebung angepasst werden. Alle Stellen, die kontrolliert bzw. angepasst werden müssen, sind in den Skripten mit dem Kommentar „TODO“ gekennzeichnet.

Bitte passt die Skripte daher auf jeden Fall an und führt diese nicht einfach „blind“ aus!

Wenn das geschafft ist, werden die Skripte noch als ausführbar markiert:

chmod +x WordpressBackup.sh
chmod +x WordpressRestore.sh

Nun können die Skripte ganz einfach wie folgt ausgeführt werden:

./WordpressBackup.sh

Das Backup wird automatisch im Verzeichnis /media/hdd/wordpress_backup erstellt. Hier wird ein Verzeichnis mit dem aktuellen Zeitstempel erstellt, z.B.: /media/hdd/wordpress_backup/20190530_081555

Wiederhergestellt werden kann ein Backup durch das Restore-Skript. Dieses erwartet den Zeitstempel eines vorhandenen Backups als Parameter:

./WordpressRestore.sh 20190530_081555

Diese Skripte sind so konzipiert, dass diese keine Benutzer-Interaktion erfordern. Daher kann die Ausführung auch einfach per Cron automatisiert werden. Besonders für das Backup-Skript ist dies sinnvoll: So kann man z.B. jede Nacht um 03:00 ein Backup des eigenen WordPress-Blogs anfertigen. Dazu kann ein Cronjob für den Webserver-User eingerichtet werden:

crontab -u www-data -e

Hier wird am Ende einfach folgender Befehl angehängt:

0 3 * * * /home/user/Wordpress-Backup-Restore/WordpressBackup.sh > /dev/null 2>&1

Dies sorgt dafür, dass jede Nacht um 03:00 ein Backup von WordPress angelegt wird. Wichtig ist hier nur, dass der absolute Pfad zu Skript angegeben wird, da die Ausführung ansonsten fehlschlagen wird.

Alternative: Backup per WordPress-Plugin

Eine Alternative zum dem gezeigten Vorgehen ist der Einsatz eines entsprechenden Plugins für WordPress. Meiner Erfahrung nach gibt es hier zwei empfehlenswerte Plugins:

Beide Plugins dienen dazu, Backups der WordPress-Instanz manuell oder automatisiert anzulegen. Das ganze wird einfach im Dashboard von WordPress konfiguriert bzw. ausgeführt. Die Plugins sind dabei mehr oder weniger selbsterklärend, so dass ich hier nicht weiter darauf eingehen werde.

Zum einen macht dies das Anfertigen von Backups einfacher. Zum anderen macht man sich allerdings in gewisser Weise abhängig von dem verwendeten Plugin. Dies ist durch ein manuelles Backup oder ein Backup per Bash-Skript nicht gegeben.

Welche Variante (manuell/per Skript oder per Plugin) die passende ist, muss jeder WordPress-Administrator für sich selbst entscheiden.

Fazit

Ein Backup einer WordPress-Instanz ist recht schnell angefertigt. Noch komfortabler geht dies mit den bereitgestellten Bash-Skripten. Mit diesen kann das Anfertigen eines Backups auch mittels Cron automatisiert werden.

Am Ende noch ein wichtiger Tipp: Nichts ist ärgerlicher, wenn man immer Backups angefertigt hat, diese aber im Ernstfall nicht wiederhergestellt werden können. Daher sollte einmal der komplette Backup- und Restore-Prozess getestet werden. Nur auf diese Weise kann man sicher sein, dass im Falle des Falles ein bestehendes Backup wiederhergestellt werden kann.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/wordpress-backups-erstellen-und-wiederherstellen-manuell-oder-per-skript/feed/ 4
Samba auf Ubuntu Server https://decatec.de/linux/samba-auf-ubuntu-server/ https://decatec.de/linux/samba-auf-ubuntu-server/#comments Mon, 27 May 2019 13:48:39 +0000 https://decatec.de/?p=5699 Samba Logo

Wenn man einen eigenen Home-Server betreibt, dann wird man diesen oftmals auch als zentrale Stelle zur Ablage von Dateien verwenden. Damit jeder Rechner im Netzwerk Zugriff auf diese  Dateien hat, muss der Server diese Daten per Netzwerk-Freigaben bereit stellen.

In einem reinen Linux-Netzwerk würde man hier vermutlich NFS verwenden. Oftmals hat man es jedoch mit gemischten Netzwerken zu tun. Hier müssen neben Linux- auch Windows- oder Mac-Clients Zugriff auf die Netzwerk-Freigaben haben. Hier nutzt man dann am besten das SMB-Protokoll, welches auf allen Plattformen unterstützt wird. Als Server-Implementierung steht unter Linux das Softwareprojekt Samba zur Verfügung.

Dieser Artikel zeigt, wie auf Ubuntu Server 18.04 LTS eine Samba-Server installiert und konfiguriert werden kann. Allerdings können alle Schritte auch auf andere Distributionen übertragen werden.

Eine wichtige Anforderung bei Netzwerk-Shares ist immer auch die Freigabe für mehrere Benutzer: Auf eine Freigabe sollen u.U. mehrere Benutzer Schreib- und Leserechte haben. Dies wird in diesem Artikel durch das Setzen von ACLs gelöst.

Installation Samba

Zunächst wird das System auf dem neusten Stand gebracht:

apt-get update && apt-get upgrade -V && apt-get dist-upgrade && apt-get autoremove

Anschließend kann Samba installiert werden:

apt-get install samba-common samba

Das Paket samba-common sollte auf jeden Fall mit installiert werden, da dies wichtige Tools (wie z.B. smbpasswd) beinhaltet.

Benutzer hinzufügen

Damit ein Benutzer später auf die Samba-Netzwerk-Freigaben zugreifen kann, muss dieser Benutzer zunächst einmal angelegt werden. Wichtig ist ist in diesem Zusammenhang, dass der Benutzer sowohl als System-Benutzer, als auch als Samba-Benutzer angelegt werden muss.

Wenn es den Benutzer noch nicht als System-Benutzer gibt, dann wird dieser angelegt und danach ein Passwort für den Benutzer hinterlegt:

adduser bob

Alternative: Normalerweise legt man diese Benutzer nur an Home-Server an, damit diese später Zugriff auf die Samba-Freigaben haben. In diesem Fall macht es keinen Sinn, dass sich diese Benutzer direkt am System anmelden. Hier kann man den User folgendermaßen anlegen, so dass sich dieser nicht am Server selbst anmelden kann:

adduser --no-create-home --disabled-login --shell /bin/false bob

Anschließend wird noch ein Passwort für den System-Benutzer hinterlegt:

passwd bob

Anschließend muss der entsprechende User noch als Samba-User angelegt und aktiviert werden:

smbpasswd -a bob

Empfehlenswert ist hier, das gleiche Passwort wie schon für den System-Benutzer zu vergeben, dies ist jedoch nicht zwingend erforderlich.

Für jeden weiteren Benutzer ist der Vorgang zu wiederholen. Neben Bob gibt es in diesem Artikel als weiteren User auch Alice:

adduser --no-create-home --disabled-login --shell /bin/false alice
passwd alice
smbpasswd -a alice

Verzeichnisse für Netzwerk-Shares vorbereiten

Als nächstes werden beispielhaft drei Verzeichnisse vorbereitet, die später im Netzwerk verfügbar sein sollen. Auf das erste Verzeichnis sollte nur der Benutzer Bob Zugriff haben, daher werden anschließend gleich die entsprechenden Besitzrechte gesetzt:

mkdir -p /media/hdd1/networkshares/bob
chown -R bob /media/hdd1/networkshares/bob

Das gleiche wird für ein Verzeichnis für Alice wiederholt:

mkdir -p /media/hdd1/networkshares/alice
chown -R alice /media/hdd1/networkshares/alice

Ein drittes Verzeichnis soll nachher für beide Benutzer zur Verfügung stehen. Hier wird lediglich das Verzeichnis erzeugt:

mkdir -p /media/hdd1/networkshares/shared

Nun haben wir allerdings ein Problem mit den Verzeichnisrechten: Beide Benutzer sollen hier Vollzugriff haben. Per chown kann allerdings nur ein User als Owner definiert werden.

Hier gibt es nun zwei Varianten, wie die entsprechenden Rechte gesetzt werden können: Per ACL oder per Gruppen.

Rechte für mehrere Benutzer setzen – Variante 1: Per ACL

ACL (Access Control List) ergänzen das normale Rechtesystem von Linux. Man kann sich dies als zusätzliche „Schicht“ über dem normalen Rechtesystem vorstellen. Dies ist eine einfache Möglichkeit, Benutzern/Gruppen gezielt Zugriffsrechte auf Dateien und Verzeichnisse zu geben bzw. zu entziehen.

Hinweis: Beim Setzen der Rechte über ACLs gestaltet sich die Konfiguration der Netzwerk-Shares über Samba im weiteren Verlauf etwas einfacher. Daher ist dies meine bevorzugte Variante.

ACL wird während der Installation von Ubuntu Server automatisch installiert. Wenn dies nicht der Fall sein sollte, dann kann das zu einem späteren Zeitpunkt nachgeholt werden:

apt-get install acl

Nun können ACLs für das Verzeichnis gesetzt werden, auf das später beide Benutzer Zugriff haben sollen:

setfacl -R -d -m u:bob:rwx,u:alice:rwx /media/hdd1/networkshares/shared

Dieser Befehl bewirkt folgendes:

  • Die Rechte werden rekursiv gesetzt (-R).
  • Mittels -d wird ein Default gesetzt, der auch bei zukünftig angelegten Dateien und Verzeichnissen wirkt.
  • Mit dem Parameter -m werden evtl. bereits vorhandene Rechte modifiziert und nicht einfach überschrieben.
  • Die genauen Rechte für einen User werden z.B. durch u:bob:rwx gesetzt: Hier sollen die Benutzer Bob und Alice Vollzugriff auf das Verzeichnis haben.

Ein weiteres Setzen der Rechte über chown/chmod ist nicht erforderlich.

Rechte für mehrere Benutzer setzen – Variante 2: Per Gruppe

Für die zweite Variante nutzen wir Gruppen um die entsprechenden Rechte zu setzen.

Hinweis: Die Variante mit Gruppen macht die Einrichtung der Netzwerk-Shares später etwas komplizierter. Daher bevorzuge ich mittlerweile die erste Variante (ACL) zum Setzen der Rechte.

Beide Benutzer werden dazu in eine Gruppe aufgenommen. Dann wird der Gruppe die entsprechenden Besitzrechte gegeben und anschließend per chmod die passenden Zugriffsrechte gesetzt:

addgroup bobundalice
usermod -aG bobundalice bob
usermod -aG bobundalice alice
chown -R bob:bobundalice /media/hdd1/networkshares/shared
chmod -R 775 /media/hdd1/networkshares/shared

Samba Konfiguration

Bleibt eigentlich nur noch die Einrichtung des Samba-Servers. Die Konfiguration befindet sich in folgender Datei:

nano /etc/samba/smb.conf

Allgemeine Einstellungen

Zunächst werden in der Sektion [Global] ein paar Werte gesetzt. map to guest ist meist schon vorhanden, die anderen Werte werden einfach darunter eingefügt:

map to guest = never
security = user
encrypt passwords = true
invalid users root

Im einzelnen wird damit folgendes konfiguriert:

  • map to guest = never deaktiviert den Gast-Zugriff auf den Samba-Server. Ohne diese Einstellung könnte man sich am Samba-Server auch als Gast anmelden.
  • security = user gibt an, dass die Authentifizierung am Samba-Server mittels Username/Passwort erfolgt.
  • encrypt passwords = true sorgt dafür, dass Passwörter nur verschlüsselt übertragen werden.
  • invalid users root deaktiviert den Zugriff auf die Samba-Shares für den Root-User.

Weiter unten in der Konfigurations-Datei findet man Sektionen, mit den Drucker-Freigaben eingerichtet werden. Diese sind standardmäßig aktiv. Möchte man keine Drucker freigeben, dann kommentiert man die beiden Sektionen [printers] und [print$] am besten aus.

Freigabe für einen Benutzer

Bob und Alice sollen jeweils eine eigene Freigabe haben, auf die kein anderer Benutzer Zugriff hat. Dazu werden in der smb.conf ganz am Ende folgende Blöcke eingefügt:

[bob]
valid users = bob
path = /media/hdd1/networkshares/bob
guest ok = no
writeable = yes

[alice]
valid users = alice
path = /media/hdd1/networkshares/alice
guest ok = no
writeable = yes

Folgende Angaben sind hier zu machen:

  • [bob]: Der Sektions-Name legt fest, wie die Freigabe heißen soll.Über diesen Namen werden die Netzwerk-Shares dann später auf den Client-Rechnern eingerichtet.
  • valid users: Hier werden die Benutzer festgelegt, welche Zugriff auf die Freigabe haben sollen. Bei Einzel-Freigaben ist dies auch immer nur ein User.
  • path: Legt den lokalen Pfad fest, auf dem die Freigabe auf den lokalen Rechner liegen soll.
  • guest ok = no: Hiermit wird festgelegt, dass sich Gäste nicht auf diese Freigabe verbinden können.
  • writeable = yes: Dies wird nochmals explizit angegeben, dass der Benutzer unter valid users Schreibzugriff auf die Freigabe haben soll.

Freigabe für mehrere Benutzer – Variante 1: ACL

Bei den Freigaben für mehrere Benutzer gibt es wieder zwei Varianten, abhängig davon, wie zuvor die Rechte auf Dateisystem-Ebene gesetzt wurden (ACL oder Gruppen).

Ich bevorzuge das Setzen der Rechte per ACL. In diesem Fall sieht die Konfiguration der Freigabe folgendermaßen aus. Der Name der Freigabe lautet hier shared:

[shared]
valid users = bob alice
path = /media/hdd1/networkshares/shared
guest ok = no
writeable = yes

Wie man sieht, unterscheidet sich diese Variante kaum von der Einrichtung einer Freigabe für einen einzelnen User. Es werden lediglich mehrere Benutzer unter valid users angegeben.

Freigabe für mehrere Benutzer – Variante 2: Gruppen

Wenn keine ACLs gesetzt wurden, sondern beide Benutzer in eine Gruppe hinzugefügt wurden, müssen für das Konfigurieren der Freigabe ein paar zusätzliche Angaben gemacht werden:

[shared]
valid users = @bobundalice
path = /media/hdd1/networkshares/shared 
guest ok = no
write list = @bobundalice
directory mask = 0775
create mask = 0775

Folgendes gilt es hier zu beachten:

  • valid users: Hier wird die Gruppe der User angegeben, die Zugriff auf die Freigabe haben soll. Vor dem Gruppen-Namen muss dazu ein @ Symbol stehen.
  • write list: Hier wird wiederum die Gruppe angegeben, die Schreibzugriff auf die Freigabe haben soll.
  • directory mask/create mask: Hier werden die Datei- bzw. Verzeichnisrechte gesetzt, ähnlich wie beim Befehl chmod. Dies sorgt dafür, dass die Dateien mit den entsprechenden Rechten versehen werden, wenn diese (durch die Benutzer der Freigabe) erstellt werden.

Konfiguration der Freigaben abschließen

Damit wäre die Konfiguration von Samba abgeschlossen. Mit folgenden Befehlen wird die aktuelle Konfiguration getestet und Samba anschließend neu gestartet:

testparm
service smbd restart

Falls die Firewall ufw auf dem System aktiv ist, muss hier noch eine Freigabe für Samba erfolgen. Am einfachsten funktioniert dies mit einem Applikations-Filter:

ufw allow from 192.168.178.0/24 to any app Samba

In diesem Beispiel erfolgt die Freigabe nur für das lokale Netzwerk (192.168.178.0/24). Damit haben nur Clients innerhalb des gleichen Netzwerks Zugriff auf die Samba-Freigaben.

Einbinden der Netzwerk-Shares

Nach der Einrichtung von Samba können die Freigaben nun ganz einfach auf den Client-Rechnern eingebunden werden.

Linux

Unter Linux kann die Freigabe entweder temporär oder dauerhaft eingebunden werden.

Temporärer Zugriff auf die Freigaben per Datei-Manager

Auf die Freigaben kann man mit jedem Datei-Manager zugreifen, indem man in die Adressziele den SMB-Speicherort eingibt, z.B. smb://192.168.178.60.

Direkter Zugriff auf die Freigaben (Manjaro/Thunar)

Direkter Zugriff auf die Freigaben (Manjaro/Thunar)

Hier werden alle Freigaben angezeigt. Bei einem Zugriff muss dann noch die Eingabe von Username/Passwort erfolgen.

Temporäres Einbinden per Kommandozeile

Hier wird das Paket cifs-utils benötigt:

apt-get install cifs-utils

Damit nicht immer das Passwort beim Mounten der Freigabe eingegeben werden muss, sollte sich der entsprechende Nutzer in seinem Home-Verzeichnis eine Datei anlegen, in der Username und Passwort gespeichert ist:

cd ~
nano .smbcredentials

Der Inhalt der Datei ist dabei recht einfach:

username=<User>
password=<Password>

Auf diese Datei sollte nur der entsprechende User Zugriff haben:

sudo chmod 600 .smbcredentials

Als nächstes werden die Verzeichnisse angelegt, in die die Freigaben gemountet werden sollen:

mkdir -p /mnt/bob
mkdir -p /mnt/shared

Soll die Freigabe nun temporär gemountet werden, können dazu folgende Befehle genutzt werden:

mount -t cifs -o credentials=~/.smbcredentials //192.168.178.60/bob /mnt/bob
mount -t cifs -o credentials=~/.smbcredentials //192.168.178.60/shared /mnt/shared

Hier wird folgendes angegeben:

  • -o credentials=~/.smbcredentials: Hier werden Benutzername/Passwort mit der soeben angelegten Datei übergeben.
  • //192.168.178.60/bob: IP des Samba-Servers und Name der Freigabe, wie auf dem Samba-Server in der Datei smb.conf als Sektions-Name angegeben.
  • /mnt/bob: In diesen Ordner wird die Freigabe gemountet.

Ein Aushängen (unmount) der Freigabe kann folgendermaßen durchgeführt werden:

umount /mnt/bob

Auch nach einem Neustart des Systems ist die Freigabe aber wieder verschwunden.

Dauerhaftes Mounten per fstab

Die Freigaben können aber auch per fstab gemountet werden. Damit stehen die Freigaben dann direkt nach einem System-Neustart zur Verfügung:

nano /etc/fstab

Am Ende der Datei wird nun folgendes hinzugefügt (die bereits bestehenden Einträge in der Datei sollte man nicht verändern):

//192.168.178.60/bob /mnt/bob cifs credentials=/home/bob/.smbcredentials,noperm,_netdev,noauto,x-systemd.automount 0 0
//192.168.178.60/shared /mnt/shared cifs credentials=/home/bob/.smbcredentials,noperm,_netdev,noauto,x-systemd.automount 0 0

Das Einbinden erfolgt ähnlich wie schon beim temporären Einbinden, jedoch gibt es einige Unterschiede:

  • Die Pfadangabe für die Datei mit den Credentials muss absolut erfolgen.
  • Mit noperm wird angegeben, dass die Credentials nicht Client-seitig, sondern nur auf dem Server geprüft werden.
  • _netdev gibt an, dass der Mount abhängig von einer Netzwerk-Verbindung ist.
  • Die Parameter noauto,x-systemd.automount sorgen dafür, dass die Freigabe erst beim ersten Zugriff gemountet wird. Dies macht das Einbinden etwas effizienter.

Ob das Mounten erfolgreich durchgeführt werden kann, testet man anschließend mit folgendem Befehl (als Root-User):

mount -a

Nun stehen die Freigaben direkt nach dem Systemstart zur Verfügung.

Windows

Auch unter Windows kann man die Freigaben temporär oder dauerhaft einbinden.

Temporärer Zugriff auf die Freigaben per Explorer

Um im Explorer direkten Zugriff auf die Freigaben zu erhalten, gibt man einfach die entsprechende Adresse des Samba-Servers ein, z.B. \\192.168.178.60. Nach der Eingabe von Benutzername und Passwort werden die Freigaben angezeigt:

Direkter Zugriff auf die Freigaben (Windows)

Direkter Zugriff auf die Freigaben (Windows)

Dauerhaftes Einbinden unter Windows

Um die Eingaben dauerhaft einzubinden, nutzt man im Explorer einfach die Funktion Netzlaufwerk verbinden:

Windows: Netzlaufwerk verbinden

Windows: Netzlaufwerk verbinden

Im zweiten Schritt werden die Daten des Netzlaufwerks angegeben:

Windows: Verbindung mit Netzlaufwerk herstellen

Windows: Verbindung mit Netzlaufwerk herstellen

Neben dem zuzuweisenden Laufwerks-Buchstaben und dem Netzwerk-Pfad der Freigabe sollte die Option Verbindung mit anderen Anmeldeinformationen herstellen gewählt werden. Anschließend gibt man Benutzername und Passwort des Linux/Samba-Users an.

Fazit

Ein Samba-Server ist schnell auf einem Linux Server installiert. Die Konfiguration erfordert etwas Handarbeit. Gerade für Freigaben, die mehreren Benutzern zur Verfügung stehen sollen, sind zwei Varianten möglich (ACL und Bilden von Gruppen). Ich bevorzuge hier die Nutzung von ACLs, da das Konfigurieren der Freigaben bei Samba sehr viel einfacher erfolgen kann.

Wenn der Samba-Server fertig konfiguriert ist, steht dieser dauerhaft als Speicherort im Netzwerk zur Verfügung. Durch das weit verbreitete SMB-Protokoll können diese Freigaben dann auf beliebigen Systemen eingebunden werden.

Links

]]>
https://decatec.de/linux/samba-auf-ubuntu-server/feed/ 4
Nextcloud: Die eigenen Cloud auf neue Domain umziehen https://decatec.de/home-server/nextcloud-die-eigenen-cloud-auf-neue-domain-umziehen/ https://decatec.de/home-server/nextcloud-die-eigenen-cloud-auf-neue-domain-umziehen/#comments Thu, 16 May 2019 15:04:47 +0000 https://decatec.de/?p=5622 Nextcloud Logo

In diesem Artikel soll es um die Änderung der Domain einer bestehenden Nextcloud-Instanz gehen. Dies sollte zwar im Normalfall nicht notwendig sein, dennoch gibt es einige denkbare Szenarien, bei dem der Umzug auf eine andere Domain erforderlich sein kann.

Beispiel: Beim Self-Hosting kommt im privaten Bereich oftmals eine DynDNS-Adresse zum Einsatz. Einmal im Router eingerichtet, wird die DynDNS-Domain dann auf die (öffentliche) IP-Adresse des Routers gemappt. Folglich ist der eigene Server dann direkt aus dem Internet über die DynDNS-Domain erreichbar.

Allerdings ist man nun in gewissem Maße vom DynDNS-Anbieter abhängig. Ist ein solcher Dienst dann mal nicht verfügbar (z.B. durch technische Probleme beim Anbieter) oder wird komplett eingestellt (was bei kostenlosen Anbietern durchaus mal passieren kann), dann ist die eigenen Cloud nicht mehr aus dem Internet erreichbar.

Genau dann kann es erforderlich sein, den DynDNS-Provider zu wechseln, was meistens eine neue Domain für die Cloud bedeutet.

Update-Historie (letztes Update 17.08.2019)
  • 17.08.2019:
    • acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
  • 18.05.2019:
    • dynv6 als weiteren empfohlenen DynDNS-Dienst hinzugefügt.

 

Voraussetzungen

Als Basis dient folgendes System:

  • Betriebssystem: Ubuntu Server 18.04
  • Webserver: nginx
  • Let’s Encrypt Client: acme.sh
  • Nextcloud 16

Allerdings können auch andere Distributionen, Webserver und Let’s Encrypt Clients zum Einsatz kommen. Die gezeigten Schritte sind also generell auch auf andere Systeme übertragbar, auch wenn hier ggf. Anpassungen an die jeweilige Umgebung erfolgen muss.

Ich gehe im folgenden davon aus, dass das bestehende Nextcloud-Setup voll funktionsfähig ist und nur auf eine andere Domain umgezogen werden soll. Grundlage dafür ist der Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban.

Für die Generierung der HTTPS-Zertifikate nutze ich das Shell-Script acme.sh, mehr Infos dazu findet man im Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx. Ebenfalls nutze ich hier sowohl RSA- als auch ECDSA-Zertifikate („hybrid“). Was es damit auf sich hat, findet man im Artikel RSA und ECDSA-Zertifikate mit nginx (Hybrid-Lösung).

Wie immer empfiehlt es sich, vor Änderungen an Nextcloud ein komplettes Backup der Cloud vorzunehmen. Mehr Informationen zu dem Thema findet man im Artikel Nextcloud: Backups erstellen und wiederherstellen – manuell oder per Skript.

Die neue Domain

Die Cloud soll also umgezogen werden? Ein Backup ist erstellt? Dann kann es losgehen…

Im Rahmen des Artikels nutze ich beispielhaft die Domains alt.meinedomain.de und neu.meinedomain.de. Damit ist jederzeit klar, welche Domain (alt oder neu) gerade gemeint ist.

Zunächst braucht man jedoch überhaupt eine neue Domain, die man als DynDNS-Domain verwenden kann. Dazu gibt es sog. DynDNS-Dienste. Viele davon sind kostenlos, einige verlangen einen geringen Preis für ihre Dienste. Es gibt auch Webspace-Provider, die die Möglichkeit bieten, Domains als DynDNS-Domains zu deklarieren. Ein (aus eigener Erfahrung) empfehlenswerter Anbieter ist hier All-Inkl.com (Affiliate Link) (ab dem Paket „Privat Plus“).

Bei den kostenlosen DynDNS-Diensten gibt es mittlerweile sehr viele Anbieter. Aus Gründen des Datenschutzes sollte man bei der Auswahl darauf achten, Anbieter mit Serverstandort Deutschland zu wählen.
Meiner Meinung nach sind beispielsweise folgende Anbieter empfehlenswert:

Zum Thema kostenlos vs. kostenpflichtig: Die meisten kostenlosen DynDNS-Dienste werden privat, oder durch kleine Vereine/Unternehmen betreut. Hier kann es passieren, dass ein Dienst mal eine Zeit lang (z.B. durch eine technische Störung) nicht erreichbar ist und es ein paar Stunden oder gar Tage dauert, bis wieder alles wie gewohnt funktioniert. Auch könnten solche Dienste einfach vom einen auf den anderen Tag eingestellt werden.
Bei kostenpflichtigen Diensten gibt es meist einen (professionellen) Support, der im Fehlerfall auch schnell helfen kann. Auch ist es hier unwahrscheinlich, dass ein solcher Dienst von heute auf morgen einfach eingestellt wird.
Das soll nun aber keineswegs heißen, dass man mit kostenpflichtigen DynDNS-Diensten besser bedient ist als mit kostenlosen Diensten. Auch kostenlose DynDNS-Anbieter können eine hohe Verfügbarkeit und einen guten Support bieten.

Neue Domain im Router hinterlegen

Wenn eine neue Domain vorliegt, muss diese erst einmal als neue DynDNS-Domain im Router hinterlegt werden. Leider hängt das genaue Vorgehen sowohl von Marke/Modell des Routers, als auch vom DnyDNS-Domain-Provider ab, so dass ich hier keine detaillierte Beschreibung liefern kann.

Wichtig ist, dass nach dieser Änderung sämtliche Webdienste (v.a. Nextcloud) nicht mehr über die alte Domain erreichbar sind.

Für produktive Nextcloud-Instanzen sollte man hier im Vorfeld die Benutzer darauf aufmerksam machen, dass ein Domain-Umzug stattfindet und die Cloud für einen gewissen Zeitraum nicht mehr erreichbar ist. Recht komfortabel kann man die mit der Nextcloud-App Announcement center lösen, indem man als Administrator eine Benachrichtigung an alle Cloud-User schickt.

Hier ist es generell empfehlenswert, die Nextcloud direkt vor dem Domain-Umzug in den Maintenance-Mode zu versetzten. Das sorgt dafür, dass keine Verbindungen zur Cloud möglich sind und beugt Datenverlusten vor, wenn Cloud-Benutzer gerade aktiv mit der Cloud arbeiten:

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

Neue Domain im Webserver hinterlegen und HTTPS-Zertifikate erzeugen

Also nächstes müssen die vHost(s) von nginx so konfiguriert werden, dass diese auf den neuen Domain-Namen hören. Angepasst werden muss hier nur der Gateway-Host:

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

Hier muss die Variable server_name auf den neuen Domain-Namen angepasst werden:

server_name neu.meinedomain.de 192.168.178.60;

Dies muss sowohl im server-Block für HTTP, als auch im server-Block für HTTPS angepasst werden.

Anschließend wird der Webserver neu gestartet:

service nginx restart

Hier sollten keine Fehlermeldungen angezeigt werden.

Anschließend muss das Let’s Encrypt-Zertifikat für die neue Domain erzeugt werden.

Hinweis: acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher sollte ein spezieller User eingerichtet werden, mit dem die Zertifikate generiert/verwaltet werden. Wie hierfür vorzugehen ist, kann dem Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx entnommen werden.

Diesen Befehl am besten kopieren und mittels Suchen und Ersetzen in einem beliebigen Texteditor die eigene Domain einfügen – das beugt Tippfehlern vor:

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

Wenn RSA und ECDSA-Zertifikate parallel eingesetzt werden sollen, dann ist der Befehl nochmals für ECDSA zu wiederholen:

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

Zum Schluss müssen die neuen Zertifikate noch dem Webserver bekannt gemacht werden. Dazu wird die Datei editiert, mit der auf die Zertifikate für den vHost verwiesen wird. Ich nutze hier eine spezielle Datei, in der alle SSL-Einstellungen enthalten sind, diese können aber auch direkt im Gateway-Host enthalten sein.

nano /etc/nginx/snippets/ssl.conf

Hier werden einfach die neuen Zertifikate angegeben:

# Certificates used
# RSA
ssl_certificate /etc/letsencrypt/neu.meinedomain.de/rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/neu.meinedomain.de/rsa/key.pem;
 
# ECC
ssl_certificate /etc/letsencrypt/neu.meinedomain.de/ecc/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/neu.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
ssl_trusted_certificate /etc/letsencrypt/neu.meinedomain.de/ecc/ca.pem;
 
# Diffie-Hellman parameter, recommended 4096 bits
ssl_dhparam /etc/nginx/dhparams/dhparams.pem;

Wie schon zuvor: Wenn sowohl RSA- als auch ECDSA-Zertifikate genutzt werden, sind beide Varianten anzugeben.

Im Listing ist auch die Einbindung der Diffie-Hellman-Parameter zu sehen. Diese müssen bei einem Domain-Umzug nicht neu erzeugt werden, sondern können wiederverwendet werden.

Nach diesen Änderungen ist der Webserver neu zu starten:

service nginx restart

Der Webserver ist nun für den Domain-Umzug vorbereitet, nun kann es mit der Nextcloud-Konfiguration weitergehen.

Nextcloud für neue Domain konfigurieren

Neben der Anpassung des Webservers sind ebenfalls Änderungen in Nextcloud durchzuführen.

Hierzu öffnet man einfach die config.php von Nextcloud:

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

Prinzipiell sind hier alle Werte anzupassen, die auf die alte Domain verweisen. Hier wird dementsprechend der neue Domain-Name gesetzt. Meistens sind das die folgenden zwei Variablen: trusted_domains und overwrite.cli.url:

<span class="s1">'overwrite.cli.url'</span> <span class="o">=&gt;</span> <span class="s1">''</span><span class="p">,</span>

'trusted_domains' =>
  array (
    '192.168.178.60',
    'neu.meinedomain.de',
  ),
'overwrite.cli.url' => 'neu.meinedomain.de',

Nun ist es an der Zeit, den Maintenance-Mode der Nextcloud wieder zu deaktivieren, damit die Cloud wieder im Internet erreichbar ist:

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Mit einem Aufruf der Nextcloud im Browser sollten nun keine Fehlermeldungen erscheinen. Ebenso sollte man einen kurzen Blick in die Admin-Oberfläche der Cloud werfen (Einstellungen > Verwaltung > Übersicht). Unter Sicherheits- & Einrichtungswarnungen sollten keine Warnungen angezeigt werden.

In der Nextcloud Admin-Oberfläche sollten keine Warnungen angezeigt werden

In der Nextcloud Admin-Oberfläche sollten keine Warnungen angezeigt werden

Auch im Nextcloud-Log (Einstellungen > Verwaltung > Protokollierung) sollten keine Meldungen bzgl. der neuen Domain zu finden sein.

Damit der der Domain-Umzug erst einmal abgeschlossen.

Abschließende Tätigkeiten

Nach dem erfolgreichen Domain-Umzug ist es wichtig, dass alle Clients ab sofort nur noch die neue Domain nutzen können. Somit müssen sämtliche Clients aller Benutzer der Nexcloud-Instanz auf die neue Domain umgestellt werden. Hier sollte man als Admin mit erhöhtem „Support-Aufkommen“ rechnen.

Wenn dies erledigt ist und man sicher ist, dass die alten Zertifikate nicht mehr gebraucht werden, dann können die Zertifikate der alten Domain vom Server entfernt werden. Mit folgendem Befehl sollten zunächst sowohl die neuen, als auch noch die alten Zertifikate angezeigt werden:

acme.sh --list

Diese alten Zertifikate können nun entfernt werden:

acme.sh --remove -d alt.meinedomain.de

Wenn neben RSA-Zertifikaten auch ECDSA-Zertifikate zum Einsatz kommen, muss das ECDSA-Zertifikat separat entfernt werden:

acme.sh --remove -d alt.meinedomain.de --ecc

Nach der Ausführung dieser Befehle ist das Zertifikat acme.sh nicht mehr bekannt und es wird auch nicht mehr per Cronjob erneuert. Die Zertifikats-Dateien verbleiben jedoch noch auf der Festplatte des Systems. in welchem Verzeichnis die nicht mehr genutzten Zertifikate liegen, zeigt acme.sh beim Entfernen der Zertifikate an (z.B. /etc/letsencrypt/alt.meinedomain.de). Dieses Verzeichnis kann anschließend entfernt werden:

rm -r /etc/letsencrypt/alt.meinedomain.de

Eine erneute Auflistung der installierten Zertifikate über den List-Befehl von acme.sh sollte nun nur noch das neue Zertifikat anzeigen.

Fazit

Der Artikel hat gezeigt, wie man die eigene Cloud in wenigen Schritten auf eine neue Domain umziehen kann. Das sollte im Normalfall eigentlich nicht notwendig sein, aber wenn wirklich mal eine neue Domain benötigt wird, dann braucht man Nextcloud nicht nochmals komplett neu aufsetzen. Das spart dem Admin Arbeit und die Benutzer können ihre gewohnte Nextcloud-Umgebung weiterhin nutzen – lediglich unter einer neuen Domain.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-die-eigenen-cloud-auf-neue-domain-umziehen/feed/ 6
Eigener Firefox Sync Server mit nginx https://decatec.de/home-server/eigener-firefox-sync-server-mit-nginx/ https://decatec.de/home-server/eigener-firefox-sync-server-mit-nginx/#comments Thu, 02 May 2019 13:17:44 +0000 https://decatec.de/?p=5492 Firefox Logo

Ein Browser ist auf fast allen Plattformen wohl das am meisten genutzte Programm. Nach den Browserkriegen sind leider viele Browser auf der Strecke geblieben, so dass es heutzutage nur noch zwei ernstzunehmende Alternativen gibt: Firefox und Chrome.

Wer Wert auf Datenschutz und Privatsphäre legt, wird allerdings um Chrome einen großen Bogen machen und stattdessen lieber Firefox nutzen.

Firefox bietet schon sehr lange ein Feature mit dem alle Browser-Einstellungen in der Cloud synchronisiert werden: Firefox Sync. Dazu wird ein Firefox-Konto benötigt, mit dem man sich im Browser einloggt. Anschließend können alle Firefox-Einstellungen (Lesezeichen, Chronik, verwendete Addons, etc.) mit der Mozilla-Cloud synchronisiert werden und sind so auch auf mehreren Endgeräten immer auf dem aktuellsten Stand.

Damit vertraut man der Mozilla Foundation seine Daten an. Die Speicherung erfolgt dabei meistens auf US-Servern. Wer dies nicht möchte, kann zunächst einmal keine Synchronisierung bei Firefox verwenden, so dass alle Einstellungen und Addons mit jeder Browser-Installation immer manuell konfiguriert werden müssen.

Allerdings kann man auch auf dem eigenen Server einen Firefox Sync Server installieren und über diesen synchronisieren. In diesem Fall profitiert man von den Sync-Funktionen des Browsers und stellt sicher, dass alle Daten nur auf dem privaten Server gespeichert werden.

Dieser Artikel zeigt nun die Installation und Konfiguration eines eigenen Firefox Sync Servers.

Hinweis: Dieser Artikel ist eher etwas für Fortgeschrittene. Den Firefox Sync Server kann man nicht einfach installieren, sondern dieser muss erst aus dem entsprechenden Repository auf GitHub gecloned und anschließend selbst gebaut werden. Auch die Konfiguration ist alles andere als trivial. Daher sollte man schon etwas Erfahrung mit Linux mitbringen.

Übrigens: Wem es hauptsächlich nur um die Synchronisierung von Lesezeichen im Browser geht, der muss nicht unbedingt einen eigenen Firefox Sync Server betreiben. In diesem Fall können bei einer vorhandenen Nextcloud-Instanz die Lesezeichen auch einfach über die private Cloud synchronisiert werden. Wie das genau funktioniert, wurde bereits in einem anderen Artikel erklärt: Nextcloud: Lesezeichen synchronisieren mit Chrome/Firefox

Update-Historie (letztes Update 08.05.2019)
  • 08.05.2019:
    • Hinwies hinzugefügt, dass die Angabe eines eigenen Sync Servers für Firefox auf iOS nicht funktioniert (siehe hier).
  • 05.05.2019:
    • Ergänzende Informationen hinzugefügt, falls andere Datenbank-Systeme für den Sync Server zum Einsatz kommen sollen (PostgreSQL oder MySQL/MariaDB).

 

Voraussetzungen

Alle Schritte wurden mit Ubuntu Server 18.04 LTS durchgeführt, sollten aber auch mit anderen Distributionen funktionieren.

Voraussetzung ist auf jeden Fall ein bereits fertig konfigurierter Webserver (in diesem Fall nginx). Dieser muss bereits so eingerichtet sein, dass Verbindungen mittels HTTPS möglich sind.

Die gezeigte Konfiguration basiert darauf, dass der Firefox Sync Server auf einer eigenen Subdomain (firefox-sync.meinedomain.de) betrieben wird. Es ist allerdings auch möglich, den Server in einem Unterverzeichnis des Webservers zu betreiben (z.B. meinedomain.de/firefox-sync). Hier unterscheidet sich lediglich die Webserver-Konfiguration (vHost). Dies wird im Abschnitt über die Webserver-Konfiguration behandelt.

Da eine detaillierte Beschreibung der Webserver-Konfiguration den Rahmen des Artikels sprengen würde, verweise ich an dieser Stelle auf weitere Artikel, die für das Thema relevant sind:

Installation

Wie bereits erwähnt, kann der Firefox Sync Server nicht einfach über die Paketverwaltung installiert werden, sondern es sind einige manuelle Handgriffe notwendig.

Wir beginnen wie üblich damit, das System auf den neusten Stand zu bringen:

apt-get update && apt-get upgrade -V

Anschließend werden die Pakete installiert, die wir zum Bauen des Sync Servers benötigen:

apt-get install make python-dev git-core python-virtualenv g++

Nun wird das entsprechende GitHub-Repository gecloned und der Sync Server gebaut:

cd /opt
git clone https://github.com/mozilla-services/syncserver
cd syncserver
make build

Die Dateien für den Sync Server liegen dann unter /opt/syncserver.

Konfiguration

Nun geht es an die Konfiguration des Sync Servers.

Als erstes benötigen wir ein „Secret“, welches dann später in der Konfiguration angegeben wird. Auch wenn es so wirkt: Dieser Schritt ist nicht optional, ohne Angabe des Secrets wird der Sync Server später nicht funktionieren.
Um das Secret zu erzeugen, nutzen wir einfach folgenden Befehl (anschließend in die Zwischenablage kopieren):

head -c 20 /dev/urandom | sha1sum

Danach kann es auch schon an die Bearbeitung der Konfiguration gehen:

cd /opt/syncserver
nano syncserver.ini

Hier zunächst die komplette Datei zur Übersicht:

[server:main]
use = egg:gunicorn
host = 127.0.0.1
port = 5000
workers = 1
timeout = 30

[app:main]
use = egg:syncserver

[syncserver]
# This must be edited to point to the public URL of your server,
# i.e. the URL as seen by Firefox.
public_url = https://firefox-sync.meinedomain.de

# By default, syncserver will accept identity assertions issued by
# any BrowserID issuer.  The line below restricts it to accept assertions
# from just the production Firefox Account servers.  If you are hosting
# your own account server, put its public URL here instead.
identity_provider = https://accounts.firefox.com/

# This defines the database in which to store all server data.
sqluri = sqlite:////opt/syncserver/syncserver.db

# This is a secret key used for signing authentication tokens.
# It should be long and randomly-generated.
# The following command will give a suitable value on *nix systems:
#
#    head -c 20 /dev/urandom | sha1sum
#
# If not specified then the server will generate a temporary one at startup.
secret = b6ff9a32108ca32272bcf8322b5274e93031fb90

# Set this to "false" to disable new-user signups on the server.
# Only requests by existing accounts will be honoured.
# allow_new_users = true

# Set this to "true" to work around a mismatch between public_url and
# the application URL as seen by python, which can happen in certain reverse-
# proxy hosting setups.  It will overwrite the WSGI environ dict with the
# details from public_url.  This could have security implications if e.g.
# you tell the app that it's on HTTPS but it's really on HTTP, so it should
# only be used as a last resort and after careful checking of server config.
force_wsgi_environ = true

Erläuterungen zu den einzelnen Einstellungen:

  • host = 127.0.0.1: Sorgt dafür, dass der Sync Server nur lokal aufgerufen werden kann – die Kommunikation „nach außen“ übernimmt später ja nginx.
  • public_url = https://firefox-sync.meinedomain.de: Dies ist die öffentliche URL des Sync Servers. Die konkrete URL hängt dabei von der Webserver-Konfiguration ab (siehe nächster Abschnitt).
  • identity_provider = https://accounts.firefox.com/: Zur Authentifizierung wird ein vorhandener Firefox-Account eingesetzt.
  • sqluri = sqlite:////opt/syncserver/syncserver.db: Angabe der Datenbank, in der die synchonisierten Objekte gespeichert werden. Hier verwenden wir einfach eine SQLite Datenbank, es wäre aber auch möglich, eine PostgreSQL oder MySQL/MariaDB Datenbank zu verwenden (Erläuterungen siehe unten).
  • secret = b6ff9a32108ca32272bcf8322b5274e93031fb90: Hier wird einfach der Wert eingetragen, den wir gerade über die Kommandozeile generiert haben.
  • allow_new_users = true: Dies sorgt dafür, dass automatisch neue Benutzerkonten angelegt werden, wenn sich diese zum erstem Mal mit diesem Sync Server verbinden. Wenn dieser Wert auf false gesetzt wird, wird die Synchronisierung für neue Accounts nicht mehr funktionieren (dazu später mehr).
  • force_wsgi_environ = true: Diese Einstellung muss in der gezeigten Konfiguration auf true gesetzt werden und sogt dafür, dass der Sync Server auch dann noch funktioniert, wenn die Public URL (die über nginx konfiguriert wird) von der URL abweicht, die der Sync Server intern „sieht“. Durch die Verwendung von nginx als Proxy für den Sync Server werden diese beiden URLs in diesem Kontext nie gleich sein, daher muss der Wert an dieser Stelle angepasst werden.

Ergänzende Informationen bei anderen Datenbanken

Für kleinere Sync Server Instanzen reicht die SQLite-Datenbank vollkommen aus. Ebenso ist diese am einfachsten zu konfigurieren, da hier keine zusätzlichen Schritte erforderlich sind.

Allerdings können auch andere Datenbank-Systeme zum Speichern der Daten eingesetzt werden, z.B. PostgreSQL oder MySQL/MariaDB. Empfehlenswert dürfte dies nur bei Servern sein, die sehr viele Nutzer bedienen müssen, oder wenn das entsprechende Datenbank-System bereits auf dem Server installiert ist. Aus diesem Grund gehe ich bei den folgenden Schritten davon aus, dass PostgreSQL bzw. MySQL/MariaDB bereits auf dem System installiert und konfiguriert ist.

PostgreSQL

Um eine Verbindung zu PostgreSQL herstellen zu können, sind ein paar zusätzliche Programme zu installieren:

apt-get install postgresql-server-dev-10 python-pip
cd /opt/syncserver
./local/bin/pip install psycopg2

Nun muss noch eine Datenbank speziell für den Sync Server erstellt werden. Am besten geschieht das über die PostgreSQL Kommandozeile:

sudo -u postgres psql

Die Datenbank mit dem entsprechenden User wird dann folgendermaßen angelegt:

CREATE USER firefox_sync_db_user WITH PASSWORD 'MeInPaSsw0rT';
CREATE DATABASE firefox_sync_db WITH OWNER firefox_sync_db_user TEMPLATE template0 ENCODING 'UTF8'

Beendet wird die PostgreSQL Kommandozeile durch die Eingabe von /q.

In der syncserver.ini wird die Verbindung zur Datenbank dann mittels dieser Einstellung konfiguriert:

sqluri = postgresql://firefox_sync_db_user:MeInPaSsw0rT@localhost/firefox_sync_db

MySQL/MariaDB

Ähnliche Schritte sind durchzuführen, wenn MySQL/MariaDB zum Einsatz kommt:

apt-get install python-pip
cd /opt/syncserver
./local/bin/pip install PyMySQL

Anschließend öffnet man die MySQL-Kommandozeile:

mysql -u root -p

Nun folgt die Anlage der Datenbank:

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

In der syncserver.ini wird die Datanbnak dann folgendermaßen angesprochen:

sqluri = pymysql://firefox_sync_db_user:MeInPaSsw0rT@localhost/firefox_sync_db

Webserver konfigurieren

Bevor das System nun einsatzfähig ist, muss zunächst noch der Webserver entsprechend konfiguriert werden. Die genauen Details zur Konfiguration des Webservers würden leider den Rahmen des Artikels sprengen, daher erwähne ich hier nur zwei mögliche Webserver-Konfigurationen.

Wichtig ist hier nur, dass der Webserver bereits so konfiguriert ist, dass dieser mittels HTTPS angesprochen werden kann und die Verbindung damit stets verschlüsselt ist.

Nach der Anpassung des Webserver muss dieser in jedem Fall noch neu gestartet werden:

service nginx restart

Wichtig: Je nach verwendeter Konfiguration unterscheidet sich die URL, unter der der Sync Server erreichbar ist. Dies muss im weiteren Verlauf des Tutorials beachtet werden, da entsprechende URLs angepasst werden müssen.

Sync Server mit eigener Subdomain

Wenn der Sync Server mit einer eigenen Subdomain betrieben werden soll (https://firefox-sync.meinedomain.de), dann benötigt man einen separaten vHost, der für diese Subdomain verantwortlich ist.

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name firefox-sync.meinedomain.de;

        root /var/www;

	location / {
		return 301 https://$host$request_uri;
	}
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name firefox-sync.meinedomain.de;

        # Include SSL configuration (and certificates)
        include /etc/nginx/snippets/ssl.conf;

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

        #
        # Configuration for Firefox Sync Server
        #

        location / {
		proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_redirect off;
                proxy_read_timeout 120;
                proxy_connect_timeout 10;
                proxy_pass http://127.0.0.1:5000/;
        }
}

Sync Server in einem Unterverzeichnis des Webservers

Man kann den Sync Server allerdings auch in einem Unterverzeichnis einer bereits bestehenden (Sub-)Domain installieren. Die URL lautet dann beispielsweise https://meindomain.de/firefox-sync

Hierzu muss ein bereits bestehender vHost, der für die Domain meinedomain.de verantworlich ist, um folgenden location-Block erweitert werden. Die hinzuzufügenden Zeilen sind hier markiert:

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

	# Include SSL configuration
	include /etc/nginx/snippets/certs_pub.conf;
	include /etc/nginx/snippets/ssl.conf;

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

	location ^~ /firefox-sync/ {
		proxy_set_header Host $http_host;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_redirect off;
		proxy_read_timeout 120;
		proxy_connect_timeout 10;
		proxy_pass http://127.0.0.1:5000/;
	}
}

Sync Server starten

Manueller Start

Nun kann der Sync Server über folgenden Befehl gestartet werden:

cd /opt/syncserver
make serve

Hier sollten keine Fehler angezeigt werden. Die Anzeige ist allerdings „live“, d.h. es scheint erst einmal so, als ob nichts weiter passieren würde:

./local/bin/gunicorn –paste ./syncserver.ini
[2019-04-27 17:23:21 +0000] [2292] [INFO] Starting gunicorn 19.6.0
[2019-04-27 17:23:21 +0000] [2292] [INFO] Listening at: http://127.0.0.1:5000 (2292)
[2019-04-27 17:23:21 +0000] [2292] [INFO] Using worker: sync
[2019-04-27 17:23:21 +0000] [2296] [INFO] Booting worker with pid: 2296

Daher stoppen wir nach diesem kurzen Test den Prozess mit STRG+C.

Nun ist es natürlich nicht optimal, wenn man den Sync Server immer manuell starten muss und dieser dann immer die Konsole blockiert. Hier könnte man sich zwar mit einem Screen weiterhelfen, aber das ist auch nicht die beste Lösung. Der Sync Server sollte im Idealfall direkt bei Systemstart automatisch mitgestartet werden.

Autostart

Um dies zu erreichen, legen wir zunächst einen eigenen User für den Sync Server an:

useradd firefox-sync -s /bin/false --no-create-home

Dieser User muss der Owner des Programmverzeichnisses sein:

chown -R firefox-sync:firefox-sync /opt/syncserver

Nun kann auch schon eine systemd Unit angelegt werden:

nano /etc/systemd/system/firefox-sync.service

Mit folgenden Zeilen wird die Unit definiert:

[Unit]
Description=Firefox Sync Server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
User=firefox-sync
Group=firefox-sync
Umask=007
Restart=on-abort
ExecStart=/opt/syncserver/local/bin/gunicorn --paste /opt/syncserver/syncserver.ini

[Install]
WantedBy=multi-user.target

Nun sollte der Service über folgenden Befehl gestartet werden können (anschließend mit service firefox-sync status testen):

service firefox-sync start

Damit der Service nun immer automatisch bei Systemstart hochgefahren wird, ist noch ein Befehl notwendig:

systemctl enable firefox-sync

Am besten auch hier nochmal das System neu starten und dann mit service firefox-sync status prüfen, ob der Autostart auch wirklich klappt.

Browser-Konfiguration

Bevor nun Firefox den neuen Sync Server nutzen kann, sollte noch ein kurzer Test erfolgen, ob der Sync Server wie gewünscht zu erreichen ist. Dazu einfach die URL des eigenen Sync Servers in die Adress-Leiste des Browsers eingeben (https://firefox-sync.meinedomain.de). Der Browser sollte dies mit einer simplen Meldung „it works!“ quittieren. Wenn es noch nicht wie erwartet funktioniert, wird eine Meldung ausgegeben, die einen Hinweis auf das Problem liefern sollte. In diesem Fall muss zunächst dieses Problem beseitigt werden, da ansonsten kein Browser mit dem Sync Server synchronisieren kann.

Wenn der Sync Server einwandfrei läuft, kann man nun Firefox so konfigurieren, dass dieser auch den eigenen Sync Server nutzt.

Wenn der Browser schon über ein Firefox-Konto synchronisiert wurde, muss die Verknüpfung mit diesem Konto zunächst einmal getrennt werden, da sich ansonsten kein neuer Sync Server konfigurieren lässt. Dazu einfach in die Browser-Einstellungen gehen, unter Firefox-Konto findet man die Schaltfläche zum Trennen des Kontos.

Nun fragt Firefox, ob er die bereits synchronisierten Daten  auch lokal entfernen soll. Hier sollte man keine Optionen anhaken, sondern einfach nur auf Nur trennen klicken.

Die Verbindung zum Firefox-Konto wird erst einmal getrennt

Die Verbindung zum Firefox-Konto wird erst einmal getrennt

Für die Angabe des eigenen Sync Servers muss man nun in die erweiterte Browser-Konfiguration wechseln, indem man in der Adress-Leiste about:config eingibt.

Hier suchen wir nun nach folgendem Wert: identity.sync.tokenserver.uri

Mit einem Doppelklick kann der Wert geändert werden und wir geben hier die URL des eigenen Sync Servers an: https://firefox-sync.meinedomain.de/token/1.0/sync/1.5

Über about:config wird der eigene Sync-Server angegeben

Über about:config wird der eigene Sync-Server angegeben

Wichtig ist, dass neben der eigentlichen Domain, die man in der syncserver.ini angegeben hat, noch die Erweiterung token/1.0/sync/1.5 notwendig ist.

Nachdem die Einstellung gesetzt ist, muss der Browser kurz beendet und neu gestartet werden. Nun kann man wieder in die Account-Einstellungen in Firefox gehen und die Verbindung zum Firefox-Konto wieder herstellen. Der Account an sich ist dabei der gleiche, aber der verwendete Sync Server ist nun ein anderer.

Nach ein paar Augenblicken sollte die erste Synchronisierung erfolgreich durchgelaufen sein. Allerdings erhält man keine Fehlermeldung, wenn der Sync aus irgendeinem Grund nicht klappen sollte. Daher gibt man am besten nach der ersten Synchronisierung about:sync-log in die Adress-Zeile des Browsers ein. Hier sollten dann keine Einträge zu finden sein, die zeitlich zur ersten Synchronisierung passen.

Falls doch, kann man dem Eintrag öffnen und Firefox gibt technische Details zu diesem Fehler preis. Damit sollte man den Fehler dann weiter eingrenzen können.

Diese Schritte zur Verbindung vom Firefox zum eigenen Sync Server müssen dann auf allen Rechnern wiederholt werden, damit nur noch der eigene Sync Server genutzt wird.

Auf Mobilgeräten (z.B. Firefox auf Android) funktioniert das Vorgehen übrigens analog: Firefox-Konto trennen, about:config bearbeiten und erneut mit dem Firefox-Konto anmelden. Leider funktioniert die Angabe eines eigenen Sync Servers unter Firefox für iOS (noch) nicht (siehe hier).
Die mobile Version von Firefox zeigt hier übrigens in den Einstellungen Details zum verwendeten Sync Server an (bei Firefox für den Desktop ist das leider nicht der Fall).

Firefox auf Android zeigt die URL des verwendeten Sync Servers an

Firefox auf Android zeigt die URL des verwendeten Sync Servers an

Abschließende Schritte

Wenn man nun alle Firefox-Konten auf den eigenen Sync Server umgehoben hat, sollten noch ein paar Schritte durchgeführt werden.

Sync Server auf bekannte Accounts beschränken

Der Sync Server wäre nun öffentlich über das Internet erreichbar. Damit niemand sonst den Server nutzen kann, wird das Anlegen neuer User im Sync Server einfach unterbunden:

cd /opt/syncserver
nano syncserver.ini

Hier ändern wir einfach den entsprechenden Konfig-Eintrag:

allow_new_users = false

Ab jetzt können sich keine neuen Accounts mehr am Sync Server anmelden. Wenn man hier nachträglich doch noch andere Firefox-Accounts hinzufügen möchte (z.B. für Familienmitglieder), dann muss man diesen Wert natürlich temporär wieder auf true ändern.

Abschließend wird der Sync Server neu gestartet:

service firefox-sync restart

Daten auf den Mozilla-Servern entfernen

Ganz zum Schluss kann man ebenfalls sämtliche Daten von den Mozilla-Servern entfernen. Hier kann ein einfaches Script genutzt werden. Wenn die Zwei-Faktor-Authentifizierung für den Firefox-Account aktiv ist, muss diese zuvor alledings deaktiviert werden, da das Skript ansonsten auf Fehler läuft. Nach dem Ausführen des Skripts kann diese wieder aktiviert werden.

apt-get update && apt-get install python-pip
cd /opt/syncserver
pip install PyFxA
python ./bin/delete_user_data.py meine@email.de

Die E-Mail-Adresse muss natürlich die Adresse des eigenen Mozilla-Accounts sein.

Sync Server updaten

Von Zeit zu Zeit können Updates für den Sync Server erscheinen. In diesem Fall kann man das Update auch lokal „nachziehen“.

Zunächst wird dazu der Service gestoppt:

service firefox-sync stop

Da Update an sich funktioniert dann wieder über git:

cd /opt/syncserver
git stash
git pull
git stash pop
make build

Nun werden noch die Rechte entsprechend angepasst:

chown -R firefox-sync:firefox-sync /opt/syncserver

Der Service sollte sich danach problemlos mit service firefox-sync start gestartet werden können. Auch das automatische Starten nach Systemstart sollte weiterhin funktionieren.

Fazit

Zugegeben: Die Einrichtung eines eigenen Firefox Sync Servers ist nicht gerade einfach, da dieser nicht einfach aus der Paketverwaltung der verwendeten Distribution installiert werden kann. Da ist schon einiges an Handarbeit notwendig.

Wenn man die Schritte durchgearbeitet hat, kann man aber sicher sein, dass die Browser-Daten nicht mehr in „irgendeiner Cloud“ synchronisiert werden, sondern ausschließlich auf dem eigenen Server gespeichert werden.

Es wird zur Synchronisierung zwar weiterhin ein Firefox-Konto benötigt, dieses dienst von nun an allerdings nur noch zur Authentifizierung. Die Daten werden nur noch mit dem eigenen Firefox Sync Server abgeglichen.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/eigener-firefox-sync-server-mit-nginx/feed/ 51
Passwörter verwalten mit Nextcloud/KeePass https://decatec.de/home-server/passwoerter-verwalten-mit-nextcloud-keepass/ https://decatec.de/home-server/passwoerter-verwalten-mit-nextcloud-keepass/#comments Sun, 21 Apr 2019 07:39:59 +0000 https://decatec.de/?p=5399 Nextcloud KeePassXC Logo

Man liest es in letzter Zeit häufiger: Irgendein Online-Dienst wurde gehackt und es wurden Nutzerdaten entwendet. Jüngstes Beispiel ist wohl der Hack der offiziellen Server des Messenger-Dienstes Matrix.org. Die User werden dann meistens dazu aufgefordert, umgehend ihre Passwörter zu ändern.

Wenn man aber nun für mehrere Dienste immer das gleiche Passwort verwendet, dann ist nach einem solchen Hack immer die Wahrscheinlichkeit gegeben, dass die Daten für anderen Online-Dienste, Webshops, etc. missbraucht werden. Daher sollte es sich mittlerweile herumgesprochen haben, dass man für jeden Online-Dienst ein eigenes Passwort verwenden soll.

Der folgende Artikel zeigt, wie man Passwörter einfach und effizient mit KeePass und Nextcloud verwalten kann.

Passwörter mit System

Aus den o.g. Gründen sollte „Passwort-Recycling“ also vermieden werden. Folglich muss man sich aber auch immer mehr Passwörter merken, je mehr Online-Dienste genutzt werden. Hierzu gibt es verschiedene Ansätze. Einer davon ist, dass man sich einen leicht zu merkenden Satz ausdenkt: „Grillen kann man nicht nur bei schönem Wetter, sondern auch wenn es regnet“. Nun nimmt man die Anfangsbuchstaben der einzelnen Wörter und erhält somit: gkmnnbswsawer. Nun kommen noch Groß-/Kleinbuchstaben, evtl. Sonderzeichen und weitere Ersetzungen zum Einsatz: gKm2nbSws4w3R – hier wurde das „nn“ einfach durch 2n“ und ein paar Buchstaben durch Zahlen (Leetspeak) ersetzt.
„gKm2nbSws4w3R“ ist nun das Basis-Passwort, dass man nun noch mit einem „Dienst-Teil“ ergänzt (z.B. die Anfangsbuchstaben des Dienstes). Für Amazon wäre das fertige Passwort also z.B. „aMgKm2nbSws4w3R“, für eBay z.B. „eBgKm2nbSws4w3R“.

Mit einem solchen System ist man nun etwas sicherer unterwegs. Dennoch besteht die Möglichkeit, dass das System dahinter erkannt werden kann, z.B. wenn von mehreren Diensten Daten entwendet wurden. In diesem Fall ist ein solches System auch nicht mehr als sicher anzusehen.

Besser wären Passwörter in der Form „k;%([uhk[3@!o6?m’2SQ}>MLN/Bf,ngPb“ – also eine zufällige Folge aus Buchstaben/Zahlen/Sonderzeichen. Jeder Dienst bekommt dann ein eigenes Passwort, d.h. dass hier kein System dahinter steckt, dem man auf die Schliche kommen kann.
Nun hat man allerdings ein Problem: Kein Mensch kann sich solche Passwörter merken…

Passwort-Verwaltung mit KeePass

Hier kommen dann sog. Passwort-Safes wie z.B. KeePass zum Einsatz. Passwörter können hier ganz einfach mit beliebigen Zusatzinformationen gespeichert werden, z.B. Benutzernamen oder Notizen, sogar Datei-Anhänge sind möglich. Verwaltet werden diese Passwort-Einträge in einer speziellen Datei (kdbx), die komplett verschlüsselt ist. Öffnen lässt sich der Passwort-Safe dann nur mit dem Master-Passwort, einer Schlüsseldatei, oder auch weiteren Verfahren (z.B. mittels eines YubiKeys). Auch eine Kombination der Verfahren zum Entschlüsseln ist möglich, so dass man z.B. sowohl das Master-Passwort eingeben, als auch eine Schlüsseldatei bereitstellen muss.

Man muss sich nun also nur noch das Master-Passwort merken. Die Passwörter für die einzelnen Dienste werden dann nur noch über den Passwort-Manager verwaltet und können beliebig lang/komplex sein. Ebenso kann man mit KeePass Passwörter erzeugen lassen, so dass man sich nicht mal mehr eigene Passwörter ausdenken muss.

Neben dem originalen KeePass gibt es eine Reihe weiterer Programme, die mit KeePass kompatibel sind. Mein Favorit darunter ist das Programm KeePassXC, welches aus einem Fork aus KeePass hervorgegangen ist.

Geöffnete Passwort-Datenbank mit KeePassXC

Geöffnete Passwort-Datenbank mit KeePassXC

Ebenso gibt es KeePass kompatible Clients für mobile Systeme. Unter Android verwende ich hierzu gern die App Keepass2Android.

Auf der Download-Seite von KeePass findet man hierzu eine Liste an alternativen Programmen/Apps.

Ebenfalls gibt es für KeePassXC Browser-Addons (Firefox, Chrome), die Passwörter aus einer (geöffneten) kdbx-Datenbank auslesen und bei der Anmeldung im Browser automatisch ausfüllen können.

KeePass und Nextcloud

Für den Zugriff auf die eigenen Passwörter braucht man also nur die KeePass-Datenbank (kdbx-Datei) und einen KeePass-Client. Wenn man nun allerdings von mehreren Geräten Zugriff auf die Passwörter haben möchte, muss man immer erst noch die aktuelle Version der kdbx-Datei auf das jeweilige Gerät kopieren. Das ist mühselig und auch fehleranfällig: Wo liegt nun nochmal die aktuelle Version der KeePass-Datenbank? Habe ich diese zuletzt auf dem Notebook oder auf dem PC bearbeitet?

Hier kommt dann Nextcloud ins Spiel: Für eine solche Cloud-Anwendung ist das Synchronisieren von Dateien eine der leichtesten Übungen. Am besten lädt man direkt nach der Erstellung des Passwort-Safes die kdbx-Datei in die eigene Nextcloud-Instanz in einen eigenen Ordner (z.B. „Passwörter“) hoch. Ab nun liegt immer die aktuellste Version dieser Datei in der Cloud.

Ab jetzt befindet sich die aktuellste Version der KeePass-Datenbank immer in der Nextcloud

Ab jetzt befindet sich die aktuellste Version der KeePass-Datenbank immer in der Nextcloud

Nun muss man nur noch sicher stellen, dass jedes Gerät immer mit der aktuellsten Version der Datei arbeitet. Am PC/Notebook nutzt man dazu am besten den Desktop-Sync-Client von Nextcloud: Man fügt einfach für den Order „Passwörter“ eine Synchronisation hinzu:

Nextcloud-Client: Synchronisation für den Passwort-Ordner hinzufügen

Nextcloud-Client: Synchronisation für den Passwort-Ordner hinzufügen

Nun ist auf diesem Gerät die aktuellste kdbx-Datei immer im jeweiligen Sync-Order für Nextcloud vorhanden, also z.B. /home/user/Nextcloud/Passwörter/Passwörter.kdbx.
Über KeePassXC öffnet man nun einfach diese Datei. Nach dem Bearbeiten der Einträge wird die Datei gespeichert. Sofort springt der Sync-Client von Nextcloud an und lädt die veränderte Version in die Cloud.

Wichtig: Falls man die KeePass-Datenbank mit Passwort und Schlüsseldatei gesichert hat, sollte man die Schlüsseldatei natürlich nicht neben der kdbx-Datei in der Cloud bereit stellen, sondern getrennt davon abspeichern: Am besten nur auf den jeweiligen Geräten selbst, auf einem USB-Stick, etc.

Auf einem Mobilgerät (z.B. mit Keepass2Android) läuft die Sache etwas anders ab: Hier wird die KeePass-Datenbank direkt per WebDAV geöffnet. Beim Öffnen der App gibt man daher den direkten Link zur kdbx-Datei ein, also z.B. https://meinedomain.de/nextcloud/remote.php/dav/files/user/Passwörter/Passwörter.kdbx.
Gespeichert wird wiederum per WebDAV, so dass die kdbx-Datei nach der Bearbeitung direkt in der Cloud aktualisiert wird.

KeePass-Datei direkt in Nextcloud öffnen

Es geht allerdings noch komfortabler: Mit KeeWeb existiert ein weiterer KeePass-Client, der auch im Web lauffähig ist. Und genau diesen Client (in der Web-Version) gibt es auch als eigenständige Nextcloud-App:
Im Nextcloud App Store findet man dazu in der Kategorie „Werkzeuge“ die App Keeweb.

Nach der Installation aus dem App Store ist allerdings noch ein kleiner Schritt notwendig, damit die in der Cloud gespeicherten kdbx-Dateien direkt per Klick geöffnet werden können. Dazu legen wir eine neue Datei im gleichen Order an, in dem auch schon die config.php von Nextcloud enthalten ist, also z.B.:

nano /var/www/nextcloud/config/mimetypemapping.json

Hier fügen wir folgenden Inhalt ein:

{
  "kdbx": ["application/x-kdbx"]
}

Damit die Änderungen greifen, muss noch ein Datei-Scan von Nextcloud angestoßen werden:

sudo -u www-data php /var/www/nextcloud/occ files:scan --all

Nun kann die Passwort-Datei in der Nextcloud-Instanz ganz einfach per Klick geöffnet werden:

Geöffnete KeePass-Datei in Nextcloud/Keeweb

Geöffnete KeePass-Datei in Nextcloud/Keeweb

Damit kann man sich die Synchronisierung der kdbx-Datei auf die einzelnen Geräte eigentlich sparen, da man nun jederzeit direkt in der eigenen Nextcloud an die gespeicherten Passwörter kommt. Einen „echten“ Desktop-Client wie KeePassXC braucht man eigentlich nur noch, wenn man z.B. die Integration mittels Browser-Addon benötigt.

Die Alternativen

Für Nextcloud-User, die KeePass bereits nutzen, ist die Integration der bestehenden Passwort-Verwaltung in die eigenen Cloud sicherlich sinnvoll. An dieser Stelle soll allerdings auch erwähnt werden, dass es darüber hinaus noch zwei Alternativen gibt:

Im Nextcloud App Store befinden sich mit Passman und Passwords noch zwei weitere Apps, mit den Passwörter in der eigenen Nextcloud verwaltet werden können. Beide Apps speichern ihre Einträge dabei direkt in der Cloud und nicht in kdbx-Dateien, daher sind die Apps auch nicht kompatibel mit KeePass. Dennoch bieten die Apps z.T. erweiterte Features, wie z.B. das direkte Teilen von einzelnen Passwörtern mit anderen Nextcloud-Benutzern oder per Link. Mit der KeePass-Lösung kann man nur die gesamte kdbx-Datei teilen, daher gilt hier das Motto „alles oder nichts“.

Fazit

In diesem Artikel wurde gezeigt, wie man seine Passwörter ganz einfach in der eigenen Nextcloud-Instanz verwalten kann. Nutzer von KeePass oder alternativen Clients können im einfachsten Fall die Funktionen zur Datei-Synchronisierung von Nextcloud nutzen, aber auch eine direkte Integration ist per App möglich, so dass kdbx-Dateien direkt in der Cloud geöffnet und bearbeitet werden können.

Darüber hinaus gibt es mit den Apps Passman und Passwords noch Alternativen für die Passwort-Verwaltung mit Nextcloud. Welche Lösung hier die beste (oder komfortabelste) ist, muss jedoch jeder für sich selbst herausfinden. Dazu können die Apps auch erst einmal im Parallelbetrieb installiert/getestet werden.

Wenn man sich für eine Lösung entschieden hat, werden die eigenen Passwörter zukünftig in der eigenen Cloud verwaltet. Durch den Einsatz eines Online-Password-Managers muss man sich nun nie mehr komplizierte Passwörter ausdenken und schon gar nicht merken.

Ich bin zwar kein Fan von Wechsel dein Passwort-Tagen, aber vielleicht ist dieser Artikel mal ein Anreiz, den Umgang mit eigenen Passwörtern zu überdenken und ggf. anzupassen.

Was haltet ihr davon? Wie verwaltet ihr eure Passwörter? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/passwoerter-verwalten-mit-nextcloud-keepass/feed/ 15
RSA und ECDSA-Zertifikate mit nginx (Hybrid-Lösung) https://decatec.de/home-server/rsa-und-ecdsa-zertifikate-mit-nginx-hybrid-loesung/ https://decatec.de/home-server/rsa-und-ecdsa-zertifikate-mit-nginx-hybrid-loesung/#comments Sun, 17 Mar 2019 14:13:33 +0000 https://decatec.de/?p=5314 Let's Encrypt Logo

Wer Webdienste wie Nextcloud betreibt, der sollte auf jeden Fall sicher stellen, dass die Verbindung zum Server stets mittels HTTPS verschlüsselt ist. Damit dies funktioniert, benötigt man ein TLS-Zertifikat. Dank Let’s Encrypt kann man solche Zertifikate kostenlos beziehen und die Generierung geht leicht von der Hand.

Zum Thema TLS-Zertifikate und v.a. auch Let’s Encrypt sind hier im Blog schon einige Beiträge veröffentlicht worden. Heute soll es um eine spezielle Optimierung gehen:

RSA und ECDSA-Zertifikate im Hybrid-Betrieb mit dem Webserver nginx. Damit kommen moderne Zertifikate (ECDSA) zum Einsatz und gleichzeitig wird die Kompatibilität zu älteren Clients mittels RSA-Zertifikaten sicher gestellt.

Update-Historie (letztes Update 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
  • 17.08.2019:
    • acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
  • 26.07.2019:
    • Hinweis hinzugefügt, dass das Verzeichnis, in dem die Zertifikate installiert werden, vor der Generierung der Zertifikate angelegt werden muss.
  • 24.07.2019:
    • Anpassungen für TLSv1.3 (ssl_ciphers und ssl_ecdh_curve).
  • 15.06.2019:
    • ECDHE-RSA-AES256-SHA384 aus den ssl_ciphers entfernt (wird beim Qualys SSL Labs Test als „weak“ eingestuft).
  • 18.05.2019:
    • Hinweis hinzugefügt, dass bei der Generierung der Zertifikate am besten Copy&Paste und „Suchen & Ersetzen“ genutzt wird.

 

Ein kleiner Ausflug in die Kryptografie

Zunächst soll erst einmal mit einfachen Worten geklärt werden, was sich hinter RSA bzw. ECDSA verbirgt.

Ohne nun zu weit in die Theorie abzuschweifen, sind beides asymmetrische kryptografische Verfahren, die zum Verschlüsseln, also auch zum digitalen Signieren genutzt werden. Dabei wird ein Schlüsselpaar bestehend aus einem öffentlichen und einem privaten Schlüssel genutzt. Ganz allgemein ausgedrückt können mittels des öffentlichen Schlüssels Nachrichten verschlüsselt werden, die nur mit dem privaten Key wieder entschlüsselt werden können.
Ein Anwendungsgebiet ist dabei die Kommunikation über HTTPS: Der öffentliche Schlüssel ist im Zertifikat enthalten, so dass ein Client (z.B. Browser) damit eine Nachricht verschlüsseln kann. Der private Schlüssel ist nur dem Webserver bekannt, so dass nur dieser die HTTPS-Nachrichten entschlüsseln kann.

RSA ist dabei das ältere Verfahren, welches schon in den 1970er Jahren zum Einsatz kam. Für die Sicherheit spielt hier die Schlüssellänge eine entscheidende Rolle. Momentan werden meist Schlüssellängen von 4096 empfohlen. Dennoch wird sich das vermutlich in Zukunft ändern, da immer leistungsstärkere Rechner zum Einsatz kommen, mit dem eine solche Verschlüsselung irgendwann geknackt werden kann. Hier helfen dann nur längere Schlüssel, da zum Ver- und Entschlüsseln mehr Rechenleistung benötigt wird, je länger der verwendete Schlüssel ist.

ECDSA ist ein neueres asymmetrisches Verfahren, welches auf elliptischen Kurven basiert. Der Vorteil bei ECDSA ist, dass sehr viel kürzere Schlüssellängen (bei gleicher oder gar besserer Sicherheit) zum Einsatz kommen können. So entspricht eine Schlüssellänge von 384 Bit bei ECDSA einer Schlüssellänge von 7680 bei RSA (siehe OpenSSL Wiki).

Ich möchte hier nun nicht weiter auf die technischen/mathematischen Details beider Krypto-Verfahren eingehen. Wer es genau wissen möchte, findet in den entsprechenden Artikeln bei Wikipedia genug Informationen.

Zusammengefasst kann man sagen, dass ECDSA-Zertifikate effizienter sind als RSA-Zertifikate, da durch eine kürzere Schlüssellänge weniger Rechenleistung für die Ver- und Entschlüsselung benötigt werden.

Warum sollte man nun RSA- und ECDSA-Zertifikate parallel einsetzen? Dies liegt darin begründet, dass ECDSA das neuere Verfahren ist, welches gerade von älteren Clients nicht immer unterstützt wird. Das ECDSA-Zertifikat sollte bevorzugt zum Einsatz kommen. Falls jedoch ein Client ECDSA nicht unterstützt, kommt das RSA-Zertifikat sozusagen als Fallback zum Zug.

Voraussetzungen

In diesem Artikel liegt der Fokus nur auf der Erzeugung der passenden Zertifikate und deren Einbindung in nginx. Damit das Ganze funktioniert, müssen ein paar Voraussetzungen erfüllt sein:

  • Es muss eine Domain vorhanden sein (Let’s Encrypt kann Zertifikat nur auf Domains, nicht jedoch auf IP-Adressen ausstellen). Im Heim-Bereich wird dies in den meisten Fällen eine DynDNS-Adresse sein, unter der der eigene Router aus dem Internet erreichbar ist. In diesem Artikel wird dazu beispielhaft die Domain meinedomain.de verwendet.
  • Der Router muss in diesem Fall so konfiguriert sein, dass ein Portweiterleitung für die Ports 80 und 443 für die Maschine eingerichtet ist, auf der der Webserver läuft.
  • Webserver: nginx (ab Version 1.11.0)
  • Ein Let’s Encrypt Client, der sowohl RSA-, als auch ECDSA-Zertifikate unterstützt. Ich empfehle hier den Client acme.sh.
  • Der Webserver muss bereits so eingerichtet sein, dass Zertifikate von Let’s Encrypt bezogen werden können. Dazu müssen Verbindungen über Port 80 zur URL http://meinedomain.de/.wellknown/acmechallenge möglich sein.

Details zur möglichen Einrichtung des Webservers und der Verwendung des Let’s Encrypt Clients acme.sh sind im Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx zu finden.

Einrichtung acme.sh und Vorbereiten der Verzeichnisstruktur

Hinweis: acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher sollte ein spezieller User eingerichtet werden, mit dem die Zertifikate generiert/verwaltet werden.

Dieser wird folgendermaßen angelegt und anschließend der Gruppe www-data hinzugefügt:

adduser letsencrypt
usermod -a -G www-data letsencrypt

Der User braucht nun die Berechtigungen, um nginx später ohne Passwort neu laden zu können:

visudo

Am Ende wird folgende Zeile hinzugefügt:

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

Für die Installation von acme.sh wechseln wird nun den User:

su - letsencrypt

Anschließend kann acme.sh installiert werden:

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

Am Ende wechseln wir wieder auf den normalen User:

exit

Nun sollte noch die die Verzeichnisstruktur vorbereitet 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/meinedomain.de/rsa
mkdir -p /etc/letsencrypt/meinedomain.de/ecc
chown -R www-data:www-data /etc/letsencrypt 
chmod -R 775 /etc/letsencrypt

Generierung der Zertifikate

Wenn alle Voraussetzungen erfüllt sind, dann kann es an die Generierung der Zertifikate gehen.

Da zwei unterschiedliche kryptografische Verfahren für die Zertifikate zum Einsatz kommen, müssen dementsprechend auch zwei Zertifikate getrennt voneinander erzeugt werden.

Hinweis: Da wir einen speziellen User nutzen, müssen die Befehle zum Generieren der Zertifikate unter diesem Benutzer ausgeführt werden:

su - letsencrypt

RSA-Zertifikate

Als erstes kümmern wir uns um das „klassische“ RSA-Zertifikat.

Hier kann mittels acme.sh mit folgendem beispielhaften Befehl das Zertifikat erstellt werden.

Tipp: Am besten übernimmt man den Befehl mittels Copy&Paste in einen beliebigen Text-Editor, mit dem man dann die Domain mit „Suchen und Ersetzen“ einfach durch die tatsächlich verwendete Domain einfügt. Auf diese Weise kann man Tippfehler vermeiden.

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

Durch die Angabe

--keylength 4096
wird ein RSA-Zertifikat mit der Schlüssellänge von 4096 Bit erzeugt.

Wenn die Konfiguration des Webservers passt, sollte das Zertifikat nach wenigen Augenblicken generiert worden sein.

ECDSA-Zertifikate

Der zweite Schritt ist nun die Erzeugung des ECDSA-Zertifikats.

Auch hier nutzen wir wieder folgenden beispielhaften Befehl:

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

Dieser Befehl sieht eigentlich genau so aus wie der vorhergehende. Lediglich über den Parameter

--keylength ec-384
wird angegeben, dass diesmal ein ECDSA-Zertifikat (384 Bit) angefordert wird.

Am Ende können wir uns wieder mit den User letsencrypt ausloggen:

exit

Zertifikate einbinden

Wenn die Zertifikate ohne Fehler erzeugt wurden, können diese anschließend in der Webserver-Konfiguration eingebunden werden. Ich lagere dabei alle SSL-spezifischen Einstellungen immer in eine gesonderte Datei aus. Dies ist kein Muss, sondern dient nur der besseren Übersichtlichkeit.

nano /etc/nginx/snippets/ssl.conf

Hier der gesamte Inhalt:

# Certificates used
# RSA
ssl_certificate /etc/letsencrypt/meinedomain.de/rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/meinedomain.de/rsa/key.pem;

# ECC
ssl_certificate /etc/letsencrypt/meinedomain.de/ecc/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/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
ssl_trusted_certificate /etc/letsencrypt/meinedomain.de/ecc/ca.pem;

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

# Not using TLSv1 will break:
#	Android <= 4.4.40
#	IE <= 10
#	IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
# TLSv1.3 is not supported by most clients, but it should be enabled.
ssl_protocols TLSv1.2 TLSv1.3;

# Prefer the SSL ciphers for ECDSA:
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';
 
# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;

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

# OCSP Stapling
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# This is the IP if yout DNS-Server (in most cases: your router's IP)
resolver 192.168.178.1;

# SSL session handling
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

Wichtig für die Kombination RSA/ECDSA-Zertifikate sind hier besonders folgende Einstellungen:

  • Zunächst werden mit ssl_certificate und ssl_certificate_key die Zertifikate eingebunden. Diese Anweisungen sind doppelt (einmal für RSA, einmal für ECDSA) aufgeführt, da wir ja auch zwei Zertifikate parallel einbinden wollen.
  • Welches Zertifikat vorzugsweise zum Einsatz kommt, wird durch die ssl_ciphers gesteuert: Dadurch, dass die Ciphers ECDHE-ECDSA-CHACHA20-POLY1305 (speziell für ECDSA) am Anfang aufgeführt sind, wird erst mal versucht, damit eine Verbindung aufzubauen. Wenn das klappt, kommt automatisch das ECDSA-Zertifikat zum Einsatz. Falls das nicht klappen sollte, kommen die anderen Ciphers (und damit das RSA-Zertifikat) zum Zug. Dadurch haben wir einen effizienten Fallback-Mechanismus, falls z.B. der Client keine ECDSA-Zertifikate unterstützt.
  • Alle anderen Einstellungen bzgl. SSL sind nicht spezifisch für RSA/ECDSA und sind hier einfach nur für maximale Sicherheit ausgelegt.

Die Datei mit den SSL-spezifischen Einstellungen kann dann in den virtuellen Hosts von nginx durch eine einzige Zeile eingebunden werden (im server-Block für den HTTPS-Server):

include /etc/nginx/snippets/ssl.conf;

Nach der Durchführung der Änderungen muss der Webserver natürlich noch neu gestartet werden:

service nginx restart

Hier sollten keine Fehler auftreten. Falls doch, liegt vermutlich in der Konfiguration noch ein Fehler vor. Um das genaue Problem zu ermitteln, hilft in diesem Fall folgender Befehl, der die genaue Zeile in den vHosts anzeigen sollte, wo die Ursache des Fehlers zu finden ist:

nginx -t

Wenn alles geklappt hat, läuft nginx im „Zerifikat-Hybrid-Betieb“ und wir können uns ansehen, wie sich das in der Praxis auswirkt.

Test der Zertifikate

Zum Testen der Zertifikate nutze ich immer gern den SSL-Test von Qualys SSL Labs. Hier sollte zunächst einmal ein A+ Rating erzielt werden können (inkl. 100% bei allen Kategorien). Das wäre aber auch mit einem reinen RSA-Zertifikat möglich. Durch das zusätzliche ECDSA-Zertifikat sollte der Test nun allerdings zwei Zertifikate anzeigen: Ein RSA-Zertifikat mit der Schlüssellänge von 4096 Bit und ein ECDSA-Zertifikat mit der Schlüssellänge von 384 Bit.

Beim SSL-Test werden zwei Zertifikate angezeigt (RSA und ECDSA)

Beim SSL-Test werden zwei Zertifikate angezeigt (RSA und ECDSA)

Falls beim SSL-Test kein A+ Rating erreicht wurde, sollten nochmals die SSL-Einstellungen des Webservers überprüft werden.

Auch im Browser (z.B. Firefox) sollte man nun bei den Details zum verwendeten Zertifikat sehen, dass ein ECDSA-Zertifikat zum Einsatz kommt.

Firefox nutzt nun automatisch das ECDSA-Zertifikat

Firefox nutzt nun automatisch das ECDSA-Zertifikat

Welches Zertifikat genutzt wird, lässt sich übrigens Client-seitig nicht festlegen. Der Client wird hier immer den ersten SSL-Cipher nehmen, mit dem er kompatibel ist. ECDSA wird hier vom Webserver bevorzugt behandelt, da die entsprechenden Ciphers am Anfang der Cipher-Liste aufgeführt sind.

Fazit

Der Artikel hat gezeigt, wie man mit dem Webserver nginx auf einfache Weise RSA- und ECDSA-Zertifikate im Hybrid-Betrieb installieren kann.

Was bringt das nun? In der Praxis wird man hier kaum einen Unterschied feststellen können, ob nun ein (traditionelles) RSA-, oder ein (moderneres) ECDSA-Zertifikat zum Einsatz kommt. Trotzdem ist bei einem ECDSA-Zertifikat weniger Rechenleistung für die Ver- und Entschlüsselung notwendig.

Durch den allgemeinen Anstieg der Leistung moderner Rechner ist zu erwarten, dass immer längere Schlüssel für TLS-Zertifikate benötigt werden – vielleicht ist hier in Zukunft ein RSA-Zertifikat mit 4096 Bit auch schon nicht mehr ausreichend. Mit dem Hybrid-Betrieb RSA/ECDSA ist man auf jeden Fall mit einem modernen Schlüsselaustausch (ECDSA) bestens für die Zukunft gerüstet, währenddessen der Einsatz von RSA die Kompatibilität mit älteren Clients sicherstellt.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/rsa-und-ecdsa-zertifikate-mit-nginx-hybrid-loesung/feed/ 24
Linux: Einfach E-Mails versenden mit msmtp https://decatec.de/linux/linux-einfach-e-mails-versenden-mit-msmtp/ https://decatec.de/linux/linux-einfach-e-mails-versenden-mit-msmtp/#comments Wed, 27 Feb 2019 14:57:15 +0000 https://decatec.de/?p=5049 Linux Mail Logo

Oftmals macht es Sinn, wenn man von einem Linux-System direkt eine E-Mail senden kann. Anwendungsbeispiele wären z.B. der Versand einer Mail, wenn ein Cronjob fehlschlägt oder auch eine Benachrichtigung, wenn durch fail2ban eine IP auf Grund zu vieler fehlgeschlagener Anmeldeversuche gebannt wurde.

Nun könnte man einfach einen Mail Transfer Agent, wie z.B. Sendmail oder Postfix auf dem System aufsetzen. Allerdings ist es recht umständlich einen „echten“ Mail-Server zu betreiben, v.a. wenn man nur einfache Mails zur Benachrichtigung versenden will.

Hierzu gibt es dann einfache Programme, die nicht mit einem echten Mailserver zu vergleichen sind, sondern die einfach Mails an einen bereits bestehenden STMP-Server senden können – dazu braucht man einfach nur einen SMTP-Client).

Vor einiger Zeit habe ich in diesem Blog schon mal den SMTP-Client sSMTP vorgestellt. Heute will ich eine Alternative dazu vorstellen: msmtp

Auch wenn der Artikel auf Ubuntu 18.04 basiert, sollte es kein Problem sein, das gezeigte Vorgehen auf anderen Systemen/Distributionen umzusetzen.

Update-Historie (letztes Update 31.08.2019)
  • 31.08.2019:
    • Anpassungen für /etc/mail.rc ist notwendig, damit Mails versendet werden können.
    • Hinweise hinzugefügt, wenn Mails auch von anderen Benutzern (ohne Root-Rechte) versendet werden sollen.
  • 16.05.2019:
    • Reihenfolge der auszuführenden Schritte verändert: Der Alias muss noch vor dem Versenden der Test-Mail gesetzt werden.

 

sSMTP läuft doch problemlos – was spricht dagegen?

Ich habe mit sSMTP immer gute Erfahrungen gemacht. Jedoch wird dieses Programm nicht mehr weiterentwickelt (Quelle: Arch Wiki). Dadurch kann ich sSMTP nicht mehr ohne Einschränkungen empfehlen. Wenn beispielsweise Bugs oder Sicherheitslücken gefunden werden, ist es fraglich, ob diese noch ausgebaut werden.

Generell sollte man aus diesen Gründen Abstand von Software nehmen, die nicht mehr aktiv weiterentwickelt wird. Trotzdem soll das nun nicht heißen, dass man sSMTP ab sofort nicht mehr verwenden sollte: Wer sSMTP bereits eingerichtet hat und damit keine Probleme hat, muss sich nun nicht sofort nach einer Alternative umsehen – trotzdem sollte man über kurz oder lang über ein „Update“ zu msmtp nachdenken.

Wer aber gerade auf der Suche nach einem leichtgewichtigen SMTP-Client ist, der sollte lieber gleich zu msmtp greifen.

Installation und Konfiguration vom msmtp

Zunächst bringen wir das System wie immer auf den neusten Stand:

apt-get update && apt-get upgrade -V

Anschließend wird msmtp installiert:

apt-get install msmtp msmtp-mta mailutils

Das Paket mailutils wird zwar nicht unbedingt benötigt, jedoch ist dies beim späteren Verwenden von Mails sehr hilfreich,.

Für die Konfiguration des Programms gibt es zwei unterschiedliche Konfigurations-Dateien:

  • Eine systemweite Konfiguration
  • Eine benutzerspezifische Konfiguration.

Wo diese unterschiedlichen Konfigurations-Dateien gespeichert sind, ermittelt man einfach mit folgendem Befehl:

msmtp --version

Für das weitere Vorgehen nutzen wir hier die systemweite Konfiguration, da E-Mails nur vom System selbst verschickt werden sollen (z.B. bei fehlgeschlagenen Cronjobs).

msmtp: Speicherort der Konfigurations-Dateien

msmtp: Speicherort der Konfigurations-Dateien

Beide Dateien sind nach einer neuen Installation nicht vorhanden (so dass man diese einfach nur auf die eigenen Bedürfnisse abändern könnte), allerdings gibt es auf der Website von msmtp eine Beispiel-Konfiguration.

Für die systemweite Konfiguration wird nun folgende Datei bearbeitet:

nano /etc/msmtprc

Hinweis: Mit dieser Konfiguration ist es nur als Root-User möglich, E-Mails zu versenden. Wenn weiteren Benutzern diese Möglichkeit gegeben werden soll, müssen diese Benutzer eine User-spezifische Konfigurations-Datei anlegen:

nano ~/.msmtprc

Inhaltlich sind die Dateien (systemweite und benutzerspezifische Konfiguration) gleich aufgebaut. Der Inhalt kann beispielsweise so aussehen (hier am Beispiel eines fiktiven Mail-Accounts meinedomain.de):

# Set default values for all following accounts.
defaults

# Use the mail submission port 587 instead of the SMTP port 25.
port 587

# Always use TLS.
tls on

# Set a list of trusted CAs for TLS. The default is to use system settings, but
# you can select your own file.
tls_trust_file /etc/ssl/certs/ca-certificates.crt

# If you select your own file, you should also use the tls_crl_file command to
# check for revoked certificates, but unfortunately getting revocation lists and
# keeping them up to date is not straightforward.
#tls_crl_file ~/.tls-crls

# Mail account
# TODO: Use your own mail address
account bob@meindedomain.de

# Host name of the SMTP server
# TODO: Use the host of your own mail account
host smtp.meindedomain.de

# As an alternative to tls_trust_file/tls_crl_file, you can use tls_fingerprint
# to pin a single certificate. You have to update the fingerprint when the
# server certificate changes, but an attacker cannot trick you into accepting
# a fraudulent certificate. Get the fingerprint with
# $ msmtp --serverinfo --tls --tls-certcheck=off --host=smtp.freemail.example
#tls_fingerprint 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33

# Envelope-from address
# TODO: Use your own mail address
from bob@meindedomain.de

# Authentication. The password is given using one of five methods, see below.
auth on

# TODO: Use your own user name fpr the mail account
user bob@meindedomain.de

# Password method 1: Add the password to the system keyring, and let msmtp get
# it automatically. To set the keyring password using Gnome's libsecret:
# $ secret-tool store --label=msmtp \
#   host smtp.freemail.example \
#   service smtp \
#   user joe.smith

# Password method 2: Store the password in an encrypted file, and tell msmtp
# which command to use to decrypt it. This is usually used with GnuPG, as in
# this example. Usually gpg-agent will ask once for the decryption password.
#passwordeval gpg2 --no-tty -q -d ~/.msmtp-password.gpg

# Password method 3: Store the password directly in this file. Usually it is not
# a good idea to store passwords in plain text files. If you do it anyway, at
# least make sure that this file can only be read by yourself.
# TODO: Use the password of your own mail account
password pAssW0Rd123

# Password method 4: Store the password in ~/.netrc. This method is probably not
# relevant anymore.

# Password method 5: Do not specify a password. Msmtp will then prompt you for
# it. This means you need to be able to type into a terminal when msmtp runs.

# Set a default account
# TODO: Use your own mail address
account default: bob@meindedomain.de

# Map local users to mail addresses (for crontab)
aliases /etc/aliases

Alle Einstellungen, die man individuell anpassen muss, sind hier mit „# TODO“ gekennzeichnet. Bitte auch die Kommentare in der Datei beachten.

Noch ein Hinweis auf die Authentifizierungs-Methode: In diesem Beispiel nutzen wird die einfachste Form der Authentifizierung, indem das Passwort des Mail-Accounts direkt in der Konfiguration gespeichert wird. msmtp unterstützt hier allerdings auch weitere Authentifizierungs-Methoden. Mehr Informationen dazu findet man in der Dokumentation zu msmtp.

Als nächstes sorgen wir dafür, dass nicht jeder Zugriff auf die Datei hat (besonders wichtig, wenn das Passwort direkt in der Konfiguration gespeichert ist):

chmod 600 /etc/msmtprc

Auch bei einer benutzerspezifischen Konfiguration müssen die Rechte angepasst werden:

chmod 600 ~/.msmtprc

Zum Schluss wird noch ein Alias angelegt, so dass die Empfänger-Adresse des Root-Accounts (oder des Accounts, mit dem später E-Mail versendet werden sollen) bekannt ist. Dies wird in der Datei angegeben, die auch schon ganz am Ende der Konfiguration von msmtp aufgeführt wurde:

nano /etc/aliases

Hier wird nun die Empfänger-Adresse des Root-Accounts angegeben. An diese Adresse werden nun E-Mails verschickt, wenn z.B. ein Cronjob fehlschlagen sollte. Daneben wird noch eine allgemeine „Fallback-Empfänger-Adresse“ angegeben, falls System-Meldungen nicht im Kontext des Root-Accounts auftreten:

root: admin@meinedomain.de
default: admin@meinedomain.de

Bevor nun eine erste Test-Mail versendet werden kann, muss noch das Mail-Programm definiert werden:

nano /etc/mail.rc

Der Inhalt sieht dabei folgendermaßen aus:

set sendmail="/usr/bin/msmtp -t"

Nach der erfolgten Konfiguration vom msmtp können E-Mails nun ganz einfach über die Kommandozeile verschickt werden:

echo "Inhalt der E-Mail" | mail -s "Betreff" test@mail.de

Am besten gleich mal ausprobieren, indem ihr euch selbst eine Test-E-Mail schickt.

Fazit

Mit msmtp ist es einfach möglich, von einem Linux-System E-Mails zu versenden, ohne einen „schwergewichtigen“ Mail-Server aufsetzen zu müssen. Es wird einfach ein vorhandener Mail-Account (z.B. eines Freemailers) benutzt und die Konfiguration gestaltet sich auch sehr einfach.

Neben dem Mail-Versand von der Kommandozeile erhält man nun auch ganz komfortabel Benachrichtigungen per E-Mail, wenn beispielsweise ein Cronjob ausgeführt wurde, oder auch eine IP-Adresse von Fail2ban gebannt wurde.

Weiterführende Artikel

Links

]]>
https://decatec.de/linux/linux-einfach-e-mails-versenden-mit-msmtp/feed/ 75
Let’s Encrypt: Umstieg von Certbot auf acme.sh (nginx) https://decatec.de/linux/lets-encrypt-umstieg-von-certbot-auf-acme-sh-nginx/ https://decatec.de/linux/lets-encrypt-umstieg-von-certbot-auf-acme-sh-nginx/#comments Sat, 09 Feb 2019 14:19:10 +0000 https://decatec.de/?p=5268 Let's Encrypt Logo

Im letzten Artikel ging es um das Erstellen von TLS-Zertifikaten von Let’s Encrypt. Als Client kam hier acme.sh zum Einsatz. In meinen bisherigen Artikeln habe ich bisher immer Certbot als Client für Let’s Encrypt empfohlen. Da acme.sh meiner Meinung nach allerdings einige Vorteile bietet, wird dies vermutlich auch meine zukünftige Empfehlung zur Generierung von TLS-Zertifikaten von Let’s Encrypt sein.

Da aber etliche Leser meines Blogs wohl noch Certbot nutzen, möchte ich in diesem Artikel einen Leitfaden zum Umstieg auf acme.sh nachliefern.

Besonders wichtig dürfte die Umstellung auf acme.sh für Debian-Nutzer sein, da die in den Paketquellen enthaltene Certbot-Version nur ein Validierungsverfahren beherrscht, welches Let’s Encrypt bald nicht mehr unterstützen wird (mehr Infos dazu gibt es hier).

Wer Certbot bisher noch nicht verwendet hat: Dieser Artikel richtet sich ausschließlich an Umsteiger von Certbot zu acme.sh. Wer das erste mal TLS-Zertifikate erzeugen möchte, der sollte sich an den Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx halten.

Update-Historie (letztes Update 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
  • 17.08.2019:
    • acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
  • 24.07.2019:
    • Anpassungen für TLSv1.3 (ssl_ciphers und ssl_ecdh_curve).
  • 15.06.2018:
    • ECDHE-RSA-AES256-SHA384 aus den ssl_ciphers entfernt (wird beim Qualys SSL Labs Test als „weak“ eingestuft).
  • 18.05.2019:
    • Hinweis hinzugefügt, dass bei der Generierung der Zertifikate am besten Copy&Paste und „Suchen & Ersetzen“ genutzt wird.
  • 13.02.2018:
    • Hinweis für die Berechtigungen des Verzeichnisses /var/www/letsencrypt hinzugefügt.
  • 11.02.2019:
    • Hinweis auf Überschreiben der Crontab durch Installation von acme.sh hinzugefügt/Sichern der bestehenden Crontab.
  • 10.02.2019:
    • Reihenfolge der im Tutorial ausgeführten Schritte angepasst – das Umkopieren der alten Zertifikate war nicht notwendig, da diese von Certbot in einem anderen Verzeichnis gespeichert wurden.

 

Voraussetzungen

Ich gehe im Folgenden davon aus, dass die TLS-Zertifikate mit Certbot gemäß dem Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban erstellt wurden.

Im Detail heißt dies:

  • Certbot wurde installiert und der automatisch eingerichtete Cronjob zur Erneuerung der Zertifikate wurde genutzt.
  • Es wurden durch Certbot bereits Zertifikate generiert (d.h. der Webserver ist fertig eingerichtet und im Router sind die entsprechenden Port-Weiterleitungen bereits eingerichtet).
  • Die Zertifikate sind im Verzeichnis /etc/letsencrypt/live/meinedaomin.de gespeichert (meinedomain.de dient hier nur als Beispiel-Domain) und bestehen aus den Dateien cert.pem, chain.pem, fullchain.pem und privkey.pem.
  • Diffie-Hellman-Parameter sind ebenfalls bereits vorhanden (/etc/nginx/ssl/dhparams.pem).

Vorbereitungen – alte Zertifikate kopieren

Bevor die neuen Zertifikate erstellt werden können, müssen die alten Zertifikate erst einmal an eine andere Stelle kopiert werden. Dies ist notwendig, da bei der späteren Deinstallation von Certbot der komplette Order /etc/letsencrypt entfernt wird.

mkdir -p /etc/certs-temp
cp -r /etc/letsencrypt/* /etc/certs-temp

Damit diese Kopie der Zertifikate (temporär) vom Webserver verwendet wird, sind die SSL-Einstellungen im Gateway-Host zu bearbeiten:

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

Hier sind die Verzeichnis-Angaben für die Zertifikat-Dateien anzupassen:

ssl_certificate /etc/certs-temp/live/meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/certs-temp/live/meinedomain.de/privkey.pem;
ssl_trusted_certificate /etc/certs-temp/live/meinedomain.de/chain.pem;

Ein Neustart von nginx sollte dann problemlos verlaufen und die (temporären) Zertifikate werden genutzt:

service nginx restart

Certbot deinstallieren

Nun kann Certbot komplett vom System entfernt werden. Mit der Installation von Certbot wurden nicht nur die Programm-Dateien installiert, sondern es wurde darüber hinaus noch ein Cronjob eingerichtet, der für die automatische Erneuerung der Zertifikate sorgt. Diesen Cronjob kann man mit folgendem Befehl ermitteln:

systemctl list-timers

In der Auflistung sollte dann der Cronjob von Certbot auftauchen:

systemctl list-timers listet den Cronjob von Certbot

systemctl list-timers listet den Cronjob von Certbot

Als erstes sollte Certbot deinstalliert werden. Dies geschieht über folgenden Befehl:

apt-get purge certbot

Dies deinstalliert neben den Programm-Dateien auch noch sämtliche Konfigurationen, Abhängigkeiten und auch die alten Zertifikate.

Anschließend sollte ein systemctl list-timers den Cronjob für Certbot nicht mehr aufführen und Certbot ist restlos vom System entfernt worden.

Neue Zertifikate generieren

Der Einfachheit halber werden am besten gleich ganz neue Zertifikate über acme.sh erstellt. Das sollte kein Problem darstellen, wenn man die alten Zertifikate nicht ein paar Tage zuvor mit Certbot erstellt hat – Let’s Encrypt hat gewisse „Rate Limits“, d.h. man kann in einem bestimmten Zeitraum nur eine gewisse Anzahl an Zertifikaten beantragen (siehe hier).

Details zu dem Vorgehen und zur „Installation“ von acme.sh sind im Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx zu finden, daher hier im Schnelldurchlauf.

Hinweis: acme.sh sollte nicht mit Root-Rechten ausgeführt werden. Am besten legt man dafür einen speziellen User an. Wie man dazu vorgehen kann, ist im oben genannten Artikel detailliert erklärt.

Wichtig: Falls bereits Cronjobs (für den entsprechenden User) eingerichtet sind, dann solltet ihr euch vorher die aktuelle Crontab sichern, da acme.sh diese bei der Installation ungefragt überschreibt:

crontab -l > crontab.bak

Nach der Installation von acme.sh können mittels dieser Datei die „alten“ Cronjobs wieder mit contab -e hinzugefügt werden.

Nun legen wir zunächst das Verzeichnis an, in dem später die Zertifikate gespeichert werden und passen die Rechte an:

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/meinedomain.de
chown -R www-data:www-data /etc/letsencrypt
chmod -R 775 /etc/letsencrypt

Die Generierung der Zertifikate erfolgt dann über einen Befehl. Dieser muss mit dem speziell eingerichteten User ausgeführt werden:

su - letsencrypt

Tipp: Am besten übernimmt man den Befehl mittels Copy&Paste in einen beliebigen Text-Editor, mit dem man dann die Domain mit „Suchen und Ersetzen“ einfach durch die tatsächlich verwendete Domain einfügt. Auf diese Weise kann man Tippfehler vermeiden.

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

Da wird am Webserver ansonsten nichts bzgl. Let’s Encrypt geändert haben, sollte die Generierung der Zertifikate erfolgreich abgeschlossen werden können.

Anschließend kann man wieder auf den normalen User wechseln:

exit

Die Diffie-Hellman-Parameter müssen nicht neu generiert werden, sondern können wiederverwendet werden. Dennoch kopieren wir die Datei an einen anderen Speicherort, somit ist das Vorgehen zum vorherigen Artikel identisch:

mkdir -p /etc/nginx/dhparams
cp /etc/nginx/ssl/dhparams.pem /etc/nginx/dhparams/dhparams.pem

Einbinden der neuen Zertifikate

Nun können die neu Generierten Zertifikate auch schon eingebunden werden. Für eine bessere Übersichtlichkeit lagern wir dazu aber auch noch sämtliche Webserver-Einstellungen bzgl. SSL in eine eigene Datei aus.

Wichtig: Diese Datei darf nicht in dem Verzeichnis gespeichert werden, in dem nginx die virtuellen Hosts erwartet (also /etc/nginx/conf.d).

mkdir -p /etc/nginx/snippets
nano /etc/nginx/snippets/ssl.conf

Hier werden nun die folgenden Anweisungen aufgenommen:

# Certificates used
ssl_certificate /etc/letsencrypt/meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/meinedomain.de/key.pem;

# This should be ca.pem (certificate with the additional intermediate certificate)
# See here: https://certbot.eff.org/docs/using.html
ssl_trusted_certificate /etc/letsencrypt/meinedomain.de/ca.pem;

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

# Not using TLSv1 will break:
#	Android <= 4.4.40
#	IE <= 10
#	IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
# TLSv1.3 is not supported by most clients, but it should be enabled.
ssl_protocols TLSv1.2 TLSv1.3;

# Cipher suite from https://cipherli.st/
# Max. security, but lower compatibility 
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';

# Cipher suite from https://wiki.mozilla.org/Security/Server_Side_TLS
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# (Modern) cipher suite from https://mozilla.github.io/server-side-tls/ssl-config-generator/
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;

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

# OCSP Stapling
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

resolver 192.168.178.1;

# SSL session handling
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

Die markierten Zeilen betreffen die neuen Zertifikat-Dateien, alle anderen Anweisungen sind identisch zu den Anweisungen im Gateway-Host.

Damit die SSL-Einstellungen nur noch aus der Datei ssl.conf gezogen werden, muss der Gateway-Host angepasst werden:

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

Sämtliche Einstellungen, die schon in der ssl.conf aufgeführt werden, sind aus dem Gateway-Host zu entfernen. Diese werden dann durch eine einzige Zeile ersetzt (am besten direkt nach der Direktive server_name):

include /etc/nginx/snippets/ssl.conf;

Ein Neustart des Webservers bindet nun die neuen Zertifikate ein und sollte ohne Fehlermeldung ablaufen. Falls hier dennoch Fehler auftreten, sind vermutlich noch ein paar SSL-Anweisungen doppelt vorhanden (im Gateway-Host und in der ssl.conf). Welche Anweisungen zum Fehler führen, kann man einfach mit folgendem Befehl herausfinden:

nginx -t

Abschlussarbeiten

Zum Schluss können noch die (kopierten) alten Zertifikate und Diffie-Hellman-Parameter entfernt werden:

rm -r /etc/certs-temp
rm -r /etc/nginx/ssl

Überprüfung der neuen Zertifikate

Zum Schluss können die neuen Zertifikate noch getestet werden. Hierzu ist der SSL Server Test von Qualys SSL Labs gut geeignet. Hier sollte ein Rating mit A+ und 100% in allen Kategorien erreicht werden können:

Ergebnis des SSL-Tests

Ergebnis des SSL-Tests

Falls die Bewertung schlechter ausfällt, sollten sollten nochmals die Einstellungen des Webservers kontrolliert werden, v.a. die Anweisungen in der ssl.conf.

Erneuerung der Zertifikate

Die Zertifikate von Let’s Encrypt nur eine begrenzte Gültigkeit von 90 Tagen (Begründung siehe hier), danach müssen sie erneuert werden.

acme.sh hat aber bereits bei der Installation einen Cronjob eingerichtet, der sich um die automatische Erneuerung der Zertifikate kümmert – hier ist also nach dem ersten Generieren der Zertifikate nichts weiter zu tun.

Die Gültigkeitsdauer der installierten Zertifikate kann übrigens mit folgendem Befehl ermittelt werden:

acme.sh --list

Fazit

Der Artikel hat gezeigt, wie man von Certbot auf acme.sh für die Generierung von Let’s Encrypt Zertifikaten umsteigen kann. Darüber hinaus wurde die Verwaltung der SSL-Einstellungen am Webserver vereinfacht, indem die entsprechenden Anweisungen in eine eigene Datei ausgelagert wurden.

Nach Erfolgreicher Umstellung sollte man nur mal nach ca. 90 Tagen (Gültigkeitsdauer der Let’s Encrypt Zertifikate) kontrollieren, ob die Zertifikate auch automatisch erneuert wurden. Ist dies der Fall, kann man sich entspannt zurück lehnen und muss sich nicht mehr manuell um die Zertifikate oder deren Erneuerung kümmern.

Weiterführende Artikel

Links

]]>
https://decatec.de/linux/lets-encrypt-umstieg-von-certbot-auf-acme-sh-nginx/feed/ 50
Let’s Encrypt Zertifikate mit acme.sh und nginx https://decatec.de/linux/lets-encrypt-zertifikate-mit-acme-sh-und-nginx/ https://decatec.de/linux/lets-encrypt-zertifikate-mit-acme-sh-und-nginx/#comments Wed, 30 Jan 2019 14:36:40 +0000 https://decatec.de/?p=5213 Let's Encrypt Logo

Wer eine eigene Website oder auch eine Nextcloud-Instanz betreibt, der sollte auch großen Wert auf Sicherheit legen. In der heutigen Zeit gehört dabei HTTPS zum Sicherheits-Standard, wenn es um die verschlüsselte Übertragung von Daten im Internet geht.

Um die eigene Seite mittels HTTPS abzusichern, ist zunächst einmal ein SSL-Zertifikat notwendig. Früher musste man sich ein solches Zertifikat von einer Zertifizierungsstelle für viel Geld kaufen. Im Jahr 2015 trat jedoch Let’s Encrypt auf den Plan – eine Zertifizierungsstelle, die kostenlos Zertifikate für TLS anbietet, um damit verschlüsselte Verbindungen im Web zum Standard zu machen. Gerade im privaten Bereich hat sich Let’s Encrypt zu einem de-facto Standard entwickelt.

Seitdem kann sich jedermann selbst Zertifikate für HTTPS ausstellen lassen. Dazu wird lediglich ein Let’s Encrypt Client benötigt, der die eigentliche Generierung der Zertifikate übernimmt. In meinen Tutorials habe ich bisher immer Certbot als Client für Let’s Encrypt empfohlen, da dieses Programm in den Paketquellen fast aller Distributionen enthalten ist. Dennoch könnte sich genau dieser Umstand als Nachteil erweisen. So schaltet Let’s Encrypt aus Sicherheitsgründen das Validierungsverfahren „TLS-SNI-01“ bald ab. Nutzer von Debian laufen bald Gefahr, dass die Zertifikate nicht mehr erneuert werden können, da die Version von Certbot in Debian Stable zu alt ist und keine anderen Validierungsmethoden unterstützt (siehe hier).

Ein alternativer Let’s Encrypt Client ist acme.sh. Wie der Name bereits vermuten lässt, handelt es sich hierbei um ein reines Shell-Skript, welches die Generierung der Zertifikate übernimmt. Man ist damit nicht mehr von Programmen in den Paketquellen der Linux-Distributionen abhängig. Darüber hinaus ist acme.sh ein sehr fortschrittlicher Client, der bisher alle Features von Let’s Encrypt unterstützt. Grund genug, die diesen Let’s Encrypt Client einmal genauer anzusehen.

Der Artikel basiert dabei auf Ubuntu Server 18.04 LTS, alle gezeigten Schritte sollten sich aber auch auf anderen Distributionen umsetzen lassen. Als Webserver kommt nginx zum Einsatz.

Update-Historie (letztes Update 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
  • 17.08.2019:
    • acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
  • 24.07.2019:
    • Anpassungen für TLSv1.3 (ssl_ciphers und ssl_ecdh_curve).
  • 15.06.2019:
    • ECDHE-RSA-AES256-SHA384 aus den ssl_ciphers entfernt (wird beim Qualys SSL Labs Test als „weak“ eingestuft).
  • 18.05.2019:
    • Hinweis hinzugefügt, dass bei der Generierung der Zertifikate am besten Copy&Paste und „Suchen & Ersetzen“ genutzt wird.
  • 18.02.2019:
    • Hinweis für Meldung „-bash: /home/user/.acme.sh/acme.sh.env: Permission denied“ hinzugefügt.
  • 13.02.2019:
    • Hinweis für die Berechtigungen des Verzeichnisses /var/www/letsencrypt hinzugefügt.
  • 11.02.2019:
    • Anleitung zum Upgrade von acme.sh hinzugefügt.
    • Hinweis auf Überschreiben der Crontab durch Installation von acme.sh hinzugefügt/Sichern der bestehenden Crontab.
  • 09.02.2019:
    • Hinweis auf neuen Artikel zum Umstieg von Certbot auf acme.sh hinzugefügt.

 

Installation von acme.sh

Es handelt sich bei acme.sh nur um ein Skript, jedoch kann es in gewisser Art installiert werden. Die Installation beinhaltet hauptsächlich die Einrichtung eines Cronjobs zur automatischen Erneuerung ausgestellter Zertifikate.

acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher legen wir einen speziellen User an und fügen diesen der Gruppe www-data hinzu:

adduser letsencrypt
usermod -a -G www-data letsencrypt

Der User braucht nun die Berechtigungen, um nginx später ohne Passwort neu laden zu können:

visudo

Am Ende wird folgende Zeile hinzugefügt:

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

Für die Installation von acme.sh wechseln wird nun den User:

su - letsencrypt

Hinweis: Wenn ein bereits bestehender User für die Generierung der Zertifikate genommen wird, sollte nun kontrolliert werden, ob bereits Conjobs für diesen User angelegt wurden, da acme.sh bei der Installation sämtliche bereits bestehenden Conjobs überschreibt.

Falls bereits Cronjobs eingerichtet sind, dann solltet ihr euch daher vorher die aktuelle Crontab sichern:

crontab -l > crontab.bak

Nach der Installation von acme.sh können mittels dieser Datei die „alten“ Cronjobs wieder mit contab -e hinzugefügt werden.

Diese Installation besteht eigentlich nur in der Ausführung des Skripts mit bestimmten Parametern und gestaltet sich recht einfach. Dazu gibt es eine spezielle Seite, die das Skript zur Installation beinhaltet: https://get.acme.sh.

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

Hinweis: Es ist immer gefährlich, eine unbekannte Quelle direkt in die Shell zu pipen, da man nie so genau weiß, was diese Quelle (in diesem Fall das Skript genau ausführt). Man sollte sich die Quelle (in diesem Fall https://get.acme.sh) vor der Ausführung des Befehle genau ansehen und überprüfen, ob hier nichts verdächtiges passiert. Für wen das Pipen auf die Shell nicht in Frage kommt, der findet noch ein paar alternative Installationsmöglichkeiten auf der Wiki-Seite des GitHub-Projekts.

Die "Installation" von acme.sh

Die „Installation“ von acme.sh

Nach der Installation muss das Terminal einmal geschlossen und wieder geöffnet werden. Alternativ kann man den Rechner auch einfach neu starten.

Damit ist die Installation bereits abgeschlossen, so dass wir wieder auf den normalen User wechseln können:

exit

Als nächstes wird das System auf die Verwendung von SSL-Zertifikaten vorbereitet.

Vorbereitung des Systems

Zunächst richten wir die benötigten Verzeichnis ein, die später für die Zertifiakt-Generierung benötigt werden. Ebenfalls passen wir gleich die Berechtigungen entsprechend an:

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/meinedomain.de
chown -R www-data:www-data /etc/letsencrypt
chmod -R 775 /etc/letsencrypt

Ich nutze hier immer einen Unterordner, der mit der Domain übereinstimmt, für welche die Zertifikate ausgestellt werden sollen (in diesem Beispiel einfach meinedomain.de).

Als nächstes muss der Webserver in der Lage sein, über HTTP (Port 80) im Unterverzeichnis /.wellknown/acmechallenge für Let’s Encrypt erreichbar zu sein. Im virtuellen Host für die entsprechende Domain könnte dies dann folgendermaßen aussehen:

server {
	listen 80 default_server;
    listen [::]:80 default_server;
	server_name meinedomain.de 192.168.178.60;
 
	root /var/www;
	
	location ^~ /.well-known/acme-challenge {
		default_type text/plain;
		root /var/www/letsencrypt;
	}		
}

Zertifikate mit acme.sh erzeugen

Nach den Vorbereitungen sind wir nun soweit, dass wir Zertifikate über acme.sh ausstellen lassen können.

Ich gehe im folgenden davon aus, dass auf dem System bereits nginx als Webserver installiert und eingerichtet wurde. Für die Generierung der Zertifikate wird daher der sog. Webroot-Modus genutzt. acme.sh unterstützt allerdings auch andere Modi (z.B. einen Standalone-Modus, wenn kein Webserver auf dem System läuft). Es gibt auch einen speziellen Modus für nginx, allerdings werden hier die virtuellen Hosts vom Webserver bei der Generierung/Erneuerung der Zertifikate kurzzeitig verändert/ausgetauscht. Da ich meine vHosts lieber unangetastet lassen möchte, nutze ich daher immer nur den Webroot-Modus.

Zunächst wechseln wir auf den speziell angelegten User:

su - letsencrypt

Ein Zertifikat wird durch einen einzigen Befehl erzeugt.
Tipp: Am besten übernimmt man den Befehl mittels Copy&Paste in einen beliebigen Text-Editor, mit dem man dann die Domain mit „Suchen und Ersetzen“ einfach durch die tatsächlich verwendete Domain einfügt. Auf diese Weise kann man Tippfehler vermeiden.

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

Mit den Parametern werden die Details zu Generierung der Zertifikate angegeben:

  • Mit 
    -d meinedomain.de
      wird die Domain angegeben, für die das Zertifikat erzeugt werden soll.
  • --keylength 4096
      gibt die Schlüssellänge des RSA-Zertifikats an. Standardmäßig werden hier 2048 Bit verwendet. Das ist in der Regel ausreichend, jedoch sollte man für erhöhte Sicherheit auf eine Schlüssellänge von 4096 Bit setzen.
  • Mit
    -w /var/www/letsencrypt
      wird das Verzeichnis angegeben, in dem die Challenge-Dateien gespeichert werden. Dies muss das Verzeichnis sein, welches bei nginx als root Verzeichnis für /.well-known/acme-challenge angegeben wurde (im jeweiligen virtuellen Host).
  • acme.sh speichert die Zertifikat-Dateien im Verzeichnis ~/.acme.sh/meinedomain.de. Es wird davon abgeraten, diese Dateien direkt in den virtuellen Hosts des Webservers zu referenzieren. Aus diesem Grund wird mit den Parametern
    --key-file
    ,
    --ca-file
    ,
    --cert-file
      und
    --fullchain-file
      die Speicherorte der Dateien angegeben, wo die entsprechenden Dateien „installiert“ werden sollen. Nur diese Dateien werden dann später in den vHosts von nginx eingebunden.
  • --reloadcmd
      gibt den Befehl an, der nach erfolgreicher Ausstellung/Erneuerung der Zertifikate ausgeführt werden soll. Damit der Webserver die neuen Zertifikate korrekt einbinden kann, wird nginx hier einfach kurz neu gestartet. Wenn hier mehrere Befehle ausgeführt werden sollen, sind diese durch ein Semikolon zu trennen.

Nach dem Generieren können alle von acme.sh ausgestellten Zertifikate auf dem System durch folgenden Befehl angezeigt werden:

acme.sh --list

Ebenfalls wird durch diesen Befehl die Gültigkeitsdauer der Zertifikate angezeigt (dazu später mehr).

Nun wechseln wir wieder auf den normalen User zurück:

exit

Diffie-Hellman-Parameter erzeugen

Die Zertifikate selbst sind der wichtigste Punkt, wenn es um die Verschlüsselung der Verbindung über HTTPS geht. Um die Sicherheit noch weiter zu erhöhen, sollten noch sog. Diffie-Hellman-Parameter genutzt werden. Ohne nun die technischen Details zu beleuchten, geht es um einen sicheren Schlüsselaustausch bei Verbindungsaufbau. Die Generierung des Schlüssels muss dabei nur einmal erfolgen.

Achtung: Die Erzeugung der Diffie-Hellman-Parameter dauert gerade auf schwächerer Hardware sehr lange. Hier muss man bis zur Fertigstellung u.U. mehrere Stunden warten. In diesem Fall kann auch eine Schlüssel mit „nur“ 2048 Bit berechnet werden (die Zahl des zweiten Befehls gibt hierbei die Länge des Schlüssels in Bit an). Auf stärkerer Hardware ist allerdings eine Schlüssellänge von 4096 Bit empfehlenswert.

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

Einbinden der Zertifikate in nginx

Die Zertifikate können nun einfach mit nginx verwendet werden. Ich beschränke mich hier auf das reine Einbinden der Zertifikate und der entsprechenden SSL-Einstellungen.

Damit das Ganze übersichtlich bleibt, lagere ich die SSL-Settings immer in eine spezielle Datei aus, die dann später in die virtuellen Hosts eingebunden wird. Auf diese Weise sind alle Einstellungen bzgl. SSL nur an einem Ort zu finden.

Dazu legen wir zunächst eine neue Datei an:

mkdir -p /etc/nginx/snippets
nano /etc/nginx/snippets/ssl.conf

Hier werden dann ausschließlich die Anweisungen für SSL aufgeführt:

# Certificates used
ssl_certificate /etc/letsencrypt/meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/meinedomain.de/key.pem;

# This should be ca.pem (certificate with the additional intermediate certificate)
# See here: https://certbot.eff.org/docs/using.html
ssl_trusted_certificate /etc/letsencrypt/meinedomain.de/ca.pem;

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

# Not using TLSv1 will break:
#	Android <= 4.4.40
#	IE <= 10
#	IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
# TLSv1.3 is not supported by most clients, but it should be enabled.
ssl_protocols TLSv1.2 TLSv1.3;

# Cipher suite from https://cipherli.st/
# Max. security, but lower compatibility 
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';

# Cipher suite from https://wiki.mozilla.org/Security/Server_Side_TLS
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# (Modern) cipher suite from https://mozilla.github.io/server-side-tls/ssl-config-generator/
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# Use multiple curves.
ssl_ecdh_curve secp521r1:secp384r1;

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

# OCSP Stapling
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

resolver 192.168.178.1;

# SSL session handling
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

Neben dem Einbinden der eigentlichen Zertifikate dienen alle weiteren Anweisung ebenso der Sicherheit/Verschlüsselung. Daher bitte auch die Kommentare in der Datei beachten.

Im jeweiligen virtuellen Host für HTTPS ist dann einfach diese ssl.conf einzubinden:

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain.de 192.168.178.60;
	
	include /etc/nginx/snippets/ssl.conf;	
	
	#
	# Here you would add the statements for some web applications, e.g. Nextcloud.
	#
}

Wichtig: Die SSL-Anweisungen dürfen nicht doppelt im server-Block für HTTPS aufgeführt werden. Wenn hier bereits Optionen angegeben sind, die ebenfalls in der Datei ssl.conf aufgeführt sind, dann sind diese im server-Block für HTTPS zu entfernen.

Nach einem Neustart des Webservers sollten die Zertifikate korrekt eingebunden worden sein:

service nginx restart

Überprüfung der Zertifikate

Abschließend lohnt eine Überprüfung der Zertifikate. Hierzu ist der SSL Server Test von Qualys SSL Labs gut geeignet. Mit der gezeigten Konfiguration sollte ein Rating mit A+ und 100% in allen Kategorien erreicht werden:

Ergebnis des SSL-Tests

Ergebnis des SSL-Tests

Falls hier eine niedrigere Bewertung angezeigt werden sollte, liegt dies vermutlich an der SSL-Konfiguration des Webservers. In diesem Fall sollten die entsprechenden Anweisungen der Datei ssl.conf nochmals kontrolliert werden.

Erneuerung der Zertifikate

Die Zertifikate von Let’s Encrypt sind nur für die Dauer von 90 Tagen gültig (Begründung siehe hier) und müssen anschließend erneuert werden.

Bei der Installation von acme.sh wurde ein Cronjob angelegt, der regelmäßig prüft, ob Zertifikate erneuert werden müssen und diese Erneuerung dann ggf. automatisch ausführt. Im Grunde genommen muss man sich daher gar nicht weiter um die Zertifikate kümmern.

Dennoch sollte man nach dem initialen Ausstellen der Zertifikate und Ablauf der 90 Tage kontrollieren, ob die automatische Erneuerung auch wirklich durchgeführt wurde.

Die Gültigkeitsdauer der installierten Zertifikate kann wieder mit folgendem Befehl ermittelt werden:

su - letsencrypt
acme.sh --list

Upgrade von acme.sh

Für acme.sh werden regelmäßig auch Updates veröffentlicht (siehe GitHub Release-Page). In diesem Fall kann das Skript mit nur einem Befehl auf den neusten Stand gebracht werden:

su - letsencrypt
acme.sh --upgrade

Das Reizvolle daran ist nun, dass man diese Updates komplett ohne Abhängigkeiten von den Paketquellen der jeweiligen Distributionen einspielen kann.

Fazit

acme.sh macht als Let’s Encrypt Client einen sehr soliden Eindruck. Die Bedienung gestaltet sich recht einfach und da es sich um ein reines Shell Skript handelt, ist man unabhängig von Programmversionen in den Paketquellen einzelner Linux-Distributionen. Ebenfalls wird automatisch ein Cronjob für die Erneuerung der Zertifikate angelegt, so dass man sich nach der ersten Generierung der Zertifikate nicht mehr um deren Erneuerung kümmern muss. Aus genau diesen Gründen werde ich in Zukunft auch acme.sh als Let’s Encrypt Client empfehlen.

Abschließend noch ein Hinweis für Webserver-Admins, die noch einen anderen Let’s Encrypt Client verwenden und auf acme.sh umsteigen wollen: Der nächste Artikel hier im Blog wird den Umstieg zu acme.sh im Detail beleuchten…

Update: Der Artikel zum Umstieg von Certbot auf acme.sh ist online: Let’s Encrypt: Umstieg von Certbot auf acme.sh (nginx)

Weiterführende Artikel

Links

]]>
https://decatec.de/linux/lets-encrypt-zertifikate-mit-acme-sh-und-nginx/feed/ 70
Nextcloud: Direkter Zugriff auf Dateien über das Dateisystem https://decatec.de/home-server/nextcloud-direkter-zugriff-auf-dateien-ueber-das-dateisystem/ https://decatec.de/home-server/nextcloud-direkter-zugriff-auf-dateien-ueber-das-dateisystem/#comments Tue, 15 Jan 2019 17:10:40 +0000 https://decatec.de/?p=5062 Nextcloud Logo

Heute gibt es einen praktischen Tipp für Nextcloud: Der Artikel zeigt, wie man einen direkten Zugriff auf Cloud-Dateien direkt über das Dateisystem realisieren kann, ohne den Umweg über die Weboberfläche von Nextcloud oder WebDAV nehmen zu müssen.

Das Datenverzeichnis von Nextcloud

Bei der Installation von Nextcloud wird während des Setups das Datenverzeichnis der Cloud angegeben. Das ist ein lokales Verzeichnis, in dem u.a. die Daten gespeichert werden, die die Benutzer in die Cloud hochladen.

Der Zugriff die diese Dateien erfolgt dann üblicherweise über die Weboberfläche von Nextcloud. Alternativ kann auch per WebDAV auf die Cloud-Dateien zugegriffen werden, indem z.B. ein WebDAV-Netzlaufwerk unter Windows eingebunden wird.

Eine Anforderung könnte nun sein, dass ein direkter Zugriff auf die Nextcloud-Daten über das Dateisystem möglich sein soll. Auch wenn man nicht direkt Dateien auf dem Server kopieren/verschieben wird, ist diese Szenario durchaus relevant: Eine Freigabe per Samba oder FTP ist relativ schnell eingerichtet, da könnte man auf die Idee kommen, einfach das Nextcloud-Datenverzeichnis auf diese Art zugänglich zu machen. Anschließend könnte man nun Daten z.B. per Netzwerkfreigabe oder FTP ins Datenverzeichnis von Nextcloud transferieren. Diese sollten dann auch automatisch in der Weboberfläche von Nextcloud auftauchen, oder?

Leider ist die Sache nicht ganz so einfach. Wenn man versucht, Dateien auf diese Art Nextcloud „unterzujubeln“, dann wird man diese in der Weboberfläche nicht zu sehen bekommen. Die Begründung dafür ist recht einfach: Jede Datei und jedes Verzeichnis besteht nicht nur aus einem Eintrag im Dateisystem, sondern auch aus einem Eintrag in der Datenbank von Nextcloud. Ist die Datei nun auf dem Dateisystem vorhanden, aber es existiert kein Eintrag in der Datenbank, dann ist diese Datei für Nextcloud quasi nicht vorhanden.

Da dies nicht automatisch funktioniert, muss man nun Nextcloud veranlassen, das ganze Datenverzeichnis nach neuen und geänderten Dateien zu durchsuchen. Dazu bemühen wir einfach occ:

sudo -u www-data php /var/www/nextcloud occ files:scan --all

Je nach Umfang der Cloud kann dieser Befehl einige Zeit in Anspruch nehmen, aber nach dem Scan sind nun auch Dateien sichtbar, die man einfach manuell über das Dateisystem zum Datenverzeichnis hinzugefügt hat.

Für die Praxis ist dies leider keine gute Lösung, da man nun den Scan-Vorgang immer wieder anwerfen muss, wenn Dateien „hinten rum“ in das Datenverzeichnis kopiert wurden.

Die bessere Lösung: Verwendung von externem lokalem Speicher

Nextcloud überwacht sein Datenverzeichnis als nicht von selbst auf geänderte Dateien. Diese Option ist allerdings bei externem Speicher verfügbar. Hier kann man Nextcloud anweisen, bei jedem aktiven Zugriff auf neue und geänderte Dateien zu achten. Genau diese Option machen wir uns nun zu Nutze, damit man Dateien auch direkt über das Dateisystem der eigenen Cloud hinzufügen kann.

Lokalen externen Speicher einbinden

Zum Einbinden von lokalem externen Speicher benötigen wir erst einmal ein Verzeichnis auf dem lokalen Dateisystem, auf das Nextcloud (d.h. der Webserver-Benutzer) zugreifen kann:

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

Auch PHP braucht natürlich Zugriff auf dieses Verzeichnis, so dass wir noch die Variable open_basedir anpassen müssen.

Für PHP FPM muss dazu der virtuelle Host für Nextcloud (siehe hier) modifiziert werden. Das soeben angelegte Verzeichnis wird bei fastcgi_param PHP_VALUE einfach bei open_basedir hinzugefügt. Der komplette Block kann dann z.B. so aussehen.

fastcgi_param PHP_VALUE "open_basedir=/var/www:/tmp/:/var/nextcloud_data:/dev/urandom:/proc/meminfo:/var/nextcloud_external_data/
	upload_max_filesize = 10G
	post_max_size = 10G
	max_execution_time = 3600
	output_buffering = off";

Nach der Anpassung des vHosts muss der Webserver noch neu gestartet werden:

service nginx restart

Damit auch der Cronjob von Nextcloud Zugriff auf das Verzeichnis hat, wird dieses ebenfalls in der entsprechenden php.ini Datei unter open_basedir hinzugefügt:

nano /etc/php/7.2/cli/php.ini

Der Eintrag kann hier z.B. dann so aussehen:

open_basedir = /var/www/:/tmp/:/var/nextcloud_data/:/var/nextcloud_external_data/

In den Einstellungen von Nextcloud kann dieses Verzeichnis nun als externer lokaler Speicher eingebunden werden. Dies kann jedoch nur in den Admin-Einstellungen erfolgen, da Benutzer nicht selbst externen lokalen Speicher einbinden können.

Nextcloud: Lokalen externen Speicher einbinden

Nextcloud: Lokalen externen Speicher einbinden

Folgende Optionen sind hier wichtig:

  • Ordnername: Kann beliebig vergeben werden. In der Dateiübersicht von Nextcloud erscheint der externe Speicher dann unter diesem Namen.
  • Konfiguration: Hier ist der Order auf dem lokalen Dateisystem anzugeben. In diesem Beispiel also /var/nextcloud_external_data.
  • Verfügbar für: Hier werden die Benutzer/Gruppen hinterlegt, für die der externe Speicher zugänglich sein soll.
  • Auf Änderungen prüfen: Diese Einstellung verbirgt sich in den erweiterten Optionen (Menü mit drei Punkten). Wichtig ist hier die Angabe Einmal bei jedem Direktzugriff.

Nach dem Speichern der Einstellungen sollte der externe Speicher erfolgreich eingebunden worden sein.

Hinzufügen von Dateien direkt über das Dateisystem

Durch die Option, dass Nextcloud den soeben eingebundenen externen Speicher bei jedem Zugriff auf Änderungen durchsuchen soll, können nun einfach Dateien über das Dateisystem hinzugefügt werden. Für einen schnellen Test legen wir einfach eine einfache Textdatei an:

nano /var/nextcloud_external_data/test.txt

Der Inhalt spielt für den Funktionstest keine Rolle, daher einfach irgendwas eingeben und die Datei speichern.

Wenn man nun wieder über die Nextcloud-Oberfläche im Browser das Verzeichnis des externen Speichers öffnet, wird die neu erzeugte Datei von Nextcloud erkannt und kann auch direkt bearbeitet werden.

Der nächste Schritt würde nun darin bestehen, einen „Direktzugriff“ auf das Verzeichnis des externen Speichers zu legen, beispielsweise per Samba-Freigabe oder auch per FTP.

Anschließend hat man einen direkten Zugriff auf die Dateien von Nextcloud (zumindest auf jene, die auf dem externen lokalen Speicher liegen).

Aus der Praxis – OCR von gescannten Dokumenten

Nun fragt sich der eine oder andere sicher: „Was bringt mir das?“

In der Praxis hat sich bei mir das gezeigte Vorgehen bei der Verwaltung von (gescannten) Dokumenten bewährt.

Dazu habe ich zwei lokale externe Speicher eingebunden: Scan Eingang und Dokumente Eingang. In das Verzeichnis Scan Eingang werden nun Dokumente oder Bilder gespeichert, die vom Scanner erfasst wurden (z.B. als PDF). Diese Dokumente besitzen noch keinen Text-Layer (OCR).

Um diesen Text-Layer hinzuzufügen nutze ich nun das Script OCRmyFiles. Details zu diesem Script habe ich bereits im Artikel Linux: OCR-Texterkennung für PDF-Dateien und Bilder beschrieben. Dieses Script wird nun regelmäßig per Cronjob aufgerufen (z.B. alle 30 Minuten). Das Script ist so konfiguriert, dass es als Eingangs-Verzeichnis den Order /var/nextcloud_external_data/scan_eingang nutzt (Eingebunden als Order Scan Eingang in Nextcloud). Als Ausgabeordner nutze ich /var/nextcloud_external_data/dokumente_eingang (In Nextcloud als Dokumente Eingang eingebunden).

Nun sorgt das Script dafür, dass Dokumente ohne Text-Layer erfasst werden, per OCR mit Text versehen werden und anschließend in den Order Dokumente Eingang in der eigenen Cloud verschoben werden.

Das ganze wäre nicht möglich, wenn die OCR-Dokumente direkt in das Nextcloud-Datenverzeichnis verschoben werden würden. Erst durch die Nutzung von lokalem externen Speicher bekommt Nextcloud mit, dass im Ordner Dokumente Eingang neue gescannte Dokumente mit Text-Layer verfügbar sind.

Zu guter Letzt werden die Dokumente dann vom Ordner Scan Eingang dann in den jeweils passenden Order verschoben (über die Weboberfläche von Nextcloud).

Fazit

Der direkte Zugriff auf Nextcloud-Dateien über das Dateisystem mag zunächst nicht sonderlich aufregend klingen. In der Praxis merkt man allerdings schnell, dass das Nextcloud-Datenverzeichnis nicht aktiv auf Änderungen überwacht wird.

Der kleine Umweg über lokalen externen Speicher lohnt allemal: Damit wird es zum einen möglich, dass Benutzer Dateien direkt über eine Samba-Freigabe oder auch FTP der Cloud hinzufügen können. Zum anderen eröffnen sich dadurch auch weitere Möglichkeiten, die Cloud-Infrastruktur durch Scripte, o.ä. für Automatisierungen zu nutzen.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-direkter-zugriff-auf-dateien-ueber-das-dateisystem/feed/ 29
Nextcloud: Lesezeichen synchronisieren mit Chrome/Firefox https://decatec.de/home-server/nextcloud-lesezeichen-synchronisieren-mit-chrome-firefox/ https://decatec.de/home-server/nextcloud-lesezeichen-synchronisieren-mit-chrome-firefox/#comments Sat, 05 Jan 2019 13:42:08 +0000 https://decatec.de/?p=4706 Logo Nextcloud Bookmarks

Mit Nextcloud kann jedermann seine persönliche Cloud betreiben, ohne dabei von den großen Cloud-Anbietern abhängig zu sein. Beim Thema Cloud denken viele zunächst einmal an eine Datei-Ablage, die von überall aus erreichbar ist. Doch Nextcloud hat hier deutlich mehr zu bieten. Die eigene Cloud kann nach Belieben mit Apps erweitert werden. Nicht nur eine Verwaltung von Kontakten und Kalendern ist hier möglich, sondern auch das Speichern der eigenen Browser-Lesezeichen.

Der folgende Artikel zeigt, wie Lesezeichen in der eigenen Nextcloud gespeichert werden und mit Chrome/Chromium und Firefox synchronisiert werden können.

Voraussetzung für dieses Tutorial ist die Verwendung der Nextcloud-App „Bookmarks“ ab der Version 0.14. Ältere Versionen der App sind nicht empfehlenswert, da hier noch keine Ordnerstruktur bei der Verwaltung von Lesezeichen unterstützt wurde.

Übrigens: Wer nur Firefox nutzt und nicht nur Lesezeichen, sondern auch andere Einstellungen (Addons, Chronik, etc.) synchronisieren möchte, der kann auch einen eigenen Sync Server für Firefox auf dem eigenen Server betreiben. Wie dies gemacht wird, ist im Artikel Eigener Firefox Sync Server mit nginx beschrieben.

Update-Historie (letztes Update 02.05.2019)
  • 02.05.2018:
    • Hinweis für Firefox-Nutzer hinzugefügt, dass alle Browser-Einstellungen (und damit auch Lesezeichen) über einen eigenen Firefox Sync Server synchronisiert werden können.

 

Bookmarks-App in Nextcloud aktivieren

Damit Nextcloud Lesezeichen verwalten kann, ist zunächst einmal die App „Bookmarks“ notwendig. Diese ist schnell in der eigenen Cloud installiert. Im Nextcloud App Store findet man die App unter der Kategorie Organisation:

Die Bookmarks App in Nextcloud App Store

Die Bookmarks App in Nextcloud App Store

Nach einem Klick auf Herunterladen und aktivieren und einem Refresh der Seite sollte man in der oberen App-Leiste die Bookmarks-App finden (der Stern).

Überblick über die Bookmarks-App

Die App macht zunächst, was man auch erwarten würde: Lesezeichen speichern. Das Ganze gestaltet sich recht intuitiv, daher gibt es bei der App auch wenige Einstellungen.

Die Bookmarks-App ist recht intuitiv zu bedienen

Die Bookmarks-App ist recht intuitiv zu bedienen

Lesezeichen können dabei auf mehrere Arten hinzugefügt werden:

  • Durch die Schaltfläche oben links (+ Lesezeichen hinzufügen) und direkte Eingabe der URL.
  • Mit einem sog. Bookmarklet: Dazu einfach die Einstellungen der App öffnen (siehe Pfeil im oberen Screenshot). Anschließend kann man den Button Hinzufügen zu Nextcloud z.B. in die Lesezeichen Symbolleiste ziehen. Wenn man nun eine interessante Webseite gefunden hat, kann man nun einfach auf die Schaltfläche Hinzufügen zu Nextcloud (Pfeil im unteren Screenshot) klicken. Es öffnet sich ein Popup, in dem man weitere Daten angeben kann (z.B. Titel des Lesezeichens) und den Bookmark in die Cloud übernehmen kann.
  • Wenn man Bookmarks als HTML aus einem Browser exportiert hat, kann man diese hier über die Schaltfläche Import in der Bookmarks-App importieren.
Hinzufügen eines Lesezeichens mit dem "Bookmarklet"

Hinzufügen eines Lesezeichens mit dem „Bookmarklet“

Die angelegten Lesezeichen können nun einfach durch einen Klick aufgerufen werden.

Seit der Version 0.14 unterstützt die Bookmarks App das Verwalten der Lesezeichen in einer Ordnerstruktur. Neue Ordner können dabei auf der linken Seite einfach angelegt werden.

Ebenso kann man Lesezeichen Tags zuweisen, um diese leichter zu kategorisieren.

Synchronisierung mit Chrome/Firefox

Lesezeichen werden eigentlich direkt im Browser gespeichert, damit man diese beim Surfen immer schnell und unkompliziert aufrufen kann. Der Umweg über die Web-Oberfläche von Nextcloud zum Aufrufen von Lesezeichen ist hier etwas umständlich.

Daher sollen die Lesezeichen im nächsten Schritt mit dem Browser synchronisiert werden. Ich beschränke mich hier auf die populärsten Browser: Chrome und Firefox. Für diese beiden Browser gibt es jeweils das Add-On floccus, mit dem diese Aufgabe realisiert werden kann.

Vorbereitung für die Lesezeichen-Synchronisierung mit floccus

Bevor wir das Add-On nun installieren und die Synchronisierung mit Nextcloud einrichten, sollen noch einige Vorbereitungen getroffen werden.

Im Browser vorhandene Lesezeichen werden am besten erst einmal als HTML-Datei exportiert. In Chrome geschieht dies über den Lesezeichen-Manager, bei Firefox über die Option Lesezeichen verwalten. Diese exportieren Lesezeichen können dann später auch in der Nextcloud Bookmarks-App importiert werden.

Den Export sollte man in jedem Fall ausführen: Zum einen können dann keine Lesezeichen verloren gehen, sollte bei der ersten Synchronisierung etwas schief laufen. Zum anderen können die Lesezeichen dann später in einem Rutsch per Browser nach Nextcloud übernommen werden.

Lesezeichen-Export in Firefox

Lesezeichen-Export in Firefox

Wer seine Lesezeichen vorher immer über den Mozilla- bzw. Google-Account synchronisiert hat, kann dieses Feature nun ausschalten, da die Lesezeichen ab nun ausschließlich mit der eigenen Cloud synchronisiert werden sollen. Da werden alle Lesezeichen zunächst einmal gelöscht, damit diese dann beim nächsten Sync aus den Clouds von Mozilla bzw. Google verschwinden.

Anschließend wird die Lesezeichen-Synchronisierung im Browser deaktiviert. Bei Firefox kann man diese Option unter den Einstellungen bei Firefox-Konto finden. Hier einfach unter den Sync-Einstellungen die Option Lesezeichen deaktivieren.

Firefox: Lesezeichen-Synchronisierung ausschalten

Firefox: Lesezeichen-Synchronisierung ausschalten

Da die Synchronisierung nun nicht mehr über das Firefox-Konto bzw. die Google-Cloud läuft, können die als HTML-Datei exportierten Lesezeichen wieder im Browser importiert werden. Diese sind dann für den Moment nur lokal im Browser verfügbar, aber das ändern wir gleich im Anschluss.

Installation und Einrichtung von floccus

Das Add-On kann einfach im Chrome Web-Store bzw. im Firefox Add-ons dem jeweiligen Browser hinzugefügt werden. Beispielhaft beschreibe ich hier die Vorgehensweise für Firefox, unter Chrome läuft die Einrichtung allerdings analog ab.

In der Add-On-Verwaltung von Firefox sucht man dazu einfach nach „floccus“ und installiert die Erweiterung einfach über die Schaltfläche Zu Firefox hinzufügen.

floccus bei Firefox Add-ons

floccus bei Firefox Add-ons

Direkt nach der Installation des Add-Ons macht sich floccus mit einem Icon in der Browser-Toolbar bemerkbar, mit dem Accounts hinzugefügt werden können.

floccus in der Toolbar von Firefox

floccus in der Toolbar von Firefox

Beim Klick auf dieses Icon öffnet sich ein Menü, in dem man einen Account über die Schaltfläche Add Account hinzufügen kann. Für Nextcloud stehen hier zwei Auswahlmöglichkeiten zur Verfügung: Einmal Nextcloud Bookmarks (legacy) – dies ist die richtige Option, wenn noch eine ältere Version der Bookmarks-App verwendet werden soll. Für diese Anleitung ist die Option Nextcloud Bookmarks (with folders) die richtige.

Nach einem Klick auf die Schaltfläche Add Account gibt man nun einfach die URL der eigenen Nextcloud (z.B. https://meinedomain.de/nextcloud) und Benutzername/Passwort an.

Hinweis für Firefox unter Linux: Momentan gibt es hier manchmal ein Problem mit floccus unter Linux. Hier stürzt das Add-On ab, wenn man hier die Passwort-Textbox aktivieren will. Hier kann man den Account nur an anderer Stelle hinzufügen. Dazu einfach über das Firefox-Menü den Punkt Add-ons aufrufen. Anschließend gibt es hier neben floccus den Button Einstellungen. An dieser Stelle können nun Accounts hinzugefügt werden, ohne dass das Add-On abstürzt.

Wenn man den Account nun mit den Standard-Einstellungen hinzufügt, ist das Ergebnis vermutlich nicht wie erwartet. floccus fügt dann nämlich im Lesezeichen-Menü einfach einen Ordner für diesen Account an und synchronisiert alle Lesezeichen einfach in diesen Ordner. Wenn man Lesezeichen nicht unbedingt über mehrere Nextcloud-Instanzen verteilt, dies sicher nicht das gewünschte Verhalten. Daher…

floccus-Tipp: Lesezeichen im Lesezeichen-Menü bzw. der Lesezeichen-Symbolleiste

Damit die Lesezeichen genau so verhalten, als hätte man diese direkt über den Sync-Mechanismus des Browsers synchronisiert hätte, ist noch ein kleiner zusätzlicher Schritt notwendig.

Hier bedarf es zunächst einmal einer Trennung zwischen den normalen Lesezeichen (die dann im Lesezeichen-Menü des Browsers zu finden sein sollen) und den Lesezeichen, die dann in der Lesezeichen-Symbolleiste angezeigt werden sollen. Dazu legen wir uns in der Nextcloud Bookmarks App einfach zwei Ordner an, z.B. Lesezeichen für die normalen Lesezeichen und FavBar für die Lesezeichen-Symbolleiste.

Vorbereitung der Browser-Synchronisierung

Vorbereitung der Browser-Synchronisierung

Der eigentliche Trick ist nun, einfach zwei Accounts für die Lesezeichen-Synchronisierung hinzuzufügen: Einen für die normalen Bookmarks und einen weiteren extra für die Lesezeichen-Symbolleiste.

Für die normalen Lesezeichen wählt man beim Hinzufügen eines Accounts einfach das Lesezeichenmenü als Local folder:

  • Bei Firefox heißt der Ordner „Lesezeichen-Menü“.
  • Bei Chrome muss man hier „Weitere Lesezeichen“ wählen.

Unter Server folder ist hier das Verzeichnis der Nextcloud Bookmarks App anzugeben, welches man zuvor angelegt hat. In diesem Beispiel ist dies einfach /Lesezeichen (man beachte den Slash am Anfang). Die Option Run sync in parallel kann man an dieser Stelle auch noch gleich aktivieren, dann werden sämtliche Sync-Vorgänge parallel ausgeführt.

floccus: Sync-Einstellungen für Firefox (Lesezeichen-Menü)

floccus: Sync-Einstellungen für Firefox (Lesezeichen-Menü)

Für die Lesezeichen der Lesezeichen-Symbolleiste fügt man nun einen zweiten Account mit folgenden Daten hinzu:

  • Firefox:
    • Local folder: Lesezeichen-Symbolleiste
    • Server folder: /FavBar (wichtig ist hier der Slash am Anfang).
  • Chrome:
    • Local folder: Lesezeichenleiste
    • Server folder: /FavBar (wichtig ist hier der Slash am Anfang).
floccus: Sync-Einstellungen für Firefox (Lesezeichen-Symbolleiste)

floccus: Sync-Einstellungen für Firefox (Lesezeichen-Symbolleiste)

Wenn man die beiden Sync-Einstellungen festgelegt hat, muss man diese noch aktivieren (Option enabled):

floccus: Synchronisierung einschalten

Erstbestückung der Nextcloud-Lesezeichen mit dem Browser

Wenn die Einrichtung von floccus wie beschrieben durchgeführt wurde, können nun sämtliche Lesezeichen, die wir zuvor als HMTL-Datei exportiert haben, in einem Rutsch in die Cloud übernommen werden.

Dazu sorgen wir zunächst einmal dafür, dass in der Cloud keine Lesezeichen mehr gespeichert sind. Dazu nutzen wir in der Nextcloud Bookmarks-App einfach den Button Lesezeichen löschen.

Im nächsten Schritt importieren wir die HTML-Datei mit unseren Lesezeichen in den Browser (nicht in die Bookmarks-App). Bei der nächsten Synchronisierung mit floccus landen die Lesezeichen in der Nextcloud Bookmarks-App.

Zukünftig wird man neue Lesezeichen nun nicht in der Nextcloud Bookmarks-App, sondern wie gewohnt im Browser hinzufügen. Das Ganze verhält sich dann analog zum eingebauten Sync-Mechanismus von Chrome/Firefox. Der große Unterschied ist nun, dass die Lesezeichen nicht auf den Servern von Google oder Mozilla landen, sondern nur noch in der persönlichen Cloud gespeichert sind.

Bookmark-App für Smartphones

Einen Nachteil hat diese Lösung dennoch: Die Synchronisierung funktioniert nicht für die mobilen Varianten von Chrome/Firefox. Chrome lässt in der Mobil-Version keine Installation von Add-Ons zu. Bei Firefox wäre dies zwar kein Problem, jedoch funktioniert hier floccus (noch) nicht.

Zumindest für Android gibt es jedoch eine App speziell für Lesezeichen in der eigenen Cloud: Nextcloud Bookmarks

Diese ist im Google Play Store oder bei F-Droid (hier sogar kostenlos) erhältlich.

Die Nextcloud Bookmarks App unter Android

Die Nextcloud Bookmarks App unter Android

Leider ist mir momentan keine Lösung bekannt, um Nextcloud Bookmarks mit iOS-Geräten zu synchronisieren. Kennt ihr hier eine Möglichkeit? Hinterlasst mir dazu doch einfach einen Kommentar, ggf. werde ich den Artikel dann erweitern.

Fazit

Nach der einmaligen Einrichtung der Lesezeichen-Verwaltung mit der Nextcloud Bookmarks App, ist die Lesezeichen-Synchronisierung über die eigene Cloud genau so einfach und intuitiv wie die integrierte Lesezeichen-Synchronisierung in Chrome/Firefox. Anschließend kann man die Lesezeichen zwischen verschiedenen Browsern/Betriebssystemen synchronisieren. Dabei hat man das gute Gefühl, dass keine Daten in den Clouds von Google bzw. Mozilla gespeichert werden, sondern ausschließlich in der eigenen Cloud.

Synchronisiert ihr eure Lesezeichen bereits über die eigene Nextcloud? Nutzt ihr dafür auch die Browser-Erweiterung floccus, oder habt ihr eine bessere Alternative gefunden? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-lesezeichen-synchronisieren-mit-chrome-firefox/feed/ 19
phpMyAdmin neben Nextcloud installieren (nginx) https://decatec.de/home-server/phpmyadmin-neben-nextcloud-installieren-nginx/ https://decatec.de/home-server/phpmyadmin-neben-nextcloud-installieren-nginx/#comments Sat, 15 Dec 2018 09:49:16 +0000 https://decatec.de/?p=4894 phpMyAdmin Logo

phpMyAdmin ist eine Webanwendung zur Administration von MySQL-Datenbanken. Zwar kann eine Datenbank auch über den Befehl mysql auf der Kommandozeile direkt administriert werden, jedoch ist die grafische Benutzeroberfläche von phpMyAdmin weitaus intuitiver zu bedienen, als SQL-Befehle direkt in der Kommandozeile einzutippen.

Dies Artikel zeigt daher, wie man phpMyAdmin auf einem Ubuntu Server 18.04.1 in Verbindung mit nginx als Webserver installieren und einrichten kann. In dieser Konfiguration sind nach der Installation noch einige Optimierungen für phpMyAdmin notwendig. Als Grundlage dienen hier zwei bereits bekannte Artikel:

Ich gehe daher im Folgenden davon aus, dass Nextcloud mit MariaDB/MySQL bereits auf dem System installiert ist. Für die verschlüsselte Verbindung über HTTPS sollte ein gültiges SSL-Zertifikat ebenso bereits vorhanden sein.

Update-Historie (letztes Update 13.01.2019)
  • 13.01.2019:
    • Anweisungen für PHP_VALUE  und client_max_body_size angepasst, so dass nun auch größere SQL-Dumps verarbeitet werden können.

 

Installation phpMyAdmin

Zunächst bringen wir das System auf den neusten Stand:

apt-get update && apt-get upgrade -V

Anschließend kann phpMyAdmin durch folgenden Befehl installiert werden:

apt-get install phpmyadmin

Der Installer läuft dabei interaktiv ab, so dass eine Grundkonfiguration bereits nach der Installation des Paketes gegeben ist.

In einem ersten Schritt folgt die automatische Konfiguration des Webservers. Hier werden leider nur die Optionen apache2 und lighttpd angeboten – nginx befindet sich nicht in der Auswahl.

phpMyAdmin Setup: Auswahl des Webservers

phpMyAdmin Setup: Auswahl des Webservers

Daher wird hier keine Option ausgewählt, sondern der Schritt einfach mit Enter übersprungen.

Die Installation wird nun fortgesetzt und nach einer kurzen Zeit erscheint ein Hinweis, dass für den Betrieb von phpMyAdmin eine Datenbank installiert und konfiguriert sein muss.

phpMyAdmin Setup: Konfiguration mittels dbconfig-common

phpMyAdmin Setup: Konfiguration mittels dbconfig-common

Achtung: Die Datenbank (MariaDB) wurde bereits beim Setup von Nextcloud installiert und aufgesetzt (siehe hier bzw. hier). Falls man hier nun Yes wählt, erhält man im nächsten Schritt einen Fehler. Daher muss an dieser Stelle No gewählt werden.

Nach wenigen Augenblicken ist die Installation von phpMyAdmin dann auch schon abgeschlossen.

Konfiguration nginx für phpMyAdmin

Während der Installation von phpMyAdmin stand nginx als Webserver leider nicht zur Auswahl, daher muss der Webserver nach dem Setup noch manuell angepasst werden.

Der richtige Ort für die Änderungen ist dabei der Gateway-Host:

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

Hier fügen wir nun ganz am Ende (aber vor der letzten schließenden Klammer) folgenden Inhalt ein:

location /phpmyadmin {
	root /usr/share/;
	index index.php index.html index.htm;

	client_max_body_size 100M;
	
	location ~ ^/phpmyadmin/(.+\.php)$ {
		try_files $uri =404;
		root /usr/share/;
		fastcgi_pass php-handler;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
		fastcgi_param PHP_VALUE "open_basedir=/var/www:/tmp/:/usr/share/phpmyadmin:/usr/share/php:/etc/phpmyadmin/
			upload_max_filesize = 100M
			post_max_size = 100M
			max_execution_time = 3600";
    }
	
	location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
	   root /usr/share/;
	}
}

Am Ende wird der Webserver noch neu gestartet, damit die Änderungen wirksam werden:

service nginx restart

Optimierung der phpMyAdmin-Installation

Da nun alle Vorbereitungen getroffen wurden, kann man sich nun mit folgender URL bei phpMyAdmin anmelden:

https://meinedomain.de/phpmyadmin

Es erscheint eine Anmeldemaske, mit der man sich nun als User root an der Datenbank anmelden kann. Das Root-Passwort wurde bei der ursprünglichen Installation von MariaDB angelegt (siehe hier). Eine Anmeldung mit Root ist notwendig, da man ansonsten nicht die erforderlichen Rechte an der Datenbank besitzt, um umfangreiche Änderungen durchzuführen.

phpMyAdmin: Anmeldung mit Root-Account

phpMyAdmin: Anmeldung mit Root-Account

Direkt nach dem Login wird man mit zwei Warnungen konfrontiert. Um die Einrichtung von phpMyAdmin abzuschließen ist leider noch etwas Handarbeit notwendig.

phpMyAdmin: Fehler nach erstem Login

phpMyAdmin: Fehler nach erstem Login

Passwort zur Verschlüsselung generieren

Zunächst kümmern wir uns um die untere Fehlermeldung („blowfish_secret“). Dabei handelt es sich um ein Sicherheits-Feature, bei dem ein Passwort zur Verschlüsselung der Verbindung in einer Konfigurations-Datei von phpMyAdmin hinterlegt werden muss.

Dieses Passwort muss genau 32 Zeichen lang sein. Am einfachsten kann man ein entsprechendes Passwort (oder besser gesagt den entsprechenden Hash-Wert) über die Seite Blowfish password hash generator generieren lassen.

Blowfish password hash generator

Blowfish password hash generator

Dazu gibt man in das entsprechende Eingabefeld einfach ein möglichst komplexes Passwort ein. Einfacher geht es über die Schaltfläche zur automatischen Generierung eines Passwortes (roter Pfeil). Dieses Passwort muss man sich dabei nicht merken, daher kann es eine beliebige Zeichenfolge (am besten mit Sonderzeichen) sein. Anschließend wird der Hash-Wert über den Button Generate erzeugt. Dieses Hash-Wert muss man nun kopieren.

Nachfolgend wird folgende Datei bearbeitet:

nano /etc/phpmyadmin/config.inc.php

Ganz am Ende der Datei wird nun folgende Zeile mit dem soeben kopierten Hash-Wert eingefügt:

$cfg['blowfish_secret'] = '$2a$07$ZHGuhpP7Gl3913T9GOMDk.EbFoBpbGBkuNesqXPvM0NTufx0BCAmm';

Verwaltungsdatenbank für phpMyAdmin anlegen

Wenn man die phpMyAdmin-Seite neu lädt, sollte nun nur noch eine Fehlermeldung zu sehen sein: Es muss noch eine Verwaltungsdatenbank für phpMyAdmin angelegt werden. Dazu klickt man einfach auf den Link Finden Sie heraus warum in der Meldung.

Anschließend klickt wiederum auf den Link anlegen auf der erscheinenden Seite.

Nach einem kurzen Moment sollte die neue Datenbank erfolgreich angelegt worden sein.

phpMyAdmin: Die Verwaltungs-Datenbank wurde erfolgreich angelegt

phpMyAdmin: Die Verwaltungs-Datenbank wurde erfolgreich angelegt

Fehler beim Öffnen von Tabellen

Auf der Übersichts-Seite von phpMyAdmin sollten nun keine Fehlermeldungen mehr angezeigt werden. Man wird beim Arbeiten mit phpMyAdmin jedoch auf ein weiteres Problem stoßen, wenn man eine Tabelle in einer Datenbank öffnen möchte.

Hier wird dann die Meldung count(): Parameter must be an array or an object that implements countable angezeigt:

phpMyAdmin: Fehler nach dem Öffnen einer Tabelle

phpMyAdmin: Fehler nach dem Öffnen einer Tabelle

Hierbei handelt es sich um einen Fehler im Quellcode des phpMyAdmin-Paketes, welches in den Ubuntu Paketquellen enthalten ist. Hier muss noch eine kleine Änderung am Sourcecode vorgenommen werden.

Dazu öffnen wir folgende Datei:

nano /usr/share/phpmyadmin/libraries/sql.lib.php

Anschließend suchen wir nach folgender Zeile (am besten folgende Zeile kopieren und in nano mittels STRG + W danach suchen):

|| (count($analyzed_sql_results['select_expr'] == 1)

Diese eine Zeile (und nur diese!) wird dann gelöscht und durch folgende Zeile ersetzt:

|| ((count($analyzed_sql_results['select_expr']) == 1)

Nach dieser kleinen Änderung sollte kein Fehler mehr beim Öffnen einer Tabelle erscheinen.

Fehler beim Importieren/Exportieren von Datenbanken

Das nächste Problem wird man bemerken, wenn man Datenbanken importieren oder exportieren möchte. In beiden Fällen wird man folgende Fehlermeldung bekommen:

Warning in ./libraries/plugin_interface.lib.php#551
count(): Parameter must be an array or an object that implements Countable

Auch hier muss man den Code modifizieren, so dass meine Fehlermeldungen mehr erscheinen.

Dazu öffnen wir die betroffene Datei:

nano /usr/share/phpmyadmin/libraries/plugin_interface.lib.php

Anschließend wird die betroffene Code-Zeile gesucht (STRG + W):

if ($options != null && count($options) > 0) {

Die komplette Zeile wird nun durch Folgendes ersetzt:

if ($options != null) {

Nach dem Speichern der Datei wird der Fehler beim Importieren/Exportieren nicht mehr erscheinen.

Optional: Zugriff auf phpMyAdmin nur über das lokale Netzwerk

Der Zugriff auf die Datenbankverwaltung ist mit dem gezeigten Setup von überall aus möglich – auch aus dem Internet. Aus Gründen der Sicherheit ist es hier eine Überlegung wert, ob man den Zugriff auf phpMyAdmin auf das lokale Netzwerk (LAN) beschränken möchte.

In diesem Fall müssen nochmals die Anweisungen für phpMyAdmin im Gateway-Host angepasst werden:

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

Ganz oben im location-Block für phpMyAdmin fügen wir nun folgende Anweisungen ein:

allow 192.168.178.0/24;
deny all;

Nach einem Neustart des Webserver ist phpMyAdmin nur noch im lokalen Netzwerk (192.168.178.xxx) erreichbar. Beim Zugriff über das Internet erscheint dann nur ein Fehler HTTP 403 (Forbidden).

Fazit

Die Installation von phpMyAdmin ist schnell erledigt, jedoch sind hier und da noch einige Nacharbeiten notwendig, bis das Datenbankverwaltungs-Tool einwandfrei funktioniert.

Jedoch lohnt sich hier der Aufwand, da man nun die Datenbanken auf dem System komfortabel mit einer grafischen Oberfläche bearbeiten kann. Das ist viel intuitiver, als mit dem Tool mysql die Datenbanken auf der Kommandoziele zu bearbeiten.

Trotzdem sollte man immer beachten, dass man mit phpMyAdmin Admin-Zugriff auf alle Datenbanken hat (zumindest, wenn man sich mit dem User ‚root‘ einloggt). Beim Bearbeiten der Datenbanken sollte man Vorsicht walten lassen – eine falsche Bearbeitung von Tabellen kann hier dazu führen, dass die auf der Datenbank basierende Anwendung nicht mehr wie erwartet funktioniert.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/phpmyadmin-neben-nextcloud-installieren-nginx/feed/ 27
Nextcloud Talk mit eigenem TURN-Server (coturn) https://decatec.de/home-server/nextcloud-talk-mit-eigenem-turn-server-coturn/ https://decatec.de/home-server/nextcloud-talk-mit-eigenem-turn-server-coturn/#comments Wed, 21 Nov 2018 15:12:55 +0000 https://decatec.de/?p=4930 Nextcloud Talk Logo

Für Nextcloud ist schon seit einiger Zeit eine Erweiterung als App verfügbar, mit der Chats und (Video-)Telefonate über die eigene Cloud geführt werden können: Nextcloud Talk.

Im Normalfall muss man dafür einfach die App im Nextcloud App Store herunterladen und kann sofort loslegen, mit anderen Nutzern der Cloud zu kommunizieren. Dank der Verfügbarkeit von mobilen Apps für Android und auch iOS kann diese Lösung auch als Alternative zu den bekannten Kommunikation-Apps (wie z.B. WhatsApp) genutzt werden. Das Hauptargument für Nextcloud Talk ist dabei sicherlich, dass Chats und (Video-)Telefonate komplett verschlüsselt über die eigene Nextcloud-Instanz ablaufen und so vor den neugierigen Blicken von Konzernen geschützt sind.

Dennoch treten bei Nextcloud Talk oftmals Probleme auf, wenn sich die genutzten Endgeräte nicht im selben Netzwerk befinden. Hier können dann keine (Video-)Telefonate geführt werden, da sich die Geräte einfach nicht finden können.

Damit über Nextcloud Talk jederzeit problemlos kommuniziert werden kann, ist ein eigener TURN-Server notwendig. Mit coturn ist ein solcher auch unter Ubuntu verfügbar. Dieser Artikel beschreibt daher die Installation und Konfiguration von coturn, um optimal mit Nextcloud Talk zusammen zu arbeiten.

Als Basis dient wie immer der Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban.

Wichtig: Auch wenn ein eigener TURN-Server bei Nextcloud Talk zum Einsatz kommt, sind dennoch Videokonferenzen mit maximal 4 bis 6 Teilnehmern möglich. Für mehr Teilnehmer ist dann ein externer „Signaling Server“ notwendig, den man allerdings nur in Verbindung mit einer Nextcloud Enterprise Subscription nutzen kann.
Wenn an die Videokonferenz-Lösung höhere Ansprüche gestellt werden, könnte Jitsi Meet eine geeignetere Lösung sein (siehe Artikel Jitsi Meet: Videokonferenz-System unter Ubuntu Server mit nginx)

Update-Historie (letztes Update: 12.04.2020)
  • 12.04.2020:
    • Hinweis zu den Einschränkungen von Nextcloud Talk hinzugefügt.
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.

 

Probleme mit Nextcloud Talk mit eigenem STUN/TURN-Server lösen

Nextcloud Talk basiert auf WebRTC. Die bei der Kommunikation beteiligten Endgeräte bauen dabei eine direkte Peer-to-Peer-Verbindung auf.

Im gleichen Netzwerk (LAN) ist dies kein Problem, hier müssen alle Endgeräte lediglich WebRTC unterstützen.

Wenn sich die Geräte in unterschiedlichen Netzwerken befinden, müssen die Geräte sowohl ihre interne, also auch ihre externe IP-Adresse kennen. Diese Umsetzung ist die Aufgabe eines STUN-Servers (Session Traversal Utilities for NAT). Für Nextcloud Talk ist ein eigener STUN-Server verfügbar (stun.nextcloud.com:443), daher sollte dies auch kein Problem darstellen.

Wenn nun allerdings Firewalls mit im Spiel sind, kann der STUN-Server die „Übersetzung“ der Adressen nicht mehr leisten. In diesen Fällen spricht man von einem Symmetric NAT: Hier wird durch die Firewall verhindert, dass von außen (d.h. aus dem Internet) initiierte Verbindungen in das lokale Netzwerk möglich sind. In diesem Szenario ist dann ein TURN-Server (Traversal Using Relays around NAT) notwendig, über den sämtliche Verbindungen geleitet werden.

Diese Thematik ist durchaus komplex, aber vereinfacht kann man sagen, dass man einen TURN-Server benötigt, wenn die Verbindung zwischen Geräten in unterschiedlichen Netzwerken nicht aufgebaut werden kann (z.B. PC im Heimnetzwerk, Smartphone in Mobilfunknetz). Im Heimnetzwerk-Bereich ist dies vermutlich immer der Fall.

Unter Ubuntu ist coturn als quelloffene Implementierung eines STUN/TURN-Servers verfügbar.

Installation und Konfiguration coturn

coturn kann ganz einfach auf dem gleichen System installiert werden, auf dem auch schon Nextcloud läuft.

Zunächst bringen wir das System auf den neusten Stand:

apt-get update && apt-get upgrade -V

Anschließend kann coturn auch schon installiert werden, da es bereits Teil der Ubuntu-Paketquellen ist:

apt-get install coturn

Nach der Installation muss coturn nun nur noch konfiguriert werden, damit eine optimale Zusammenarbeit mit Nextcloud Talk gewährleistet ist.

Dazu wird coturn erst einmal aktiviert. Dies geschieht in folgender Datei:

nano /etc/default/coturn

Hier muss folgende Zeile eingefügt werden. Diese ist nach der Installation bereits vorhanden, ist allerdings auskommentiert. Daher entfernen wird einfach das Zeichen ‚#‘ am Anfang der Zeile:

TURNSERVER_ENABLED=1

Als nächstes werden die Einstellungen von coturn bearbeitet.
Diese befinden sich in folgender Datei:

nano /etc/turnserver.conf

Hier müssen die folgenden Werte angepasst werden. Die meisten Werte sind hier bereits vorhanden, allerdings auskommentiert. Auch hier entfernen wir die Raute (‚#‘) vor der entsprechenden Zeile.

  • tls-listening-port=5349
  • fingerprint
  • lt-cred-mech
  • use-auth-secret
  • static-auth-secret=<secret>
  • realm=meinedomain.de
  • total-quota=100
  • bps-capacity=0
  • stale-nonce=600
  • cert=/etc/letsencrypt/live/meinedomain.de/cert.pem
  • pkey=/etc/letsencrypt/live/meindomain.de/privkey.pem
  • cipher-list=“ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384″
  • no-loopback-peers
  • no-multicast-peers
  • dh-file=/etc/nginx/ssl/dhparams.pem
  • no-tlsv1
  • no-tlsv1_1
  • no-stdout-log

Zu den angegebenen Werten hier noch ein paar Erklärungen:

  • tls-listening-port: Hier verwende ich den Standard-Port für TLS-Verbindungen zu coturn (5349). Hier könnte man auch einen anderen Port angeben. Diesen sollte man sich merken, da man diesen nachher in der Firewall freischalten muss.
  • static-auth-secret: Dies ist ein Passwort, welches zur Nutzung des TURN-Servers benötigt wird. Dies ist ein Sicherheitsmerkmal, so dass kein Dritter ohne Kenntnis dieses Passwortes den TURN-Server verwenden kann. Dieses Passwort muss man sich nicht merken und wird später nur in den Nextcloud-Einstellungen hinterlegt, daher lässt man sich dies am besten einfach durch folgenden Befehl generieren: openssl rand -hex 32
  • cert/pkey/dh-file: Dies sind die SSL-Zertifikate bzw. Diffie-Hellman-Parameter, die für die verschlüsselte Verbindung über TLS benötigt werden. Hierzu verwenden wir einfach die bereits vorhandenen Zertifikate für die eigene Domain (siehe hier und hier).
  • cipher-list: Legt die Cipher-Suite für die TLS-Verbindung zum TURN-Server fest. Hier kann die Cipher-Suite angegeben werden, die auch schon der Webserver nginx verwendet (hier heißt die Variable ssl_ciphers, siehe hier).

Nach der Anpassung der Konfiguration von coturn wird das Programm neu gestartet, damit die Änderungen übernommen werden.

service coturn restart

Portfreigaben einrichten

Nach der Einrichtung des TURN-Servers muss nun noch eine Portfreigabe eingerichtet werden, damit coturn auch „von außen“ erreichbar ist.

Wichtig ist hier der Port, der bei der Variable tls-listening-port in der coturn-Konfiguration angegeben wurde. In diesem Beispiel verwende ich dazu den Standard-Port 5349.

Zunächst muss hier eine entsprechende Portweiterleitung im Router eingerichtet werden. Das genaue Vorgehen unterscheidet sich hier von Router zu Router, daher kann an dieser Stelle keine detaillierte Anleitung erfolgen. Hier sollte man aber alle notwendigen Informationen auf den Hersteller-Seiten finden (so z.B. auf den AVM Hilfeseiten, wenn man eine FritzBox im Einsatz hat). Wichtig ist hier, dass die Freigabe für die beiden Protokolle TCP und UDP angelegt werden. Dazu ist meistens das Anlegen von zwei Freigaben notwendig, hier am Beispiel einer FritzBox:

Portfreigaben für cotun (FritzBox)

Portfreigaben für cotun (FritzBox)

Wenn darüber hinaus auch noch eine Firewall auf dem System installiert ist, auf dem coturn eingerichtet wurde, so muss auch hier eine Freigabe erfolgen. Auf vielen Systemen wird wohl ufw (uncomplicated firewall) eingerichtet sein. Hier erfolgt die Freigabe dann über folgende Befehle:

ufw allow 5349/tcp
ufw allow 5349/udp

Nextcloud Talk mit eigenem STUN/TURN-Server

Nun kann Nextcloud Talk mit dem eigenen STUN bzw. TURN-Server betrieben werden.

Zunächst muss – falls noch nicht geschehen – die App Talk aus dem Nextcloud App Store heruntergeladen werden. Diese befindet sich in der Kategorie Kommunikation.

Talk im Nextcloud App Store

Talk im Nextcloud App Store

Nach der Installation der App muss diese noch konfiguriert werden, damit diese coturn als STUN bzw. TURN-Server nutzt. Die dazugehörigen Optionen findet man in den Admin-Einstellungen von Nextcloud unter dem Punkt Talk.

Nextcloud Talk: Einstellungen für eigenen STUN/TURN-Server

Nextcloud Talk: Einstellungen für eigenen STUN/TURN-Server

Zunächst fügen wir mit der Plus-Schaltfläche einen zusätzlichen STUN-Server hinzu:

meinedomain.de:5349

Die Einstellungen für den TURN-Server sehen dann folgendermaßen aus:

  • URI: meinedomain.de:5349: Der Port wurde zuvor in der coturn-Konfiguration (tls-listening-port) hinterlegt.
  • Gemeinsames Geheimnis: Hier muss das Passwort angegeben werden, welches bei der Konfiguration von coturn als Variable static-auth-secret hinterlegt wurde.
  • UDP und TCP: Nextcloud Talk soll hier für maximale Kompatibilität sowohl TCP- als auch UDP-Verbindungen nutzen.

Unter Signalisierungsserver sind keine Eingaben notwendig.

Die Konfiguration kann nun ganz einfach mit der entsprechenden Schaltfläche getestet werden (siehe Pfeil oberes Bild). Hier sollte dann nach einem kurzen Augenblick auch eine Erfolgsmeldung erscheinen:

TURN-Server ist richtig konfiguriert

TURN-Server ist richtig konfiguriert

Chats und (Video-)Telefonie über die eigene Nextcloud

Ab sofort können über Nextcloud Talk Chats, Telefonate und auch Video-Telefonate geführt werden. Dies ist auf den verschiedensten Endgeräten möglich: Zum einen kann Nextcloud Talk ganz einfach im Browser verwendet werden. Dazu in der oberen Menüleiste einfach auf das Talk-Symbol klicken. Nun noch den passenden (Nextcloud-)Kontakt auswählen und schon kann es losgehen.

Nextcloud Talk in Aktion

Nextcloud Talk in Aktion

Richtig interessant wird die Sache allerdings mit mobilen Geräten, wie z.B. Smartphones. Hier stehen App sowohl für iOS, als auch für Android bereit:

Nextcloud Talk (Kostenlos, Google Play) →

‎Nextcloud Talk (Kostenlos, App Store) →

Der Funktionstest des eigenen TURN-Servers erfolgt am besten mit einem Smartphone: Wenn dieses nicht mit dem Heimnetzwerk, sondern mit dem Mobilfunknetz verbunden ist, sollten sowohl Chats, auch als (Video-)Telefonate mit einem Gerät im Heimnetzwerk problemlos möglich sein.

Troubleshooting

Falls Probleme mit Nextcloud Talk auftreten, sollte zunächst einmal die grundsätzliche Konfiguration durch die entsprechende Schaltfläche in den Admin-Einstellungen zu Talk überprüft werden (siehe Screenshot weiter oben). Anschließend kann es auch sinnvoll sein, die Nextcloud-Logs zu überprüfen. Diese findet man in der Admin-Oberfläche von Nextcloud unter dem Punkt Protokollierung.

Wenn im Nextcloud-Log keine Einträge vorhanden sind, die sich mit Talk in Verbindung bringen lassen, sollte die Funktion von coturn überprüft werden. Die Log-Dateien von coturn befinden sich im Verzeichnis /var/log. Die gesuchten Log-Dateien beginnen alle mit turn_ und beinhalten eine Datumsangabe im Dateinamen, z.B. turn_1352_2018-11-08.log. In diesen Log-Dateien sollte dann zumindest ein Hinweis zu finden sein, warum es zu Problemen gekommen ist.

Fazit

Im Heim-Bereich funktioniert Nextcloud Talk leider nicht immer out-of-the-box – mit dem Aktivieren der App ist es hier meistens nicht getan. Allerdings kann mit coturn recht einfach ein eigener STUN/TURN-Server in Betrieb genommen werden. Der entsprechende Konfigurations-Aufwand hält sich hierfür auch in Grenzen.

Mit Hilfe des eigenen TURN-Servers ist es nun aber möglich, über die eigene Cloud Chats und (Video-)Telefonate zu führen. Dieses Konzept ist im Vergleich zu den bekannten Apps (wie z.B. WhatsApp) besonders interessant, da die Kommunikation ausschließlich verschlüsselt über die persönliche Cloud abläuft, ohne dass hier Konzerne wie Google oder Facebook „mitlesen“ können.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-talk-mit-eigenem-turn-server-coturn/feed/ 82
Nextcloud: Online-Office mit ONLYOFFICE (mit eigener Subdomain) https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice-mit-eigener-subdomain/ https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice-mit-eigener-subdomain/#comments Fri, 09 Nov 2018 15:06:37 +0000 https://decatec.de/?p=4850 Nextcloud OnlyOffice Logo

Nextcloud bietet neben dem Speichern von Dateien auch noch erweiterte Funktionen wie z.B. die Verwaltung von Kontakten und Kalendern. Ebenso sind Online-Office-Funktionalitäten mit der eigenen Cloud-Lösung möglich: Hier gibt es die Alternativen ONLYOFFICE und Collabora. Für welche Lösung man sich hier entscheidet, ist zunächst einmal Geschmackssache.

Zum Thema ONLYOFFICE gab es bereits einen Artikel in diesem Blog. Die hier gezeigte Lösung hatte allerdings einen entscheidenden Nachteil: Die Office-Funktionalitäten waren nur verfügbar, wenn man über das lokale Netzwerk (LAN) auf die eigene Cloud zugegriffen hat. Das Bearbeiten von Dokumenten über das Internet war auf diese Art und Weise nicht möglich, da beim Bearbeiten von Dokumenten immer direkt auf die IP zugegriffen wurde, auf der ONLYOFFICE installiert wurde. Diese LAN-IP war über das Internet natürlich nicht erreichbar.

In diesem Artikel soll es daher wieder mal um die Einrichtung von ONLYOFFICE mittels Docker unter Nextcloud gehen. Dieses Mal sollen jedoch keine Einschränkungen für die Benutzung des Online-Office gelten: Somit ist dann der Zugriff sowohl über das lokale Netzwerk, also auch über das Internet möglich.

Als Grundlage dient wie immer der Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban.

Update-Historie (letztes Update 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
  • 07.12.2019:
    • Troubleshooting: Hinweise bzgl. X-Frame-Options hinzugefügt.
  • 05.09.2019:
    • Hinweise hinzugefügt, falls acme.sh statt Certbot verwendet wird.
  • 23.12.2018:
    • Zeilenangaben für das Übertragen der SSL-Einstellungen in die ssl.conf hinzugefügt.
  • 19.12.2018:
    • Die SSL-Konfiguration wird nun in das Verzeichnis /etc/nginx/snippets/ssl.conf ausgelagert, ansonsten kam es z.T. zu Problemen mit den Setzen der HTTP-Header.
  • 12.11.2018:
    • Die SSL-Konfiguration wird nun unter /etc/nginx/conf.d/ssl.conf gespeichert/ausgelagert.

 

Zweite (Sub-)Domain für ONLYOFFICE

Ich gehe in diesem Artikel davon aus, dass der eigene Server, auf dem Nextcloud bereits läuft, über die DynDNS-Domain meindomain.de erreichbar ist. DynDNS sorgt hier dafür, dass die öffentliche IP-Adresse des Routers auf eine Domain gemappt wird. Im Router wird die Domain dazu in den DynDNS-Einstellungen hinterlegt. Leider unterscheidet sich das Vorgehen von Router zu Router, daher würde eine detaillierte Anleitung für verschiedene Router-Modelle dem Umfang des Artikels sprengen.

Voraussetzung für ONLYOFFICE ist nun eine zweite (Sub-)Domain, über die der Dokumenten-Server später erreichbar sein wird. Als Beispiel nehme ich hier einfach die Domain onlyoffice.meinedomain.de. Diese zweite Domain muss dabei ebenfalls auf die öffentliche IP-Adresse des Routers „zeigen“, ist sozusagen auch eine zweite (oder besser gesagt alternative) DynDNS-Domain.

Mehrere DynDNS-Domains mittels CNAME

Und genau das ist hier das Problem. In fast allen Router-Modellen kann nur ein DynDNS-Anschluss mit nur einer Domain festgelegt werden. Die Lösung für dieses Problem stellt ein sog. CNAME-Eintrag für eine zweite (Sub-)Domain dar. Mittels CNAME wird einfach ausgedrückt ein alternativer Name für eine Domain hinterlegt: Der CNAME-Eintrag der Office-Domain muss daher die bereits vorhandene DynDNS-Domain sein.

Wo kann man diesen CNAME-Eintrag nun hinterlegen? Dies passiert normalerweise in der Domain-Verwaltung des Webspace-Providers. Auch hier unterscheidet sich das Vorgehen von Anbieter zu Anbieter, gute Erfahrungen konnte ich hier allerdings mit All-Inkl.com (Affiliate-Link) machen.

Hier loggt man sich zunächst im Kundenportal (KAS) ein und legt eine neue Subdomain an. Dazu findet man im Menü den Eintrag Subdomain. Über den Punkt Neue Subdomain anlegen kann hier eine neue Subdomain beantragt werden. Hier kann man alle Einstellungen einfach übernehmen, da diese Domain später nicht auf den Webspace, sondern die öffentliche IP-Adresse des eigenen Routers zeigen wird.

All-Inkl.com: Neue Subdomain anlegen

All-Inkl.com: Neue Subdomain anlegen

Um nun noch den CNAME-Eintrag für die neue Subdomain hinzuzufügen, muss man die Domain-Einstellungen unter Tools > DNS-Einstellungen bearbeiten. Hier sieht man dann die eigene Domain, über die auch der DynDNS-Anschluss läuft (meinedomain.de). Mit einem Klick auf Bearbeiten kann diese Domain modifiziert werden. Hier klickt man dann auf den Punkt neuen DNS Eintrag erstellen. Folgende Einstellungen sind hier vorzunehmen:

  • Name: Der Name der Subdomain (hier also onlyoffice.meinedomain.de).
  • Typ/Prio.: CNAME
  • Data: Hier wird die eigentliche DynDNS-Domain eingetragen (also meinedomain.de).
All-Inkl.com: CNAME-Eintrag für Subdomain erstellen

All-Inkl.com: CNAME-Eintrag für Subdomain erstellen

Nach einem Klick auf Speichern werden die Änderungen übernommen.

SSL-Zertifikat für die neue Domain hinzufügen

Damit die Verbindung zu ONLYOFFICE stets verschlüsselt, also über HTTPS abläuft, muss für die neue Subdomain noch ein SSL-Zertifikat über Let’s Encrypt erzeugt werden. Dazu wird das bereits für Nextcloud verwendete Zertifikat modifiziert, indem wir dieses Zertifikat um eine weitere (Sub-)Domain erweitern. Hierfür sind keine Änderungen an den virtuellen Hosts von nginx erforderlich. Ebenfalls müssen bereits vorhandene Diffie-Hellman-Parameter (siehe Beschreibung) nicht neu erzeugt werden und können aus der bestehenden Installation übernommen werden.

Certbot

Wenn für die Generierung der Zertifikate Certbot zum Einsatz kommt, dann reicht hier folgender Befehl auf der Kommandozeile, um neue Zertifikate für beide (Sub-)Domains auszustellen:

certbot certonly --webroot -w /var/www/letsencrypt -d meinedomain.de -d onlyoffice.meinedomain.de --rsa-key-size 4096

Wichtig ist hier die Angabe aller (Sub-)Domains mit dem Parameter -d. Nach diesem Befehl werden die Zertifikats-Dateien unter /etc/letsencrypt/live/meinedaomin.de erneuert. Nicht wundern, hier wird nicht für jede (Sub-)Domain ein Zertifikat erzeugt, sondern nur ein Zertifikat, welches für mehrere Domains ausgestellt ist.

acme.sh

Falls acme.sh für die Generierung der Zertifikate verwendet wird, sollten zunächst die Grundlagen zu acme.sh aus dem Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx entnommen werden.

Der konkrete Befehl zum Erzeuigen der Zertifikate sieht in diesem Fall dann so aus:

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

Hier werden dann ebenfalls alle (Sub-)Domains mittels des Parameters -d angegeben und in einem einzigen Zertifikat „verpackt“.

Auslagern der SSL-Einstellungen aus dem virtuellen Host für Nextcloud

Für die neue Domain muss nun natürlich ein neuer virtueller Host angelegt werden. Dieser zielt wieder auf SSL ab, daher sind hier auch sämtliche SSL-Einstellungen wie ssl_certificate, ssl_protocols, ssl_ciphers, etc. notwendig. Damit wir diese nicht doppelt pflegen müssen (im Gateway-Host und im virtuellen Host für ONLYOFFICE), lagern wir diese Anweisungen für SSL einfach aus.

Vorher sollten alle virtuellen Hosts gesichert werden, falls beim Umzug etwas schief gehen sollte.

Dazu erstellen wir zunächst einen neuen Ordner, in dem die SSL-Einstellungen gespeichert werden sollen:

mkdir /etc/nginx/snippets

In diesem Ordner erstellen wir anschließend eine neue Datei speziell für allgemeine SSL-Einstellungen, die für alle (Sub-)Domains gelten sollen.

Hinweis: Diese ausgelagerten Einstellungen dürfen nicht im selben Ordner wie die restlichen vHosts (/etc/nginx/conf.d) gespeichert werden, da es ansonsten Probleme mit dem Setzen der HTTP-Header gibt.

In diese Datei werden nun die Anweisungen übernommen, die für die SSL- und Header-Einstellungen zuständig sind. In diesem konkreten Beispiel (siehe hier) sind die Zeilen 32-95 im Gateway-Host betroffen. Dieser Block wird nun aus dem Gateway-Host kopiert und in die ssl.conf eingefügt.

nano /etc/nginx/snippets/ssl.conf

In diesem Beispiel sind es die folgenden Inhalte.

# Certificates used
ssl_certificate /etc/letsencrypt/live/meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/meinedomain.de/privkey.pem;

# Not using TLSv1 will break:
#	Android <= 4.4.40
#	IE <= 10
#	IE mobile <=10
# Removing TLSv1.1 breaks nothing else!
# TLSv1.3 is not supported by most clients, but it should be enabled.
ssl_protocols TLSv1.2 TLSv1.3;

# Cipher suite from https://cipherli.st/
# Max. security, but lower compatibility 
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';

# Cipher suite from https://wiki.mozilla.org/Security/Server_Side_TLS
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# (Modern) cipher suite from https://mozilla.github.io/server-side-tls/ssl-config-generator/
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

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

# Use multiple curves.
# secp521r1: Not supported by Chrome
# secp384r1: Not supported by Android (DAVdroid)
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;

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

# OCSP Stapling
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# This should be chain.pem
# See here: https://certbot.eff.org/docs/using.html
ssl_trusted_certificate /etc/letsencrypt/live/meinedomain.de/chain.pem;

resolver 192.168.178.1;

# SSL session handling
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

#
# Add headers to serve security related headers
#  
# 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;";
add_header X-Content-Type-Options "nosniff";	
add_header Referrer-Policy "no-referrer";	
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;

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

Im nächsten Schritt werden nun diese SSL-Einstellungen aus dem Gateway-Host entfernt. Beispielweise also wieder die Zeilen 32-95. Damit die SSL-Einstellungen nun auch für den Gateway-Host gelten, wird nun statt dem entfernten Block einfach folgende Zeile mit übernommen:

include /etc/nginx/snippets/ssl.conf;

Wichtig ist hier v.a., dass die Anweisungen nicht doppelt aufgeführt sind (einmal im Gateway-Host direkt und einmal durch den Include). Daher müsen die eigentlichen SSL-Anweisungen auch aus dem Gateway-Host entfernt werden.

Anschließend starten wir den Webserver neu:

service nginx restart

Nun sollte man zunächst einmal testen, ob alle vorhandenen Web-Anwendungen (wie z.B. Nextcloud) noch wie erwartet funktionieren. Erst wenn diese Überprüfung erfolgreich war, sollte man hier weitermachen.

Virtuellen Host für ONLYOFFICE hinzufügen

Alles funktioniert noch? Gut! Dann weiter…

Im nächsten Schritt wird für die neue Subdomain ein eigener vHost hinzugefügt:

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

Der Inhalt ist hier recht übersichtlich:

server {
        listen 443 ssl http2;
        server_name onlyoffice.meinedomain.de;

        # Include SSL configuration
        include /etc/nginx/snippets/ssl.conf;

        #
        # Configuration for OnlyOffice
        #
        location / {
                proxy_pass https://192.168.178.60:4433;
                proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-Proto $scheme;
        }
}

Die SSL-Einstellungen haben wird ja zuvor ausgelagert, so dass diese nun in diesem zweiten vHost einfach wiederverwendet werden können.

Wichtig bei der Angabe des proxy_pass:

  • Für die Verbindung zur Maschine, auf der später ONLYOFFICE laufen wird, nutzen wir ebenfalls HTTPS. Wenn dies der gleiche Rechner ist, auf dem auch Nextcloud schon läuft, könnte man hier auch einfach auf HTTP setzen, da die Kommunikation dann nur Rechner-intern abläuft (dazu später mehr).
  • Die IP ist hier die lokale IP-Adresse des Rechners, auf dem ONLYOFFICE später laufen wird. Dies kann also die IP der Maschine sein, auf der auch der Webserver (und z.B. Nextcloud) läuft, oder auch eine andere Maschine im LAN.
  • Als Port habe ich hier 4433 angegeben. Dies ist besonders wichtig, wenn ONLYOFFICE auf dem gleichen Rechner installiert wird, auf dem auch der Webserver/Nextcloud läuft. Der Standard-Port für HTTPS 443 wäre hier schon (durch den Gateway-Host) belegt, also muss man auf einen anderen Port ausweichen.

Installation und Einrichtung ONLYOFFICE

Nachdem nun sämtliche Voraussetzungen erfüllt sind, kann es an die Installation von ONLYOFFICE gehen. Ich bevorzuge hier den Weg über Docker, da eine komplett manuelle Installation sehr aufwendig ist. Hier ist es auch egal, auf welcher Maschine ONLYOFFICE installiert wird. Entweder man installiert das Online-Office direkt auf dem Rechner, auf dem auch Nextcloud bereits läuft, oder man nimmt eine zweite Maschine (oder VM), auf der dann nur ONLYOFFICE betrieben wird.

Docker sollte auf jeden Fall bereits installiert sein. Fall nicht, sollte dieser Schritt wie im Artikel Docker auf Ubuntu Server nun nachgeholt werden.

Alle folgenden Schritte müssen auf der Maschine ausgeführt werden, auf der ONLYOFFICE installiert werden soll.

Vorbereitungen für die Installation

Die Verbindung zu ONLYOFFICE sollte aus Sicherheitsgründen immer verschlüsselt, also über HTTPS ablaufen. Durch den vHost für ONLYOFFICE ist die Verbindung über das Internet auch bereits verschlüsselt. Bleibt nur der Verbindungsweg vom Webserver auf die Maschine, auf der das Online-Office später laufen wird (also die Verbindung im lokalen Netzwerk). Diese Verbindung sollte ebenfalls verschlüsselt werden, damit auch LAN-intern stets sichere Verbindungen aufgebaut wird.

Wenn ONLYOFFICE auf dem gleichen Rechner gehostet wird, auf dem schon Nextcloud und der Webserver laufen, ist dieser Schritt eigentlich optional, da hier nur eine Rechner-interne Verbindung zustande kommt. Trotzdem empfehle ich diese Schritte auszuführen, besonders wenn die Office-Lösung und der Webserver/Nextcloud auf unterschiedlichen Maschinen installiert werden.

Da wir hier ja nur mit einer IP-Adresse arbeiten (die beim proxy_pass angegeben wird), können wir hierfür kein Let’s Encrypt Zertifikat erstellen, da diese Zertifikate nicht auf IP-Adressen, sondern nur auf Domains ausgestellt werden können. Daher greifen wir hier auf ein selbst signiertes Zertifikat zurück.

Dieses wird mit folgenden Befehlen erzeugt:

mkdir -p /app/onlyoffice/DocumentServer/data/certs
cd /app/onlyoffice/DocumentServer/data/certs
openssl genrsa -out onlyoffice.key 4096
openssl req -new -key onlyoffice.key -out onlyoffice.csr
openssl x509 -req -days 3650 -in onlyoffice.csr -signkey onlyoffice.key -out onlyoffice.crt
openssl dhparam -out dhparam.pem 4096
chmod 400 onlyoffice.key
chmod 400 onlyoffice.crt
chmod 400 onlyoffice.csr
chmod 400 dhparam.pem

  • Beim Befehl openssl req -new -key onlyoffice.key -out onlyoffice.csr wird man nach dem „Common Name“ gefragt (Common Name (e.g. server FQDN or YOUR name)). Hier ist einfach die IP des lokalen Systems anzugeben (in diesem Fall 192.168.178.60). Ebenso kann man ein „challenge password“ angeben. Dieses kann man einfach leer lassen (einfach mit Enter bestätigen).
  • Achtung: Die Erzeugung der sog. Diffie-Hellmann-Parameter mit einer Länge von 4096 Bit (openssl dhparam -out dhparam.pem 4096) kann u.U. sehr lange dauern. Auf schwacher Hardware kann das schon einmal mehrere Stunden in Anspruch nehmen. Wer nicht so lange warten möchte, kann die Schlüssel-Länge auf 2048 Bit reduzieren (openssl dhparam -out dhparam.pem 2048).
  • Das Zertifikat hat eine Gültigkeit von 3650 Tagen (10 Jahre). Hier kann bei Bedarf auch eine andere Gültigkeitsdauer angegeben werden.

Installation ONLYOFFICE

Die Installation beschränkt sich dann dank Docker auf einen einzigen Befehl:

docker run --name=ONLYOFFICEDOCKER -i -t -d -p 4433:443 -e JWT_ENABLED='true' -e JWT_SECRET='geheimes-secret' --restart=always -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver

Hier gilt es folgende Punkte zu beachten:

  • Den Container nennen wir hier ONLYOFFICEDOCKER, damit dieser später über diesen Namen und nicht über eine kryptische ID angesprochen werden kann.
  • Da bereits der Webserver auf Port 443 lauscht (wenn ONLYOFFICE auf dem gleichen Rechner gestartet wird), müssen wird hier auf einen alternativen Port ausweichen. Der Parameter -p 4433:443 sorgt hier dafür, dass der Port 4433 des Docker-Hosts auf den Port 443 innerhalb des Docker-Containers gemappt wird. Wichtig ist hier, dass dieser Port (4433) mit demjenigen übereinstimmt, der beim proxy_pass im vHost für ONLYOFFICE angegeben wurde.
  • Die nächsten zwei Parameter (-e JWT_ENABLED=’true‘ -e JWT_SECRET=’geheimes-secret‘) erhöhen die Sicherheit, da zur Kommunikation mit dem Container ein sog. JSON Web Token benötigt wird. Im Grunde genommen handelt es sich dabei um ein Passwort (geheimes-secrethier sollte man natürlich ein eigenes Passwort wählen), welches später in Nextcloud hinterlegt werden muss, damit die Verbindung zu ONLYOFFICE aufgebaut werden kann. Dies verhindert, dass der ONLYOFFICE-Container „unbemerkt“ von anderen Verbindungen genutzt werden kann.
  • Mit —restart=always wird der Container bei jedem Systemstart automatisch gestartet.
  • Mit dem letzten Parameter (-v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver) wird ein sog. Volume definiert: Alle Dateien, die im Verzeichnis /app/onlyoffice/DocumentServer/data des Hosts liegen, werden innerhalb des Containers im Verzeichnis /var/www/onlyoffice/Data onlyoffice/documentserver bereitgestellt. Diese Funktion wird benötigt, damit der Container das zuvor erzeugte Zertifikat finden und nutzen kann.

Nun wird das entsprechende Docker-Image heruntergeladen und auch gleich gestartet.

Installation von ONLYOFFICE mittels Docker

Installation von ONLYOFFICE mittels Docker

Nach dem Starten des Containers läuft ONLYOFFICE bereits. Wenn man nun im Browser die Domain onlyoffice.meinedomain.de oder die IP-Adresse der jeweiligen Maschine (dann aber mit dem alternativen Port 4433) aufruft, sollte folgende Seite erscheinen:

ONLYOFFICE läuft

ONLYOFFICE läuft

Einbinden von ONLYOFFICE in Nextcloud

Nachdem ONLYOFFICE läuft, geht es nun mit der eigenen Nextcloud weiter, damit hier Online-Office-Funktionalitäten hinzugefügt werden können.

Die passende App findet man dabei im Nextcloud App Store in der Kategorie Büro & Text:

ONLYOFFICE im Nextcloud App-Store

ONLYOFFICE im Nextcloud App-Store

Wenn die App aktiviert wurde, können die Einstellungen nun in der Admin-Oberfläche von Nextcloud unter dem Punkt ONLYOFFICE angepasst werden (damit alle Einstellungen angezeigt werden, muss man auf den Punkt Erweiterte Servereinstellungen klicken).

Nextcloud: ONLYOFFICE-Einstellungen in der Admin-Oberfläche

Nextcloud: ONLYOFFICE-Einstellungen in der Admin-Oberfläche

  • Serviceadresse der Dokumentbearbeitung: Hier wird die Subdomain angegeben, die wir extra für ONLYOFFICE angelegt habe, in diesem Beispiel also https://onlyoffice.meinedomain.de.
  • Geheimer Schlüssel (freilassen, um zu deaktivieren): Hier ist das JWT-Token anzugeben, welches beim Starten des Docker-Containers angegeben wurde (geheimes-secret).
  • Alle anderen Felder kann man leer lassen.

Nach einem Klick auf Speichern sollte eine Meldung erscheinen, dass die Einstellungen erfolgreich übernommen wurden.

Anschließend können Office-Dokumente ganz einfach direkt in der Cloud bearbeitet werden:

Online-Office mit Nextcloud und ONLYOFFICE

Online-Office mit Nextcloud und ONLYOFFICE

Update von ONLYOFFICE

Von Zeit zu Zeit erscheint ein neues Docker-Image für ONLYOFFICE. Leider ist es etwas umständlich herauszufinden, welche Version gerade installiert ist und ob es eine neue Container-Version gibt.

Um zu ermitteln, welche Version aktuell installiert ist, öffnet man am besten ein beliebiges Office-Dokument. Mit der Info-Schaltfläche wird die installierte Version von ONLYOFFICE angezeigt:

Über die Info-Schaltfläche kann die installierte Version ermittelt werden

Über die Info-Schaltfläche kann die installierte Version ermittelt werden

Die Version des aktuellsten Images kann nun über Docker Hub (eine Art Suche für Docker-Images) ermittelt werden. Dazu sucht man einfach nach onlyoffice und lässt sich dann die Tags anzeigen. Schneller geht es über diesen Direktlink. Hier werden dann alle Versionen des Images angezeigt:

Die aktuelle Version im Docker Hub

Die aktuelle Version im Docker Hub

Zwar werden in der ONLYOFFICE-Hilfe nur drei Versionsnummern angezeigt, allerdings sollte man auch anhand des Datums sehen können, wenn eine neue Version des Containers bereitsteht.

Das Update selbst kann man dann in wenigen Schritten durchführen:

Zunächst wird der aktuelle Container gestoppt und entfernt:

docker stop ONLYOFFICEDOCKER
docker rm ONLYOFFICEDOCKER

ONLYOFFICEDOCKER ist hier der Name des Containers, den wir beim ersten Start angegeben haben. Hier könnte man auch die ID des Containers angeben (kann man mit docker ps ermitteln).

Optional: Bei der Arbeit mit Docker bleiben oft Reste auf dem System zurück (z.B. alte, ungenutzte Container). Gerade wenn auf dem System ausschließlich ONLYOFFICE per Docker betrieben wird, empfiehlt es sich, das komplette Docker-System zu bereinigen. Dazu werden einfach folgende Befehle ausgeführt:

docker system prune -a
docker image prune -a
docker container prune

Anschließend wird die neuste Version des Containers heruntergeladen und über den bekannten Befehl gestartet:

docker pull onlyoffice/documentserver
docker run --name=ONLYOFFICEDOCKER -i -t -d -p 4433:443 -e JWT_ENABLED='true' -e JWT_SECRET='geheimes-secret' --restart=always -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver

Beim zweiten Befehl ist hier nur wichtig, dass genau das gleiche JWT_SECRET wie schon beim Start des Containers angegeben wird, ansonsten kann nach dem Update keine Verbindung mehr von Nextcloud hergestellt werden.

Troubleshooting

Generelle Fehlersuche

Manchmal kann es vorkommen, dass ONLYOFFICE nicht wie erwartet funktioniert. Bei dem System sind ziemlich viele Komponenten beteiligt (Webserver, Nextcloud, Docker-Container), so dass man zunächst einmal das Problem eingrenzen sollte.

Zunächst sollte immer erst die Subdomain für ONLYOFFICE aufgerufen werden: onlyoffice.meinedomain.de

Erscheint hier nicht die Übersichtsseite von ONLYOFFICE, dann tritt das Problem wohl auf dem Verbindungsweg vom Internet zum Webserver auf. Dann sollten zunächst einmal die Logs des Webservers kontrolliert werden (auf der Maschine, wo der Gateway-Host zu finden ist und auch Nextcloud installiert ist).

nano /var/log/nginx/error.log

Hier sollten dann Fehlermeldungen zu finden sein, mit den man das Problem weiter eingrenzen kann.

Wenn die Seite erreichbar ist, aber ONLYOFFICE trotzdem nicht funktioniert, sollte in diesem Fall zunächst einmal das Nextcloud-Log überprüft werden (in der Admin-Oberfläche von Nextcloud unter Protokollierung).

Falls hier auch nichts auffälliges zu sehen ist, sollten die Logs des Docker-Containers überprüft werden:

docker logs ONLYOFFICEDOCKER

Hier sind dann u.U. Hinweise zu finden, dass ein benötigter Dienst nicht gestartet werden konnte. In diesem Fall hilft es meistens, den Rechner, auf dem ONLYOFFICE läuft, einfach mal neu zu starten.

Erst wenn dies auch zu keinen neuen Erkenntnissen führt, kann man sich auch auf die Kommandozeile des Containers selbst einloggen. Dazu einfach auf der Docker-Maschine folgenden Befehl ausführen:

sudo docker exec -it ONLYOFFICEDOCKER bash

Auf der Kommandozeile des Containers kann dann eine detaillierte Fehlersuche stattfinden. Mit folgendem Befehl kann man beispielsweise die Webserver-Logs einzusehen:

nano /var/log/nginx/error.log

Um die Kommandozeile des Containers wieder zu verlassen, reicht folgender Befehl:

exit

Spezifische Fehler

Das Öffnen eines Dokuments resultiert in einem leeren Browser-Fenster, obwohl der Document Server läuft

Dieser Fehler äußert sich meist so, dass der Document Server anscheinend ordnungsgemäß gestartet wurde und der Aufruf der OnlyOffice-Domain im Browser (https://onlyoffice.meinedomain.de) eine entsprechende Meldung anzeigt.
Allerdings können in Nextcloud keine Dokumente geöffnet werden – das Browser-Fenster bleibt einfach leer.

Hier werfen wir zunächst einen Blick in die Developer-Konsole des Browsers (F12). Hier wird vermutlich eine Fehlermeldung angezeigt, die auf ein Problem mit den „X-Frame-Options“ hinweist:

Laden verboten durch X-Frame-Options: „SAMEORIGIN“ von „https://onlyoffice.meinedomain.de/5.4.2-46//web-apps/apps/…46&lang=de-DE&customer=ONLYOFFICE&frameEditorId=iframeEditor“, Website erlaubt keine quellübergreifende (cross-origin) Frames von „https://meinedomain.de/nextcloud/apps/onlyoffice/169?filePath=test.ods“

Die Ursache ist dabei, dass der Header X-Frame-Options beim Aufruf der OnlyOffice-Domain gesetzt wurde. Dieser darf für den virtuellen Host, der für die OnlyOffice-Domain zuständig ist, nicht gesetzt werden.

Die Lösung besteht nun dain, die Stelle zu finden, an der dieser Header für die OnlyOffice-Domain gesetzt wird. Dazu durchsucht man den vHost für OnlyOffice und alle inkludierte Konfigurationen. Eine entsprechende Zeile kann dann beispielsweise folgendermaßen aussehen:

add_header X-Frame-Options "SAMEORIGIN" always;

Diese Anweisung ist dann für die OnlyOffice-Domain zu entfernen.

Nach den Änderungen und einem Neustart des Webservers kann es nun noch sein, dass der Browser-Cache einmal geleert werden muss. Anschließend sollten sich OnlyOffice-Dokumente über Nextcloud öffnen und bearbeiten lassen.

Fazit

Es sind schon einige Schritte notwendig, um ONLYOFFICE in Verbindung mit Nextcloud zum Laufen zu kriegen. Dennoch lohnt es sich, da man nun direkt in der eigenen Cloud ein Online-Office nutzen kann. Wer vorher beispielsweise Google Docs verwendet hat, wird sich auch bei ONLYOFFICE sehr schnell zurechtfinden – und das ohne die neugierigen Blicke von Google & Co, da alle Daten sicher in der eigenen Nextcloud gespeichert sind.

Weiterführende Artikel

Links

 

]]>
https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice-mit-eigener-subdomain/feed/ 180
Scanbot und Nextcloud zur Verwaltung digitaler Dokumente (mit OCR) https://decatec.de/home-server/scanbot-und-nextcloud-zur-verwaltung-digitaler-dokumente-mit-ocr/ https://decatec.de/home-server/scanbot-und-nextcloud-zur-verwaltung-digitaler-dokumente-mit-ocr/#comments Sun, 21 Oct 2018 11:57:30 +0000 https://decatec.de/?p=4719 Nextcloud Scanbot Logo

Wer eine persönliche Cloud mit Nextcloud betreibt, wird diese sicherlich schon für viele Dinge des digitalen Alltags nutzen: Das Speichern von Dateien, Kalendern und Kontakten sind sicherlich nur einige Anwendungsbeispiele.

Besonders interessant wird die Sache mit dem Verwalten (digitaler) Dokumente. In der heutigen Zeit hat man im Normalfall noch sehr viel „Papierkram“, den man meistens in Ordnern oder Schnellheftern ablegt. Diese verstauben dann meist in irgendeinem Schrank und wenn man die Dokumente dann doch mal braucht, muss man immer erst umständlich suchen.

Hier wäre es doch sicherlich eine Erleichterung, wenn man den ganzen Papierkram digitalisieren könnte und einfach in der eigenen Cloud speichern könnte – geschützt vor den neugierigen Blicken großer Cloud-Anbieter.

Scannen von Dokumenten mit dem Smartphone

Für den Prozess der Digitalisierung denkt man zunächst einmal an einen Scanner. Gute Erfahrungen konnte ich hier mit Multifunktionsgerät (MuFu) wie dem Brother MFC-9142 (Affiliate Link) sammeln: Hier können (auch mehrseitige) Dokumente gleich als PDF mit verschiedenen Optionen (z.B. Farbe/schwarz-weiß) gescannt werden. Es gibt hier auch eine Option zur automatischen Texterkennung (OCR), allerdings kann man als Zielformat dann kein PDF wählen. Wenn man also PDF-Dateien scannen will, muss die Texterkennung nachträglich erfolgen, wie beispielsweise im Artikel Linux: OCR-Texterkennung für PDF-Dateien und Bilder erklärt wird.

Aber es gibt noch eine andere Möglichkeit: Jedes Smartphone hat mittlerweile eine Kamera mit an Bord, mit der man natürlich auch Dokumente abfotografieren kann. Ein Foto ist für ein Dokument nicht unbedingt das richtige Format, daher sollte eine App diese Dokumente gleich als PDF speichern können. Als ich noch ein Windows-Phone hatte (ja, es gab mal Leute, die ein Windows-Phone gern genutzt haben!), fiel meine Wahl hier auf die App Office Lens. Damit bekam man schon recht beeindruckende Ergebnisse, was z.B. die automatische Perspektiven-Korrektur anging. OCR war auch möglich, allerdings gestaltete sich die Integration in ownCloud/Nextcloud etwas umständlich, da man alle Dokumente manuell hochladen musste.

Scanbot: App zum Scannen von Dokumenten

Unter Android bin ich dann auf Scanbot gestoßen: Eine App, die genau die Features bietet, die ich für meinen Workflow benötige:

  • Einfaches Scannen von Dokumenten mit der Smartphone-Kamera.
  • Automatische Korrektur (Perspektive/Farbwerte).
  • Speichern diese Dokumente als PDF.
  • Texterkennung (OCR) für gescannte Dokumente. Wichtig war mir hierbei, dass die Texterkennung nicht in „irgendeiner Cloud“ abläuft, sondern rein lokal auf dem Smartphone ausgeführt wird.
  • Automatisches Hochladen der gescannten Dokumente nach der Texterkennung.

Die App an sich kostet erst einmal nichts. Erst wenn man erweiterte Funktionen nutzen möchte (wie z.B. OCR), dann ist eine Lizenz für Scanbot Pro für ein paar Euro notwendig.

Mittlerweile nutze ich diese App recht häufig zum Scannen von Dokumenten mit anschließendem Upload in meine Nextcloud. Daher möchte ich euch hier zeigen, wie man Scanbot am besten einrichtet, um mit eurer persönlichen Cloud zusammen zu arbeiten.

Scanbot mit Nextcloud verbinden

Wenn ihr Scanbot in Verbindung mit eurer Nextcloud verwenden möchtet, dann muss in der App zunächst einmal die Verbindung zur eigenen Cloud hergestellt werden.

Dazu geht ihr zunächst in den Einstellungen. Hier findet ihr die Option für die Cloud Dienste.

Scanbot: Einstellungen

Scanbot: Einstellungen

Den prominenten Eintrag für Google Drive lassen wir hier natürlich erst einmal links liegen und konfigurieren uns unsere eigene Verbindung mittels Dienst hinzufügen:

Scanbot: Einstellungen - Cloud Dienste

Scanbot: Einstellungen – Cloud Dienste

Anschließend wählen wir WebDAV:

Scanbot: Einstellungen - Cloud Dienste - WebDAV

Scanbot: Einstellungen – Cloud Dienste – WebDAV

Hier werden nun die Zugangsdaten für Nextcloud eingegeben. Neben Benutzername und Passwort ist auch eine WebDAV-URL notwendig. Hier geben wir einfach die WebDAV-URL des Root-Verzeichnisses der Cloud mit folgendem Schema an:

https://meinedomain.de/nextcloud/remote.php/dav/files/<User>/

Wichtig an dieser Stelle ist der Slash (‚/‘) am Ende der URL.

Scanbot: WebDAV Einrichtung

Scanbot: WebDAV Einrichtung

Wenn die Verbindung mit Nextcloud hergestellt werden konnte, dann erscheint die neue Verbindung nun im unteren Bildschirmbereich unter Verfügbare Cloud Dienste.

Nun können gescannte Dokumente einfach über die Schaltfläche MEHR… an diesen Cloud Dienst übertragen werden. Vor dem Upload muss lediglich das Verzeichnis angegeben werden, in das die jeweiligen Dokumente hochgeladen werden sollen.

Automatischer Upload mit Scanbot

Richtig komfortabel wird die Sache nun durch einen automatischen Upload, so dass gescannte Dokumente automatisch in der eigenen Cloud landen.

Hierzu gehen wir wieder in die Einstellungen der App unter Cloud Dienste. Hier kann nun unter Automatischer Upload das automatische Hochladen aktiviert werden:

Scanbot: Automatischen Upload aktivieren

Scanbot: Automatischen Upload aktivieren

Im erscheinenden Popup-Menü wählen wir nun die soeben angelegte WebDAV-Verbindung (in diesem Beispiel Bob). Nun sollte eine Meldung erscheinen, dass die Verbindung mit WebDAV erfolgreich konfiguriert wurde. Durch Klick auf den Ordner kann nun ein Upload-Ordner gewählt werden, in den gescannte Dokumente automatisch hochgeladen werden sollen. in diesem Beispiel wähle ich den Ordner /AutoUpload/Scanbot (neue Ordner können auch einfach aus der App heraus angelegt werden).

Ebenso kann die Option aktiviert werden, dass bereits bestehende Scans hochgeladen werden sollen:

Scanbot: Upload-Optionen

Scanbot: Upload-Optionen

Mit dem konfigurierten automatischen Upload läuft nun direkt nach dem Scan die Texterkennung (nur Scanbot Pro) und das Dokument wird automatisch in das angegebene Nextcloud-Verzeichnis hochgeladen.

Verwaltung digitalisierter Dokumente in Nextcloud

OK, wir haben also ein (Papier-)Dokument digitalisiert und in die eigene Cloud hochgeladen. Dieses befindet sich nun in diesem Beispiel im Ordner AutoUpload/Scanbot und hat den Dateinamen, der in Scanbot vergeben wurde. Meist ist dies einfach Scan JJJJ-MM-TT hh.mm.ss.pdf. Die Vorlage für Dateinamen kann in Scanbot übrigens unter Einstellungen – Dateinamen Vorlage geändert werden – hier gibt es dann noch weitere Variablen wie z.B. Stadt, Straße, Postleitzahl, etc.

Gescanntes Dokument nach dem Upload zu Nextcloud

Gescanntes Dokument nach dem Upload zu Nextcloud

Dateinamen digitalisierter Dokumente

Als erstes sollte das Dokument nun umbenannt werden. Ich verwende hier folgendes Schema: JJJJMMTT – Inhalt. Wenn ich beispielsweise eine Rechnung für eine neu gekaufte Tastatur gescannt habe, bekommt das Dokument den Dateinamen 20181001 – Tastatur.pdf. Der Dateiname bezieht sich dabei nur auf den Inhalt des Dokuments und nicht auf den Dokumenttyp.

Ordnerstruktur für Dokumente

Den Dokumenttyp (z.B. Rechnung) verwalte ich dann über eine Ordnerstruktur. Bei vielen unterschiedlichen Dokumenten macht es hier Sinn, nicht alle Dokumente in nur einem Ordner zu speichern, sondern sich eine sinnvolle Ordnerstruktur zu überlegen. Damit kann dann eine gewisse Ordnung in die Dokumente gebracht werden. Diese Ordnerstruktur ist immer von den individuellen Bedürfnissen abhängig, daher kann hier keine konkrete Empfehlung gegeben werden.

Beispielhafte Ordnerstruktur für Dokumente in der Cloud

Beispielhafte Ordnerstruktur für Dokumente in der Cloud

Nach dem Umbenennen des Dokuments verschiebe ich es abschließend noch in den entsprechenden „Typ-Ordner“ im Dokumenten-Verzeichnis.

Dokumente mit Tags versehen

Eine Variante oder Erweiterung des Vorgehens wäre es nun noch, wenn man keine Ordnerstruktur verwendet, sondern alternativ (oder zusätzlich) die Dokumente mit den entsprechenden Tags (z.B. Rechnung) versieht. Nextcloud unterstützt das Taggen von Dateien (und Ordnern) mit dem Feature „Collaborative Tags“: Dazu einfach in den Details zu einer Datei unter Tags das gewünschte Tag eingeben.

Nextcloud: Zuweisen von Tags zu Dokumenten

Nextcloud: Zuweisen von Tags zu Dokumenten

Als Erweiterung dazu gibt es im Nextcloud App Store noch die App Files automated tagging: Hiermit können Tags automatisch nach bestimmten Regeln vergeben werden. Im Nextcloud Administration Manual findet man hierzu einige Beispiele.

Dokumente mit der Volltextsuche finden

Den größten Vorteil bei digitalisierten Dokumenten bietet allerdings die Volltextsuche. Da bei Scanbot Pro bereits auf dem Smartphone eine Texterkennung gelaufen ist, kann man nun das Dokument und die entsprechenden Inhalte ganz einfach in der Cloud wiederfinden. Alles was wir dafür benötigen, liefert die Nextcloud-App Full Text Search: Mit der Volltextsuche für Nextcloud kann man ganz einfach nach Dateien oder Datei-Inhalten suchen, wie im Artikel Volltextsuche in Nextcloud (mit OCR) beschrieben.

Dank Texterkennung können Dokumente und Inhalte mittels Volltextsuche gefunden werden

Dank Texterkennung können Dokumente und Inhalte mittels Volltextsuche gefunden werden

Tipps & Tricks für Scanbot

Abschließend noch ein paar allgemeine Tipps & Tricks für das Scannen von Dokumenten mit Scanbot.

In bestimmten Situationen kann es hilfreich sein, keinen automatischen Upload zu konfigurieren, sondern den Upload immer manuell vorzunehmen.

Zum einen kann man Dateien noch vor dem Upload direkt in Scanbot umbenennen. Einfach die Datei in Scanbot öffnen und oben auf den Dateinamen klicken. Auf den ersten Blick mag es keine große Rolle spielen, ob man die Dateien nun in der App oder in Nextcloud umbenennt. Allerdings unterstützt Scanbot das Umbenennen von Dokumenten z.B. durch Ortungsdienste: Hier kann dann mit wenigen Klicks die Datei so umbenannt werden, dass beispielsweise gleich der Ort oder eine Sehenswürdigkeit in den Dateinamen einfließen. Das geht u.U. dann schneller von der Hand als das manuelle Umbenennen in der Cloud.

Scanbot: Umbenennen von Dokumenten

Scanbot: Umbenennen von Dokumenten

Mit dem zweiten Tipp kann man durch Komprimierung die Größe des Dokuments beeinflussen. Scanbot nimmt die Dokumente immer mit der nativen Auflösung der Smartphone-Kamera auf. Für einige Dokumente ist diese Auflösung zu hoch und die Scans benötigen dann relativ viel Speicherplatz. Scanbot bietet hier eine hilfreiche Funktion, um die Dokumente zu komprimieren. Dabei wird einfach die Auflösung der gescannten Dokumente verringert, was für einfachere Dokumente (z.B. Visitenkarten) vollkommen ausreicht.
Hierzu wird das Dokument wieder in der App geöffnet. Über das erweiterte Menü – die drei Punkte (Mehr) – kann man dann Komprimieren wählen.

Nach dem Umbenennen und dem Komprimieren eines Dokuments kann dies dann manuell in die eigenen Nextcloud hochgeladen werden. Auf diese Weise hat man bereits direkt nach dem Upload einen „richtigen“ Dateinamen und spart sich darüber hinaus noch etwas Speicherplatz.

Fazit

Mit dem Scannen von Dokumenten und dem Speichern dieser Dokumente in digitaler Form in der eigenen Nextcloud kann man sich einiges an „Papierkram“ sparen. Spätestens, wenn man ein spezielles Dokument sucht, wird man die Vorteile der Dokumentenverwaltung in der eigenen Cloud zu schätzen wissen: Nie mehr in irgendwelchen verstaubten Ordnern nach Rechnungen oder Schreiben suchen! Einfach den entsprechenden Ordner in Nextcloud öffnen, schon hat man alle Dokumente bei der Hand. Noch schneller geht es dann mit der Volltextsuche in Nextcloud. Hier findet man dann meist in wenigen Augenblicken das gesuchte Dokument.

Wieder ein Schritt weiter in Richtung „Papierloses Büro“.

Gewinnt eine von vier Lizenzen von Scanbot Pro

Neugierig geworden? Dank des freundlichen Supports von Scanbot habe ich vier Lizenzen für Scanbot Pro zu vergeben (Android oder iOS).

Was ihr dafür tun müsst? Hinterlasst mir einfach einen Kommentar unter diesem Beitrag. Beschreibt dabei, wie ihr eure Nextcloud zur Verwaltung von digitalen Dokumenten nutzt. Scannt ihr eure Dokumente mittels Scanner oder einer mobilen App? Welche Rolle spielt die Texterkennung (OCR) für euch? Wie bringt ihr Ordnung in eure Dokumente (z.B. per Tags oder spezieller Ordnerstruktur in der Cloud)?

Unter allen bis zum 15.11.2018 eingereichten Kommentaren werden vier Gewinner nach dem Zufallsprinzip ausgewählt und per E-Mail benachrichtigt.

Update: Gewinnspiel beendet, die Gewinner werden per Mail informiert. Vielen Dank an alle Teilnehmer des Gewinnspiels!

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/scanbot-und-nextcloud-zur-verwaltung-digitaler-dokumente-mit-ocr/feed/ 29
Linux: OCR-Texterkennung für PDF-Dateien und Bilder https://decatec.de/it/linux-ocr-texterkennung-fuer-pdf-dateien-und-bilder/ https://decatec.de/it/linux-ocr-texterkennung-fuer-pdf-dateien-und-bilder/#comments Tue, 25 Sep 2018 07:55:08 +0000 https://decatec.de/?p=4656 Logo OCR

Die Texterkennung (sog. OCROptical Character Recognition) sorgt bei Dokumenten verschiedenster Art dafür, dass Datei-Inhalte maschinell lesbar sind. Dadurch lassen sich Datei-Inhalte zum einen leicht markieren/kopieren (z.B. bei PDF-Dateien). Zum anderen werden die Inhalte der Dateien leicht durchsuchbar.

Der folgende Artikel zeigt daher, wie PDF-Dateien mit einer Texterkennung verarbeitet werden können. Ebenso wird gezeigt, wie Bilder einfach in PDF-Dokumente umgewandelt werden können, so dass diese danach ebenfalls maschinenlesbar sind.

OCR kurz erklärt

Bei OCR handelt sich es um die sog. Optical Character Recognition, also die Texterkennung bei Dokumenten, die an sich erst einmal nicht maschinenlesbar sind. Als Beispiel soll hier ein PDF-Dokument genannt sein. Der PDF-Standard wurde mit dem Gedanken entwickelt, dass PDF-Dateien unabhängig vom Anwendungsprogramm, vom Betriebssystem oder von der Hardware-Plattform jederzeit originalgetreu wiedergegeben werden können.

Nun wird euch sicherlich schon aufgefallen sein, dass es bei manchen PDF-Dateien vorkommt, dass hier keine Inhalte markiert/kopiert werden können. Hier fehlt dann ein sog. Text-Layer, der die Inhalte der Datei nochmals in maschinenlesbarer Form enthält. Wenn ein solcher Text-Layer vorhanden ist, lassen sich Inhalte in der PDF-Datei markieren und somit auch kopieren.

PDF mit Text-Layer: Hier können Inhalte markiert und kopiert werden

PDF mit Text-Layer: Hier können Inhalte markiert und kopiert werden

Genau dieser Text-Layer kann nun mittels OCR „nachgerüstet“ werden. Anschließend können Datei-Inhalte markiert/kopiert werden und sind – da maschinenlesbar – auch durchsuchbar. Beispielsweise kann im Windows-Explorer nach Inhalten gesucht werden, indem dem Suchbegriff noch „inhalt: “ vorangestellt wird.

Suche nach Datei-Inhalten im Windows-Explorer

Suche nach Datei-Inhalten im Windows-Explorer

Einziger Nachteil: Durch den zusätzlichen Text-Layer werden die Dateien etwas größer. Angesichts der Vorteile, die ein Text-Layer bietet, ist dieser Nachteil allerdings zu vernachlässigen.

Auf der Suche nach Programmen, die PDF-Dateien mit einem OCR-Text-Layer versehen können, gibt es unter Windows leider nicht viele Programme: Diese sind zudem meist kostenpflichtig oder zwingen den Benutzer zu einem bestimmten Workflow bei der Bearbeitung von PDF-Dateien.

Unter Linux sieht die Sache allerdings anders aus…

OCR für PDF-Dateien: OCRmyPDF

OCRmyPDF ist ein Kommandozeilen-Programm für Linux, mit dem PDF-Dateien einfach mit einem Text-Layer versehen werden können. Tesseract kommt dabei als OCR-Engine zum Einsatz.

Installation OCRmyPDF

Bei Debian und Ubuntu ist es bereits in den Paketquellen enthalten, so dass es einfach mit einem Befehl installiert werden kann:

apt-get update
apt-get install ocrmypdf

Auch wenn das Programm bei manchen Distributionen nicht in den Paketquellen enthalten ist, kann es mit der Installationsanleitung auch hier installiert werden.

Bei der Installation werden alle automatisch alle Abhängigkeiten installiert, die für die Erkennung von englischen Texten benötigt werden. Damit auch Texte in anderen Sprachen erkannt werden können, müssen noch zusätzliche Sprach-Dateien für Tesseract installiert werden. Um beispielsweise auch deutsche Texte erkennen zu können, wird das deutsche Sprachpaket installiert:

apt-get install tesseract-ocr-deu

Eine Liste mit allen verfügbaren Sprach-Dateien findet man hier.

OCR mit OCRmyPDF

Um nun eine PDF-Datei mit einem Text-Layer zu versehen, reicht folgender Befehl:

ocrmypdf /mnt/temp/Dokument.pdf /mnt/temp/Dokument-OCR.pdf

Die originale PDF-Datei (/mnt/temp/Dokument.pdf) wird dabei nach der Verarbeitung als neue Datei (/mnt/temp/Dokument-OCR.pdf) gespeichert.

Der Aufruf kann noch mit Parametern versehen werden, um die Umwandlung besser kontrollieren zu können. Um beispielsweise einen Hinweis auf die enthaltenen Sprachen zu geben, erweitern wir den Befehl um den Parameter -l deu+eng. Damit wird der OCR-Engine mitgeteilt, dass im umzuwandelnden PDF vermutlich die Sprachen Deutsch und Englisch enthalten sind.

Eine Übersicht über alle möglichen Parameter findet man in der Dokumentation zu OCRmyPDF.

An dieser Stelle sei erwähnt, dass OCRmyPDF teilweise Warnungen ausgibt. Dies kann verschiedenste Ursachen haben, meistens ist dabei allerdings die Qualität des Ausgangs-Dokuments ausschlaggebend. Wenn dieses ein schlechter Scan ist, dann tut sich die Texterkennung hier schwer. Die Warnungen von OCRmyPDF können dabei allerdings ignoriert werden, es kann lediglich sein, dass die Texterkennung nicht sehr gut war und im Text-Layer des PDFs nicht alle Worte korrekt erkennt worden sind.

OCRmyPDF erzeugt standardmäßig PDF/A-Dateien. PDF/A ist dabei ein Dateiformat zur Langzeitarchivierung von PDF-Dateien. Alle Elemente, die zur Anzeige von PDF/A-Dokumenten benötigt werden, müssen dabei in der Datei selbst enthalten sein. Das sorgt dafür, dass PDF/A-Dateien immer etwas größer sind als normale PDF-Dateien. Es kann auch passieren, dass PDF/A-Dateien nicht alle Funktionen normaler PDF-Dateien bieten (da z.B. kein Javascript enthalten sein darf). Für den Privatgebrauch ist es daher eine Überlegung wert, für maximale Kompatibilität statt PDF/A-Dateien normale PDFs erzeugen zu lassen. Dies kann einfach mit dem Parameter –output-type pdf bewerkstelligt werden.

Ein vollständiger Aufruf von OCRmyPDF kann daher meist so aussehen:

ocrmypdf -l deu+eng --output-type pdf /mnt/temp/Dokument.pdf /mnt/temp/Dokument-OCR.pdf

OCR für Bilder: Umwandlung in (OCR-)PDF mittels Tesseract

Als ich vor etlichen Jahren angefangen habe, Dokumente (wie z.B. Rechnungen) zu Scannen, um diese auf dem Rechner archivieren zu können, habe ich diese noch nicht als PDF-Dateien, sondern als einfache Bild-Dateien (JPG) gespeichert. Dieses Dateiformat ist für diesen Zweck nicht gerade optimal, daher sollten diese Bild-Scans in PDF-Dateien konvertiert werden.

Hier kann OCRmyPDF auch zum Einsatz kommen, um diese Bilder in PDF-Dateien umzuwandeln. Allerdings habe ich hier mit Tesseract bessere Erfahrungen gemacht, so dass ich diese Dokument-Bilder eigentlich immer direkt über Tesseract in PDFs konvertieren lasse.

Die OCR-Engine Tesseract wurde ja bereits mit OCRmyPDF installiert. Falls dies noch nicht geschehen ist, reichen folgende Befehle, um Tesseract und die entsprechenden Sprach-Dateien zu installieren:

apt-get update
apt-get install tesseract-ocr tesseract-ocr-eng tesseract-ocr-deu

Hier werden die Sprach-Dateien für Englisch und Deutsch mit installiert. Eine Übersicht über alle vorhandenen Sprach-Dateien findet man hier.

Die Umwandlung in PDFs mit Text-Layer erfolgt dann über folgenden Befehl:

tesseract /mnt/temp/Dokument.jpg /mnt/temp/Dokument-OCR -l deu+eng pdf

Der erste Parameter ist dabei das Input-Bild. Mit dem zweiten Parameter wird die Output-Datei angegeben (ohne Datei-Endung „.pdf“). Mit -l deu+eng wird der OCR-Engine wieder ein Hinweis auf die enthaltenen Sprachen gegeben. Der letzte Parameter (pdf) sorgt letzten Endes für die Umwandlung in eine PDF-Datei (und setzt die richtige Datei-Endung für die Output-Datei).

Automatisiert mit Skript

Jede PDF-/Bild-Datei nun einzeln mit einem Text-Layer zu versehen oder in eine (OCR-)PDF-Datei umzuwandeln, erfordert jedoch einiges an Aufwand. Das dachte ich mir auch, als ich die Vorgabe hatte, hunderte Dateien durch die Texterkennung zu jagen.

Aus diesem Grund habe ich ein Bash-Skript erstellt, welches die oben genannten Aufrufe automatisiert.

OCRmyFiles @ Codeberg

Nach dem Download des Skripts sollten noch folgende Punkte im selbst Skript angepasst werden:

  • inputDirDefault/outputDirDefault: Standard-Verzeichnisse für Eingabe/Ausgabe.
  • ocrmypdfCmdArgs: Parameter für den Aufruf von OCRmyPDF.
  • imageConvertCmdArgs: Parameter für den Aufruf von Tesseract zur Umwandlung von Bildern in PDF-Dateien.

Bevor das Skript nun ausgeführt werden kann, muss dieses noch als auführbar markiert werden:

sudo chmod +x OCRmyFiles.sh

Nun erwartet das Skript beim Aufruf zwei Parameter:

  • Ein Eingangs-Verzeichnis, in dem sämtliche PDFs/Bilder enthalten sind, die mittels Texterkennung behandelt werden sollen.
  • Ein Ausgangs-Verzeichnis, in dem die Ergebnisse gespeichert sind

Ein typsicher Aufruf des Skripts sieht dann folgendermaßen aus:

ocrmyfiles.sh /mnt/OCR/Input /mnt/OCR/Output

Wenn diese Parameter weggelassen werden, werden die Standard-Verzeichnisse für Eingang/Ausgang genutzt (definiert in den Variablen inputDirDefault/outputDirDefault, siehe oben).

Das Skript führt nun folgendes aus:

  • Es scannt das Eingangs-Verzeichnis (rekursiv) auf PDF-Dateien und Bilder.
  • PDF-Dateien werden mittels OCRmyPDF mit einem Text-Layer versehen.
  • Bild-Dateien werden in (OCR-)PDFs umgewandelt.
  • Alle anderen Dateien werden ohne Änderung in das Ausgabe-Verzeichnis kopiert.

Nach dem Aufrufen des Skripts sollten sich im Ausgangs-Verzeichnis die gleiche Anzahl Dateien und dieselbe Verzeichnisstruktur befinden wie im Eingangs-Verzeichnis. Die (PDF-)Dateien werden jedoch etwas größer sein, da sie nun einen zusätzlichen Text-Layer beinhalten.

Das Skript ist unter MIT-Lizenz frei auf Codeberg verfügbar, so dass jeder es an die eigenen Bedürfnisse anpassen und erweitern kann.

Aus der Praxis

Mit diesem Skript wurde die Texterkennung von PDFs und Dateien nun weitgehendst automatisiert. Dies kann nun beispielsweise genutzt werden, um Dokumente durchsuchbar in der Cloud abzuspeichern. Im vorherigen Artikel Volltextsuche in Nextcloud (mit OCR) wurde beschrieben, wie man eine Volltextsuche in Nextcloud installieren kann. Hat man nun seine PDF-Dateien mittels OCR mit einem Text-Layer versehen, können diese in der Cloud einfach durchsucht werden.

Wenn man nun z.B. Dokumente mittels Scanner als PDF scannt, landen diese zunächst einmal in einem speziellen Eingangs-Verzeichnis (z.B. /mnt/LinuxShare/OCR/Input – in meinem Fall ist dies eine Netzwerk-Freigabe unter Windows). Anschließend lässt man das Skript für die Texterkennung laufen. Dieses erzeugt in einem Ausgangs-Verzeichnis (z.B. /mnt/LinuxShare/OCR/Output) die mit einem Text-Layer versehenen PDF-Dateien. Nun können diese Dateien in die Cloud hochgeladen werden. Nach dem nächsten Durchlaufen des Cronjobs für Nextcloud werden die neuen Dateien von der Volltextsuche erfasst und können anschließend über die Suche in der Dateien-App gefunden werden (sowohl über den Datei-Namen, als auch über Datei-Inhalte).

Volltextsuche in Nextcloud: PDFs mit Text-Layer können hier einfach durchsucht werden

Volltextsuche in Nextcloud: PDFs mit Text-Layer können hier einfach durchsucht werden

Fazit

Nach dem OCR-Scan für PDFs und Bilder können Inhalte dieser Dateien leicht kopiert werden. Darüber hinaus sind die Datei-Inhalte durchsuchbar. Gerade zu Zwecken der Archivierung ist dies unabhängig vom verwendeten Speicherort (Cloud, lokales Dateisystem, etc.) eine äußerst sinnvolle Angelegenheit. Damit kommt man dem „papierlosen Büro“ schon einen großen Schritt näher.

Weiterführende Artikel

Links

]]>
https://decatec.de/it/linux-ocr-texterkennung-fuer-pdf-dateien-und-bilder/feed/ 21
Volltextsuche in Nextcloud (mit OCR) https://decatec.de/home-server/volltextsuche-in-nextcloud-mit-ocr/ https://decatec.de/home-server/volltextsuche-in-nextcloud-mit-ocr/#comments Sat, 15 Sep 2018 14:47:53 +0000 https://decatec.de/?p=4620 Nextcloud Logo

Nextcloud stellt mittlerweile eine echte Alternative zu kommerziellen Cloud-Anbietern dar. Wenn man sich erst einmal von Google, Microsoft, Dropbox, etc. losgesagt hat, wird man die eigene Nextcloud früher oder später vermehrt nutzen und so zu einem echten „Nextcloud-Power-User“.

Über die Zeit werden sich in der eigenen Cloud immer mehr Daten ansammeln, so dass man schnell mal den Überblick verlieren kann. Hier ist eine ordentliche Suchfunktion dann essentiell. Nextcloud hat bereits ab Werk eine Suchfunktion mit an Bord, diese ist allerdings eher rudimentär: Beispielsweise kann man in der Datei-Übersicht nur nach Dateinamen suchen, nicht jedoch nach Datei-Inhalten.

Update-Historie (letztes Update: 25.05.2019)
  • 26.05.2019:
    • Hinweis hinzugefügt, dass die Einrichtung der Volltextsuche auf einem Raspberry Pi nicht empfohlen wird.
  • 21.08.2018:
    • Hinweise hinzugefügt, wenn der Elasticsearch-Dienst nach einem Update nicht mehr bei Systemstart gestartet wird.

Volltextsuche mit Full Text Search

Genau hier setzt die App Full Text Search an: Die komplette Cloud wird hier indiziert und kann danach auf einfache Art und Weise durchsucht werden. Dies beschränkt sich jedoch nicht nur auf Dateinamen, sondern auch die Inhalte von Dateien können gesucht werden.

Durch einfaches Aktivieren der App im Nextcloud App Store ist es allerdings nicht getan. Damit die App Full Text Search ihren Dienst verrichten kann, sind einige Voraussetzungen zu erfüllen. Die App ist auf eine Installation der Suchmaschine Elasticsearch angewiesen. Diese Anwendung ist wiederum in Java geschrieben, so dass ebenso eine Java-Laufzeitumgebung installiert sein muss. Der folgende Artikel beschreibt daher die Installation und Konfiguration aller benötigten Komponenten, um anschließend die Volltextsuche in Nextcloud aktivieren zu können.

Der Artikel basiert wie immer auf dem Tutorial Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban.

Voraussetzungen

Die im Rahmen dieses Artikels installierten Programme haben an sich keine besonderen Anforderungen. Allerdings wird der Speicherverbrauch durch Elasticsearch erheblich steigen. Aus der Praxis: Elasticsearch verbraucht auf meinem Testsystem (VM mit 6 GB dynamischen RAM) über 1 GB Speicher.

Die Volltextsuche funktioniert theoretisch auch auf einem Raspberry Pi (Affiliate-Link). Dennoch wird hier sehr viel RAM benötigt, so dass der Kleinst-Computer damit etwas überfordert ist. Daher wird die Einrichtung der Volltextsuche auf einem Raspberry Pi nicht empfohlen.

Installation Full Text Search

Bevor die App an sich aktiviert werden kann, sind einige andere Programme zu installieren.

Wir beginnen zunächst einmal mit der Aktualisierung des Systems:

apt-get update && apt-get upgrade -V

Installation der Java-Laufzeitumgebung

Zunächst überprüfen wir, ob bereits eine Java-Laufzeitumgebung installiert ist:

java -version

Wenn Java bereits installiert ist, wird die Java-Version angezeigt. Wenn dies Version 8 oder größer ist, ist hier nichts weiter zu installieren und die Installation von Java kann übersprungen werden.

Falls hier jedoch eine ältere Version oder folgende Meldung angezeigt wird, ist Java nicht aktuell oder gar nicht installiert:

Command ‚java‘ not found, but can be installed with:

apt install default-jre
apt install openjdk-11-jre-headless
apt install openjdk-8-jre-headless

In diesem Fall installieren wir die Laufzeitumgebung durch folgende Befehle:

apt-get install apt-transport-https ca-certificates
apt-get install openjdk-8-jre

Installation Elasticsearch

Als nächstes kann die Suchmaschine installiert werden. Dazu wird erst einmal der Key des Repositories im System bekannt gemacht, da es ansonsten später zu Warnungen während der Installation kommen wird:

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Nun wird das entsprechende Repository den Paket-Sourcen hinzugefügt:

echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list

Danach wird Elasticsearch mit diesem Befehl installiert:

apt-get update && apt-get install elasticsearch

Konfiguration Elasticsearch

Nach der Installation muss die Suchmaschine noch fertig konfiguriert werden, bevor diese durch Nextcloud genutzt werden kann.

Elasticsearch wird nach der Installation nicht automatisch nach dem Start des Betriebssystems gestartet. Mit folgenden Befehlen wird der Dienst nach dem Systemstart automatisch mit gestartet:

systemctl daemon-reload
systemctl enable elasticsearch
systemctl start elasticsearch

Anschließend installieren wir ein Plugin für Elasticsearch, damit später auch PDF-Dateien durchsucht werden können:

/usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-attachment

Zu guter Letzt soll die Suchmaschine nur lokal angesprochen werden können. Dazu wird die Konfigurationsdatei geöffnet:

nano /etc/elasticsearch/elasticsearch.yml

Hier suchen wir nach network.host und ändern die entsprechende Zeile ab:

network.host: 127.0.0.1

Am Ende wird der Dienst neu gestartet, damit die Änderungen übernommen werden:

service elasticsearch restart

Installation Tesseract (für OCR)

Tesseract ist eine Software für die Texterkennung (OCR). Damit wird es möglich, Text aus Bildern zu extrahieren und damit durchsuchbar zu machen. Die Installation der OCR-Software ist optional, ist aber im Rahmen der Volltextsuche empfehlenswert, da so nicht nur in Text-Dokumenten, sondern auch in Bildern gesucht werden kann.

Was heißt das nun konkret? Man stelle ich ein Foto vor, welches mit dem Smartphone aufgenommen wurde und beispielsweise ein Ortsschild zeigt. Mittels OCR kann nun auch nach dem Namen des Ortes gesucht werden und dank Volltextsuche wird einem dieses Bild auch in den Ergebnissen angezeigt. Für mich ist das ein sehr hilfreiches Feature, daher empfehle ich die Installation von Tesseract.

Dies ist auch nicht weiter aufwändig, es reicht ein Befehl:

apt-get install tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng

Hier werden auch gleich die Dateien installiert, welche für die Texterkennung für deutsche und englische Texte benötigt werden. Soll die OCR-Engine auch weitere Sprachen erkennen, so müssen zusätzlich Pakete der Form tesseract-ocr-<language> installiert werden. Eine Übersicht über alle verfügbaren Sprachen findet man hier.

Ansonsten ist nicht weiter für die Texterkennung zu installieren bzw. zu konfigurieren.

Einrichtung der Volltextsuche in Nextcloud

Nachdem nun alle Voraussetzungen installiert wurden, starten wir Elasticsearch zunächst einmal neu:

service elasticsearch restart

Installation der Apps für die Volltextsuche

Anschließend werden die entsprechenden Apps über den Nextcloud App Store installiert. Diese findet man in der Kategorie Suche.

Nextcloud App Store: Apps für die Volltextsuche

Nextcloud App Store: Apps für die Volltextsuche

  • Full text search: Diese App bietet die Grundfunktionen zur Volltextsuche.
  • Full text search – Elasticsearch Platform: Dies stellt die Verbindung zur Suchmaschine her.
  • Full text search – Files: Erweitert die Dateien-App um die Volltextsuche.
  • Full text search – Files – Tesseract OCR: Wenn im vorherigen Schritt die OCR-Engine installiert wurde, ist dies die Verbindung zu Tesseract.

Es gibt in dieser Kategorie evtl. noch mehrere Apps, die die Volltextsuche erweitern. Momentan gibt es hier beispielsweise noch die App für Lesezeichen: Wenn man die App Bookmarks in Nextcloud aktiviert hat, können mit Full text search – Bookmarks auch diese Lesezeichen durchsucht werden.

Konfiguration der Volltextsuche

Bevor die Volltextsuche nun verwendet werden kann, muss diese noch innerhalb Nextcloud konfiguriert werden. Dies geschieht in den Admin-Einstellungen unter Volltextsuche.

Nextcloud-Einstellungen für die Volltextsuche

Nextcloud-Einstellungen für die Volltextsuche

  • Allgemein: Allgemeine Einstellungen zur Volltextsuche.
    • Search Platform: Da momentan nur Elasticsearch installiert ist, kann man hier auch nur diesen einen Eintrag wählen.
  • Elastic Search: Einstellungen für die Suchmaschine.
    • Address of the Servlet: Dies ist die URL, unter der Elasticsearch verfügbar ist. In unserem Fall ist dies http://localhost:9200
    • Index: Eine Elasticsearch-Installation kann mehrere Such-Indizes gleichzeitig verwalten. Im diese Indizes auseinanderzuhalten zu können, wird hier der Name des Such-Indexes angegeben. Dies kann eine beliebige Zeichenfolge sein, z.B. der Domain-Name der Cloud-Instanz.
  • Dateien: Einstellungen für die Datei-Suche.
    • Damit sowohl lokale Dateien, als auch Dateien indiziert werden, die auf externem Speicher liegen, aktivieren wir hier sowohl Local files, als auch External Files.
  • Types: Einstellungen für verschiedene Dateitypen.
    • Wir aktivieren hier Extract PDF, als auch Extract Office, damit auch PDF- und Office-Dateien durchsucht werden können. Dazu muss zuvor das Elasticsearch-Plugin ingestattachment installiert worden sein.
  • Files – Tesseract OCR: Einstellungen für die Texterkennung mit Tesseract.
    • Enable OCR: Muss aktiviert werden, damit die Volltextsuche OCR verwenden kann.
    • Languages: Hier sind alle Sprachen anzugeben, die zuvor im Rahmen der Installation von Tesseract mit installiert wurden. In unserem Fall: eng,deu

Die Einstellungen werden direkt nach der Eingabe übernommen.

Index anlegen

Nachdem die Volltextsuche nun einsatzbereit ist, muss der erste Index über das Kommandozeilentool occ angelegt werden. Dies geschieht über folgenden Befehl:

sudo -u www-data php /var/www/nextcloud/occ fulltextsearch:index

Achtung: Je nach Größe der Nextcloud-Instanz kann dieser Befehl sehr lange dauern. Wenn ihr also bereits viele Dateien in eurer Nextcloud gespeichert habt, rechnet mal mit ein paar Stunden, bevor der erste Index erzeugt wurde.

Nach dem ersten Erzeugen des Indexes muss der o.g. Befehl nicht mehr regelmäßig ausgeführt werden. Die Aktualisierung des Indexes erfolgt dann im Rahmen des Cronjobs von Nextcloud.

Wichtig dafür ist nur, dass Nextcloud auch so konfiguriert wurde, dass ein Cronjob genutzt wird. Bei einer Ausführung von Hintergrundaufgaben per AJAX wird der Suchindex nicht auf dem Laufenden gehalten.

Die Volltextsuche in Aktion

Nach dem Anlegen des Indexes kann die Volltextsuche nun ganz einfach in Nextcloud genutzt werden. In der Datei-Übersicht kann die Suche wie bisher verwendet werden, nur dass diese nun durch die Volltextsuche ersetzt wurde.

Nextcloud Volltextsuche: Suche nach Datei-Inhalten

Nextcloud Volltextsuche: Suche nach Datei-Inhalten

Bei der Neuanlage von Dokumenten dauert es übrigens ein wenig, bis diese durch die Volltextsuche gefunden werden können. Das liegt daran, dass ein neues Dokument erst mit dem nächsten Cronjob-Lauf in den Index mit aufgenommen wird. Das sollte allerdings maximal 15 Minuten dauern.

Wenn Tesseract als OCR-Engine installiert wurde, kann nun nicht nur nach dem Inhalt von Dokumenten, sondern auch nach Bild-Inhalten (Text in Bildern) gesucht werden.

Syntax für die Suche

Zum Schluss noch ein paar Hinweise für die Syntax beim Suchen über Full Text Search:

  • Nextcloud
    Findet Dateien, die „Nextcloud“ im Pfad/Dateinamen oder als Inhalt haben.
  • Nex*
    Findet Dateien, die „Nex“ und weitere Zeichen im Pfad/Dateinamen oder als Inhalt haben (also z.B. Nextcloud, Nexus, etc.).
  • Nextcloud Volltextsuche App
    Findet Dateien, die „Nextcloud“ oder „Volltextsuche“ oder „App“ im Pfad/Dateinamen oder als Inhalt haben.
  • „Nextcloud Volltextsuche“ App
    Findet Dateien, die „Nextcloud Volltextsuche“ oder „App“ im Pfad/Dateinamen oder als Inhalt haben (hier wird z.B. eine Datei mit „Nextcloud und Volltextsuche“ nicht gefunden).
  • +Nextcloud Volltextsuche App
    Findet Dateien, die auf jeden Fall „Nextcloud“ und vielleicht „Volltextsuche“ oder „App“ im Pfad/Dateinamen oder als Inhalt haben.
  • +“Nextcloud Volltextsuche“ -App
    Findet Dateien, die auf jeden Fall „Nextcloud Volltextsuche“, aber nicht „App“ im Pfad/Dateinamen oder als Inhalt haben.
  • Nextcloud in:filename
    Findet Dateien, die „Nextcloud“ im Pfad oder Dateinamen enthalten (funktioniert dann wie die Standard-Suche in Nextcloud, die nur nach Dateinamen/Pfaden suchen kann).
  • Nextcloud in:content
    Findet Dateien, die „Nextcloud“ als Inhalt haben.

Update Elasticsearch

Da wir Elasticsearch in die Paketquellen eingetragen haben, wird von Zeit zu Zeit ein Update von Elasticserarch installiert werden, wenn das System mit apt-get upgrade auf den neusten Stand gebracht wird.

Nach einem Update kann es passieren, dass die Volltextsuche in Nextcloud nicht mehr funktionsfähig ist und folgende Fehlermeldung ausgibt:

No alive nodes found in your cluster

In diesem Fall ist der Dienst für Elasticsearch vermutlich nicht gestartet. Überprüft werden kann dies mit:

service elasticsearch status

Falls hier angezeigt wird, dass der Dienst nicht gestartet werden konnte, sollten auf jeden Fall die Logs kontrolliert werden:

nano /var/log/elasticsearch/elasticsearch.log

In den meisten Fällen wird hier das Plugin „ingest-attachment“ verantwortlich sein, was man an folgender Fehlermeldung sehen kann.

org.elasticsearch.bootstrap.StartupException: java.lang.IllegalArgumentException: Plugin [ingest-attachment] was built for Elasticsearch version 6.4.0 but version 6.4.1 is running

Hier muss das Plugin aktualisiert werden. Zunächst wird die alte Version entfernt:

/usr/share/elasticsearch/bin/elasticsearch-plugin remove ingest-attachment

Anschließend kann die aktualisierte Version installiert werden:

 

/usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-attachment

Nach einem Neustart des Systems sollte der Dienst wieder gestartet sein und die Volltextsuche sollte in Nextcloud auch wieder funktionieren.

Falls nicht, sollte der Dienst nochmal so konfiguriert werden, dass dieser beim Systemstart mitgestartet wird:

systemctl daemon-reload
systemctl enable elasticsearch
systemctl start elasticsearch

Fazit

Eine Volltextsuche ist eine sinnvolle Erweiterung für jede Nextcloud-Installation. Gerade wenn in der Cloud nach einiger Zeit sehr viele Dateien gespeichert sind, wird man die Volltextsuche zu schätzen wissen. Ebenso kommt es vor, dass man zwar weiß, dass in irgendeinem Dokument bestimmte Inhalte zu finden sind, man sich aber nicht mehr erinnert, in welcher Datei diese Inhalte zu finden sind. Mit der Volltextsuche ist auch das kein Problem mehr.

Die OCR-Erweiterung durch Tesseract sorgt darüber hinaus, dass auch nach Inhalten in Bildern gesucht werden kann. Dies macht dann besonders Sinn, wenn man z.B. die Fotos vom Smartphone mit Hilfe der Nextcloud-App automatisch in die Cloud hochladen lässt.

Auch wenn die Einrichtung der Volltextsuche in Nextcloud etwas aufwändiger ist und zusätzliche System-Ressourcen benötigt werden, der Aufwand wird sich in den meisten Fällen allerdings wirklich lohnen.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/volltextsuche-in-nextcloud-mit-ocr/feed/ 119
Nie mehr Werbung – Pi-hole auf Ubuntu Server 18.04 https://decatec.de/home-server/nie-mehr-werbung-pi-hole-auf-ubuntu-server-18-04/ https://decatec.de/home-server/nie-mehr-werbung-pi-hole-auf-ubuntu-server-18-04/#comments Sun, 02 Sep 2018 13:04:11 +0000 https://decatec.de/?p=4460 Pi-hole Logo

Wer kennt das nicht: Wenn man sich durch das Internet bewegt, wird man unweigerlich mit Werbung konfrontiert. Wenn diese Werbung eher dezent platziert ist, sollte dies nicht weiter stören. Leider gibt es immer mehr Webseiten, die den Bogen überspannt haben. Spätestens, wenn der Lesefluss durch übermäßige Werbung gestört wird, möchte man die Webseite am liebsten sofort wieder verlassen.

Werbebanner sind dabei allerdings noch das kleinere Übel: Bedenklich wird es spätestens beim sog. Malwaretising (Verteilung von Schadcode über Online-Werbung) oder dem Einsatz von Mining-Code auf Webseiten (Code, der im Hintergrund – und meist ohne Wissen der Website-Besucher – Mining für Kryptowährungen ausführt). Das Tracking von Benutzern ist ein weiteres Thema, welches den meisten Nutzern nicht recht sein dürfte.

Werbeblocker (Adblocker) wirken diesen Problemen entgegen: Meistens sind dies Erweiterungen für den Browser, die Werbung und Schadcode im Hintergrund blockieren. Die bekanntesten Vertreter sind hier wohl AdBlock Plus und uBlock Origin. Diese Erweiterungen wirken allerdings nur im Browser, für den sie installiert wurden.

Doch nicht nur Browser sind von der Problematik betroffen. Sämtliche Geräte, die mit dem Internet verbunden sind, wollen meist „nach Hause telefonieren“. So sendet ein Windows-PC regelmäßig Telemetrie-Daten zu Microsoft. Spätestens seit Windows 10 lässt sich dieses Verhalten nicht mehr komplett abschalten. Ich spreche hier absichtlich von Geräten (und eben nicht von Computern), da dies auch auf andere Geräte-Klassen zutrifft. Man denke hier z.B. an Streaming-Multimedia-Systeme oder auch LED-Lichterketten, die komfortabel mit dem Handy bedient werden können.
Irgendwie kommunizieren solche Geräte immer mit irgendwelchen Webdiensten, ohne dass dies dem Nutzer klar ist oder er dieses Verhalten abschalten könnte.

Update-Historie (letztes Update 19.01.2019)
  • 18.01.2019:
    • Empfehlungen für Blocklisten für Facebook hinzugefügt.
  • 17.01.2019:
    • Von Stubby verwendete Ports geändert.
    • Hinweis auf die gleichzeitige Nutzung mehrerer Upstream-DNS-Server mit Stubby hinzugefügt.
  • 13.01.2019:
    • Als Upstream-DNS-Server werden nun die DNS-Server von Digitalcourage empfohlen.
    • Hinweis hinzugefügt, dass auf der Maschine für Pi-Hole kein bereits eingerichteter Webserver laufen sollte.
    • Hinweis hinzugefügt, dass die Installation mittels curl | bash problematisch sein könnte. Alternative Installationsmethode hinzugefügt.
  • 14.12.2018:
    • Empfehlung für Block-Listen von Akamaru hinzugefügt.

 

Pi-hole: Ein Adblocker für das gesamte Netzwerk

Pi-hole ist ein Projekt zum Blockieren von Werbung, Schadcode und Trackern. Im Unterscheid zu Browser-Addons wird Pi-hole nicht Client-seitig installiert (wie z.B. als Addon im Browser), sondern wirkt Netzwerk-weit. Dazu wird das Programm einfach auf einem Rechner im Netzwerk installiert .Ursprünglich war dafür ein Raspberry Pi (Affiliate Link), vorgesehen, was sich ja schon aus dem Namen des Projekts erahnen lässt. Pi-hole läuft mittlerweile allerdings auf den verschiedensten (Linux-)Plattformen.

Einmal installiert und eingerichtet, blockiert das Programm unerwünschte Werbung und Schadcode – und zwar im kompletten Netzwerk. Als praktisches Beispiel sei hier der Browser Chrome auf einem Android Smartphone erwähnt: In der mobilen Variante können keine Addons genutzt werden, die man von der Desktop-Version kennt. Daher wird man im mobilen Chrome immer Werbung angezeigt bekommen. Nicht jedoch, wenn Pi-hole im gleichen Netzwerk installiert ist, über das das Smartphone mit dem Internet verbunden ist. Dann wird Werbung ohne weiteres Zutun des Nutzers auch im mobilen Browser blockiert – quasi von Geisterhand.

Ein paar Anmerkungen vorweg

Wenn ihr dem Tutorial folgt, dann müsst ihr euch folgender Punkte bewusst sein:

  • Mit der Installation von Pi-hole als Netzwerk-weiten Adblocker greift ihr tief in die Netzwerk-Infrastruktur ein. Wenn hier irgendetwas nicht klappen sollte, dann ist das komplette Netzwerk offline, d.h. es kann nicht mehr gesurft werden, da keine Domains mehr aufgelöst werden können.
  • Dessen solltet ihr euch bewusst sein und auch einen „Plan B“ haben, mit dem ihr die Änderungen durch Pi-hole wieder rückgängig machen könnt. Dies hängt wiederum von der Variante ab, die ihr gewählt habt, um Pi-hole im Netzwerk als DNS-Server zu installieren (siehe Abschnitt Netzwerk-Konfiguration).
  • Die Maschine mit Pi-hole muss immer laufen. Sollte die Maschine mal nicht verfügbar sein (Absturz oder auch nur ein kurzer Reboot), dann ist das Netzwerk in dieser Zeit offline.
  • Ich versuche hier eine möglichst detaillierte Anleitung für die Installation von Pi-hole zu liefern. Trotzdem kann ich nicht garantieren, dass diese Konfiguration mit allen Netzwerk-Konstellationen läuft. Ich übernehme daher keinerlei Haftung für evtl. auftretende Probleme, die nach der Installation von Pi-hole auftreten könnten.
  • Das Thema Adblocker wird kontrovers diskutiert: Zum einen kann Werbung im Internet wirklich nervig sein, besonders wenn man Webseiten besucht und sofort von Werbung überhäuft wird. Dann macht die Suche nach Informationen und das Surfen im Allgemeinen wenig Spaß.
    Auf der anderen Seite muss man bedenken, dass sich viele Webseiten durch Werbung finanzieren. Gerade für viele kleinere Websites und Blogs sind die Einnahmen durch Werbebanner die einzige „Finanzspritze“, damit die Kosten für das Hosting (zumindest teilweise) gedeckt sind. Wenn hier die Einnahmen ausbleiben, darf man sich nicht wundern, wenn private Websites/Blogs irgendwann aus dem Netz verschwinden.
    Ich will hier gar nicht den Moral-Apostel spielen, aber dies sollte man immer im Hinterkopf behalten, wenn man sich mit einem aktiven Adblocker durch das Internet bewegt. Wenn eine Webseite hilfreich und informativ ist, dann gibt es in den meisten Fällen auch die Möglichkeit, den Betreiber direkt zu unterstützen (z.B. durch eine kleine Spende oder auch durch das Einkaufen über Affiliate-Links).

Voraussetzungen

Auch wenn man Pi-hole problemlos auf einem Raspberry Pi betreiben kann, möchte ich in diesem Artikel die Installation des Adblockers auf einem Ubuntu Server zeigen. Zum einen habe ich mit Ubuntu (Server) durch meine Blog-Artikel schon einiges an Erfahrung sammeln können, zum anderen lässt sich Ubuntu recht einfach über Hyper-V virtualisieren, d.h. man kann den Adblocker ohne viel Aufwand auf einer virtuellen Maschine betreiben.

Als Grundlage für die Installation des Betriebssystems dient wie schon so oft der Artikel Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten. Meine Empfehlung dabei ist, Pi-hole auf einer extra VM zu installieren, auf der ansonsten nichts weiter läuft. In diesem Fall kann man die virtuelle Maschine auch recht klein bemessen: Pi-hole braucht nicht viele Hardware-Ressourcen. Auch die virtuelle Festplatte muss nicht viel Speicherplatz bieten: 10 GB reichen hier für Betriebssystem und Pi-hole aus.

Es ist wichtig, dass auf der Maschine kein zusätzlicher Webserver läuft, da im Rahmen der Installation von Pi-hole ein eigener Webserver installiert wird (lighttpd), der ansonsten mit einem bereits eingerichteten Webserver kollidieren könnte.

Wichtig dabei ist nur, dass die Pi-hole-VM eine statische IP im Netzwerk hat. Am besten nimmt man die entsprechende Konfiguration gleich im Rahmen des Installations-Prozesses des Betriebssystems vor.

Funktionsweise Pi-hole

Bevor es in den praktischen Teil geht, soll kurz die Funktionsweise des Werbeblockers erklärt werden.

Alles beginnt mit einem der wichtigsten Dienste im Internet: Dem Domain Name System (DNS). Dieses funktioniert ähnlich wie eine Telefonauskunft. Wenn man z.B. in einem Browser eine Website aufrufen möchte, dann wird eine DNS-Abfrage gestartet, da für die URL (z.B. decatec.de) zuerst die tatsächliche IP-Adresse ermittelt werden muss (in diesem Beispiel 85.13.128.144). Erst über diese IP-Adresse ist die Website erreichbar und der Request kann ausgeführt werden.

Pi-hole arbeitet nun als DNS-Proxy, der sich zwischen den Geräten im Netzwerk und dem eigentlichen DNS-Server sitzt. Möchte ein Nutzer im Netzwerk eine Website aufrufen, wird dieser DNS-Request von Pi-hole einfach an den eigentlichen DNS-Server durchgeschleift und die Client-Anwendung bekommt die passende IP-Adresse geliefert.

Sind auf dieser Website dann allerdings Werbebanner zu finden, werden weitere DNS-Abfragen gestartet, da die Werbebanner ja nicht auf dem Webspace der Internet-Seite gehostet werden, sondern über ein Content-Delivery-System verteilt werden. Wenn sich nun die URL eines Werbebanners auf einer schwarzen Liste vom Pi-hole befindet, blockiert der Adblocker die Anfrage, indem er den eigentliche DNS-Server gar nicht befragt, sondern einfach nur seine eigene IP-Adresse zurück liefert. Da unter dieser IP-Adresse nichts gefunden werden kann, wird in der Client-Anwendung das entsprechende Werbebanner gar nicht angezeigt.

Zwei DNS-Abfragen mit Pi-hole: Die obere Abfrage wird an den DNS-Server weitergeleitet, die untere Abfrage beantwortet Pi-hole mit seiner eigenen LAN-IP und leitet diese nicht an den DNS-Server weiter

Zwei DNS-Abfragen mit Pi-hole: Die obere Abfrage wird an den DNS-Server weitergeleitet, die untere Abfrage beantwortet Pi-hole mit seiner eigenen LAN-IP und leitet diese nicht an den DNS-Server weiter

Als Nebeneffekt spart man sich dadurch auch etwas Bandbreite, da der Web-Request für das Werbebanner das lokale Netzwerk niemals verlässt.

Installation und Konfiguration Pi-hole

Die Installation von Pi-hole wird durch ein einfaches Skript erledigt. Anschließend muss die Netzwerk-Umgebung so konfiguriert werden, dass das Pi-hole als DNS-Proxy verwendet wird.

Vorbereitungen

Bevor das Installations-Skript ausgeführt werden kann, muss sichergestellt sein, dass das Ubuntu Universe-Repository in den Paketquellen eingerichtet ist. Gerade nach einer frischen Installation von Ubuntu Server 18.04.1 ist dies nicht der Fall, daher muss das Repository mit folgendem Befehl hinzugefügt werden:

sudo add-apt-repository universe

Installation Pi-hole

Die Installation erfolgt dann über den Aufruf eines Skripts:

curl -sSL https://install.pi-hole.net | bash

Hinweis: Das Abrufen eines Skripts und dir direkte Ausführung mittels bash ist durchaus problematisch – hier hat man keine Kontrolle darüber, was genau passiert (siehe hier). Besser ist es in diesem Fall das Install-Skript erst einmal herunter zu laden:

wget -O basic-install.sh https://install.pi-hole.net

Nach der Inspizierung des Skript, kann dieses zur Installation von Pi-hole verwendet werden:

sudo bash basic-install.sh

Nach der Überprüfung aller Abhängigkeiten wird das Setup von Pi-hole gestartet. Das System wird durch mehrere Installationsschritte konfiguriert.

Nach den einleitenden Worten wird darauf hingewiesen, dass das System eine statische IP-Adresse haben muss. Im Idealfall hat man dies gleich während der Installation des Betriebssystems so eingerichtet. Andernfalls wird der Setup-Assistent dazu auffordern, die Netzwerk-Konfiguration entsprechend anzupassen.

Pi-hole Setup: Hinweis auf statische IP-Adresse

Pi-hole Setup: Hinweis auf statische IP-Adresse

Anschließend wählt man den sog. Upstream DNS-Provider. Dies ist der DNS-Server, den Pi-hole befragen soll, wenn eine DNS-Abfrage nicht blockiert werden soll. Ich empfehle hier den DNS-Server von Cloudflare, besser bekannt als 1.1.1.1. Dies ist ein schneller DNS-Server, der nach eigenen Angaben Wert auf Privatsphäre legt (dennoch werden wir später einen anderen DNS-Server verwenden – doch dazu später mehr).
Man kann den verwendeten Upstream-DNS-Server allerdings auch nachträglich in der Weboberfläche von Pi-hole jederzeit ändern.

Pi-hole Setup: Auswahl des Upstream-DNS-Servers

Pi-hole Setup: Auswahl des Upstream-DNS-Servers

Als nächstes werden die Block-Listen konfiguriert. Hier wird bereits ein Standard-Set an Block-Listen vorgeschlagen, die man alle aktiviert lassen sollte.
Auch hier können die Block-Listen nach dem Setup jederzeit in der Weboberfläche geändert werden.

Pi-hole Setup: Auswahl der Block-Listen

Pi-hole Setup: Auswahl der Block-Listen

Im nächsten Schritt wird festgelegt, ob Pi-hole sowohl IPv4, als auch IPv6-Verbindungen überwachen soll. Hier sollten beide Optionen aktiviert sein.

Pi-hole Setup: Auswahl Protokolle (IPv4/IPv6)

Pi-hole Setup: Auswahl Protokolle (IPv4/IPv6)

Es folgen ein paar informative Schritte im Assistenten, bis gefragt wird, ob man die Web-Oberfläche von Pi-hole installieren möchte. Dies sollte man auf jeden Fall aktivieren, da man ansonsten alle Einstellungen nur umständlich über die Kommandozeile ändern kann.

Pi-hole Setup: Die Web-Oberfläche sollte mit installiert werden

Pi-hole Setup: Die Web-Oberfläche sollte mit installiert werden

Da Pi-hole für die Web-Oberfläche einen Webserver benötigt, sollte dieser im folgenden Schritt ebenfalls mit installiert werden.

Pi-hole Setup: Der Webserver sollte ebenfalls installiert werden

Pi-hole Setup: Der Webserver sollte ebenfalls installiert werden

Im letzten Schritt wird man gefragt, ob man die Queries loggen möchte. Auch diese Option sollte aktiviert sein, da man sich ansonsten schwertut, fehlerhaft geblockte Inhalte zu identifizieren.

Pi-hole Setup: Auch die Queries sollten geloggt werden

Pi-hole Setup: Auch die Queries sollten geloggt werden

Nun startet der eigentliche Installations-Prozess.

Im Anschluss wird nochmals eine Zusammenfassung und das initiale Passwort für die Admin-Oberfläche angezeigt.

Pi-hole Setup: Installation abgeschlossen

Pi-hole Setup: Installation abgeschlossen

Wieder zurück in der Kommandozeile sollte man dieses Passwort am besten sofort ändern. Dies geschieht über folgenden Befehl:

pihole -a -p

Dann noch zwei Mal das gewünschte Passwort eingeben und das Setup ist endgültig abgeschlossen.

Nun kann die Weboberfläche über die URL http://192.168.178.64/admin/ erreichen (wenn die IP-Adresse der Maschine 192.168.178.64 ist). Im Menü kann man sich über Login mit dem soeben angelegten Passwort anmelden, damit man Zugriff auf sämtliche Optionen von Pi-hole erhält.

Pi-hole: Admin-Oberfläche

Pi-hole: Admin-Oberfläche

Pi-hole Einstellungen

Nun sollten als erstes die Einstellungen vom Pi-hole überprüft und ggf. angepasst werden. Dazu einfach (nach dem Login) in linken Menü auf Settings klicken. Über das obere Menü können nun verschiedene Optionen eingeblendet werden:

  • System: Dies ist eine einfache Übersicht des Systems. Von Interesse sind hier erst einmal nur die IP-Adressen (IPv4 und IPv6), über die Pi-hole erreichbar ist. Diese werden später noch für die Netzwerk-Konfiguration benötigt, daher sollten die Adressen am besten gleich notiert werden.
  • Blocklists: Die Übersicht der Block-Listen, die Pi-hole momentan verwendet (im Jargon von Pi-hole „Gravity“ genannt). Das Standard-Set an Block-Listen wurde bereits während der Installation angelegt. An dieser Stelle können Block-Listen hinzugefügt oder entfernt werden.
  • DNS: Hier sind alle Einstellungen bzgl. DNS zu finden. Zunächst einmal sind dies die DNS-Server, die Pi-hole als Upsteam-DNS verwendet. Wir haben im Rahmen des Setups die Cloudflare-DNS-Server angegeben, daher sind hier die entsprechenden Optionen angehakt sein (sowohl für IPV4, als auch IPv6).Wer hier Wert auf Privatsphäre legt, der sollte hier einen anderen DNS-Server angeben. Ein guter DNS-Server, der nicht zensiert und auch nicht loggt, ist z.B. der DNS-Server von Digitalcourage. Hierzu ist es notwendig, einen Custom-DNS-Server anzugeben:

    Custom 1 (PVv4): 46.182.19.48
    Custom 3 (IPv6): 2a02:2970:1002::18

    Damit ausschließlich der DNS-Server von Digitalcourage verwendet wird, müssen die Optionen zum Verwenden der Cloudflare-DNS-Server deaktiviert werden.

    Pi-hole Einstellungen: DNS (mit Digitalcourage DNS-Server)

    Pi-hole Einstellungen: DNS (mit Digitalcourage DNS-Server)

    Eine Übersicht über weitere DNS-Server, die Wert auf Privatsphäre legen findet man z.B. hier.

    Etwas weiter unten findet man die Option für DNSSEC, welche nach der Installation zunächst einmal deaktiviert ist. Dabei handelt es sich um die Domain Name System Security Extensions. Vereinfacht ausgedrückt kann man damit die Validierung der über DNS erhaltenen Daten einschalten. Unterstützt der verwendete DNS-Dienst DNSSEC (was bei Cloudflare der Fall ist), sollte diese Option gleich aktiviert werden.

Alle anderen Optionen können auf Standard-Werten belassen werden.

Netzwerk-Konfiguration

Pi-hole ist nun einsatzbereit, wird jedoch noch nicht genutzt. Um dies zu ändern, muss jeder Client im Netzwerk die IP-Adresse von Pi-hole als DNS-Server verwenden. Hier gibt es prinzipiell zwei Ansätze. Welche Variante die passende ist, hängt vom jeweiligen Einsatzzweck und Anforderungen ab.

Variante 1: Pi-hole als DNS-Server am Router

Wenn man nicht auf jedem Client einzeln einen den DNS-Server angeben möchte, dann sollte man den Pi-hole einmal zentral als DNS-Server festlegen. Dies passiert in der Weboberfläche des Routers.

Ich empfehle diese Vorgehensweise, da man ohne viel Aufwand zum gewünschten Ergebnis kommt und die Konfiguration für 99% der privaten Netzwerke passen sollte.

Pi-hole als DNS-Server am Router

Pi-hole als DNS-Server am Router

Leider unterscheidet sich die Vorgehensweise von Router zu Router. An dieser Stelle wird das Vorgehen exemplarisch an einer FritzBox gezeigt.

Die DNS-Einstellungen befinden sich hier unter Internet > Zugangsdaten > DNS-Server. Hier sind die IP-Adressen (jeweils IPv4 und IPv6) von Pi-hole einzutragen.

DNS-Einstellungen der FritzBox

DNS-Einstellungen der FritzBox

Wichtig: Wie im Screenshot zu erkennen, werden für den bevorzugten und alternativen DNS-Server jeweils die gleichen IP-Adressen angegeben. Hier sollten nur die Adressen des Pi-hole und keine anderen DNS-Server (wie z.B. 1.1.1.1) angegeben werden. Hintergrund ist, dass die FritzBox wahlweise mal den bevorzugten und den alternativen DNS-Server nutzt. Wenn hier nun noch ein zweiter DNS-Server eingetragen werden würde, hätte dies zur Folge, dass Werbung manchmal blockiert werden würde und manchmal jedoch nicht.

Wenn die Einstellungen übernommen wurden, nutzt die FritzBox Pi-hole als einzigen DNS-Server. Alle Clients (PCs, Tablets, Smartphones, etc.) die nun ihrerseits die FritzBox als DNS-Server verwenden sind dann automatisch und ohne weiteres Zutun durch Pi-hole „geschützt“.

Vorteile Variante 1:

  • Es sind keine Anpassungen auf den Clients notwendig, die den Router als DNS-Server verwenden.
  • Daher kann ein Client auch nicht falsch konfiguriert werden und kann die DNS-Abfrage über Pi-hole nicht „umgehen“.
  • Gilt sowohl für DHCP-Clients, als auch Geräte mit statischer IP (siehe Variante 2).

Nachteile Variante 1:

  • Um eine DNS-Abfrage durchzuführen wird hier ein zusätzlicher „Hop“ benötigt (Client -> Router -> Pi-hole -> Upstream-DNS-Server). Dies kostet etwas mehr Zeit pro DNS-Abfrage, allerdings sollte dies in der Praxis nicht spürbar sein.
  • Im Normalfall nutzen alle Clients den Router als DNS-Server (und damit nun auch Pi-hole). Soll ein Client nicht durch Pi-hole geschützt werden, so müssen die DNS-Einstellungen dieses Clients manuell angepasst werden.

Variante 2: Pi-Hole als DNS-Server im Router (DHCP)

Die meisten Heimnetzwerke sind so konfiguriert, dass alle Clients eine IP über DHCP vom Router zugewiesen bekommen. Da über DHCP auch der zu verwendende DNS-Server mitgegeben wird, kann man sich dies bei Variante 2 zu Nutze machen.

Pi-hole als DNS-Server am Router (per DHCP)

Pi-hole als DNS-Server am Router (per DHCP)

Hier wird nicht der DNS-Server für den ganzen Router geändert, sondern nur die DHCP-Einstellungen angepasst. Exemplarisch findet man bei einer FritzBox diese Einstellungen unter Heimnetz > Netzwerk > Netzwerkeinstellungen > IP-Adressen > IPv4-Adressen/IPv6-Adressen.

Unter Lokaler DNS-Server ist hier die IP der Maschine mit Pi-hole anzugeben.

DHCP-Einstellungen der FritzBox (IPv4)

DHCP-Einstellungen der FritzBox (IPv4)

Neben den DHCP-Einstellungen für IPv4 müssen dann ebenso die Einstellungen für IPv6 angepasst werden.

Wichtig: Dieses Vorgehen ist sehr praktisch, wenn alle Client im Netzwerk ihre IP per DHCP zugewiesen bekommen. Wenn Client allerdings eine statische IP haben, ist diese meist manuell konfiguriert. Hier ist dann kein DHCP im Spiel und somit müssen alle Clients mit statischer IP auf den neuen DNS-Server „umgehoben“ werden.

Vorteile Variante 2:

  • Es sind keine Anpassungen auf den Clients notwendig, wenn diese ihre IP über DHCP zugewiesen bekommen.
  • DHCP-Clients können Pi-hole nicht umgehen.
  • Man spart sich einen „Hop“ bei einer DNS-Abfrage (DHCP-Client -> Pi-hole -> Upstream-DNS-Server).

Nachteile Variante 2:

  • Clients mit statischer IP (ohne DHCP) müssen manuell konfiguriert werden, so dass Pi-hole als DNS-Server genutzt wird. Wird dies an einem Client vergessen, wird hier weiterhin Werbung angezeigt werden.
  • Wenn viele Clients mit statischer IP im Netzwerk vorhanden sind, ist Variante 2 u.U. sehr aufwendig, da wieder jeder Client einzeln konfiguriert werden muss.

Variante 3: Pi-hole als DNS-Server auf den Clients

Als Alternative kann können aber auch sämtliche Clients so konfiguriert werden, dass diese Pi-hole als DNS-Server verwenden (und nicht mehr den Router). In diesem Fall müssen alle Geräte, die von Werbung befreit werden sollen, einzeln konfiguriert werden.

Pi-hole als DNS-Server auf den Clients

Pi-hole als DNS-Server auf den Clients

Auch hier ist es schwierig eine detaillierte Anleitung zu liefern, da sich die Vorgehensweise von Gerät zu Gerät unterscheidet. Hier soll daher nur die Vorgehensweise unter Windows 10 exemplarisch demonstriert werden.

Dazu muss in den Netzwerk-Einstellungen von Windows ein eigener DNS-Server angegeben werden. Dazu einfach in der Windows-Suche nach „Netzwerk“ suchen und Netzwerk- und Freigabecenter wählen. Hier werden dann alle verfügbaren Netzwerk-Schnittstellen aufgelistet. Durch einen Klick auf die jeweilige Verbindung wird der Status der Verbindung gezeigt. Hier wählt man nun Eigenschaften und geht durch einen Doppelklick in die Einstellungen von Internetprotokoll, Version 4 (TCP/IPv4). In diesem Dialog kann dann ein eigener DNS-Server angegeben werden.

DNS-Einstellungen unter Windows 10 (IPv4)

DNS-Einstellungen unter Windows 10 (IPv4)

Wichtig: Auch hier sollte ausschließlich die IP-Adresse der Pi-hole Maschine sowohl als bevorzugter, als auch alternativer DNS-Server angegeben werden.

Vorteile Variante 3:

  • Hier können Clients selektiv konfiguriert werden. Soll auf einem Client keine Werbung blockiert werden, kann dieser so konfiguriert werden, dass dieser weiterhin den Router als DNS-Server verwendet und daher von der Filterung durch Pi-hole nicht betroffen ist.
  • Man spart sich einen „Hop“ bei einer DNS-Abfrage (Client -> Pi-hole -> Upstream-DNS-Server).

Nachteile Variante 2:

  • Man muss jeden Client einzeln so konfigurieren, so dass Pi-hole als DNS-Server verwendet wird. Vergisst man dies bei einem Client, wird dieser weiterhin Werbung angezeigt bekommen.
  • Da der zu verwendende DNS-Server auf jedem Betriebssystem/Gerät anders eingerichtet wird, ist diese Variante gerade bei großen Netzwerken sehr aufwändig.

Test der Funktionalität

Nachdem nun alle Clients Pi-hole als DNS-Server verwenden, wird es Zeit für einen ersten Test. Dazu einfach eine Website aufrufen, die normalerweise Werbung anzeigt. Wenn alles geklappt hat, dann sollte diese Werbung nun wie von Geisterhand verschwunden sein.

Darüber hinaus gibt es auf der Website von Pi-hole eine spezielle Testseite, mit der man die Funktion von Pi-hole testen kann.

Das Tolle ist nun, dass man nicht nur am PC/Browser nicht mehr von Werbung bombardiert wird, sondern dass alle netzwerkfähigen Geräte davon profitieren, egal ob Smartphones, Tablets oder gar Smart-TVs.

Pi-hole in Aktion auf dem Smartphone (hier am Beispiel der Google News App)

Pi-hole in Aktion auf dem Smartphone (hier am Beispiel der Google News App)

DNS over TLS mit Stubby

Viele Webseiten nutzen Verschlüsselung über HTTPS. Hier können die Website-Inhalte also nicht von einem Angreifer, der sich zwischen den Webserver und einen Client „einhängt“ (Man-in-the-Middle) mitgelesen werden. DNS-Abfragen werden in der Regel unverschlüsselt über UDP übertragen. D.h. der Kommunikationsweg zwischen Client und DNS-Server ist mehr oder weniger ungeschützt. Auch wenn ein Angreifer nicht an die (dank HTTPS verschlüsselten) Inhalte herankommt, so kann er jedoch die DNS-Abfragen eines Clients mitlesen und ggf. auch manipulieren.

Um diese Lücke zu schließen, wurde das Protokoll DNS over TLS (DoT) entwickelt. Dabei werden sämtliche DNS-Abfragen über TLS verschlüsselt. Mit dem zusätzlichen Programm Stubby kann man mit Pi-hole ebenfalls DNS over TLS nutzen, so dass sämtliche DNS-Abfragen nicht mehr unverschlüsselt über die Leitung gehen.

Pi-hole als DNS-Server am Router mit Stubby

Pi-hole als DNS-Server am Router mit Stubby

Wie man auf dem Bild erkennen kann, ist hier ein zusärtlicher „Hop“ erforderlich (Client -> Router -> Pi-hole -> Stubby -> Upstream-DNS-Server). Ebenso gibt es einen gewissen Overhead durch das verwendete Protokoll für DNS over TLS. Daher dauern bei dieser Variante DNS-Abfragen nochmals ein bisschen länger. Die Praxis zeigt allerdings, dass man auch hier im Alltag keinen Unterschied feststellen wird.

Voraussetzungen

Um dies umzusetzen sind zwei Voraussetzungen zu erfüllen:

  • Pi-hole ab Version 4.0.0
  • Der Upstream-DNS-Server muss DNS over TLS unterstützen. Bei den hier gezeigten Servern von Cloudflare ist aber auch diese Voraussetzung erfüllt.

Installation Stubby

Das kleine Programm Stubby ist ein DNS-Daemon: Das Tool beantwortet DNS-Anfragen lokal auf dem „traditionellen Weg“ (also unverschlüsselt über UDP), nach außen (zum Upstream-DNS-Server) kommt jedoch DNS over TLS zum Einsatz.

Stubby ist bereits in den Paketquellen von Ubuntu enthalten und kann durch folgenden Befehl installiert werden:

apt-get update && apt-get install stubby

Falls das Paket nicht gefunden werden kann, muss evtl. das Universe-Repository in die Paketquellen von Ubuntu mit aufgenommen werden (siehe Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten).

Konfiguration Stubby

Nach der Installation von Stubby muss noch die Konfiguration des Tools angepasst werden, damit es mit Pi-hole zusammenarbeiten kann.

Die Konfiguration wird in der folgenden Datei vorgenommen:

nano /etc/stubby/stubby.yml

Hier sollten zwei Änderungen vorgenommen werden:

  • Ändern der verwendeten Ports: Da der DNS-Server von Pi-hole bereits auf Port 53 lauscht, muss Stubby auf einen anderen Port „ausweichen“. Dazu sucht man in der Konfiguration nach listen_addresses und ändert die folgenden Zeilen ab, damit Stubby auf Port 65053 läuft:
    listen_addresses:
      - 127.0.0.1@65053
      -  0::1@65053
  • Upstream-DNS-Server festlegen: Der von Stubby verwendete DNS-Server wird weiter unten in der Datei angegeben. Hier sind bereits mehrere DNS-Server hinterlegt, die Stubby verwenden kann. Diese können jedoch alle auskommentiert werden, da die zu nutzenden DNS-Server selbst festgelegt werden sollen.
    Hier empfehle ich zwei DNS-Server, die nicht zensieren und auch keine Anfragen protokillieren: Zum einen den DNS-Server von Digitalcourage, zum anderen den DNS-Server von dismail.de:
    # Digitalcourage DNS (IPv4)
    # https://digitalcourage.de/support/zensurfreier-dns-server
    - address_data: 46.182.19.48
      tls_auth_name: "dns2.digitalcourage.de"
      tls_pubkey_pinset:
        - digest: "sha256"
          value: v7rm6OtQQD3x/wbsdHDZjiDg+utMZvnoX3jq3Vi8tGU=
    
    # Digitalcourage DNS (IPv6)
    # https://digitalcourage.de/support/zensurfreier-dns-server
    - address_data: 2a02:2970:1002::18
      tls_auth_name: "dns2.digitalcourage.de"
      tls_pubkey_pinset:
        - digest: "sha256"
          value: v7rm6OtQQD3x/wbsdHDZjiDg+utMZvnoX3jq3Vi8tGU=
    
    # dismail.de (IPv4)
    # https://dismail.de/info.html#dns
    - address_data: 80.241.218.68
      tls_auth_name: "fdns1.dismail.de"
      tls_pubkey_pinset:
        - digest: "sha256"
          value: MMi3E2HZr5A5GL+badqe3tzEPCB00+OmApZqJakbqUU=
    
    # dismail.de (IPv6)
    # https://dismail.de/info.html#dns
    - address_data: 2a02:c205:3001:4558::1
      tls_auth_name: "fdns1.dismail.de"
      tls_pubkey_pinset:
        - digest: "sha256"
          value: MMi3E2HZr5A5GL+badqe3tzEPCB00+OmApZqJakbqUU=
    Eine Übersicht über weitere DNS-Server, die Wert auf Privatsphäre legen findet man z.B. hier.

    Durch die Angabe vom mehreren Upstream-DNS-Servern nutzt Stubby zur Bearbeitung von DNS-Requests auch mehrere Server (z.T. auch parallel). Dadurch kann auch nochmals die Privatsphäre verbessert werden, da nicht alle DNS-Anfragen an den gleichen Anbieter gehen.

    Alle weiteren DNS-Server, die in der Datei vorhanden sind, sollten auskommentiert werden (einfach eine Raute ‚#‘ vor jede Zeile schreiben).

Stubby in Pi-hole als Upstream-DNS-Server einrichten

Der letzte Schritt zum funktionierenden DNS over TLS führt wieder in die Admin-Oberfläche von Pi-hole: Unter Settings > DNS wählt man dazu alle vorkonfigurierten DNS-Server ab. Nun wird Stubby als Custom DNS-Server eingetragen:

  • Custom 1 (IPv4): 127.0.0.1#65053
  • Custom 3 (IPv6): ::1#65053

Der Port wird hier nicht wie üblich durch einen Doppelpunkt, sondern durch eine Raute von der IP getrennt.

Pi-hole Einstellungen: DNS über Stubby

Pi-hole Einstellungen: DNS über Stubby

Nach dem Übernehmen der Einstellungen ist Stubby als Upstream-DNS-Server von Pi-hole eingerichtet und alle DNS-Abfragen werden über DNS over TLS verschlüsselt.

Der Alltag mit Pi-hole

Nach der Installation von Pi-hole sollte euer Netzwerk nun so gut wie werbefrei sein. Meine Erfahrung zeigt, dass man nach der Ersteinrichtung zunächst einmal ein paar Tage abwarten und beobachten sollte, die das System wirkt. Anschließend kann man Pi-hole auf seine eigenen Bedürfnisse anpassen.

Whitelisting

Evtl. wird man feststellen, dass einige Dienste nicht mehr wie gewohnt funktionieren. Hier kann Pi-hole die Ursache sein, indem zu viel geblockt wird. In diesem Fall kann man einige Domains wieder in eine Whitelist aufnehmen, so dass diese in Zukunft nicht mehr geblockt werden.

Dazu muss man zunächst einmal herausfinden, welche Domains fälschlicherweise geblockt werden. Hier kann das Log von Pi-hole helfen, welches man unter Tools Tail pihole.log findet. Wenn man das Log aufruft und anschließend den Dienst startet, der nicht mehr richtig funktioniert, dann wird man in diesem Log Einträge finden, die vom Dienst ausgehen und geblockt werden. Diese Domains kann man dann unter Whitelist eintragen, so dass diese zukünftig nicht mehr geblockt werden.

Da die fälschlicherweise geblockten Domains meist nicht so offensichtlich sind, muss man hier meistens etwas herumprobieren. Wenn eine Domain auf der Whitelist nicht die gewünschte Wirkung erzielt, dann probiert man eben weitere Domains aus, die beim Starten des entsprechenden Dienstes angesprochen werden. Das kann u.U. etwas Zeit in Anspruch nehmen, bis man die richtige(n) Domain(s) ausgemacht hat.

Hinzufügen weiterer Filterlisten

Beim Setup von Pi-hole wurden bereits einige Filterlisten hinzugefügt. Diese sind für den Anfang erst einmal ausreichend. Man kann jedoch jederzeit unter Settings > Blocklists weitere Listen hinzufügen. Welche Listen zum Einsatz kommen, ist natürlich von den eigenen Bedürfnissen abhängig. Hier sollte man es aber nicht übertreiben: Je mehr Block-Listen in Pi-hole geladen werden, desto höher ist auch die Wahrscheinlichkeit, dass bestimmte Dienste nicht mehr wie gewohnt funktionieren.

Bei den Block-Listen kann man generell zwischen zwei Arten unterscheiden: Zum einen gibt es Listen, die eher allgemein Werbung/Tracking blockieren (z.B. EasyList). Zum anderen gibt es auch besondere Listen, die sich auf das Blocken von einzelnen Diensten (z.B. Facebook oder HBB-TV)   spezialisiert haben.

Folgende Seiten sind eine gute Quelle für weitere Block-Listen:

Pi-hole + VPN

Pi-hole wirkt prinzipiell nur, wenn man sich im gleichen Netzwerk wie der Werbeblocker befindet. Sobald man beispielsweise mit dem Smartphone im Mobilfunknetz unterwegs ist, wird man wieder Werbung zu Gesicht bekommen.

Hier besteht jedoch die Möglichkeit, einen VPN-Tunnel ins Heimnetzwerk aufzubauen. Dies ist z.B. mit der App VpnCilla unter Android möglich. Hier befindet man sich dann dank VPN wieder im gleichen Netzwerk wie die Maschine, auf der Pi-hole läuft und als „Nebeneffekt“ wird dann wieder automatisch Werbung blockiert. Somit ist man dann auch im Mobilfunknetz wieder praktisch werbefrei unterwegs.

Der Vorteil, dass man durch Pi-hole etwas Bandbreite spart, ist im Heimnetzwerk eher weniger relevant. Bei den Mobilfunk-Volumen-Tarifen ist dies jedoch ein handfester Vorteil.

Pi-hole Admin-Oberfläche über das Internet erreichen

Pi-hole wurde in diesem Artikel auf einer separaten Maschine eingerichtet, so dass die Admin-Oberfläche nur im lokalen Netzwerk erreichbar ist. Dies sollte in den meisten Fällen ausreichend sein.

Wer jedoch aus dem Internet Zugriff auf die Pi-hole-Oberfläche benötigt, kann dies ebenfalls einrichten. Die genaue Vorgehensweise ist bereits im Artikel Zweite Web-Anwendung neben ownCloud/Nextcloud einrichten (am Beispiel WordPress) beschrieben, daher soll an dieser Stelle nur kurz auf diese Möglichkeit verwiesen werden.

Fazit

Sobald Pi-hole eingerichtet ist, ist man im Heimnetzwerk werbefrei unterwegs. Dies ist zunächst einmal eine Erleichterung, da man nicht mehr von Werbung überflutet wird, zusätzlich spart man auf diese Art und Weise auch etwas Bandbreite. Durch die zentrale Installation im Netzwerk wirkt dies auch ohne weiteres Zutun auf alle Geräte im Heimnetzwerk.

Dennoch muss man sich bewusst sein, dass man durch das Blockieren von Werbung Website-Betreibern schaden kann. Denn gerade kleinere Anbieter sind auf die Einnahmen durch Online-Werbung angewiesen. Hier sollte man sich Gedanken machen, ob man seine Lieblings-Webseiten nicht auf anderem Wege unterstützen oder zumindest eine Ausnahme in Pi-hole für diese Webseiten hinzufügen möchte.

Wie steht ihr zum Thema Adblocker? Habt ihr Pi-hole bereits im Einsatz und könnt weitere Block-Listen empfehlen, oder habt weitere Tipps und Tricks zum Netzwerk-weiten Werbeblocker? Hinterlasst mir dazu doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nie-mehr-werbung-pi-hole-auf-ubuntu-server-18-04/feed/ 26
Nextcloud App-Vorstellung: Lesbare Links mit ShareRenamer https://decatec.de/home-server/nextcloud-app-vorstellung-lesbare-links-mit-sharerenamer/ https://decatec.de/home-server/nextcloud-app-vorstellung-lesbare-links-mit-sharerenamer/#comments Sun, 26 Aug 2018 09:49:37 +0000 https://decatec.de/?p=4430 Nextcloud Logo

Heute möchte ich eine App für Nextcloud vorstellen: Mit der App ShareRenamer können geteilte Links einfach umbenannt werden.

Wenn man in Nextcloud einen Ordner oder eine Datei per Link teilt, dann erhält diese Freigabe automatisch einen öffentlichen Link zugewiesen. Leider sind diese Links immer eher kryptischer Natur, da diese aus einer zufälligen Zeichenfolge bestehen (z.B. https://meindomain.de/nextcloud/s/BMAASDej9BfdF2R). Diese Zeichenfolge kann sich natürlich niemand merken, so dass man die Freigabe-Links immer per Mail an Freunde, Verwandte oder auch Kunden verteilen.

Schön wäre es nun, wenn man diese Links umbenennen könnte, so dass aus https://meindomain.de/nextcloud/s/BMAASDej9BfdF2R beispielsweise https://meindomain.de/nextcloud/s/MeinGeteilterLink werden würde. Leider bietet Nextcloud dieses Feature nicht out-of-the-box…

ShareRenamer im Nextcloud App Store

Seit gestern gibt es genau dafür eine App im Nextcloud App Store: ShareRenamer

Damit ist es einfach möglich, einen geteilten Link umzubenennen. Dazu wird zunächst eine Datei oder ein Verzeichnis per Link geteilt. Dies kann in den Details zu einer Datei oder einem Verzeichnis im Reiter Teilen aktiviert werden (oder einfach auf das Teilen-Symbol in der Datei-Übersicht klicken).

ShareRenamer: Einfaches Umbenennen von geteilten Links

ShareRenamer: Einfaches Umbenennen von geteilten Links

Dank der App ShareRenamer erscheint nun unter dem Link selbst eine Schaltfläche zum Umbenennen. Hier wird dann einfach ein neuer Name für den Link angegeben. Nach einem Klick auf Umbenennen wird der Link umbenannt. Einzige Voraussetzung ist nur, dass der gewünschte Link-Name nicht schon vorher vergeben wurde.

Über das Menü („…“) des Links kann der Link auch gleich kopiert werden. Dieser kann dann einfach weitergegeben werden. Wenn die URL der eigenen Cloud soweit bekannt ist, dann muss dies dank des leicht zu merkenden Links nicht mehr zwingenderweise per Mail erfolgen.

Mein Weg zum Bereitstellen einer App im Nextcloud App Store

Die App ist sicherlich für den einen oder anderen ganz hilfreich. Eigentlich wäre der Artikel hier nun schon zu Ende.

Dennoch möchte ich hier etwas weiter ausholen und meine Erfahrungen schildern, wie die App letzten Endes im Store gelandet ist. Vielleicht kann dadurch der eine oder andere ermuntert werden, auch eine App bereit zu stellen und am Projekt Nextcloud mitzuwirken.

Da gibt’s doch bestimmt eine App dafür…

Ich hatte nämlich genau diese Anforderung für meine Nextcloud: Geteilte Links sollten umbenannt werden können, damit man sich die Links leichter merken kann.

Zunächst hatte ich einen Blick in den Nextcloud App Store geworfen. Hier sah es leider mau aus – eine entsprechende App war hier nicht zu finden. Die nächste Anlaufstelle war das Nextcloud Support Forum. Hier wurde bereits das eine oder andere Mal nach genau diesem Feature gefragt. Dazu gab es dann auch tatsächlich eine App, die jedoch nur auf GitHub verfügbar ist: Diese hört auf den Namen ShareRenamer.

…aber nicht im Nextcloud App Store

Die genannte App gab es schon länger, es gab allerdings ein Problem: Der Ersteller dieser App ist nicht mehr auf GitHub tätig – also hatte diese App momentan keinen Maintainer. Einige Leute hatten sich bereits das originale Repository geforked, um zumindest sicher zu stellen, dass diese App auch unter neueren Versionen von Nextcloud lauffähig ist (z.B. hier).

Es sah also nicht so aus, als ob diese App irgendwann einmal den Weg in den Nextcloud App Store finden würde. Ein weiteres Problem war, dass sich mit der nächsten Nextcloud-Version der Workflow zum Teilen von Ordnern und/oder Dateien ändern wird. Hier sind die Optionen zum Teilen nicht mehr direkt in der Seitenleiste verfügbar, sondern sind in einem Untermenü „verpackt“. Durch diese Änderungen wäre die App unter Nextcloud 14 nicht mehr lauffähig gewesen. Vermutlich wäre die App dann irgendwann einfach von der Bildfläche verschwunden.

Jeder kann mithelfen

Dennoch sind diese Apps meist als Open Source verfügbar, so dass jeder sich das entsprechende Repository forken und (unter bestimmten Voraussetzungen) Veränderungen durchführen kann. Auch eine veränderte Version kann dann einfach wieder veröffentlicht werden.

Ich komme zwar nicht aus der Ecke der Web-Entwicklung, aber die App nutzt im Prinzip nur etwas JavaScript, um das Umbenennen von Links zu ermöglichen. Dies sollte im Großen und Ganzen machbar sein und so war der Fahrplan eigentlich klar:

  • Die App brauchte noch etwas Feintuning, damit sich diese (qualitativ) gut in Nextcloud einfügt.
  • Die Lokalisierung der App war nicht vorhanden, so dass z.B. Fehlermeldungen immer in Englisch ausgegeben wurden. Hier mussten also einige Inhalte noch übersetzt werden.
  • Die App musste für Nextcloud 14 überarbeitet werden, damit sie auch noch mit der kommenden Nextcloud-Version lauffähig ist.

Das entsprechende Repository findet man hier: ShareRenamer@GitHub

Als ich mich an die Arbeit machte, war ich erstaunt über die Hilfsbereitschaft der Community. Ich brauchte beispielsweise Hilfe bei der Lokalisierung der App über Transifex. Morris Jobke hat nach einer kurzen Anfrage alles vorbereitet, so dass die App über die normalen Nextcloud-Lokalisierungs-Mechanismen übersetzt werden kann. Einen Tag später war die App dann bereits in verschiedene Sprachen übersetzt worden. Ein großer Dank geht daher an die Nextcloud-Community.

Hier möchte ich noch einmal darauf hinweisen, dass diese App nicht ursprünglich von mir erstellt wurde, sondern dass ich hier lediglich ein paar Anpassungen durchgeführt und die App im Nextcloud App Store veröffentlicht habe. Ich betrachte das daher nicht als „meine App“. Jeder kann hier mitwirken und neue Funktionen und/oder Bugfixes einbringen. Das ist ja das Tolle an Open Source Software.

Bei evtl. auftretenden Problemen mit der App sind dies zwei wichtige Anlaufstellen:

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-app-vorstellung-lesbare-links-mit-sharerenamer/feed/ 13
Auf dem Laufenden bleiben mit Twitter https://decatec.de/allgemein/auf-dem-laufenden-bleiben-mit-twitter/ https://decatec.de/allgemein/auf-dem-laufenden-bleiben-mit-twitter/#comments Sun, 29 Jul 2018 07:49:09 +0000 https://decatec.de/?p=4413 DecaTec Logo

Hier ein kurzer Hinweis für die Leser dieses Blogs. Die IT-Welt ist recht schnelllebig und dies merkt man besonders als Tech-Blogger. Ich versuche daher alle (auch ältere) Artikel auf einem aktuellen Stand zu halten. Wenn ich daher Änderungen an einem Artikel vornehme, pflege ich dabei immer eine Update-History, welche die vorgenommenen Änderungen an einem Artikel nachvollziehbar macht (z.B. bei neuen Programm-Versionen).

Für Leser ist dieses Vorgehen leider nicht sonderlich komfortabel. Man muss regelmäßig in meinem Blog vorbeischauen (das sehe ich natürlich gern) und dann aber noch sämtliche interessanten Artikel nach Updates durchforsten. Dies ist recht aufwändig und u.U. zeitintensiv.

Nun wurde ich schon von einigen Lesern abgesprochen, ob ich mich mal einen Newsletter einrichten könnte, mit dem ich aktiv informieren, wenn ein Artikel ein Update verpasst bekommen hat. Dank der DSGVO wäre dieses Unterfangen für mich aber leider recht aufwändig und schwer umzusetzen.

Update: Für alle, die Twitter nicht nutzen möchte, gibt es nun eine Übersichts-Seite mit allen Änderungen im Blog.

Twitter als Newsletter-Alternative

Aus diesem Grund will ich es ab nun mit Twitter als eine Art „Newsletter light“ ausprobieren. Wenn es nun ein Update gibt, werde ich dies kurz über Twitter kundtun. Dies sieht dann beispielsweise so aus:

Artikel-Update bei Twitter

Artikel-Update bei Twitter

Um nun aktiv über Änderungen in meinem Blog informiert zu werden, braucht ihr zunächst einen Twitter-Account (falls noch nicht vorhanden). Hier könnt ihr mir dann auf meinem Account @decatec_de folgen. Anschließend erscheinen Updates in regelmäßigen Abständen in eurem Twitter-Feed.

Was haltet ihr davon? Ist dies eine gute Alternative zu einem richtigen Newsletter? Hinterlasst mir dazu doch einfach einen Kommentar.

Update: Übersicht über alle Änderungen im Blog in der Update-Historie

Ich kann allerdings auch gut verstehen, wenn jemand Twitter aus verschiedenen Gründen nicht nutzen möchte.

Für diesen Fall habe ich nun eine Blog-weite Update-Historie hinzugefügt, in der zukünftig alle Änderungen und Updates des Blogs dokumentiert werden.

Die entsprechende Seite findet ihr entweder in der Header-Leiste oder unter den Direktlinks:

Update-Historie für decatec.de

Update-Historie für decatec.de

Die Leser haben nun die Wahl: Entwerder per Push-Prinzip über Twitter informiert werden, oder einfach im Pull-Prinzip regelmäßig über die Update-Seite auf dem Laufenden bleiben. So sollte für jeden etwas dabei sein.

Links

]]>
https://decatec.de/allgemein/auf-dem-laufenden-bleiben-mit-twitter/feed/ 3
Nextcloud: Online-Office mit ONLYOFFICE https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice/ https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice/#comments Fri, 29 Jun 2018 13:41:55 +0000 https://decatec.de/?p=4369 Nextcloud Logo

Ein klassisches Anwendungsgebiet für „die Cloud“ ist das Erstellen und die Bearbeitung von Office-Dokumenten. Diese können dann meistens direkt im Browser auch durch mehrere Benutzer gleichzeitig editiert werden. Nextcloud bietet dieses Feature nicht direkt out-of-the-box, allerdings kann die selbstgehostete Cloud leicht durch Apps erweitert werden. Genau hier setzt ONLYOFFICE an: Durch diese Erweiterung kann Nextcloud einfach um Online-Office-Funktionalitäten erweitert werden.

Dieser Artikel beschreibt daher die Installation und Konfiguration von ONLYOFFICE mittels Docker und das Zusammenspiel mit einer bestehenden Nextcloud-Instanz. Wie immer liegt das Augenmerk v.a. auf der Sicherheit aller beteiligten Systeme.

Achtung: Dieser Artikel ist nicht mehr aktuell. Das hier gezeigte Setup hat eine erhebliche Einschränkung: Der Zugriff auf Office-Dokumente ist hiermit nicht aus dem Internet, sondern nur aus dem lokalen Netzwerk (LAN) möglich.

In einem Folgeartikel wird ein verbessertes Setup gezeigt, bei dem diese Probleme nicht auftreten: Nextcloud: Online-Office mit ONLYOFFICE (mit eigener Subdomain)

Update-Historie (letztes Update 09.11.2018)
  • 09.11.2018:
    • Link auf den neuen Artikel über Nextcloud/ONLYOFFICE hinzugefügt.
  • 04.11.2018:
    • Hinweis auf die Einschränkungen des in diesem Artikel erwähnten Setups hinzugefügt.

 

ONLYOFFICE vs Collabora

Bevor es an die Installation geht, noch ein Hinweis: ONLYOFFICE ist nur eine Möglichkeit, Nextcloud um Online-Office-Funktionalitäten zu erweitern. Eine Alternative dazu ist Collabora. Die Installation und Einrichtung von Collabora habe ich bereits im Artikel Nextcloud: Online-Office mit Collabora beschrieben. Nun stellt sich natürlich die Frage, auf welche Lösung man setzen sollte. Hier gibt es keine eindeutige Empfehlung: Beide Lösungen integrieren sich gut in Nextcloud und bieten ähnliche Features.

Die Unterschiede zwischen den Office-Lösungen weden in diesem Artikel detailliert beschrieben. Aber Achtung: der Vergleich wurde von ONLYOFFICE veröffentlicht, daher ist es nicht auszuschließen, dass hier eine Lösung per se besser abschneidet. Der Artikel ist aber trotzdem interessant, da er auch die Unterschiede in der technischen Umsetzung beider Lösungen beleuchtet.

Was für den Endanwender sicherlich am wichtigsten ist: Collabora kommt aus der LibreOffice-Ecke und bietet daher die beste Unterstützung für die OpenDocument-Formate. Bei der Entwicklung von ONLYOFFICE wurde von Anfang an Wert auf die OOXML-Formate (Office Open XML – die von Microsoft Office bevorzugten Formate) gelegt. Nach eigenen Angaben unterstützt ONLYOFFICE die Microsoft Office Formate zu 100%.

Daher werden Anwender, die hauptsächlich mit Microsoft Office arbeiten, wohl eher die Lösung von ONLYOFFICE bevorzugen. Wer dagegen meist LibreOffice/OpenOffice nutzt, sollte sich Collabora mal näher anschauen.

Am besten einfach mal selbst beide Lösungen ausprobieren: ONLYOFFICE und Collabora können parallel installiert werden, so dass man sich nicht sofort auf eine Office-Variante festlegen muss.

Installation und Konfiguration von ONLYOFFICE

ONLYOFFICE hat einige Abhängigkeiten, so dass eine manuelle Installation durchaus aufwändig ist. Daher beschreibt der Artikel die Installation der Office-Lösung mittels Docker. Dadurch kann ONLYOFFICE in wenigen Schritten schnell und einfach installiert werden.

Voraussetzungen

Folgende Voraussetzungen sind für den Betrieb von ONLYOFFICE zu erfüllen:

  • Ein System, auf dem Docker installiert ist. Im Rahmen des Artikels setze ich Ubuntu Server ein, allerdings sollten die Schritte auch auf andere Distributionen übertragbar sein. Wie Docker selbst installiert wird, wurde bereits im Artikel Docker auf Ubuntu Server erklärt.
  • ONLYOFFICE ist recht speicherintensiv. Daher sollte auf dem entsprechenden PC/VM mindestens 4 GB RAM verfügbar sein (besser noch 6 GB). Aus genau diesem Grund wird ONLYOFFICE auch auf einem Raspberry Pi (Affiliate-Link) nicht optimal laufen. Auch wenn es prinzipiell möglich ist, ONLYOFFICE auf einem solchen Kleinst-Rechner zu betreiben, wird die Performance hier zu wünschen übriglassen.
  • Nextcloud muss über eine gesicherte SSL-Verbindung erreichbar sein. Wer die Cloud wie im Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban beschrieben installiert hat, ist bestens vorbereitet, da hier ein SSL-Zertifikat von Let’s Encrypt zum Einsatz kommt.

Häufig liest man, dass ONLYOFFICE nicht auf demselben Rechner wie Nextcloud installiert werden sollte, da es hier zu Problemen kommen könnte. Dies trifft allerdings nur dann zu, wenn ONLYOFFICE manuell installiert wird. Wenn die Office-Lösung wie hier beschrieben über Docker läuft, dann kann ONLYOFFICE problemlos auf der gleichen Maschine wie Nextcloud betrieben werden.

Es ist aber natürlich auch möglich, ONLYOFFICE auf einem anderen Rechner (z.B. eine zweite virtuelle Maschine) zu installieren. In diesem Fall müssen nur die IP-Adressen entsprechend angepasst werden.

Vorbereitung: Zertifikat erstellen

Die Kommunikation zwischen Nextcloud und ONLYOFFICE muss über eine gesicherte SSL-Verbindung erfolgen. Hier kann der Einfachheit halber ein selbst signiertes Zertifikat zum Einsatz kommen.
Es wäre auch möglich, ein eigenes Zertifikat von Let’s Encrypt speziell für die ONLYOFFICE-Verbindung zu nutzen. Der Aufwand wäre hier allerdings etwas höher, da sämtliche Requests dann durch den nginx Gateway-Host geleitet werden oder die Zertifikate immer manuell kopiert werden müssten (Let’s Encrypt Zertifikate haben nur eine Gültigkeitsdauer von 90 Tagen).
Ein selbst signiertes Zertifikat ist hier das Mittel der Wahl, da es einfach erzeugt werden kann und die Verbindung trotzdem verschlüsselt ist. Auch muss man hier keinerlei Anpassungen am Webserver vornehmen, was eine zusätzliche Fehlerquelle wäre.

Das Zertifikat wird durch die folgenden Befehle angelegt:

mkdir -p /app/onlyoffice/DocumentServer/data/certs
cd /app/onlyoffice/DocumentServer/data/certs
openssl genrsa -out onlyoffice.key 4096
openssl req -new -key onlyoffice.key -out onlyoffice.csr
openssl x509 -req -days 3650 -in onlyoffice.csr -signkey onlyoffice.key -out onlyoffice.crt
openssl dhparam -out dhparam.pem 4096
chmod 400 onlyoffice.key
chmod 400 onlyoffice.crt
chmod 400 onlyoffice.csr
chmod 400 dhparam.pem

  • Beim Befehl openssl req -new -key onlyoffice.key -out onlyoffice.csr wird man nach dem „Common Name“ gefragt (Common Name (e.g. server FQDN or YOUR name)). Hier ist einfach die IP des lokalen Systems anzugebnen (z.B. 192.168.178.60). Ebenso kann man ein „challenge password“ angeben. Dieses kann man einfach leer lassen (einfach mit Enter bestätigen).
  • Achtung: Die Erzeugung der sog. Diffie-Hellmann-Parameter mit einer Länge von 4096 Bit (openssl dhparam -out dhparam.pem 4096) kann u.U. sehr lange dauern. Auf schwacher Hardware kann das schon einmal mehrere Stunden in Anspruch nehmen. Wer nicht so lange warten möchte, kann die Schlüssel-Länge auf 2048 Bit reduzieren (openssl dhparam -out dhparam.pem 2048).
  • Das Zertifikat hat eine Gültigkeit von 3650 Tagen (10 Jahre). Hier kann bei Bedarf auch eine andere Gültigkeitsdauer angegeben werden.

Installation in einem Schritt

Die Installation von ONLYOFFICE erfolgt dann dank Docker mit nur einem einzigen Befehl:

docker run --name=ONLYOFFICEDOCKER -i -t -d -p 4433:443 -e JWT_ENABLED='true' -e JWT_SECRET='geheimes-secret' --restart=always -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver

Folgende Punkte gilt es hier zu beachten:

  • Da der Webserver bereits auf dem Port 443 (HTTPS) lauscht, kann der Docker-Container nicht den gleichen Port belegen. Der Parameter -p 4433:443 sorgt dafür, dass der Container selbst mit dem Port 443 (intern) arbeitet, nach außen wird jedoch der Port 4433 genutzt.
  • Die nächsten zwei Parameter (-e JWT_ENABLED=’true‘ -e JWT_SECRET=’geheimes-secret‘) sorgen dafür, dass zur Kommunikation mit dem Container ein sog. JSON Web Token benötigt wird. Im Grunde genommen handelt es sich dabei um ein Passwort („geheimes-secret“ – hier sollte man natürlich ein eigenes Passwort wählen), welches später in Nextcloud hinterlegt werden muss, damit die Verbindung zum ONLYOFFICE Container aufgebaut werden kann. Dies verhindert, dass der ONLYOFFICE-Container „unbemerkt“ von anderen Verbindungen genutzt werden kann.
  • Mit –restart=always wird angegeben, dass der Container bei jedem Systemstart hoch gefahren wird. Damit „überlebt“ der Docker-Container auch Neustarts des Systems.
  • Der letzte Parameter (-v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver) definiert ein sog. Volume: Alle Dateien, die im Verzeichnis /app/onlyoffice/DocumentServer/data des Hosts liegen, werden innerhalb des Containers im Verzeichnis /var/www/onlyoffice/Data onlyoffice/documentserver bereit gestellt. Diese Funktion wird benötigt, damit der Container das zuvor erzeugte Zertifikat nutzen kann.

Nun wird der ONLYOFFICE-Container heruntergeladen (ca. 650 MB), was je nach Internetverbindung ein paar Minuten dauern kann.

Installation von ONLYOFFICE mittels Docker

Installation von ONLYOFFICE mittels Docker

Ob der Container ordnungsgemäß läuft, kann man testen, indem man über den Browser eine Verbindung aufbaut (die URL dazu ist in unserem Fall https://192.168.178.60:4433). Durch den Einsatz des selbst signierten Zertifikats wird der Browser eine Warnung ausgeben, das stört uns an dieser Stelle allerdings nicht.

ONLYOFFICE läuft

ONLYOFFICE läuft

Nextcloud: ONLYOFFICE App aktivieren

Damit ONLYOFFICE nun aus Nextcloud heraus angesprochen werden kann, braucht man noch die entsprechende App. Man findet diese im App-Store von Nextcloud in der Kategorie Büro & Text.

ONLYOFFICE im Nextcloud App-Store

ONLYOFFICE im Nextcloud App-Store

Nextcloud-Konfiguration anpassen

Bevor nun die Verbindung zu ONLYOFFICE in Nextcloud hinterlegt werden kann, muss noch eine kleine Anpassung an der Konfiguration von Nextcloud erfolgen. Dazu wird die Konfiguration mit folgendem Befehl auf der Konsole geöffnet:

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

Hier wird nun am Ende der Datei (aber vor der letzten schließenden Klammer) ein Eintrag hinzugefügt:

'onlyoffice' =>
array (
    'verify_peer_off' => true,
),

Dieser Schritt ist zwingend erforderlich, da Nextcloud sonst die Verbindung zu ONLYOFFICE auf Grund des selbst signierten Zertifikats nicht zulässt.

Am Schluss sollte der ganze Rechner einmal neu gestartet werden:

reboot now

Verbindung zwischen Nextcloud und ONLYOFFICE herstellen

Der letzte Schritt zu einer Online-Office-Lösung mit Nextcloud ist nun nur noch das Hinterlegen der Verbindungs-Details zwischen der Cloud und ONLYOFFICE.

Dazu in Nextcloud einfach in die Einstellungen gehen. Unter Verwaltung > ONLYOFFICE findet man nun die entsprechenden Einstellungen:

  • Serviceadresse der Dokumentbearbeitung: Hier wird die IP-Adresse des Systems angegeben, auf dem der entsprechende Docker-Container läuft. In unserem Beispiel hat er PC die IP 192.168.178.60, daher wird hier https://192.168.178.60:4433 angegeben. Wichtig ist hier der Port, der auch beim Starten des Docker-Containers angegeben wurde (4433).
  • Geheimer Schlüssel (freilassen, um zu deaktivieren): Hier ist das JWT-Token anzugeben, welches beim Starten des Docker-Containers angegeben wurde.
  • Alle anderen Felder kann man leer lassen.
ONLYOFFICE Einstellungen in Nextcloud

ONLYOFFICE Einstellungen in Nextcloud

Nach einem Klick auf Speichern sollte eine Erfolgsmeldung kommen und die Verbindung zwischen Nextcloud und ONLYOFFICE wurde erfolgreich konfiguriert.

Online-Office im Browser

In der Datei-Ansicht von Nextcloud können nun einfach Office-Dokumente angelegt werden bzw. hochgeladen werden. Mit einem Klick werden diese nun mit ONLYOFFICE geöffnet und man kann mit der Bearbeitung beginnen.

Online-Office mit Nextcloud und ONLYOFFICE

Online-Office mit Nextcloud und ONLYOFFICE

Update von ONLYOFFICE

Von Zeit zu Zeit erscheinen nun neue Versionen des Docker-Containers von ONLYOFFICE. Um hier ein Update durchzuführen, sind nur wenige Schritte erforderlich.

Zunächst muss die ID des laufenden Containers mit folgendem Befehl ermittelt werden:

docker ps

Der Container wird gestoppt und entfernt:

docker stop <Container-ID>
docker rm <Container-ID>

Die neue Version des Containers wird über diesen Befehl herunter geladen:

docker pull onlyoffice/documentserver

Nun kann der aktualisierte Container wie gewohnt gestartet werden:

docker run --name=ONLYOFFICEDOCKER -i -t -d -p 4433:443 -e JWT_ENABLED='true' -e JWT_SECRET='geheimes-secret' --restart=always -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver

Troubleshooting

Manchmal kann es passieren, dass die Verbindung zum ONLYOFFICE-Server nicht auf Anhieb klappen will. Die Probleme können aber meist relativ schnell aus dem Weg geräumt werden.

Fehler beim Aufruf von ONLYOFFICE über den Browser

Um zu prüfen, ob ONLYOFFICE ordnungsgemäß läuft, kann man die IP der Maschine direkt im Browser aufrufen (in diesem Beispiel: https://192.168.178.60:4433). Wenn hier nur eine Fehlermeldung erscheint, dass die Website nicht erreichbar ist, sollte der laufende Docker-Container überprüft werden.

Zunächst wird die Container-ID ermittelt:

docker ps

Anschließend kann man sich die Logs des Containers anzeigen lassen:

docker logs <Container-ID>

Hier kann es vorkommen, dass ähnliche Meldungen wie diese angezeigt werden:

* Starting PostgreSQL 9.5 database server                               [ OK ]
* Starting RabbitMQ Messaging Server rabbitmq-server                    [ OK ]
Starting redis-server: redis-server.
Starting supervisor: supervisord.
* Starting nginx nginx                                                  [ OK ]
Generating AllFonts.js, please wait...Done
onlyoffice-documentserver:docservice: stopped
onlyoffice-documentserver:docservice: started
onlyoffice-documentserver:converter: stopped
onlyoffice-documentserver:converter: started
* Reloading nginx configuration nginx                                   [ OK ]
root@35b07178f48a:/#  * Starting PostgreSQL 9.5 database server          [ OK ]
* Starting RabbitMQ Messaging Server rabbitmq-server                            * FAILED - check /var/log/rabbitmq/startup_\{log, _err\}
                                                                         [fail]
Starting redis-server: redis-server.
Waiting for connection to the localhost host on port 5672
Waiting for connection to the localhost host on port 5672
Waiting for connection to the localhost host on port 5672
Waiting for connection to the localhost host on port 5672

Hier gibt es momentan wohl noch hin und wieder Probleme (siehe GitHub-Issues hier und hier). In diesem Fall hilft es meistens, den Docker-Container oder besser noch den ganzen PC neu zu starten (zur Not auch mehrmals).

Fehlermeldung beim Einbinden von ONLYOFFICE in Nextcloud

Wenn beim Konfigurieren der Verbindung zum ONLYOFFICE-Server eine Fehlermeldung auftritt (Fehler beim Anschließen (Bad Request oder Timeout Fehlermeldung)), sollte man zunächst mal das Log von Nextcloud überprüfen. Hier sollte meinst ein Hinweis auf das konkrete Problem zu finden sein.

Folgende Log-Meldung weist z.B. auf die fehlende Anpassung der config.php von Nextcloud in Bezug auf ONLYOFFICE hin (siehe hier):

file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed at /var/www/nextcloud/apps/onlyoffice/lib/documentservice.php#351

Fazit

Dank des verfügbaren Docker-Container für ONLYOFFICE kann Nextcloud schnell und einfach um Online-Office-Funktionen ergänzt werden. Da prinzipiell auch kein zweiter PC/VM zum Einsatz kommen muss, ist dies eine sinnvolle Erweiterung jeder Nextcloud-Installation.

Ihr konntet ONLYOFFICE mit diesem Tutorial erfolgreich installieren oder hattet mit der Vorgehensweise noch Probleme? Oder bevorzugt ihr Collabora als Online-Office-Lösung für Nextcloud? Dann hinterlasst doch einfach einen Kommentar.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-online-office-mit-onlyoffice/feed/ 49
Nextcloud: Web-Mail mit RainLoop https://decatec.de/home-server/nextcloud-web-mail-mit-rainloop/ https://decatec.de/home-server/nextcloud-web-mail-mit-rainloop/#comments Wed, 13 Jun 2018 14:03:42 +0000 https://decatec.de/?p=4341 Nextcloud LogoDie Cloud ist heutzutage ja der zentrale Dreh- und Angelpunkt in der digitalen Welt. Wer es mit Nextcloud geschafft hat, sich aus den Fängen der großen Cloud-Anbieter zu befreien, der möchte sicherlich möglichst viele Features auch über die eigene Cloud nutzen. Neben der Verwaltung von Dateien, Kontakten, Kalendern, u.v.m., ist es mit der App RainLoop auch möglich, die komplette E-Mail-Kommunikation in die selbstgehostete Cloud zu verlegen.

 

 

Update-Historie (letztes Update: 29.09.2018)
  • 29.09.2018:
    • Die RainLoop App für Nextcloud wird nun doch wieder weiterentwickelt und ist somit auch für Nextcloud 14 verfügbar.
  • 23.07.2018:
    • Hinweis mit aufgenommen, dass die RainLoop App für Nextcloud vermutlich nicht mehr weiterentwickelt werden wird.

Web-Mail mit Nextcloud: RainLoop oder Mail-App

Für das Senden und Empfangen von E-Mails stehen im Nextcloud App Store zwei unterschiedliche Apps bereit: RainLoop und die Nextcloud-eigene App Mail.

„Mail“ ist dabei (im Moment noch) ein ziemlich rudimentärer Webmailer mit einem recht geringen Funktionsumfang (beispielsweise ist es damit nicht möglich, E-Mail-Signaturen zu verwenden). Evtl. werden fehlende Funktionen in Zukunft noch nachgereicht. Im Moment taugt die App (meiner Meinung nach) allerdings noch nicht dazu, einen „richtigen“ E-Mail-Client zu ersetzen.

Einen sehr viel größeren Funktionsumfang bietet RainLoop. Dieser Webmailer ist schon seit einiger Zeit auf dem Markt und ist ursprünglich eine eigenständige Webanwendung, die (wie Nextcloud) im Normalfall selbst gehostet wird. Mit der Nextcloud-App gibt es aber nun die Möglichkeit, RainLoop innerhalb von Nextcloud zu nutzen, so dass „alles aus einem Guss wirkt“.

Welche der beiden Webmailer nun der bessere ist, kann man pauschal nicht sagen. Am besten einfach mal beide Apps ausprobieren.

In diesem Artikel soll es nun um die Installation und Konfiguration von RainLoop in Nextcloud gehen. Die Einrichtung ist zwar relativ einfach, dennoch gilt es, einige Schritte zu beachten.

Installation

RainLoop muss nicht separat installiert werden, sondern kann einfach über den Nextcloud App Store bezogen werden. Dazu einfach im App Store unter der Kategorie Kommunikation nach RainLoop suchen und aktivieren.

Nach ein paar Augenblicken sollte die App installiert worden sein und man findet in der Nextcloud-Menüleiste einen zusätzlichen Eintrag für Mail.

Konfiguration

Bevor man RainLoop nun nutzen kann, muss die Anwendung zunächst einmal konfiguriert werden. Dazu findet man in Nextcloud in den Admin-Einstellungen unter Zusätzliche Einstellungen den Punkt Go to RainLoop Webmail admin panel.

Nach einem Klick meldet man sich nun an:

  • Benutzername: admin
  • Passwort: 12345

Ja, dies ist ein Standard-Passwort, dass immer gleich ist und sofort geändert werden sollte. Dazu in das Menü Security wechseln und ein neues Passwort unter Admin Panel Access Credentials vergeben.

Nach diesem vielleicht wichtigsten Schritt können sämtliche anderen Optionen nach Bedarf gesetzt werden. Beispielsweise empfiehlt es sich, unter General Deutsch als Sprache zu wählen, damit die Benutzer eine Deutsche Oberfläche präsentiert bekommen.

Einen Punkt sollte man noch gleich mit anpassen: RainLoop präsentiert auf der Admin-Seite eine Warnung:

Warnung!

RainLoop data folder is accessible. Please configure your web server to hide the data folder from external access. Read more here: https://www.rainloop.net/docs/installation

Hintergrund ist, dass das Datenverzeichnis von RainLoop aus Sicherheitsgründen nicht direkt aus dem Internet erreichbar sein sollte, sondern nur über die Anwendung selbst.

Hier ist es notwendig, eine kleine Anpassung an der Webserver-Konfiguration vorzunehmen. Ich gehe im Folgenden davon aus, dass der Webserver wie im Artikel Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban eingerichtet wurde. Wenn ein anderer Webserver oder eine andere Konfiguration zum Einsatz kommt, müssen die folgenden Schritte evtl. noch ein wenig angepasst werden.

Die Änderung muss im vHost für Nextcloud vorgenommen werden:

nano /etc/nginx/conf.d/meinedomain.de_nextcloud.conf

Hier fügen wir unter dem letzten location-Block (aber noch vor der schließenden Klammer des server-Blocks) folgenden Inhalt ein:

location ^~ /nextcloud/apps/rainloop/app/data {
    deny all;
}

Durch die Änderungen am vHost muss der Webserver noch neu gestartet werden:

service nginx restart

Nun kann man wieder zu RainLoop wechseln und nach einem Refresh der Seite (STRG + F5) sollte die Warnung verschwunden sein.

Einrichtung von E-Mail-Konten

Die Einrichtung von E-Mail-Konten unterscheidet RainLoop von vielen anderen Mail-Clients. Um dem Benutzer möglichst viel Arbeit beim Hinzufügen von Accounts abzunehmen, muss der Administrator Mail-Domains vordefinieren. Die Benutzer können sich daraufhin ganz einfach mit ihrer Mail-Adresse anmelden, ohne die üblichen (technischen) Details wie IMAP/SMTP-Server-Adressen, Ports, etc. kennen zu müssen.

Dazu einfach in der Admin-Oberfläche von RainLoop den Punkt Domains wählen. Hier ist Google Mail bereits aktiv, so dass @gmail.com Adressen ohne weiteres Zutun funktionieren sollten. Wenn man nun E-Mail-Adressen von anderen Anbietern (z.B. GMX, Web.de, etc.) nutzen möchte, dann muss man diese hier als Domain konfigurieren.

Dazu einfach den Button Domain hinzufügen klicken. Wichtig ist nun, dass die komplette Domain als Name eingetragen wird. Bei GMX wäre dies also „gmx.de“ und eben nicht „gmx“, ansonsten ist eine Anmeldung an RainLoop mit einer@gmx.de Adresse nachher nicht möglich. An dieser Stelle können übrigens auch Wildcards verwendet werden: Möchte man daher sowohl Anmeldungen mit @gmx.de und @gmx.net zulassen, kann als Domain einfach „gmx.*“ eingetragen werden.
Die weitere Konfiguration (IMAP- und SMTP-Server, sowie die dazugehörigen Ports, etc.) ist abhängig vom Mail-Provider. Diese Informationen findet man häufig auf den Hilfeseiten der jeweiligen Anbieter (z.B. Serverdaten für IMAP und SMTP bei GMX).

RainLoop: Domain für GMX hinzufügen

RainLoop: Domain für GMX hinzufügen

Webmail-Oberfläche

Die Anmeldung an RainLoop ist für Benutzer dank der „Admin-Vorarbeit“ nun besonders einfach: Im Nextcloud-Menü einfach das Mail-Symbol wählen und sich mit der entsprechenden Mail-Adresse und dem Passwort des Mail-Accounts (nicht das Passwort des Nextcloud-Accounts) einloggen. Nun können sofort Mail geschrieben und empfangen werden.

Bessere Integration in Nextcloud

Leider ist RainLoop als eigenständige Webanwendung (noch) nicht so gut in Nextcloud integriert. Dies merkt man z.B., wenn man eine Mail verfassen möchte: Hier kann man nicht aus den bestehenden Kontakten aus Nextcloud wählen.

Die Integration mit Nextcloud kann daher nicht etwas verbessert werden. RainLoop kann dabei nicht direkt auf die Nextcloud-Kontakte zugreifen, sondern verwaltet diese in einer eigenen Datenbank. Diese muss dazu erst einmal auf der Kommandozeile angelegt werden:

mysql -u root -p

Nach der Eingabe des Root-Passworts kann die Datenbank für RainLoop angelegt werden:

create database rainloop_db;
create user rainloop_db_user@localhost identified by 'MeInPasSw0rT';
grant all privileges on rainloop_db.* to rainloop_db_user@localhost;
flush privileges;
exit;

Zurück in der Admin Oberfläche findet man unter dem Punkt Kontakte die Einstellungen zur Verwaltung der Kontakte.

Hier konfiguriert man zunächst einmal die Datenbank-Verbindung:

  • Typ: MySQL
  • DSN: mysql:host=localhost;port=3306;dbname=rainloop_db
  • Benutzer: rainloop_db_user
  • Passwort: Das oben vergebene Passwort

Nun sollte bei einem Klick auf Testen der Button nach ein paar Augenblicken grün werden. Das ist das Zeichen, dass die Datenbank-Verbindung erfolgreich aufgebaut werden konnte.

Zu guter Letzt aktiviert man nun weiter oben noch die Optionen Kontakte aktivieren (damit RainLoop überhaupt Kontakte unterstützt) und Kontakte-Synchronisierung erlauben (mit externem CardDAV-Server). Letzteres wird benötigt, damit die Synchronisierung mit Nextcloud funktioniert.

Nun loggt man sich wieder über Nextcloud auf einen Mail-Account bei RainLoop ein. In den Optionen des Benutzers (Zahnrad unten links) findet man nun den Menüpunkt Kontakte. Hier kann man zunächst einmal die Synchronisierung mit Nextcloud ermöglichen (Remote-Synchronisierung aktivieren).

Die CardDAV-URL findet man in der Kontakte-App von Nextcloud: Einfach beim gewünschten Adressbuch auf das Menü klicken (die drei Punkte) und den Eintrag Link kopieren wählen.

CardDAV-URL in Nextcloud ermitteln

CardDAV-URL in Nextcloud ermitteln

Diese URL kann man dann nebst Benutzername und Passwort (von Nextcloud) in den RainLoop-Kontakte-Einstellungen hinterlegen.

RainLoop: Kontakte (Einstellungen)

RainLoop: Kontakte (Einstellungen)

Die obere Option (Empfänger automatisch zu Ihrem Adressbuch hinzuzufügen) ist ein zweischneidiges Schwert: Auf der einen Seite ist es sicher praktisch, wenn Mail-Adressen automatisch nach Nextcloud synchronisiert werden, auf der anderen Seite werden kann sämtliche Empfänger-Adressen ungefragt zu Nextcloud übernommen. Wer oftmals Mails an die unterschiedlichsten Empfänger versendet, will diese Option wohl deaktivieren, da ansonsten die Kontakte-App von Nextcloud regelrecht „zugemüllt“ wird.

Nun können die Kontakte zwischen RainLoop und Nextcloud einfach über den Kontakte-Button und das erweiterte Menü (drei Balken) in RainLoop synchronisiert werden.

RainLoop: Kontakte synchronisieren

RainLoop: Kontakte synchronisieren

Fazit

RainLoop ist ein fortschrittlicher Webmailer mit einem gut durchdachten Konzept und einfacher Bedienung. Zwar merkt man hier und da, dass RainLoop als eigenständige Web-Anwendung neben Nextcloud läuft, dennoch klinkt sich der Webmailer nahtlos in die eigene Nextcloud ein.

Wer seine Mails direkt über Nextcloud verwalten möchte und keinen „schwergewichtigen“ E-Mail-Client wie Outlook oder Thunderbird nutzen möchte, der wird mit RainLoop auf jeden Fall auf seine Kosten kommen.

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-web-mail-mit-rainloop/feed/ 16
Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban https://decatec.de/home-server/nextcloud-auf-ubuntu-server-18-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/ https://decatec.de/home-server/nextcloud-auf-ubuntu-server-18-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/#comments Wed, 30 May 2018 14:04:49 +0000 https://decatec.de/?p=4137 Nextcloud LogoHinweis: Dieser Artikel zeigt die Einrichtung von Nextcloud auf Ubuntu Server 18.04 LTS. Ein aktualisiertes Tutorial für Ubuntu 20.04 LTS ist hier zu finden: Nextcloud auf Ubuntu Server 20.04 LTS mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban

 

Dieser Artikel beschreibt die Installation und Konfiguration von Nextcloud auf Ubuntu Server 18.04 LTS („Bionic Beaver“) mit nginx, MariaDB, PHP und Let’s Encrypt. Zur Verbesserung der Sicherheit und Performance wird ebenfalls die Einrichtung von Redis, Fail2ban und ufw behandelt.

Wer regelmäßig diesen Blog liest, wird der dies bestimmt bekannt vorkommen: Zu diesem Thema gab es bereits einige Artikel. Die letzte Anleitung (Nextcloud auf Ubuntu Server mit nginx, MariaDB, PHP, Let’s Encrypt, Redis und Fail2ban) war sehr ähnlich aufgebaut, jedoch kam seinerzeit Ubuntu Server 16.04 LTS zum Einsatz. Nach nun gut zwei Jahren ist im April 2018 eine neue LTS-Version von Ubuntu erschienen. Da sich hier bei der Installation und Konfiguration einiges geändert hat, ist es an der Zeit, dem Thema der selbstgehosteten Nextcloud einen neuen Artikel zu gönnen.

Update-Historie (letztes Update: 03.02.2020)
  • 03.02.2020:
    • Cipher Suite DHE-RSA-AES256-GCM-SHA384 entfernt.
  • 25.10.2019:
    • Anpassungen einiger Anweisungen im virtuellen Host von Nextcloud bzgl. PHP (Auslöser: Sicherheitslücke nginx/php-fpm, siehe hier).
  • 03.10.2019:
    • Anpassungen für Nextcloud 17:
      • Header X-Frame-Options
      • Regulärer Ausdruck für Fail2ban angepasst
  • 17.08.2019:
    • acme.sh sollte nicht mit Root-Rechten ausgeführt werden, daher wird für die Ausführung von acme.sh ein spezieller User angelegt.
  • 24.07.2019:
    • Anpassungen für TLSv1.3 (ssl_ciphers und ssl_ecdh_curve).
  • 15.06.2019:
    • ECDHE-RSA-AES256-SHA384 aus den ssl_ciphers entfernt (wird beim Qualys SSL Labs Test als „weak“ eingestuft).
  • 24.05.2019:
    • Erklärung für die Anweisung „resolver“ im Gateway-Host hinzugefügt.
  • 18.05.2019:
    • Hinweis hinzugefügt, dass bei der Generierung der Zertifikate am besten Copy&Paste und „Suchen & Ersetzen“ genutzt wird.
  • 26.04.2019:
    • Artikel komplett für Nextcloud 16 überarbeitet.
    • Manuelles Hinzufügen von Ubuntu-Paketquellen entfernt, da diese bei 18.04.2 standardmäßig enthalten sind.
    • Modifizierung der Datenbank für big int Support entfernt, da dies automatisch im Rahmen des Nextcloud-Setups erfolgt.
    • Der Cronjob für Nextcloud wird nun alle 5 Minuten ausgeführt (siehe Nextcloud Admin-Manual).
    • Eingesetzte Programm-Versionen aktualisiert.
  • 14.04.2019:
    • [arch=amd64] beim den Paketquellen für nginx (/etc/apt/sources.list.d/nginx.list) hinzugefügt.
    • Die Versionsangaben (php7.2-fpm) beim Installieren von PHP entfernt.
  • 12.04.2019:
    • Für den Versand von E-Mails von Fail2ban kommt nun msmtp zum Einsatz.
  • 07.03.2019:
    • Beim Setzen der SSL-Header wird nun der Parameter always mit angegeben, damit der Header unabhängig vom Response-Code geliefert wird.
  • 02.03.2019:
    • Anweisungen für ocm-provider bzw. ocs-provider im Gateway-Host hinzugefügt, da es ansonsten unter Nextcloud 15.0.5 zu Warnungen im Admin-Bereich kommt.
    • vHost für Nextcloud überarbeitet.
  • 27.02.2019:
    • Beschreibung zur Generierung der TLS-Zertifikate komplett auf acme.sh umgestellt, Anleitung für Certbot entfernt.
  • 02.02.2019:
    • Hinweis für acme.sh zum Generieren der TLS-Zertifikate hinzugefügt.
  • 21.01.2019:
    • Setzen von max_input_time = 3600 als PHP-Value im virtuellen Host von Nextcloud.
  • 03.01.2019:
    • Schritte zur Konvertierung der Datenbanktabellen auf big int nach dem Setup hinzugefügt.
  • 24.12.2018:
    • Verbesserung beim Anlegen der Datenbank für Nextcloud: Der UTF-8 Multibyte-Support wird nun gleich beim Anlegen der Datenbank aktiviert, so dass die Datenbank nicht mehr nach dem Nextcloud-Setup modifiziert werden muss.
    • Update der eingesetzten Programm-Versionen.
  • 19.12.2018:
    • Überarbeitung der virtuellen Hosts (Gateway-Host und vHost für Nextcloud): Überflüssige Anweisungen entfernt (proxy_set_header Answeiungen und locations für Well-Known-URLs/acme-challenge im Nextcloud vHost) und Konfiguration auf Nextcloud 15 abgestimmt.
    • Bei bestehenden Installationen bitte nochmals den Gateway-Host und den vHost für Nextcloud mit den bestehenden virtuellen Hosts abgleichen!
  • 15.12.2018:
    • Installation PHP: php-imagick hinzugefügt.
  • 12.12.2018:
    • Anpassungen für Nextcloud 15: Well-Known-URLs und angepasste Links.
  • 11.11.2018:
    • Informationen zu den Default-Werten in der Datei jail.local hinzugefügt.
  • 13.10.2018:
    • „Well-Known-URLs“ für DAV im Gateway-Host hinzugefügt, da es ansonsten ab Nextcloud 14.0.2 zu einer Warnung im Admin-Bereich kommt.
  • 04.10.2018:
    • Konfiguration der Paketquellen unter Ubuntu Server 18.04.1: Vor der Installation der Programme werden die Ubuntu-Repositories Universe, Multiverse und Restricted hinzugefügt.
  • 19.09.2018:
    • Fehler bei „Trusted Domains“ in der config.php von Nextcloud.
  • 07.09.2018:
    • Ergänzungen für Nextcloud 14.
      • Hinweis für Meldung „Die Verwendung des eingebauten PHP-Mailers wird nicht länger unterstützt“ hinzugefügt.
      • Links zum Nextcloud Administration Manual aktualisiert.
    • Im Gateway-Host wird die Referrer-Policy nun auf „no-referrer“ gesetzt.
    • Update der verwendeten Programm-Versionen.
  • 31.05.2018:
    • SSL-Konfiguration im Gateway-Host geändert: unter ssl_trusted_certificate wird nun die Datei chain.pem angegeben.
  • 02.06.2018:
    • Anleitung zum Aktivieren von 4-Byte-Support der Nextcloud-Datenbank hinzugefügt.
  • 07.06.2018:
    • Anleitung für nginx 1.15 überarbeitet (Achtung: veränderte Verzeichnisstruktur).
  • 08.06.2018:
    • Gateway-Host: Anpassung von ssl_ciphers und ssl_ecdh_curve.
    • Der SSL-Test sollte nun A+ (100%) ergeben.
  • 10.06.2018:
    • Warnung für die Aktivierung vom 4-Byte-Support hinzugefügt, da dies auf manchen Systemen zu Problemen führen kann.
  • 13.06.2018:
    • Hinweis für Internet-Anschlüsse mittels DS-Lite hinzugefügt. Um die Schritte dieses Tutorials durchzuführen, wird ein „echter“ IPv4-Anschlus benötigt.
    • Hinweis auf Zertifikat-Erneuerung durch Certbot überarbeitet, da bei der Installation automatisch ein Cronjob eingerichtet wird.

 

Motivation, Voraussetzungen und Konzept des Artikels

Wer meine Artikel regelmäßig liest, wird sicher wissen, dass ich großen Wert darauf lege, Wissen zu vermitteln. Das ist zunächst auch das Ziel dieses Tutorials. Da die Schritte zur Installation der eigenen Cloud im Prinzip einfach von oben nach unten abgearbeitet werden könnten, würde hier auch eine einfache Liste mit Anweisungen/Kommandozeilen-Befehlen reichen. Dennoch ist es meiner Meinung nach wichtig zu wissen, was man hier tut, anstatt einfach nur ein paar Befehle auf der Kommandozeile zu kopieren – besonders bei einer eigenen Cloud, in der u.U. auch sensible Daten gespeichert werden. Daher möchte ich mit dem Artikel Hintergrundwissen vermitteln, so dass der Leser nach Durcharbeiten des Tutorials die Zusammenhänge und Hintergründe versteht und somit auch eigene Lösungen bei evtl. auftretenden Problemen erarbeiten kann.

Ziele

Neben der Wissensvermittlung werden mit dem Artikel folgende konkrete Ziele verfolgt:

  • Installation der eigenen Nextcloud auf Ubuntu Server 18.04 LTS mit nginx, MariaDB und PHP.
  • Erhöhte Sicherheit der Cloud (PHP-Konfiguration, SSL, Nextcloud-Konfiguration laut Nextcloud Administation Manual).
  • Verschlüsselte Verbindung zur eigenen Cloud mittels HTTPS. Dazu kommt ein Zertifikat von Let’s Encrypt zum Einsatz.
  • Nextcloud soll in einem Unterverzeichnis des Webservers laufen und über die URL https://meinedomain.de/nextcloud erreichbar sein. Dadurch wird es möglich, neben der Cloud auch weitere Webanwendungen auf dem gleichen Server zu betreiben, siehe Zweite Web-Anwendung neben ownCloud/Nextcloud einrichten (am Beispiel WordPress).
  • In der Admin-Oberfläche von Nextcloud sollen keine Warnungen angezeigt werden.
  • Das Datenverzeichnis von Nextcloud soll außerhalb des www-Verzeichnisses liegen.
  • Verbesserung der Performance durch Verwendung von Redis für das Transactional File Locking.
  • Absicherung gegen Brute-Force-Attacken mit Fail2ban.
  • Einrichtung der Firewall ufw.

Zeitaufwand und Programm-Versionen

Zeitaufwand: ca. 3 Stunden

Eingesetzte Programm-Versionen:

  • Ubuntu Server 18.04.2 LTS („Bionic Beaver“)
  • Nextcloud 17.0.0
  • nginx 1.17.2
  • MariaDB 10.3.11
  • PHP 7.2.17
  • Redis 4.0.9
  • Fail2ban 0.10.2
  • OpenSSL 1.1.1

Voraussetzungen

Betriebssystem und Hardware

Als Betriebssystem kommt Ubuntu 18.04 LTS („Bionic Beaver“) zum Einsatz. Eine LTS-Version (Long Term Support) bietet sich für ein eigenes Cloud-Projekt an, da durch den verlängerten Support-Zeitraum (in diesem Fall fünf Jahre – bis April 2023) ein solches System über eine lange Zeit betrieben werden kann, ohne dass ein Distributions-Update zwingend erforderlich ist.

Prinzipiell kann aber auch jede andere Linux-Distribution (z.B. Debian) eingesetzt werden, die Schritte sollten überall nahezu identisch sein.

Die Hardware ist auch nicht entscheidend, erforderlich ist hierbei nur ein PC, auf dem Linux läuft. So ist es auch denkbar, das Tutorial auf einem Kleinstrechner wie dem  Raspberry Pi (Affiliate-Link) umzusetzen, da dieser weder viel Strom noch Platz braucht. Wenn etwas mehr Leistung benötigt wird, dann bietet sich auch ein Intel NUC (Affiliate Link) an.

Besonders interessant finde ich den Einsatz einer virtuellen Maschine (VM) für das Hosten der eigenen Cloud. Der Vorteil ist hierbei, dass bei virtuellen Systemen Snapshots angelegt werden können, die den Zustand der VM zu einem gewissen Zeitpunkt speichern. Im Notfall kann man dann die komplette virtuelle Maschine auf einen bestimmten Snapshot zurücksetzen. Darüber hinaus können virtuelle Systeme auch leicht in ein bestehendes Backup-Konzept mit eingebunden werden. Wie Ubuntu Server 18.04 als virtuelle Maschine unter Hyper-V eingerichtet und konfiguriert werden kann, zeigt der Artikel Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten.

Zugriff per SSH

Nach der Installation wird man einen Server normalerweise „headless“ laufen lassen, d.h. ohne angeschlossenen Monitor, Maus oder weitere Peripheriegeräte. Der Zugriff findet dann in der Regel über SSH statt (z.B. mit dem Programm PuTTY). Mehr Infos zum Zugriff mittels SSH sind ebenfalls im Artikel Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten zu finden.

DynDNS

Wenn die eigene Cloud nach der Installation auch aus dem Internet erreichbar sein soll, dann ist die Verwendung eines DynDNS-Dienstes ebenfalls eine Voraussetzung. DynDNS sorgt dabei dafür, dass die (öffentliche) IP des Servers immer auf eine DynDNS-Domain gemappt wird. Dies hat zum einen den Vorteil, dass man sich die (öffentliche) IP des Servers (genauer gesagt: des Routers) nicht merken muss. Sinnvoll wäre dies sowieso nicht, da sich nach der bei den meisten Providern üblichen Zwangstrennung nach 24 Stunden die IP-Adresse meistens ändert.
Zum anderen wird eine Domain für die Erzeugung des SSL-Zertifikats benötigt, da Let’s Encrypt keine Zertifikate für IP-Adressen ausstellen kann.

Welcher DynDNS-Dienst zum Einsatz kommst, spielt eigentlich keine Rolle. Ein solcher Dienst ist oftmals bei einem Hosting-Paket eines Webhosters bereits enthalten, so z.B. bei All-Inkl.com (Affiliate Link) im Paket „Privat Plus“.
Als kostenlosen Dienst mit gutem Support kann ich GoIP empfehlen.

Im Rahmen des Artikels verwende ich beispielhaft die Domain meinedomain.de. Diese Domain muss dann natürlich bei euch entsprechend angepasst werden.

Internet-Anschluss

Eine weitere Voraussetzung liegt beim Internet-Anschluss. In der heutigen Zeit nutzen viele Internet-Provider durch die Knappheit von IPv4-Adressen einen Mechanismus, der  Dual-Stack Lite (DS-Lite) genannt wird. Ohne nun genau auf die technischen Details einzugehen, werden im Netzwerk des Benutzers/Kunden IPv4-Adressen verwendet, nach außen (also Richtung Internet) handelt es sich jedoch um einen IPv6-Anschluss.

DS-Lite führt beim Kunden meist zu Problemen, da für portbasierte Protokolle (TCP, UDP), auf die wir im Rahmen des Tutorials angewiesen sind, keine Portfreigaben mehr eingerichtet werden können, da die Pakete an die öffentliche IP-Adresse des Kunden bereits beim Provider ausgefiltert werden.

Daher wird zum Hosten einer eigenen Cloud zwingend ein „echter“ IPv4-Anschluss benötigt. Mit einem DS-Lite-Anschluss ist es nicht möglich, mit der hier gezeigten Vorgehensweise eine eigene Cloud aufzusetzen.

Wer einen DS-Lite-Anschluss hat, kann evtl. eine Zusatz-Option für einen echten IPv4-Anschluss beim Provider dazu buchen. Falls der Provider eine solche Option nicht direkt anbietet, kann es oftmals auch helfen, beim Provider anzurufen und nach einer solchen Option zu fragen, die dann evtl. manuell gebucht werden kann.

Root-Rechte auf dem Server

Für die Installation und oftmals auch die Konfiguration von Programmen sind unter Linux meistens Root-Rechte erforderlich. Damit nicht vor jeden Befehl ein sudo mit angeführt werden muss, ist es empfehlenswert, sich am Anfang der Installation/Konfiguration einmalig Root-Rechter mit dem Befehl sudo -s zu verschaffen. Für die Dauer der Anmeldung arbeitet man dann mit Admin-Rechten auf dem System. Man sollte sich am Ende der Arbeiten allerdings wieder mit dem Befehl exit abmelden – ein dauerhaftes Arbeiten mit Root-Rechten ist nicht empfohlen.

Konzept

Dieser Artikel unterscheidet sich von vielen anderen Tutorials zum Thema Nextcloud. Der folgende Abschnitt beschreibt daher, was die Eckpfeiler dieses Artikels sind und welches Konzept sich dahinter verbirgt.

LEMP-Stack statt LAMP-Stack

Wenn es um das Webhosting geht, dann habt ihr sicher schon einmal von einen LAMP-Stack gehört. Darunter versteht man ganz einfach nur bestimmte Programme, die häufig zum Hosting von Websites verwendet werden: Linux (Betriebssystem), Apache (Webserver), MySQL (Datenbank) und PHP (Skriptsprache). Setzt man die Anfangsbuchstaben dieser Programme zusammen, versteht man, warum diese Konstellation als LAMP-Stack bezeichnet wird.

Ein sog. LEMP-Stack ist nun einfach eine Variante dieses Software-Pakets: Als Grundlage kommt hier auch Linux als Betriebssystem zum Einsatz, allerdings wird nginx als Webserver verwendet. Im Rahmen dieses Artikels habe ich mich auch gegen MySQL und für MariaDB entschieden. PHP kommt aber auch hier zum Einsatz, allein aus dem Grund, dass Nextcloud eine PHP-Anwendung ist. Die Bezeichnung LEMP-Stack ergibt sich wieder aus dem Anfangsbuchstaben der Programme (das „E“ kommt von der Aussprache von nginx: „Engine-X“).

Warum nutze ich hier also „abweichend vom Standard“ eine andere Software-Konfiguration? nginx als Webserver und MariaDB als Datenbanksystem bieten hier einige Vorteile:

  • nginx arbeitet im Allgemeinen ressourcenschonende als Apache. Hintergrund ist die Art und Weise, wie hier Web-Requests abgearbeitet werden: Apache erstellt pro Verbindung mit einem Client neue Threads bzw. Prozesse. Die Erzeugung derselben ist allerdings teuer, da vergleichsweise viel Rechenleistung benötigt wird.
    nginx geht hier etwas anders vor: Der alternative Webserver arbeitet mit einem sog. Thread-Pool, d.h. hier werden bei Start des Programms verschiedene Threads „im Voraus“ erzeugt, die dann Requests der Clients abarbeiten. Wenn die Arbeit eines Threads beendet ist, kann dieser Thread für den nächsten Request wiederverwendet werden. Dies ist besonders auf leistungsschwacher Hardware (wie z.B. einem Raspberry Pi) von Vorteil, da nginx weniger speicherintensiv zu Werke geht.
  • MariaDB ging aus einem Fork von MySQL hervor und ist zu diesem binärkompatibel. Damit ist MariaDB ein sog. Drop-In-Replacement zu MySQL (quasi ein 1:1 Ersatz). Daher müssen bei den darauf aufbauenden Anwendungen keine Änderungen am Quellcode vorgenommen werden. Ebenfalls sind alle Tools und Programme, die für MySQL entwickelt wurde auch automatisch mit MariaDB kompatibel.
    Durch die Binärkompatibilität ergeben sich hier nicht wirklich große Unterschiede zu MySQL. Allerdings steht hinter MariaDB kein großes Unternehmen (wie Oracle bei MySQL), sondern es handelt sich dabei um „echte“ Open-Source-Software. So setzen mittlerweile viele Linux-Distributionen MariaDB als Standard-Datenbanksystem ein. Somit sieht es so aus, als ob MariaDB das zukunftssicherere System wäre, was nicht „unter der Fuchtel“ eines Großkonzerns steht. Aus diesem Grund habe ich im Rahmen des Artikels MariaDB als Datenbanksystem den Vorzug gegeben.

Virtuelle Hosts und Konfigurations-Dateien von nginx

Bevor es hier etwas konkreter wird, ist es sinnvoll, sich etwas mit den Konfigurationsdateien von nginx zu beschäftigen. Der Webserver verwendet – wie schon Apache – sog. virtuelle Hosts (vHosts). Ein virtueller Host ist dabei erst einmal eine reine Textdatei, die die Webserver-Konfiguration für genau eine Website beschreibt. Folgende Dateien/Verzeichnisse sind dabei wichtig:

  • /etc/nginx/nginx.conf: Das ist zunächst einmal die globale Konfiguration des Webservers. Hier werden alle globalen Einstellungen definiert, die für alle Websites gelten sollen.
  • /etc/nginx/conf.d: In diesem Verzeichnis sucht der nginx nach virtuellen Hosts. Ein solcher vHost muss in diesem Verzeichnis liegen und mit der Dateiendung *.conf gespeichert werden. Andere Dateien, die nicht mit .conf enden, werden beim Start des Webservers ignoriert.

Die Einstellungen werden dabei vererbt: Die globalen Einstellungen gelten dabei für alle vHosts, daher müssen diese nicht in jedem virtuellen Host neu definiert werden. Allerdings kann ein vHost auch jederzeit die globalen Einstellungen überschreiben. Diese gelten dann nur im Kontext dieses einzelnen virtuellen Hosts.

Hinweis bei abweichender Verzeichnisstruktur bei nginx

Je nach verwendeter nginx-Version (siehe weiter unten), kann es sein, dass die Verzeichnisstruktur etwas abweicht. Am besten überprüft man direkt nach der Installation, wo der default-vHost zu finden ist. Wenn dieser im oben genannten Verzeichnis gespeichert ist, dann können die Schritte des Tutorials einfach weiter befolgt werden.

Wenn der default-vHost allerdings nicht in /etc/nginx/conf.d zu finden ist, dann liegt dieser meist unter /etc/nginx/sites-enabled. In diesem Fall kommt eine alternative Verzeichnisstruktur bei nginx zum Einsatz. In diesem Fall läuft die Verwaltung der virtuellen Hosts etwas anders ab:

  • /etc/nginx/sites-available: In diesem Verzeichnis sind die virtuellen Hosts enthalten, die nginx beim Start nicht lädt. Wenn man einen neuen vHost anlegt, dann nutzt man meist normalerweise dieses Verzeichnis. Die Dateiendung ist dabei egal und man lässt diese für gewöhnlich weg.
  • /etc/nginx/sites-enabled: Hier sind die vHosts enthalten, die der Webserver beim Starten lädt.
  • Um einen virtuellen Host zu aktivieren, muss sich dieser also im Verzeichnis sites-enabled befinden. Um nun nicht mit zwei unterschiedliche Dateien unter sites-available und sites-enabled hantieren zu müssen, kann einfach eine symbolische Verknüpfung für einen vHost angelegt werden. Wenn beispielsweise ein (deaktivierter) vHost /etc/nginx/sitesavailable/meinedomain.de aktiviert werden soll, dann wird eine solche Verknüpung mit diesem Befehl angelegt:
    ln -s /etc/nginx/sites-available/meinedomain.de /etc/nginx/sites-enabled/

Wenn diese alternative Verzeichnisstruktur bei nginx zum Einsatz kommt, dann ist im weiteren Verlauf des Artikels darauf zu achten, die Dateien der virtuellen Hosts an der richtigen Stelle zu platzieren.

Die Aufteilung in mehrere virtuelle Hosts

Was macht diesen Artikel nun besonders? In den meisten Tutorials zum Thema Nextcloud wird eben nur die eigene Cloud auf dem Server gehostet und ist dann direkt über die Root-Domain (also z.B. https://meinedomain.de) erreichbar. Das ist zunächst einmal kein Problem, wenn ausschließlich Nextcloud auf dem System gehostet werden soll. Aber was, wenn man sich die Möglichkeit offenhalten will, weitere Websites oder Webanwendungen auf dem gleichen Server zu hosten?

Hier gibt es prinzipiell mehrere Möglichkeiten, allerdings sollte man sich im Vorfeld Gedanken machen, wie dies mit virtuellen Hosts umgesetzt werden kann.

  • Ein einzelner virtueller Host:
    Dies ist vermutlich die naheliegendste Lösung. Hierbei werden alle Webanwendungen (bzw. die entsprechenden Webserver-Konfigurationen) in einem einzelnen virtuellen Host definiert. Das macht die Sache allerdings auf fehleranfällig, da ein kleiner Fehler in diesem virtuellen Host den ganzen Webserver und damit auch alle Websites lahmlegen kann. Ebenfalls kann eine Webanwendung nicht „mal eben schnell“ deaktiviert werden, da dazu sämtliche Anweisungen im virtuellen Host gelöscht oder auskommentiert werden müssten.

    Schematische Darstellung: Einzelner vHost für mehrere Webanwendungen

    Schematische Darstellung: Einzelner vHost für mehrere Webanwendungen

  • Ein virtueller Host pro Webanwendung:
    Ein besserer Ansatz zur Trennung der einzelnen Websites ist die Verwendung eines vHosts pro Website. Durch die strikte Trennung ist diese Lösung deutlich flexibler und weniger fehleranfällig.
    Allerdings gibt es hier evtl. ein Problem: Ein virtueller Host wird durch den Server-Namen (die Domain) und einen Port definiert. Um einen Client-Request genau einer Website zuordnen zu können, muss sich daher die Kombination Domain/Port für jede Website unterscheiden. Dieses Ziel kann man zum einen durch den Einsatz unterschiedlicher (Sub-)Domains erreichen. Im Rahmen des Artikels soll eine DynDNS-Domain verwendet werden und hier liegt evtl. das Problem: Viele Router bieten nur die Möglichkeit, eine einzelne DynDNS-Domain zu konfigurieren. Hier könnte man sich beim Einsatz mehrerer Domains mit einem sog. CNAME Resource Record behelfen, bei dem eine (Sub-)Domain einfach auf eine andere Domain (die DynDNS-Domain) gemappt wird.
    Die zweite Möglichkeit, eine Eindeutigkeit von Domain/Port zu erreichen ist natürlich die Verwendung der gleichen (Sub-)Domain bei unterschiedlichen Ports. Allerdings führt dies meistens zu Einschränkungen in der Benutzung der Webanwendungen. Wenn nämlich vom Standard (HTTP: 80, HTTPS: 443) abweichende Ports verwendet werden, müssen diese zum einen in der Firewall (Router) geöffnet werden, was Angreifern eine größere Angriffsfläche bietet. Zum anderen muss dann bei sämtlichen Client-Anwendungen die URL des entsprechenden Dienstes immer mit dem Port angegeben werden. Hier hat man dann meist einen erhöhten Aufwand bei der Einrichtung der Client-Anwendungen. Das macht diese Lösung (zumindest bei der Verwendung unterschiedlicher Ports) etwas unflexibel.

    Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Ports)

    Schematische Darstellung: Ein vHost pro Webanwendung (Eindeutigkeit durch unterschiedliche Ports)

  • Gateway-Host + einzelne virtuelle Host pro Webanwendung:
    Die dritte Möglichkeit ist eine Mischung aus den beiden anderen Vorgehensweisen. Hierzu kommt ein sog. Gateway-Host zum Einsatz, der erst einmal alle Client-Request auf den Standard-Ports (80/443) entgegennimmt. Die einzelnen Websites laufen dabei nicht im Web-Root, sondern in Unterverzeichnissen. Der Gateway-Host nutzt nun die Reverse-Proxy-Fähigkeiten von nginx, um die Anfragen auf Grund des Ziels (Verzeichnis) an einen anderen vHost weiter zu leiten. Dazu gibt es dann pro Webanwendung wieder einen virtuellen Host. Diese verwenden immer den gleichen Server-Namen (die lokale IP), aber unterschiedliche Ports. Da die vHosts „hinter“ dem Gateway-Host nur Server-intern arbeiten und nur der Gateway-Host die direkte Schnittstelle zum Internet/den Clients ist, ist die Auswahl der Ports hier nebensächlich. Dadurch müssen hier auch keine weiteren Ports in der Firewall geöffnet werden, da sämtliche Webanwendungen scheinbar die Standard-Ports 80 und 443 verwenden. Welche Webanwendung letzten Endes angesprochen werden soll, wird nur durch das Unterverzeichnis des Web-Roots (und nicht durch die Kombination Domain/Port) festgelegt.

    Schematische Darstellung: Gateway-Host und einzelne vHosts pro Webanwendung

    Schematische Darstellung: Gateway-Host und einzelne vHosts pro Webanwendung

Jede dieser drei Möglichkeiten hat dabei ihre Vor- und Nachteile. Die dritte Vorgehensweise bietet jedoch zum einen Flexibilität und ist technisch auch einfach umzusetzen. Daher ist nun das Ziel und die Besonderheit dieses Artikels, dass Nextcloud in einem Unterverzeichnis des Webservers laufen soll, später also über die URL https://meinedomain.de/nextcloud aufgerufen werden soll.

Weitere Webanwendungen können dann ohne großen Aufwand neben der eigenen Cloud auf dem gleichen Webserver betrieben werden. In einem weiterführenden Artikel habe ich bereits beschrieben, wie neben der Nextcloud auch WordPress auf dem gleichen Server installiert werden kann: Zweite Web-Anwendung neben ownCloud/Nextcloud einrichten (am Beispiel WordPress).

Installation und Konfiguration aller benötigten Programme

Nach diesem eher theoretischen Teil des Artikels soll es nun in die Praxis gehen.

Als Basis für dieses Tutorial dient der Artikel Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten, Voraussetzung ist also ein fertig installierter Ubuntu Server 18.04 LTS.

Ebenfalls sollte bereits eine statische IP-Adresse für den Server konfiguriert worden sein (die Vorgehensweise dazu ist auch im o.g. Artikel beschrieben). Ich gehe im weiteren Verlauf des Tutorials von der statischen IP 192.168.178.60 für den Server aus.

Betriebssystem-Updates

Zunächst wird das Betriebssystem auf den aktuellen Stand gebracht:

apt-get update && apt-get upgrade -V && apt-get dist-upgrade && apt-get autoremove
reboot

Programm-Installation

Bevor Nextcloud selbst installiert werden kann, müssen zunächst einmal alle anderen Programme (Webserver, Datenbank und PHP) installiert werden.

Exkurs: Installation aus dem Ubuntu-Paketquellen vs. Installation aus den Hersteller-Paketquellen

Doch vorher noch kurz ein Hinweis zu den Installationen: Meistens sind die verwendeten Programme bereits in den offiziellen Ubuntu-Paketquellen enthalten. Daher spricht erst einmal nichts dagegen, die Programme auch aus diesen Paketquellen zu installieren. Jedoch handelt es sich meistens auf Grund der Stabilität um ältere Programmversionen, die ebenfalls keine größeren (Feature-)Updates mehr bekommen, sondern nur noch kleinere Updates für Fehlerbehebungen. Dadurch kommt ein System schnell mal „in die Jahre“ und man kann beispielsweise keine Funktionen nutzen, die erst in neueren Programmversionen geliefert werden.

Die Alternative dazu ist die Installation der entsprechenden Programme aus den (offiziellen) Repositories der jeweiligen Anbieter. Diese Programmversionen sind meist wesentlich aktueller und werden auch in regelmäßigen Abständen mit (Feature-)Updates versorgt. Meist unterscheiden die Hersteller dabei nochmals zwischen zwei (oder sogar mehr) Entwicklungs-Branches: Oftmals gibt es einen Stable-Branch, der möglichst stabil gehalten wird. Auch hier sind meist keine größeren Updates mehr zu erwarten und neue Features werden erst nach z.T. langer Zeit in diesen Branch mit aufgenommen. Daneben gibt es meist noch einen Mainline-Branch, der zwar auch stabil sein sollte, aber zeitnah mit Updates und neuen Features versorgt wird.

Die Entscheidung, welche Programm-Versionen bzw. Branches zum Einsatz kommen, liegt nun beim Anwender:

  • Wenn Stabilität die wichtigste Eigenschaft der Programme ist, dann sollten die offiziellen Ubuntu-Repositories verwendet werden.
  • Meistens möchte man ein System allerdings über einen längeren Zeitraum betreiben, z.B. bis zum Erscheinen einer neuen Ubuntu LTS-Version. Wenn man hier Wert auf Stabilität legt und trotzdem einigermaßen aktuelle Software einsetzen will, dann sollte man auf den Stable-Branch der Hersteller setzen.
  • Wer dagegen gern auf neue Features setzt und die Programme auf einem möglichst aktuellen Stand halten möchte, der sollte den Mainline-Brach der Software-Hersteller nutzen.

Meine Erfahrung hat gezeigt, dass die Mainline-Branches der Hersteller ausreichend stabil sind. Ebenfalls setze ich gern auf neue Features, die meistens Vorteile in Sachen Performance geben. Zu guter Letzt möchte ich verhindern, dass die Software mit der Zeit „herausaltert“. Daher nutze ich in diesem Tutorial meist die Mainline-Branches aus den offiziellen Paketquellen der Hersteller.

Wer sich hier für andere Programm-Versionen entscheidet, der muss dies beim Eirichten der entsprechenden Repositories im späteren Verlauf beachten und ggf. die Schritte geringfügig anpassen.

Hinweis für Raspberry Pi Benutzer: Oftmals verzichten die Software-Hersteller darauf, in ihren Paketquellen Programm-Versionen für die ARM-Architektur bereit zu stellen. In diesem Fall würde ein Hinzufügen der Hersteller-Repositories zu einem Fehler bei der Programm-Installation führen. In diesem Fall muss man auf die Paketquellen von Raspbian/Debian zurückgreifen und kann keine Hersteller-Repositories einbinden.

nginx

Das erste Programm, was installiert wird, ist der Webserver.

Paketquellen hinzufügen

Optional: Wer nicht die Paketquellen aus dem offiziellen Ubuntu-Repository nutzen möchte, muss zunächst die gewünschten Paketquellen zum System hinzufügen. Ich habe mich hier für die Mainline-Version von nginx entschieden, da diese noch mit (Feature-)Updates versorgt wird und trotzdem für meine Zwecke ausreichend stabil ist (siehe nginx Blogbeitrag). Für andere Ubuntu-Versionen oder gar andere Distributionen sind die Paketquellen ggf. anders anzugeben, siehe nginx: Linux packages.

Zunächst wird der Key der nginx-Repositories auf dem System bekannt gemacht. Dieser Schritt ist notwendig, damit es bei der späteren Installation zu keinen Warnungen kommt:

wget -O - http://nginx.org/keys/nginx_signing.key | apt-key add -

Anschließend werden die Paketquellen selbst hinzugefügt. Die originale Datei für die Paketquellen (/etc/apt/sources.list) wird dabei nicht modifiziert, sondern es wird eine eigene Datei für nginx angelegt:

nano /etc/apt/sources.list.d/nginx.list

Hier fügen wir folgenden Inhalt ein:

# Nginx (Mainline)
deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ bionic nginx
deb-src [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ bionic nginx

Installation nginx

Nach der Aktualisierung der Paketquellen kann der Webserver installiert werden:

apt-get update
apt-get install nginx

Ob der Webserver korrekt läuft, kann man nach einem Neustart des Rechners durch den Aufruf der IP des Severs im Browser testen:

Der Webserver läuft

Der Webserver läuft

MariaDB

Also nächstes wird das Datenbank-System installiert.

Paketquellen hinzufügen

Bei MariaDB gibt es keine Unterscheidung zwischen Stable/Mainline, sondern nur Stable/Development. Allerdings gibt es mehrere Stable-Versionen, die parallel gepflegt werden. In den Ubuntu-Paketquellen ist ein „alter“ Stable-Release von MariaDB enthalten (10.1). Hier habe ich mich für den aktuellen Stable-Release (10.3) entschieden, da diese über einen längeren Zeitraum unterstützt wird (bis Mai 2023). Mehr Informationen zu den Releases von MariaDB gibt es in der MariaDB-Knowledgebase.

Zum einfachen Hinzufügen der MariaDB-Repositories gibt es ein praktisches MariaDB-Repository-Tool.

Wie schon bei nginx muss hier zunächst der Repository-Key bekannt gemacht werden, um später keine Warnungen zu erhalten:

apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8

Die Paketquellen werden wieder in eine eigene Datei hinzugefügt:

nano /etc/apt/sources.list.d/MariaDB.list

# MariaDB 10.3 repository list
# http://downloads.mariadb.org/mariadb/repositories/
deb [arch=amd64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu bionic main
deb-src http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu bionic main

Installation MariaDB

Nun kann das Datenbanksystem installiert werden:

apt-get update
apt-get install mariadb-server

Im Rahmen der Installation wird gleich nach einem Root-Passwort für MariaDB gefragt. Hier sollte man gleich ein ausreichend starkes Passwort wählen.

MariaDB: Angabe des Root-Passworts während des Setups

MariaDB: Angabe des Root-Passworts während des Setups

Wenn keine Abfrage nach dem Root-Passwort erscheint (z.B., wenn man keine Paketquellen für MariaDB hinzugefügt hat und die Version aus den Ubuntu Paketquellen installiert), dann wird das Passwort einfach später bei der Einrichtung von MariaDB vergeben.

PHP

In den Paketquellen von Ubuntu ist PHP 7.2 bereits enthalten. Hier gehe ich eher konservativ an die Sache heran, da in der Vergangenheit öfters mal Breaking Changes in neueren PHP-Versionen enthalten waren. Daher nehme ich hier die Version aus den Ubuntu-Repositories:

apt-get update
apt-get install php-fpm php-gd php-mysql php-curl php-xml php-zip php-intl php-mbstring php-bz2 php-json php-apcu php-imagick

Werden später weitere PHP-Pakete benötigt (z.B. zum Einbinden von SMB-Speicher unter Nextcloud), so können diese auch zu einem späteren Zeitpunkt installiert werden. Die hier aufgeführten Pakete sind quasi nur die „Minimal-Ausstattung“.

Let’s Encrypt/acme.sh

Zum Erzeugen des SSL-Zertifikats wird nun noch Let’s Encrypt benötigt. Hier gibt es mittlerweile einige Client-Implementierungen. Hier empfehle ich gerne acme.sh. Dies ist ein reines Bash-Skript, daher entfällt die Installation von Programmen aus dem Paketquellen. Hintergründe und Details sind im Artikel Let’s Encrypt Zertifikate mit acme.sh und nginx enthalten.

Hinweis: acme.sh sollte nicht mit Root-Rechten (also auch nicht mit sudo) ausgeführt werden. Daher legen wir dafür einen speziellen User an.

Dieser wird folgendermaßen angelegt und anschließend der Gruppe www-data hinzugefügt:

adduser letsencrypt
usermod -a -G www-data letsencrypt

Der User braucht nun die Berechtigungen, um nginx später ohne Passwort neu laden zu können:

visudo

Am Ende wird folgende Zeile hinzugefügt:

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

Für die Installation von acme.sh wechseln wird nun den User:

su - letsencrypt

Anschließend kann acme.sh installiert werden:

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

Am Ende wechseln wir wieder auf den normalen User:

exit

Konfiguration Programme/Server

Die soeben installierten Programme sollten für einen optionalen Betrieb von Nextcloud noch angepasst/optimiert werden.

Konfiguration nginx

Zunächst wird die globale Konfiguration von nginx angepasst:

nano /etc/nginx/nginx.conf

In den meisten Fällen ist hier die Standard-Konfiguration schon recht gut geeignet, dennoch sollten einige Punkte überprüft/angepasst werden:

  • user: Gibt den Benutzer an, unter dem der Webserver läuft. Dies sollte immer www-data sein.
  • worker_processes: Die Anzahl der Threads, die nginx dazu verwendet, Client-Requests abzuarbeiten. Mit der Angabe auto wird pro CPU-Kern ein Thread angelegt, was in den meisten Fällen bereits die optimale Einstellung darstellt.
  • server_tokens: Mit der Angabe off sorgt man dafür, dass nginx keine Versions-Informationen preisgibt (z.B. auf Fehlerseiten). Daher sollte diese Option aus Sicherheitsgründen ausgeschaltet werden. Wenn diese Variable nicht vorhanden ist, muss man diese im HTTP-Block der Datei einfügen: server_tokens off;

Default-Seite deaktivieren

Nun ist es auch an der Zeit, die Default-Seite von nginx zu deaktivieren, da diese nur zur Überprüfung gedacht ist, ob der Webserver ordentlich läuft.

Dazu wird der virtuelle Host („default“) einfach aus dem Verzeichnis /etc/nginx/conf.d umbenannt, so dass dieser nicht mehr geladen wird und der Webserver anschließend neu gestartet:

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

Konfiguration MariaDB

Die Datenbank muss nicht spezielle angepasst werden, jedoch ist diese nach der Installation noch nicht auf maximale Sicherheit getrimmt. Dies übernimmt folgender Befehl:

mysql_secure_installation

Wenn während der Installation ein Root-Passwort vergeben wurde, muss dies zunächst einmal eingegeben werden. Falls noch kein Root-Passwort festgelegt ist, sollte man spätestens an dieser Stelle unbedingt eines setzen.

Alle weiteren Fragen des Assistenten sollte man mit Ja (y) beantworten.

Konfiguration PHP

Bei PHP gibt es dann ein paar mehr Optionen die angepasst werden sollten.

In unserem Fall wird PHP über FPM (FastCGI Process Manager) betrieben. Dies ist eine performante Möglichkeit der Kommunikation zwischen PHP und dem Webserver. FPM definiert einen sog. Thread-Pool, der die Anfragen abarbeitet (ähnlich wie schon bei nginx). Die Konfiguration dazu ist in folgender Datei enthalten:

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

Folgende Anpassungen sollte man hier vornehmen:

  • user/group: Der Benutzer, unter dem PHP ausgeführt wird. Dies ist wieder unser Webserver-User, also
    user = www-data
    group = www-data
  • listen: Die Kommunikation zwischen Webserver und PHP soll über einen Socket ablaufen. Dazu muss hier folgendes angegeben werden:
    listen = /run/php/php7.2-fpm.sock
  • Umgebungs-Variablen: Umgebungs-Variablen werden von PHP standardmäßig nicht veräußert, diese sind aber für den Betrieb von Nextcloud zwingend erforderlich. Dazu suchen wir nach dem Eintrag  Pass environment variables like LD_LIBRARY_PATH. ALL $VARIABLES are taken from the current environment (Shortcut für die Suche in nano: STRG + W). Alle Einträge, die hier mit env beginnen, sind hier auskommentiert. Durch das Entfernen der Semikola am Zeilenanfang werden die Kommentare entfernt und die Weitergabe der Umgebungs-Variablen aktiviert:
    env[HOSTNAME] = $HOSTNAME
    env[PATH] = /usr/local/bin:/usr/bin:/bin
    env[TMP] = /tmp
    env[TMPDIR] = /tmp
    env[TEMP] = /tmp

Neben der Pool-Konfiguration von PHP gibt es noch weitere Stellen, die angepasst werden sollten. Die in der Datei php.ini enthaltenen Anweisungen gelten dabei für alle PHP-Anwendungen. Die meisten Einstellungen können hier auf den Standard-Werten belassen werden. Anpassungen, die nur für eine Webanwendung speziell gelten sollen, werden nachher in den vHost-Dateien von nginx definiert.

Folgende Werte sollten in der php.ini angepasst werden:

nano /etc/php/7.2/fpm/php.ini

  • cgi.fix_pathinfo: Sorgt für eine sichere Interpretation von Pfadangaben:

    cgi.fix_pathinfo = 0

  • open_basedir: Schränkt den Zugriff von PHP auf das Webroot- und das temporäre Verzeichnis ein. Dadurch kann PHP aus Sicherheitsgründen auf sonst keine Dateien des Systems zugreifen oder diese verändern.

    open_basedir = /var/www/:/tmp/

  • memory_limit: Dieser Wert gibt an, wie viel Speicher ein PHP-Skript nutzen darf. Nextcloud benötigt später 512 MB als Memory Limit:

    memory_limit = 512M

  • opcache: Dies sind die Werte zum Konfigurieren des PHP OPcache (erhöht die Performance durch das Ablegen vorkompilierten Bytecodes in den Arbeitsspeicher). Diese Einträge sollten in der php.ini bereits vorhanden sein (allerdings auskommentiert). Eine Suche in der Datei sollte einiges an Tipparbeit sparen. Folgende Werte sind hier anzugeben:

    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

Neben FPM wird PHP allerdings noch auf eine andere Art und Weise verwendet, nämlich direkt über die Kommandozeile (CLI – Command Line Interpreter/Interface). Diese Art des Zugriffs wird für Cronjobs benötigt, die im Rahmen von Nextcloud laufen (sollten). Die Einstellungen für PHP-CLI befinden sich in einer separaten php.ini:

nano /etc/php/7.2/cli/php.ini

Folgende Einstellungen sollten an dieser Stelle angepasst werden:

  • cgi.fix_pathinfo: Wie oben beschrieben:
    cgi.fix_pathinfo = 0
  • open_basedir: Hier muss die Liste der Verzeichnisse etwas erweitert werden, da diese Option beim CLI-Zugriff nicht über den Webserver laufen und daher auch nicht in den vHosts überschrieben werden kann. Somit muss das spätere Nextcloud-Datenverzeichnis in die Liste mit aufgenommen werden, da der Nextcloud-Cronjob hier Zugriff benötigt:
    open_basedir = /var/www/:/tmp/:/var/nextcloud_data

Mit einem Neustart von PHP (FPM) werden die Änderungen übernommen:

service php7.2-fpm restart

Verzeichnisstruktur vorbereiten

Als nächstes werden die für die folgenden Schritte benötigten Verzeichnisse angelegt. Die Besitzrechte sollten dabei beim Webserver-User (www-data) liegen:

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

Anlegen des Gateway-Hosts

Als erstes wird nun der Gateway-Host in einer Minimal-Ausführung hinzugefügt:

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

Hier reichen zunächst folgende Zeilen:

server {
	listen 80 default_server;
    listen [::]:80 default_server;
	server_name meinedomain.de 192.168.178.60;
 
	root /var/www;
	
	location ^~ /.well-known/acme-challenge {
		proxy_pass http://127.0.0.1:81;
		proxy_redirect off;
	}		
}

Dieser virtuelle Host lauscht somit zunächst nur einmal auf Port 80 (HTTP) und hört auf die DynDNS-URL bzw. die lokale IP des Servers. Der einzige location-Block wird später für die Erzeugung des SSL-Zertifikats benötigt und leitet die Anfrage auf einen anderen virtuellen Host weiter (proxy_pass).

Anlegen des virtuellen Hosts für Let’s Encrypt

Damit auch ein Ziel für die Weiterleitung vorhanden ist, wird nun der vHost für Let’s Encrypt angelegt:

nano /etc/nginx/conf.d/meinedomain.de_letsencrypt.conf

Auch dieser virtuelle Host ist dabei sehr einfach aufgebaut:

server {
	listen 127.0.0.1:81;
	server_name 127.0.0.1;	
	
	location ^~ /.well-known/acme-challenge {
		default_type text/plain;
		root /var/www/letsencrypt;
	}
}

Dieser vHost lauscht auf 127.0.0.1:81. Der Port ist hier entscheidend, dieser muss mit der proxy_pass Direktive aus dem Gateway-Host übereinstimmen. Die Anweisungen listen und server_name sind auf die lokale Loopback-Adresse (127.0.0.1) festgelegt, so dass dieser vHost nur Server-intern (also nur lokal) aufgerufen werden kann. Der Zugriff „von außen“ erfolgt ausschließlich über den Gateway-Host.

Damit die virtuellen Hosts geladen werden, sollte der Webserver noch neu gestartet werden:

service nginx restart

SSL-Zertifikat mit Let’s Encrypt/acme.sh erzeugen

Der Webserver ist nun soweit vorbereitet, dass nun das SSL-Zertifikat generiert werden kann.

Port-Forwarding und DynDNS einrichten

Damit der Server nun auch aus dem Internet erreichbar ist, muss ein sog. Port-Forwarding im Router für die Ports 80 (HTTP) und 443 (HTTPS) für die IP des Servers (192.168.178.60) konfiguriert werden. Das Vorgehen unterscheidet sich dabei von Router zu Router, daher kann hier keine detaillierte Anleitung erfolgen. Hier sollte ein Blick in die Anleitung des Routers die gewünschten Informationen liefern. Oftmals beschreiben die Hersteller das genaue Vorgehen auch auf ihren Internet-Seiten. Beispielsweise findet man die Vorgehensweise für die Einrichtung von Port-Weiterleitungen für eine FritzBox auf den Hilfeseiten vom AVM.

Darüber hinaus muss der Router so konfiguriert werden, dass er sich korrekt an einem DynDNS-Dienst anmeldet, um so per DynDNS-Domain aus dem Internet erreichbar zu sein. Das Vorgehen hierzu hängt wieder vom verwendeten Router-Modell, aber auch vom DynDNS-Dienst ab. Wieder sind hier die Hersteller-Seiten des Routers (z.B. AVM), aber auch die Websites der jeweiligen DynDNS-Dienste (z.B. GoIP) die richtige Anlaufstelle, um diese Informationen zu ermitteln.

Generierung des SSL-Zertifikats

Hinweis: Wie bereits erwähnt, sollte acme.sh nicht mit Root-Rechten ausgeführt werden, daher müssen einige Vorbereitungen getroffen werden.

Zunächst legen wir die entsprechenden Verzeichnisse an und vergeben die erforderlichen Rechte:

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/meinedomain.de
chown -R www-data:www-data /etc/letsencrypt
chmod -R 775 /etc/letsencrypt

Anschliueßend wechseln wir auf den User, unter dem acme.sh ausgeführt werden soll:

su - letsencrypt

Das Zertifikat selbst wird nun mit einem Befehl generiert.

Tipp: Am besten übernimmt man den Befehl mittels Copy&Paste in einen beliebigen Text-Editor, mit dem man dann die Domain mit „Suchen und Ersetzen“ einfach durch die tatsächlich verwendete Domain einfügt. Auf diese Weise kann man Tippfehler vermeiden.

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

Nun sollte nach einigen Augenblicken das Zertifikat ohne Fehlermeldung erfolgreich generiert worden sein.

Die Zertifikat-Dateien findet man anschließend im Verzeichnis /etc/letsencrypt/meinedaomin.de:

  • 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 man daher niemals weitergeben)

Im Anschluss wechseln wir wieder auf den normalen User:

exit

Diffie-Hellman-Parameter

Das soeben erzeugte SSL-Zertifikat ist der wichtigste Schritt, damit später sämtliche Verbindungen zur eigenen Cloud verschlüsselt ablaufen. Die Sicherheit dabei kann aber durch den Einsatz sog. Diffie-Hellman-Parameter weiter erhöht werden. Das Thema ist etwas komplexer, aber einfach ausgedrückt geht es hierbei um einen sicheren Schlüsselaustausch bei Verbindungsaufbau. Die Generierung der Parameter ist recht einfach.

Achtung: Auf schwächerer Hardware kann die Generierung hier einige Stunden dauern. Wer nicht so lange warten möchte, der kann auch einen Schlüssel mit „nur“ 2048 Bit errechnen lassen (die Zahl des zweiten Befehls gibt hierbei die Länge des Schlüssels in Bit an).

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

Erneuerung der Zertifikate

Zertifikate von Let’s Encrypt sind nur 90 Tage lang gültig und müssen spätestens nach dem Ablauf dieser Zeitspanne erneuert werden.

Beim hier gezeigten vorgehen über acme.sh wird auf dem System ein Cronjob eingerichtet, der die Erneuerung der Zertifikate automatisch vornimmt. Hier muss man sich dann nicht mehr selbst um die Erneuerung der Zertifikate kümmern.

Gateway-Host für Nextcloud/SSL vorbereiten

Da nun ein SSL-Zertifikat vorhanden ist und Nextcloud später einen eigenen virtuellen Host spendiert bekommt, muss der Gateway-Host nun für die Verwendung von SSL und Nextcloud vorbereitet werden.

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

Die hinzuzufügenden Abschnitte sind hier markiert:

upstream php-handler {
    server unix:/run/php/php7.2-fpm.sock;
}

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name meinedomain.de 192.168.178.60;

	root /var/www;
	
	location ^~ /.well-known/acme-challenge {
		proxy_pass http://127.0.0.1:81;
		proxy_redirect off;
	}
	
	location / {
		# Enforce HTTPS
		# Use this if you always want to redirect to the DynDNS address (no local access).
		return 301 https://$server_name$request_uri;
		
		# Use this if you also want to access the server by local IP:
		#return 301 https://$server_addr$request_uri;
    }		
}

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name meinedomain.de 192.168.178.60;
  
	# Certificates used
	ssl_certificate /etc/letsencrypt/meinedomain.de/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/meinedomain.de/key.pem;
  
	# Not using TLSv1 will break:
	#	Android <= 4.4.40
	#	IE <= 10
	#	IE mobile <=10
	# Removing TLSv1.1 breaks nothing else!
	# TLSv1.3 is not supported by most clients, but it should be enabled.
	ssl_protocols TLSv1.2 TLSv1.3;
	
	# Cipher suite from https://cipherli.st/
	# Max. security, but lower compatibility 
	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';

	# Cipher suite from https://wiki.mozilla.org/Security/Server_Side_TLS
	#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

	# (Modern) cipher suite from https://mozilla.github.io/server-side-tls/ssl-config-generator/
	#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

	# Diffie-Hellman parameter for DHE ciphersuites, recommended 4096 bits
	ssl_dhparam /etc/nginx/ssl/dhparams.pem;
  
	# Use multiple curves.
	ssl_ecdh_curve secp521r1:secp384r1;

	# Server should determine the ciphers, not the client
	ssl_prefer_server_ciphers on;
  
	# OCSP Stapling
	# fetch OCSP records from URL in ssl_certificate and cache them
	ssl_stapling on;
	ssl_stapling_verify on;
	
	# This should be ca.pem
	# See here: https://certbot.eff.org/docs/using.html
	ssl_trusted_certificate /etc/letsencrypt/meinedomain.de/ca.pem;
	
	# This is the local DNS server (e.g. the IP of the Router if it is used as DNS server in the local network)
	resolver 192.168.178.1;
  
	# SSL session handling
	ssl_session_timeout 24h;
	ssl_session_cache shared:SSL:50m;
	ssl_session_tickets off;

	#
	# Add headers to serve security related headers
	#  
	# 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;

        # Remove X-Powered-By, which is an information leak
        fastcgi_hide_header X-Powered-By;	
	
	location = / {
        # Disable access to the web root, otherwise nginx will show the default site here.
		deny all;
        }	

	#
	# Nextcloud
	#
	location ^~ /nextcloud/ {
		# Set max. size of a request (important for uploads to Nextcloud)
		client_max_body_size 10G;
		# Besides the timeout values have to be raised in nginx' Nextcloud config, these values have to be raised for the proxy as well
		proxy_connect_timeout 3600;
		proxy_send_timeout 3600;
		proxy_read_timeout 3600;
		send_timeout 3600;
		proxy_buffering off;
		proxy_request_buffering off;
		proxy_max_temp_file_size 10240m;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_pass http://127.0.0.1:82;
		proxy_redirect off;
	}

	# These two location blocks are needed, otherwise you'll get warnings in the Nextcloud admin UI later on
	location = /.well-known/carddav {
		return 301 $scheme://$host/nextcloud/remote.php/dav;
	}

	location = /.well-known/caldav {
		return 301 $scheme://$host/nextcloud/remote.php/dav;
	}
	
	# Well-known URL for Webfinger
	# Regardless of this rule, you'll get a warning in the admin UI when the social app is not installed
	location = /.well-known/webfinger {
		return 301 $scheme://$host/nextcloud/public.php?service=webfinger;
	}

	location ~ /(ocm-provider|ocs-provider)/ {
		return 301 $scheme://$host/nextcloud/$1/;
	}
}

Folgende Änderungen wurden nun durchgeführt:

  • Ein Handler für PHP wurde hinzugefügt. Durch die Platzierung im Gateway-Host ist dieser Handler auch für alle anderen vHosts verfügbar (notwendig, falls mehrere PHP-Anwendungen gehostet werden sollen).
  • Die für Let’s Encrypt benötigten Anweisungen (HTTP) wurden nicht verändert.
  • Anweisungen für die Verwendung des SSL-Zertifikats und weitere Anweisungen bzgl. SSL wurden hinzugefügt. Hintergrund ist, dass nur der Gateway-Host das SSL-Handling übernehmen soll. Alle virtuellen Hosts, die „darunter“ liegen, sollten von der Verwendung von SSL nicht mitbekommen. Auf diese Weise sind alle SSL-Einstellungen an einer Stelle zu finden.
  • Am Ende der Datei wurde eine Weiterleitung an den Nextcloud-vHost angelegt. Wie schon beim vHost für Let’s Encrypt läuft die Kommunikation hier rein Server-intern ab (also über die IP 127.0.0.1). Zu beachten, ist hier die Änderung des Ports: Da der virtuelle Host für Let’s Encrypt bereits auf Port 81 lauscht, nutzen wir hier einen abweichenden Port (82). Dieser ist später für den Nextcloud-vHost wichtig.
  • Die Anweisungen für die sog. Well-known-URLs werden empfohlen, da es ansonsten später zu Warnungen im Admin-Bereich von Nextcloud kommen kann. Die ersten beiden sind dabei für CalDAV bzw. CardDAV zuständig. Die letzte Anweisung (webfinger) wird benötigt, wenn die später die Nextcloud App Social (Nextcloud-Integration mit Mastodon und weiteren Social Media Netzwerken) genutzt werden soll.
    Wichtig dabei ist, dass diese Well-Known-URLs über die Root-Domain (meinedomain.de) und nicht nur über das Unterverzeichnis (/nextcloud) erreichbar sind.
  • Die Anweisungen für ocm-provider bzw. ocs-provider sind ebenfalls an dieser Stelle für die Root-Domain aufzuführen, ansonsten würde es auch hier später zu Warungen im Admin-Bereich der Nextcloud geben.

Ich habe in der Datei auch Kommentare hinterlassen, die es ermöglichen sollten, den Gateway-Host an die eigenen Bedürfnisse anzupassen. Daher bitte auch die Kommentare in der Datei beachten.

Ebenfalls muss hier immer die angegebene Domain meinedomain.de an die tatsächlich verwendete Domain angepasst werden.

Virtuellen Host für Nextcloud anlegen

Die Weiterleitung im Gateway-Host ist bereits konfiguriert, nun fehlt noch der eigentliche virtuelle Host für Nextcloud:

nano /etc/nginx/conf.d/meinedomain.de_nextcloud.conf

Diese Datei ist mit folgendem Inhalt zu füllen:

server {
    listen 127.0.0.1:82;
    server_name 127.0.0.1;

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

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

    location ^~ /nextcloud {
        # set max upload size
        client_max_body_size 10G;
        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/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;

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

        location /nextcloud {
            rewrite ^ /nextcloud/index.php;
        }

        location ~ ^\/nextcloud\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
            deny all;
        }
        location ~ ^\/nextcloud\/(?:\.|autotest|occ|issue|indie|db_|console) {
            deny all;
        }
    
        location ~ ^\/nextcloud\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
            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 $fastcgi_path_info;
			
			# Important: disable HTTPS, otherwise no log in will be possible!
            #fastcgi_param HTTPS on;

            fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;

            # Raise timeout values.
            # This is especially important when the Nextcloud setup runs into timeouts (504 gateway errors)
			fastcgi_read_timeout 600;
			fastcgi_send_timeout 600;
			fastcgi_connect_timeout 600;
            fastcgi_request_buffering off;
	    
            # Pass PHP variables directly to PHP.
            # This is usually done in the php.ini. For more flexibility, these variables are configured in the nginx config.
			# All the PHP parameters have to be set in one fastcgi_param. When using more 'fastcgi_param PHP_VALUE' directives, the last one will override all the others.
			fastcgi_param PHP_VALUE "open_basedir=/var/www:/tmp/:/var/nextcloud_data:/dev/urandom:/proc/meminfo
				upload_max_filesize = 10G
				post_max_size = 10G
				max_execution_time = 3600
				max_input_time = 3600
				output_buffering = off";
            
            # Make sure that the real IP of the remote host is passed to PHP.
            fastcgi_param REMOTE_ADDR $http_x_real_ip;
        }

        location ~ ^\/nextcloud\/(?:updater|ocs-provider|ocm-provider)(?:$|\/) {
            try_files $uri/ =404;
            index index.php;
        }

        # Adding the cache control header for js and css files
		# Make sure it is BELOW the PHP block
		location ~ ^\/nextcloud\/.+[^\/]\.(?:css|js|woff2?|svg|gif)$ {
			try_files $uri /nextcloud/index.php$request_uri;
			proxy_set_header Cache-Control "public, max-age=15778463";
			# Add headers to serve security related headers
			# Use 'proxy_set_header' (not 'add_header') as the headers have to be passed through a proxy.
			proxy_set_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload;";
			proxy_set_header X-Content-Type-Options nosniff;
			proxy_set_header X-XSS-Protection "1; mode=block";
			proxy_set_header X-Robots-Tag none;
			proxy_set_header X-Download-Options noopen;
			proxy_set_header X-Permitted-Cross-Domain-Policies none;
			proxy_set_header Referrer-Policy no-referrer;
			
			# Optional: Don't log access to assets
			access_log off;
		}

		location ~ ^\/nextcloud\/.+[^\/]\.(?:png|html|ttf|ico|jpg|jpeg)$ {
			try_files $uri /nextcloud/index.php$request_uri;
			# Optional: Don't log access to other assets
			access_log off;
		}
    }
}

Die Konfiguration ist an die vorgeschlagene nginx-Konfiguration im Nextcloud Administation Manual angelehnt. Zu beachten ist hier folgendes:

  • Es wird nur ein server für HTTP (nicht HTTPS) definiert, da die HTTPS-Kommunikation nur vom Gateway-Host übernommen wird. Die Weiterleitung eines Requests an den Nextcloud-vHost findet nur Server-intern statt, daher reicht hier HTTP aus.
  • Gelauscht wird hier dazu auf der lokalen IP 127.0.0.1, daher ist es nicht möglich, eine Verbindung zum Nextcloud-vHost aufzubauen, ohne vorher den Gateway-Host passiert zu haben.
  • Der Port ist diesmal 82, da Port 81 bereits vom virtuellen Host für Let’s Encrypt belegt wird. Dieser Port muss mit dem Port der Weiterleitung (proxy_pass) für Nextcloud im Gateway-Host übereinstimmen.
  • Da die Header-Anweisungen bereits im Gateway-Host konfiguriert wurden, müssen diese nicht im vHost für Nextcloud angegeben werden.
  • Der vHost für Nextcloud soll mit ein paar speziellen Einstellungen für PHP arbeiten. Daher werden per fastcgi_param PHP_VALUE die Einstellungen aus der php.ini (FPM) überschrieben. Dabei darf nur eine fastcgi_param PHP_VALUE Anweisung existieren, da sich diese ansonsten gegenseitig überschreiben. Wenn mehrere Parameter an PHP übergeben werden sollen (wie hier der Fall), müssen diese einfach durch einen Zeilenumbruch getrennt werden. Besonders wichtig ist hier die Direktive open_basedir, da PHP ansonsten keinen Zugriff auf das Datenverzeichnis von Nextcloud hat.
    Falls später z.B. eine externe Festplatte als externer Speicher eingebunden werden soll, muss auch das Verzeichnis dieses Laufwerks in die open_basedir Anweisung mit aufgenommen werden.
  • Auch hier bitte wieder auf die Kommentare in der Datei achten. Hier sind auch wieder Hinweise zu finden, um den virtuellen Host an die eigenen Bedürfnisse anzupassen.

Nach dem Anlegen des vHosts muss der Webserver noch neu gestartet werden:

service nginx restart

Installation Nextcloud

Nun ist der Server soweit fertig eingerichtet, dass nun die Installation von Nextcloud angegangen werden kann.

Download

Einen Link zur aktuellsten Version von Nextcloud erhält man auf der Download-Seite von Nextcloud. Mit einem Klick auf Details and Download options bekommt man einen Link auf ein .tar.bz2 Archiv präsentiert. Dessen Link kopiert man sich am besten in die Zwischenablage.

Download-Link für die aktuellste Nextcloud-Version ermitteln

Download-Link für die aktuellste Nextcloud-Version ermitteln

Zurück auf der Linux Maschine kann die aktuellste Version der Cloud-Software nun heruntergeladen werden (hier mit Version 17.0.0):

wget https://download.nextcloud.com/server/releases/nextcloud-17.0.0.tar.bz2

Nach ein paar Sekunden sollte der Download abgeschlossen sein und Nextcloud kann nun in das entsprechende Verzeichnis entpackt werden, was zuvor schon vorbereitet wurde. Anschließend löschen wir das Archiv wieder, da dies nicht mehr benötigt wird:

tar -xjf nextcloud-17.0.0.tar.bz2 -C /var/www
rm nextcloud-17.0.0.tar.bz2

Nun sollten nochmals die Dateiberechtigungen gesetzt werden:

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

Datenbank für Nextcloud anlegen

Bevor nun das Setup von Nextcloud aufgerufen werden kann, ist es notwendig, dass eine Datenbank für die Cloud angelegt wurde. Dies geschieht am einfachsten mit der MySQL-Kommandozeile, die mit Root-Rechten aufgerufen wird:

mysql -u root -p

Nach der Eingabe des Root-Passworts wird nun zunächst die Datenbank selbst erstellt. Im Zuge dessen wird auch gleich ein spezieller Nutzer für Nextcloud eingerichtet, der die entsprechenden Zugriffsrechte auf diese eine Datenbank hat. Die Angabe localhost sorgt dafür, dass der Zugriff auf die Datenbank nur auf dem lokalen System erfolgen kann. Ein Remote-Zugriff über das Netzwerk (auf diese Datenbank) ist damit aus Sicherheitsgründen nicht möglich. Die Befehle auf der MySQL-Kommandozeile müssen mit einem Semikolon abgeschlossen werden:

CREATE USER nextcloud_db_user@localhost IDENTIFIED BY 'MeInPasSw0rT';
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

Nun kann auch schon das Setup der Cloud-Software über die URL https://meinedomain.de/nextcloud aufgerufen werden.

Das Setup prüft daraufhin erst einmal, ob alle Voraussetzungen erfüllt sind, oder ob es noch Probleme gibt, wie z.B. fehlende Abhängigkeiten oder Schreibrechte in bestimmten Verzeichnissen. Falls Fehler gefunden werden sollten diese zunächst behoben werden, bevor das Setup nochmals aufgerufen werden kann.

Beim Setup der Cloud werden nun drei Dinge angegeben:

  • Benutzer/Passwort (Administrator): Im Rahmen des Setups wird nun ein erster Benutzer angelegt, der automatisch Admin-Rechte für die Cloud besitzt. Der Benutzername ist dabei frei wählbar, allerdings sollte man (wie eigentlich immer) auf ein starkes Passwort achten, da die Cloud ja nachher öffentlich aus dem Internet erreichbar sein wird.
  • Datenverzeichnis: Ebenso wird hier nun der Pfad des Datenverzeichnisses angegeben. Standardmäßig will das Setup diesen Datenpfad innerhalb des www-Verzeichnisses erstellen. Allerdings wird aus Gründen der Sicherheit empfohlen, dass das Datenverzeichnis außerhalb des Verzeichnisses /var/www liegen sollte (siehe Nextcloud Administration Manual). Daher sollte man hier genau darauf achten, dass hier das richtige Verzeichnis angegeben wird, welches wir vorher im Rahmen des Tutorials bereits erstellt hatten (/var/nextcloud_data).
  • Datenbank-Verbindung: Hier sind die Zugangsdaten für die soeben angelegte Datenbank zu hinterlegen.

Mit einem Klick auf Installation abschließen wird das Setup alle Einstellungen übernehmen.

Nextcloud-Setup

Nextcloud-Setup

Hinweis: Auf langsamen Rechner dauert das Setup evtl. etwas länger. Hier kann es dann vereinzelnd vorkommen, dass der Webserver irgendwann einen Timeout meldet (504 Gateway Timeout). Hier hat nginx dann die Verbindung zu Client (Browser) unterbrochen, noch bevor das Setup abgeschlossen werden konnte. In diesem Fall sollte man dem System ein paar Minuten geben und anschließend nochmals die Nextcloud-URL aufrufen. Wenn es zu keinen weiteren Problemen gekommen ist, sollte das Setup „im Hintergrund“ weitergelaufen und nach ein paar Minuten abgeschlossen worden sein. Hier wäre es dann auch eine Überlegung wert, in den virtuellen Hosts (Gateway-Host und Nextcloud-vHost) die Timeout-Werte etwas zu erhöhen.

Warnungen im Admin-Bereich

Nach erfolgreicher Installation sollte man gleich einen Blick in den Admin-Bereich der Cloud werden (oben rechts auf das Symbol für den Benutzer Klicken und dann Einstellungen wählen). Weil der erste angelegte Benutzer Admin-Rechte hat, findet man nun auf der linken Seite unter Übersicht eine Zusammenfassung über die Cloud.

Hier sollte direkt nach der Installation der Cloud nur eine Warnung angezeigt werden: Diese bezieht sich darauf, dass kein PHP-Memory-Cache konfiguriert ist.

Nextcloud: Warnung im Admin-Bereich

Nextcloud: Warnung im Admin-Bereich

Diese spezielle Warnung ist hierbei nicht als Fehler zu verstehen, sondern lediglich als Hinweis, dass die Performance der Cloud durch den Einsatz eines PHP-Memorycaches optimiert werden könnte. Dies führen wir im nächsten Abschnitt durch: Anpassen der Nextcloud-Konfiguration.

Wenn mehr Warnungen im Admin-Bereich angezeigt werden: An dieser Stelle sollte wirklich nur diese eine Warnung zu sehen sein. Wenn hier noch mehr Warnungen zu sehen sein sollten, dann bitte nochmals alle Schritte dieses Tutorials überprüfen, ob nicht ein kleines Detail ausgelassen wurde (besonders die PHP-Konfiguration).
Im Nextcloud Administration Manual findet man auch eine Übersicht über die Warnungen, die hier im Admin-Bereich angezeigt werden könnten und entsprechende Lösungsansätze.

Anpassen der Nextcloud-Konfiguration

Nextcloud speichert seine Konfiguration in der Datei /var/www/nextcloud/config/config.php. Genau hier sollten wir wegen des PHP-Memorycaches und auch wegen ein paar weiteren Einstellungen ansetzen:

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

Folgende Änderung werden hier durchgeführt:

  • PHP-Memorycache: Um die Warnung im Admin-Bereich zu entfernen und gleichzeitig die Performance der Cloud zu erhöhen, wird der Memory-Cache hinzugefügt (am Ende der Datei, aber vor der letzten geschweiften Klammer):
    'memcache.local' => '\OC\Memcache\APCu',
     
  • HTTPS als Standard definierten: Da Nextcloud hinter durch einen (HTTPS-)Proxy läuft (der Gateway-Host), kann es bei der automatischen Ermittlung von URLs zu Fehlern kommen, da hin und wieder ein http:// vorangestellt wird. Um strikt die Verbindung nur über https:// zu forcieren, sollte hier folgende Variable gesetzt werden:
    'overwriteprotocol' => 'https',
     
  •  Trusted Domains: Wenn man später auch über die lokale (LAN-)IP auf Nextcloud zugreifen möchte, dann kann man hier auch gleich die lokale IP als sog. Trusted Domain hinzufügen:
    'trusted_domains' =>
    array (
    	0 => 'meinedomain.de',
    	1 => '192.168.178.60',
    ),
     
  •  Timezone für Log-Einträge: Die richtige Zeitzone (z.B. für die Timestamps der Log-Einträge) wird durch diese Variable konfiguriert:
    'logtimezone' => 'Europe/Berlin',

Nach dem Speichern der config.php und erneutem Aufruf der Cloud sollten nun die Warnungen in der Admin-Oberfläche verschwunden sein („Alle Prüfungen bestanden“).

Eine Übersicht über alle Parameter der config.php von Nextcloud findet man im Nextcloud Administration Manual.

Cronjob für Nextcloud einrichten

Nextcloud ist darauf angewiesen, dass regelmäßig bestimmte Hintergrund-Aufgaben (z.B. Aufräumen der Datenbank) ausgeführt werden. Nach der Installation wird dies per AJAX realisiert: Immer wenn  ein User angemeldet ist und im Browser die Cloud nutzt, wird beim Laden einer Seite geprüft, ob Hintergrund-Aufgaben anstehen und werden ggf. ausgeführt. Diese Methode hat jedoch zwei Nachteile: Es wird zunächst immer ein angemeldeter Benutzer benötigt, denn nur durch diesen werden die Hintergrund-Aufgaben angestoßen (beim Laden einer Seite). Wenn die Cloud nun lange ohne Benutzeranmeldung läuft, dann werden u.U. auch lange keine Hintergrund-Jobs erledigt. Zum anderen ist die Lösung über AJAX weniger performant.

Es wird daher empfohlen, die Hintergrund-Aufgaben per Cron ausführen zu lassen. Hier prüft ein Hintergrund-Dienst in regelmäßigen Abständen, ob Hintergrund-Jobs fällig sind. Besonders auf schwächerer Hardware ist diese Methode deutlich effizienter.

Um Cron zur Erledigung der Hintergrund-Aufgaben nutzen zu können, muss zunächst ein neuer Cronjob für den Webserver-Benutzer angelegt werden:

crontab -u www-data -e

Das System fragt nun nach, mit welchem Editor die Datei bearbeitet werden soll. Hier wählt man einfachheitshalber am besten nano (1). Danach wird der Datei am Ende folgender Inhalt hinzugefügt:

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

Dies sorgt nun dafür, dass dieser Cronjob alle 5 Minuten automatisch ausgeführt wird. Theoretisch könnte hier auch eine andere Zeitspanne genutzt werden, allerdings ist die allgemeine Empfehlung 5 Minuten (siehe Nextcloud Admin-Manual).

In der Admin-Oberfläche muss nun nur noch eingestellt werden, dass zukünftig Cron zur Erledigung von Hintergrund-Jobs verwendet werden soll. Die Einstellung dazu findet man wieder in der Admin-Überfläche unter Grundeinstellungen.

Da hier auch gleich angegeben wird, wann das letzte Mal Hintergrund-Aufgaben ausgeführt wurde, kann man auf diese Weise auch erkennen, ob der Cronjob wie erwartet läuft: Immer nach 15 Minuten sollte bei Letzte Aufgabe ausgeführt folgendes stehen: Gerade eben.

Nextcloud: Ausführung von Hintergrund-Aufgaben per Cron

Nextcloud: Ausführung von Hintergrund-Aufgaben per Cron

4-Byte-Support aktivieren

Wichtig: Die folgenden Schritte sind nicht notwendig, wenn die Datenbank bereits mit UTF-8-Support angelegt wurde. Wenn ihr die Datenbank also bereits mit folgendem Befehl erzeugt habt, dann kann dieser Absatz übersprungen werden:

CREATE DATABASE IF NOT EXISTS nextcloud_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

Falls die Datenbank ohne UTF-8-Support angelegt wurde, dann sollten die Schritte in diesem Abschnitt befolgt werden. Der Befehl zum Anlegen der Datenbank ohne UTF-8-Support sah dann so aus:

CREATE DATABASE IF NOT EXISTS nextcloud_db;

Achtung: Die folgenden Schritte stellen mehr oder weniger eine Operation am offenen Herzen der Datenbank dar. Daher sollten diese Anweisungen nur dann ausgeführt werden, wenn

  • MariaDB in einer Version >= 10.3 installiert ist.
  • Der 4-Byte-Support wirklich benötigt wird.

Bei einer MariaDB-Version 10.1 oder 10.2 kann der 4-Byte-Support ebenfalls aktiviert werden, allerdings sind hier zusätzliche Schritte erfolderlich. In diesem Fall bitte nach dieser Anleitung vorgehen. Diese Anleitung ist dabei eher als experimentell anzusehen, daher sollte man hier genau wissen, was man hier tut. In jedem Fall sollte vorher ein Backup (zumindest von der Datenbank) angefertigt werden, falls im weiteren Verlauf etwas schief gehen sollte.

Nach der Installation von Nextcloud unterstützen die angelegten Tabellen noch keinen UTF8-Zeichensatz. Dadurch ergeben sich ein paar Einschränkungen: Beispielsweise können bei den Datei- und Ordnernamen keine Emojis angegeben werden (wer es denn braucht…). Versucht doch einfach mal einen Ordner mit dem Dateinamen „Test😋“ anzulegen. Hier wird eine Fehlermeldung erscheinen, dass der Ordner nicht angelegt werden kann.

Den 4-Byte-Support kann man jedoich einfach nachrüsten. Im Nextcloud Administration Manual gibt es eine Anleitung dazu, die jedoch mit MariaDB 10.3 nicht mehr funktioniert. Dies liegt darin begründet, dass die entsprechenden Variablen nicht mehr gesetzt werden können, da diese veraltet sind und bei MariaDB 10.3 entfernt wurden.

Wenn bei euch keine Dateien mit Emojis angelegt werden können, dann kann der 4-Byte-Support allerdings leicht nachgerüstet wreden: Dazu geht man einfach über die MySQL-Kommandozeile:

mysql -u root -p

Nach der Eingabe des Root-Passworts wählt man die korrekte Datenbank aus:

use nextcloud_db;

Hier wird zunächst einmal der verwendete Zeichensatz kontrolliert:

show variables like "character_set_database";

Hier sollte nach einer frischen Nextcloud-Installation latin1 ausgegeben werden.

Folgender Befehl sorgt dafür, dass der Zeichensatz geändert wird:

ALTER DATABASE nextcloud_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

Danach sollte nach nochmaliger Eingabe von

show variables like "character_set_database";

utf8mb4 ausgegeben werden. Mit exit; kann man die MySQL-Kommandozeile wieder verlassen.

Zum Schluss muss die Veränderung in den Nextcloud-Tabellen übernommen werden:

cd /var/www/nextcloud

Folgender Befehl setzt die entsprechende Variable in der Config-Datei:

sudo -u www-data php occ config:system:set mysql.utf8mb4 --type boolean --value="true"

Der letzte Befehl fürht ein Update auf die entsprechenden Tabellen durch:

sudo -u www-data php occ maintenance:repair

Anschließend kann man in Nextcloud auch Dateien mit erweiterten Zeichen (Emojis, etc.) anlegen.

Weitere Konfiguration Nextcloud

Die grundsätzliche Konfiguration von Nextcloud ist damit abgeschlossen. Am besten geht man nun noch durch sämtliche Einstellungen im Admin-Bereich der Cloud und passt die Optionen den eigenen Wünschen entsprechend an.

Es gibt nun viele Möglichkeiten, die eigene Cloud um Funktionen zu erweitern. Folgende Punkte sind auf jeden Fall einen Blick wert:

Generell ist bei der erweiterten Konfiguration von Nextcloud ein Blick ins Nextcloud Administration Manual empfehlenswert.

Optimierungen der Server-Umgebung für Nextcloud

Auch wenn die eigene Cloud nun direkt genutzt werden könnte, gibt es ein paar Möglichkeiten zur Optimierung von Nextcloud bzw. der verwendeten Server-Umgebung.

Die Umsetzung dieser Maßnahmen ist optional und hängt vom späteren Einsatzzweck der Cloud und den eigenen Bedürfnissen ab.

Fail2ban

Ab Version 11 ist bei Nextcloud ein Brute-Force-Schutz enthalten. Dieser sorgt dafür, dass nach einer bestimmten Anzahl an erfolglosen Login-Versuchen alle weiteren Logins aus dem betroffenen Subnetz gedrosselt werden. Dies führt bei Brute-Force-Attacken zu verzögerten Login-Versuchen (max. 30 Sekunden). Auch wenn dies den „Bad Guys“ das Leben etwas schwerer macht, wird dabei keine IP gebannt, so dass eine Brute-Force-Attacke lediglich verzögert wird. Daher ist hier alternativ oder zusätzlich der Einsatz von Fail2ban sinnvoll. Dieses Programm bietet im Vergleich zum eingebauten Brute-Force-Schutz folgende Vorteile:

  • Mittels Fail2ban können IPs automatisch gebannt werden. Nach einem solchen Ban kann die betroffene IP nicht mehr auf die Nextcloud-Instanz zugreifen, es wird lediglich eine Fehlermeldung des Browsers angezeigt.
  • Fail2ban arbeitet IP-basiert: Es wird nur die entsprechende IP blockiert, von der aus zu viele fehlgeschlagene Login-Versuche unternommen wurden. Andere Nutzer als dem gleichen Netzwerk (Subnet) werden dabei nicht gebannt.
  • Mit Fail2ban kann nicht nur die Nextcloud-Installation, sondern auch weitere Anwendungen auf dem Server abgesichert werden (z.B. Webserver und SSH).

Konfigurations-Dateien von Fail2ban

Bevor es um die Einrichtung von Fail2ban geht, ein Hinweis zu den Konfigurations-Dateien dieses Programms: Hier gibt es zwei Arten von Konfigurations-Dateien: *.conf und *.local. Die conf-Dateien kommen bei der Installation von Fail2ban mit. Wenn Änderungen an der Konfiguration vorgenommen werden sollen, dann sollte man die conf-Dateien nie direkt bearbeiten, da diese bei einem Update von Fail2ban jederzeit überschrieben werden können. Dafür kann man hier eine Datei mit dem gleichen Namen, aber mit der Dateiendung .local anlegen. Die local-Dateien werden dabei „on top“ auf die conf-Dateien geladen und überschreiben so die Standard-Einstellungen. Wenn nun bei einem Update von Fail2ban die conf-Dateien geändert werden, sind die individuellen Anpassungen in den local-Dateien davon nicht betroffen. Dadurch ist es nicht möglich, dass durch ein Update von Fail2ban unbeabsichtigt die Konfiguration geändert wird.

Konfiguration/Deaktivieren Nextcloud Brute-Force-Schutz

Wenn Fail2ban zum Einsatz kommt, ist der Brute-Force-Schutz von Nextcloud nicht mehr so wichtig. Dieser kann daher komplett deaktiviert werden.Dies wird wieder in der Konfigurations-Datei von Nextcloud vorgenommen:

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

Deaktiviert wird die Funktion durch das Hinzufügen folgender Zeile:

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

An dieser Stelle sollte auf jeden Fall noch einmal überprüft werden, ob für das Logging in Nextcloud die richtige Zeitzone angegeben wurde, da dies später für die Funktion von Fail2ban wichtig ist:

'logtimezone' => 'Europe/Berlin',

Optional: Wenn man den integrierten Brute-Force-Schutz in Nextcloud nicht komplett deaktivieren möchte, kann auch die App Brute-force settings aus dem Nextcloud App-Store installieren (oben auf den Benutzernamen und dann auf Apps klicken – die gesuchte App befindet sich in der Kategorie Sicherheit). Mit Hilfe dieser App kann man in den Admin-Einstellungen unter Sicherheit das eigene lokale Netzwerk in eine Whitelist mit aufnehmen. In unserem Beispiel wäre dies das Netzwerk 192.168.178.0/24. Für alle anderen Netzwerke (und v.a. auch Internet-IPs) würde der Brute-Force-Schutz dann noch greifen.

Whitelisting des LANs mittels der App "Brute-force settings"

Whitelisting des LANs mittels der App „Brute-force settings“

Einrichtung Fail2ban

Anschließend kann Fail2ban installiert werden:

apt-get update 
apt-get install fail2ban

Nun wird ein spezieller Filter für Nextcloud angelegt (Dateiendung beachten, s.o.):

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

Diese Datei wird mit folgendem Inhalt gefüllt. Dieser reguläre Ausdruck beschreibt die Logeinträge, nach den Fail2ban später in der Nextcloud-Logdatei sucht, um fehlgeschlagene Login-Versuche zu erkennen.:

[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
            ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
            ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: .* \(Remote IP: <HOST>\).*}$

Damit dieser Filter beim Start von Fai2ban auch geladen wird, muss dieser dem System noch bekannt gemacht werden:

nano /etc/fail2ban/jail.local

Der Inhalt der Datei:

[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 Teil unter [DEFAULT] gilt dabei für alle Regel-Sets (Jails). Hier werden die Standard-Einstellungen für Bans hinterlegt:

  • maxretry: Anzahl der Fehlversuche, bevor Fail2ban eine IP sperrt.
  • bantime: Zeitraum in Sekunden, für den eine IP gesperrt werden soll. Wird hier ein negativer Wert angegeben (-1), handelt es sich um eine permanente Sperre. Ansonsten wird eine IP nach dem Ablauf dieser Zeitspanne wieder automatisch entsperrt.

Unter [nextcloud] wird dann neues Jail für Nextcloud angelegt. Folgende Einstellungen werden hier angegeben und gelten nur für Nextcloud:

  • enabled: Aktivierung dieser Regel. Falls das Jail später (temporär) deaktiviert werden soll, kann dies einfach durch diese Option erfolgen.
  • port: Möglicher Port, hier nur 80 (HTTP) und 443 (HTTPS).
  • protocol: Das verwendete Protokoll.
  • filter: Name des Filters aus gleichnamiger Datei unter /etc/fail2ban/filter.d. Den Filter für Nextcloud haben wir ja bereits vorher angelegt.
  • logpath: Log-Datei, die Fail2ban für dieses Jail beobachten soll. Auf diese Datei wird der oben definierte Filter angewendet.
  • Hier könnten auch noch Werte für maxretry und bantime hinterlegt werden, die dann sie Standard-Werte überschreiben und nur für das Nextcloud-Jail gelten.

Die Anweisung unter [nginx-http-auth] aktiviert daneben noch die Überwachung der Logs des Webservers. Dieses Jail ist bereits in den Standard-Jails (/etc/fail2ban/jail.conf) definiert und wird an dieser Stelle lediglich scharf geschaltet. Dies sorgt für eine Überwachung bei anderen Webanwendungen, bei den eine HTTP-Basic-Authentifizierung zum Einsatz kommt. Die Ban-Optionen (maxretry und bantime) werden hier nicht angegeben, daher gelten die Standard-Werte, die in der Sektion [DEFAULT] angegeben wurden.

Nach einem Neustart von Fail2ban ist das Programm einsatzbereit:

service fail2ban restart

E-Mail-Versand durch Fail2ban

Das Programm arbeitet nun zunächst im Hintergrund: Wird eine IP gebannt, bekommt der Administrator davon nur etwas mit, wenn er den Status von Fail2ban überprüft (dazu später mehr) oder einen Blick in die Logs wirft.

Sinnvoll ist daher eine Konfiguration, bei der Fail2ban automatisch eine E-Mail an den Admin sendet, wenn eine IP gebannt wurde. Das geht allerdings nicht out-of-the-box, das Linux-System muss zunächst auf den Versand von Mails vorbereitet werden. msmtp ist dabei die einfachste Möglichkeit, um unter Linux einfach und schnell E-Mails versenden zu können. Die Installation und Einrichtung des Programms wurde bereits im Artikel Linux: Einfach E-Mails senden mit msmtp ausführlich erklärt.

Wenn msmtp erfolgreich konfiguriert wurde, funktioniert das Senden von E-Mails über Fail2ban erstaunlich einfach, da der Mail-Versand bereits vom Programm vorgesehen ist. Dazu reicht eine kleine Anpassung an der Datei /etc/fail2ban/jail.local. Am Anfang der Datei (in der Default-Sektion) werden einfach noch folgende Zeilen hinzugefügt (hier markiert):

[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

  • destemail ist dabei die Mail-Adresse, an die Benachrichtigungen geschickt werden sollen.
  • sender ist die Adresse, von der die E-Mail gesendet werden soll (Absender).
  • Wichtig ist insbesondere die Zeile action = %(action_mwl)s: Hierdurch werden E-Mails standardmäßig versendet.

Nun bekommt man bei allen Aktionen, die Fail2ban vornimmt, automatisch eine E-Mail geschickt. Unschön dabei: Auch wenn ein „Jail“ gestoppt oder geladen wurde, wird eine E-Mail versendet. Startet einfach mal Fail2ban neu (service fail2ban restart) und wundert euch über die „Mail-Flut“. Eigentlich interessiert uns hier ja nur, wenn Fail2ban tatsächlich eine IP gebannt hat. Damit nur noch bei diesem Ereignis eine E-Mail zu erhalten, müssen noch ein paar Anpassungen vorgenommen werden. Die betroffenen conf-Dateien im Verzeichnis /etc/fail2ban/action.d werden dabei durch entsprechende local-Dateien ergänzt:

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

Die o.g. Dateien werde dazu einfach neu angelegt und mit folgendem Inhalt gefüllt:

[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 =

Dazu am besten eine entsprechende Datei anlegen (mail-buffered.local) und diese dann einfach kopieren:

cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail-whois-lines.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/mail-whois.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/sendmail-buffered.local
cp /etc/fail2ban/action.d/mail-buffered.local /etc/fail2ban/action.d/sendmail-common.local

Nach einem Neustart von Fail2ban werden nur noch E-Mails versendet, wenn eine IP tatsächlich gebannt wurde.

Fail2ban Status und Sperren entfernen (Test der Funktionalität)

Nun kann es ja mal vorkommen, dass man sich mittels Fail2ban aus der eigenen Cloud aussperrt, weil man z.B. das Passwort zu oft falsch eingegeben hat. Dies ist zugleich ein guter Test, ob das System auch wie erwartet funktioniert. Daher gebt doch einfach drei Mal ein falsches Passwort in eurer Nextcloud-Anmeldung an. Bei der vierten Anmeldung seht ihr nun Fail2ban in Aktion: Die Website kann gar nicht mehr geladen werden (Timeout) und ihr solltet eine E-Mail erhalten haben, wenn ihr den Mail-Versand konfiguriert habt.

Um nun zu kontrollieren, welche IPs aktuell für Nextcloud gebannt sind, reicht folgender Befehl:

fail2ban-client status nextcloud

Hier sollte nun eure IP zu finden sein, mit der soeben erfolglose Anmeldeversuch unternommen wurde.

Mit diesem Befehl wird diese IP wieder entsperrt:

fail2ban-client set nextcloud unbanip 48.128.36.83

Anschließend kann man wieder wie gewohnt auf Nextcloud zugreifen.

Redis

Nextcloud nutzt das sog. Transactional File Locking, um Sperren bei parallelem Zugriff auf Dateien zu realisieren. Einfach gesagt werden Dateien „gelockt“, wenn diese gerade in Verwendung sind. Dadurch kann es zu keinen Datenverlusten kommen, wenn eine Datei z.B. durch zwei Benutzer zeitgleich geöffnet bzw. gespeichert wird.

In der Standard-Konfiguration nutzt Nextcloud für das Verwalten der Sperren die Datenbank. Hier gibt es jedoch mit Redis eine In-Memory-Datenbank, die für genau solche Aufgaben optimiert ist und daher in bestimmten Szenarien eine verbesserte Performance erzielen kann.

Auch wenn hier Optimierungs-Potential besteht, wird Redis nur in großen Cloud-Instanzen eine spürbare Verbesserung der Performance bringen. Bei kleinen Nextcloud-Installationen mit 3-5 Nutzern wird man hier kaum einen Effekt bemerken können.

Installation und Konfiguration Redis

Redis kann mit folgenden Befehlen installiert werden. Das PHP-Paket wird zusätzlich benötigt, um per PHP Zugriff auf Redis zu erhalten:

apt-get update
apt-get install redis-server php-redis

Nach der Installation wird die In-Memory-Datenbank noch konfiguriert:

nano /etc/redis/redis.conf

Wie schon bei PHP ist es bei Redis empfehlenswert, die Kommunikation über einen Socket laufen zu lassen. Dazu sind folgende Einstellungen vorzunehmen. Die Einstellungen sind etwas in der Datei verteilt und z. T. nur auskommentiert. Am besten einfach in der Datei suchen (STRG+W) und die Einstellungen anpassen.

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

Hiermit werden folgende Optionen gesetzt:

  • port: Redis „lauscht“ standardmäßig auf dem Port 6379. Da wir allerdings einen Socket zur Kommunikation bevorzugen, soll Redis auf gar keinem Port lauschen.
  • unixsocket: Hiermit wird der eigentliche Socket definiert.
  • unixsocketperm: Berechtigungen für diesen Socket.

Als nächstes muss nun der Webserver-User in die Gruppe der Redis-Benutzer aufgenommen werden, damit dieser Redis auch nutzen kann:

usermod -a -G redis www-data

Am Ende wird Redis neu gestartet, damit die Änderungen angewendet werden:

service redis-server restart

Aktivierung von Redis in Nextcloud

Damit Nextcloud nun auch die In-Memory-Datenbank nutzt, muss dieses noch in der Konfigurations-Datei eingestellt werden:

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

Folgende Zeilen werden hier eingefügt:

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

Anschließend nutzt Nextcloud Redis für das Transactional File Locking.

ufw

ufw (uncomplicated firewall) ist eine Software-Firewall, die auf einer Ubuntu-Installation standardmäßig bereits vorinstalliert ist. Normalerweise übernimmt der Router die Aufgaben einer Firewall, daher ist die Einrichtung von ufw optional. In bestimmten Szenarien kann hiermit jedoch die Sicherheit noch etwas erhöht werden.

Falls ufw noch nicht installiert sein sollte, kann man dies mit folgenden Befehlen erledigen:

apt-get update
apt-get install ufw

Die Firewall wird nun so eingerichtet, dass sämtlicher eingehender Traffic blockiert wird, jedoch mit zwei Ausnahmen:

  • SSH (Port 22): Hier soll der Zugriff nur aus dem Heimnetzwerk erlaubt sein.
  • HTTP/HTTPS (Ports 80/443): Da der Zugriff aus dem Web erforderlich ist, muss hier auch eine Ausnahme hinzugefügt werden.

Mit folgenden Befehlen werden diese Regeln umgesetzt:

ufw default deny
ufw allow proto tcp from 192.168.178.0/24 to any port 22
ufw allow 80
ufw allow 443
ufw enable

Der Status der Firewall kann jederzeit mit folgendem Kommando überprüft werden:

ufw status

Hinweis: Wenn auf dem Server weitere Anwendungen installiert werden, nutzen diese u.U. andere Ports, die mit dieser Konfiguration natürlich nicht erreichbar sind. Oftmals liegt es dann eben an dieser Firewall, wenn scheinbar alles korrekt eingerichtet und konfiguriert wurde, die Anwendung aber nicht richtig laufen will. In diesem Fall sollten die Firewall-Regeln entsprechend erweitert oder die Firewall temporär deaktiviert werden (ufw disable).

Überprüfung der Sicherheit

Die Sicherheit der eigenen Cloud war ja von Anfang an ein wichtiges Ziel dieses Artikels. Nach der Einrichtung von Nextcloud gibt es einige Tools, mit Hilfe derer geprüft werden kann, ob dieses Ziel auch erreicht wurde.

Qualys SSL Labs

Der erste Check gilt zunächst einmal der HTTPS-Verschlüsselung. Hier spielt das verwendete Let’s Encrypt Zertifikat, als auch die SSL-Einstellungen des Webservers eine wichtige Rolle.

Für diesen Test eignet sich der SSL Server Test von Qualys SSL Labs. Wenn alles richtig konfiguriert wurde, sollte man hier die beste Bewertung (A+) erzielen können. Wenn die SSL-Konfiguration des Gateway-Hosts wie oben beschrieben übernommen wurde, sollte man in jeder einzelnen Kategorie 100% angezeigt bekommen.

Ergebnis des SSL-Test

Ergebnis des SSL-Test

Falls hier eine niedrigere Bewertung angezeigt werden sollte, liegt dies vermutlich an der SSL-Konfiguration des Webservers. In diesem Fall sollten im Gateway-Host nochmals alle Einstellungen kontrolliert werden.

Nextcloud Security Scan

Ein weiterer Test ist der Nextcloud Security Scan. Dieses Tool prüft die öffentlich verfügbaren Informationen der Cloud und kann eventuelle Schwachstellen aufzeigen. Mit der hier gezeigten Konfiguration sollte ein A-Rating angezeigt werden.

Nextcloud Security Scan

Nextcloud Security Scan

Hier wird lediglich kein A+ Rating erzielt, da unter Hardenings der Eintrag __Host-Prefix bemängelt wird. Dies liegt darin begründet, dass Nextcloud über ein Unterverzeichnis aufgerufen wird und nicht im Root-Verzeichnis der Domain läuft (siehe GitHub-Issue). Dieser Punkt stellt aber kein Sicherheits-Risiko dar und kann daher ignoriert werden.

Troubleshooting

Manchmal kann es passieren, dass die Nextcloud-Installation nicht auf Anhieb erfolgreich verläuft. Daher an dieser Stelle noch ein paar Tipps für die Fehlersuche:

  • Alle Schritte korrekt ausgeführt?
    Die Installation einer eigenen Cloud ist alles andere als trivial und erfordert ziemlich viele Schritte. Die Praxis zeigt, dass man hin und wieder einen Schritt einfach übersieht. In diesem Fall kann die kleinste Abweichung dazu führen, dass „das große Ganze“ nicht mehr funktioniert. Als erster Schritt der Fehlersuche sollten daher noch einmal alle Punkte einzeln überprüft werden.
  • Log-Dateien kontrollieren
    Oftmals hilft auch ein Blick in die entsprechenden Log-Dateien:

    • nginx (/var/log/nginx/error.log): Hier findet man alle Warnungen und Fehler, die der Webserver aufgezeichnet hat. Dies ist die erste Anlaufstelle, wenn Nextcloud gar nicht aufgerufen werden kann bzw. Links nicht richtig funktionieren.
    • Nextcloud (/var/nextcloud_data/nextcloud.log): Hier sind Fehler/Warnungen von Nextcloud selbst enthalten. Die gleichen Einträge findet man in der Admin-Oberfläche der Cloud. Hier lohnt ein Blick, wenn Nextcloud prinzipiell erreichbar ist (der Webserver also vermutlich korrekt eingerichtet wurde), es aber bei der Benutzung von Nextcloud zu Problemen kommt.
  • Developer-Console im Browser
    Gerade wenn Links nicht korrekt funktionieren und man überprüfen möchte, ob beispielsweise eine Weiterleitung ins Leere führt, dann kann die Developer-Console im Browser (meist zu öffnen mit F12) wertvolle Hinweise liefern, da hier aufgezeigt wird, was auf Grund von Client-Request passiert. Die Bedienung der Console läuft in jedem Browser etwas anders ab, daher hilft ein Blick in die entsprechende Dokumentation:

Falls ihr also Probleme bei der Einrichtung von Nextcloud haben solltet, bitte erst einmal diese Punkte überprüfen. Oftmals findet man dann relativ schnell die Ursache der Probleme. Wenn alles nicht hilft, dann könnt ihr hier natürlich einen Kommentar hinterlassen, vielleicht kann euch hier schnell weitergeholfen werden.

Falls sich bestimmte Probleme häufen sollte, werde ich den Artikel ggf. anpassen und/oder erweitern.

Nextcloud: Ein sicherer Ort für all deine Daten

Dieser Slogan von Nextcloud fasst es relativ gut zusammen: Die Einrichtung der eigenen Cloud ist sicherlich etwas aufwändig und erfordert mehr Kenntnisse, als die Benutzung irgendeiner Cloud eines bestimmten Anbieters. Aber wenn die eigene Nextcloud erst einmal läuft, dann ist man Herr über seine eigenen Daten und ist nicht mehr von Anbietern wie Google, Microsoft oder Apple anhängig.

Man sollte sich nun aber auch im Klaren darüber sein, dass man nun auch für die eigenen Daten verantwortlich ist. Die eigene Cloud erfordert einen gewissen administrativen Aufwand, beispielsweise muss man selbst dafür sorgen, dass das Betriebssystem, die installierten Programme und v.a. Nextcloud auf einem aktuellen Stand gehalten werden. Der Aufwand sollte sich hier allerdings in Grenzen halten.

Ich hoffe, dass dieser Artikel hilfreich war und ich einigen unter euch etwas Zeit (und Nerven) bei der Einrichtung der eigenen Cloud ersparen konnte. Für konstruktive Kritik und Verbesserungsvorschläge bin ich immer offen, daher hinterlasst mir doch gern einen Kommentar.

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

Weiterführende Artikel

Links

]]>
https://decatec.de/home-server/nextcloud-auf-ubuntu-server-18-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/feed/ 1330
Ubuntu Server 18.04 LTS als Hyper-V Gastsystem installieren und optimal einrichten https://decatec.de/home-server/ubuntu-server-18-04-lts-als-hyper-v-gastsystem-installieren-und-optimal-einrichten/ https://decatec.de/home-server/ubuntu-server-18-04-lts-als-hyper-v-gastsystem-installieren-und-optimal-einrichten/#comments Tue, 01 May 2018 08:34:26 +0000 https://decatec.de/?p=4030 Ubuntu 18.04 + Windows

Mit der Veröffentlichung von Ubuntu 18.04 („Bionic Beaver“) ist eine neue LTS-Version der beliebten Linux-Distribution erschienen. Im folgenden Artikel wird die Installation von Ubuntu Server 18.04.1 als Gastsystem in einer Hyper-V-Umgebung beschrieben. Neben der Konfiguration der virtuellen Maschine und der Installation von Ubuntu Server geht es ebenfalls die Optimierung des Gastsystems, so dass es optimal in einer virtualisierten Umgebung laufen kann. Als Grundlage dient der schon vor einiger Zeit entstandene Artikel Ubuntu Server als Hyper-V Gastsystem installieren und optimal einrichten, in dem die Einrichtung von Ubuntu Server 16.04 gezeigt wurde. Da sich bei Ubuntu Server 18.04 einiges an der Installations-Routine geändert hat, ist es an der Zeit, dem Thema einen neuen Artikel zu gönnen.

Spezielle Linux-Kenntnisse sind dabei nicht erforderlich, wenn auch nicht hinderlich. Wer seinerzeit mit dem vorherigen Artikel eine Ubuntu-VM aufgesetzt hat, wird sich sicherlich sofort zurechtfinden.

Update-Historie (letztes Update: 10.08.2018)
  • 09.05.2018:
    • IP-Konfiguration: Hinweise für die nachträgliche Änderung der IP-Adresse hinzugefügt.
  • 01.06.2018:
    • Hinweis zum Einstellen der richtigen Zeitzone hinzugefügt.
  • 10.08.2018:
    • Angepasst an Ubuntu Server 18.04.1 (Setup-Prozess).
    • Manuelle Anpassung der Paketquellen nach der Installation.

 

Ubuntu: Virtualisierung mittels Hyper-V

Dieser Artikel ist fokussiert auf Ubuntu Server als Gast-Betriebssystem und Hyper-V als Virtualisierungs-Lösung. Warum nun genau diese Kombination?

Hyper-V

Wenn es um Virtualisierungs-Lösungen geht, kann man zwischen zwei Arten der Virtualisierung unterscheiden: Bei einem sog. Typ-1-Hypervisor läuft das Gast-Betriebssystem direkt auf der Hardware des Hosts. Dagegen setzt ein Typ-2-Hypervisor auf dem Host-Betriebssystem („eine Schicht weiter oben“) auf. Durch den Wegfall dieser Zwischenschicht läuft ein Typ-1-Hypervisor immer effizienter als ein Typ-2-Hypervisor.

Im Gegensatz zum populären VirtualBox ist Hyper-V dabei ein reiner Typ-1-Hypervisor. Daher fiel die Wahl bei diesem Artikel auf die Virtualisierungs-Lösung aus dem Hause Microsoft.

Allerdings kann dieses Tutorial auch mit jeder anderen Virtualisierungs-Software angegangen werden. Die Schritte zur Konfiguration des Gastsystems sind überall identisch.

Ubuntu Server

Microsoft öffnet sich ja zunehmend der Linux-Welt, was beispielsweise das Windows Subsystem for Linux deutlich macht. Auch die Unterstützung von Ubuntu auf Hyper-V ist mittlerweile weit vorangeschritten, wie dieser TechNet-Artikel zeigt. Prinzipiell kann hier auch eine andere Linux-Distribution zum Einsatz kommen, allerdings unterscheiden sich dann u.U. die Schritte zur Konfiguration des Gast-Betriebssystems.

Ubuntu Server herunterladen

Zunächst benötigt man ein ISO-Image des Gastsystems, welches man auf der Ubuntu-Homepage herunterladen kann. Die aktuellste Version ist dabei momentan 18.04 LTS („Bionic Beaver“). Da es sich um eine LTS-Version handelt (Long Term Support), wird diese Version ganze vier Jahre lang unterstützt.

Virtuelle Maschine erstellen

Zunächst muss die Hyper-V-Maschine erstellt werden. Als Hyper-V-Host dient dabei Windows Server 2016. Die gezeigten Schritte gelten aber auch für ältere Versionen von Windows Server bzw. Windows 10.

Virtuelle Festplatte erzeugen

Bevor die VM im Hyper-V-Manager angelegt wird, sollte die virtuelle Festplatte (vhdx) manuell mittels PowerShell erzeugt werden. Dieser Microsoft-Artikel erklärt dabei die Hintergründe: Für Linux-VMs sollte eine Block Size von 1 MB verwendet werden, da ansonsten mehr Speicherplatz auf dem Host-Betriebssystem belegt wird. Da beim Hyper-V-Manager keine benutzerdefinierte Block Size bei der Erstellung von virtuellen Festplatten angegeben werden kann, ist hier der kleine Umweg über die PowerShell notwendig.

Dazu die PowerShell mit Admin-Rechten starten. Folgender Befehl legt dann die virtuelle Festplatte mit einer Größe von 20 GB an:

New-VHD -Path "D:\Hyper-V\UbuntuServer1804\Virtual Hard Disks\UbuntuServer1804.vhdx" -SizeBytes 20GB -Dynamic -BlockSizeBytes 1MB

Virtuelle Festplatte mit PowerShell anlegen

Virtuelle Festplatte mit PowerShell anlegen

Laut den Systemanforderungen von Ubuntu Server würde zwar schon eine Festplatte mit 1,5 GB ausreichen, dennoch sollte man die Festplatte gleich etwas größer anlegen, um nachher mehr Spielraum zu haben. Durch das Erzeugen als dynamische Festplatte werden auch keine 20 GB belegt. Es wird nur so viel Speicherplatz benötigt wie die auf der Festplatte gespeicherten Daten einnehmen.

Anlegen der virtuellen Maschine

Nachdem die Festplatte schon vorbereitet wurde, geht es nun im Hyper-V-Manager an das Erzeugen der virtuellen Maschine. Dazu den Assistenten über Aktion > Neu > Virtueller Computer… aufrufen.

Name und Pfad angeben: Nach den Vorbemerkungen zum Assistenten wird der Name der virtuellen Maschine angegeben. Ebenfalls kann der Speicherort der VM konfiguriert werden. In diesem Fall gebe ich das Verzeichnis an, in dem alle Hyper-V-Maschinen gespeichert werden. Auch wenn es nicht so aussieht, sollte man den Pfad hier explizit angeben (die Option Virtuellen Computer an einem anderen Speicherort speichern muss dazu aktiviert werden), da ansonsten keine Verzeichnisstruktur erstellt wird, in der sämtliche Dateien der virtuellen Maschine unter einem Ordner gespeichert werden.

Name und Pfad der virtuellen Maschine

Name und Pfad der virtuellen Maschine

Generation angeben: Die Wahl der „Generation“ hängt vom zu installierenden Gast-Betriebssystem ab. Generation 2 ist dabei die modernere Variante und bietet mehr Virtualisierungs-Features. Da Ubuntu ab Version 14.04 Generation 2 unterstützt, wählen wir hier die entsprechende Option (siehe Microsoft-Artikel).

Generation der VM festlegen

Generation der VM festlegen

Speicher zuweisen: Als nächstes wird festgelegt, wie viel Speicher der virtuellen Maschine zur Verfügung stehen soll. 1024 MB (= 1 GB) sollte dabei vollkommen ausreichen. Hier sollte auch die Option Dynamischen Arbeitsspeicher für diesen virtuellen Computer verwenden aktiviert werden, so dass die VM nur so viel Arbeitsspeicher in Anspruch nimmt, die eben gerade benötigt wird.

Zuweisen von Arbeitsspeicher

Zuweisen von Arbeitsspeicher

Netzwerk konfigurieren: Da die VM nachher auch Netzwerkzugang benötigt, wird hier ein Netzwerkadapter angegeben. Dabei handelt es sich um einen sog. virtuellen Switch. Falls hier keine Option gewählt werden kann, muss ein solcher vermutlich erst noch angelegt werden. In diesem Artikel wird dazu die genaue Vorgehensweise erklärt.

Netzwerkkonfiguration der VM

Netzwerkkonfiguration der VM

Virtuelle Festplatte verbinden: Hier wird nun die virtuelle Festplatte der VM angegeben. Da die HDD bereits zuvor mittels PowerShell erzeugt wurde, wählen wir hier die Option Vorhandene virtuelle Festplatte verwenden und geben die entsprechende vhdx-Datei an.

Virtuelle Festplatte hinzufügen

Virtuelle Festplatte hinzufügen

Der letzte Schritt des Assistenten fasst nochmals alle gewählten Optionen zusammen. Passt alles, wird mit einem Klick auf Fertig stellen der Assistent abgeschlossen.

Einstellungen der virtuellen Maschine anpassen

Direkt nach der Erzeugung und vor dem ersten Start der virtuellen Maschine werden direkt noch einige Einstellungen vorgenommen/optimiert (Rechtsklick auf VM > Einstellungen…)

Sicherheit: Hier wird die Option Sicheren Start aktivieren eingeschaltet. Als Vorlage muss hier Microsoft UEFI-Zertifizierungsstelle gewählt werden, da die virtuelle Maschine später sonst nicht gestartet werden kann.

VM-Einstellungen: Sicherheit

VM-Einstellungen: Sicherheit

Arbeitsspeicher: Die Einstellungen für den (dynamischen) Arbeitsspeicher werden hier nochmals genauer spezifiziert. Damit die VM nicht beliebig viel Speicher beanspruchen kann, wird hier einfach das Maximum von 2048 MB (= 2 GB) angegeben.

VM-Einstellungen: Arbeitsspeicher

VM-Einstellungen: Arbeitsspeicher

Prozessor: Damit die VM auch alle zur Verfügung stehenden Prozessor-Kerne nutzen kann, wird die Anzahl der virtuellen Prozessoren soweit erhöht, dass unter Anteil der Gesamtsystemressourcen in % bei 100 steht. Falls die virtuelle Maschine nicht „so viel Dampf“ braucht, kann man hier aber auch einen kleineren Wert angeben. Dennoch ist es empfehlenswert, der VM mindestens zwei Prozessoren zuzuweisen.

VM-Einstellungen: Prozessor

VM-Einstellungen: Prozessor

SCSI-Controller: Da die erzeugte virtuelle Maschine standardmäßig kein DVD-Laufwerk besitzt, wird hier ein solches hinzugefügt. Dazu einfach den Eintrag DVD-Laufwerk markieren und auf Hinzufügen klicken. Daraufhin kann gleich die zuvor heruntergeladene ISO-Datei angegeben werden, so dass sich diese beim ersten Start der VM „im Laufwerk befindet“.

VM-Einstellungen: DVD-Laufwerk

VM-Einstellungen: DVD-Laufwerk

Firmware: Anschließend kommt noch ein kleiner Abstecher in den Menüpunkt Firmware. Hier wird einfach das soeben hinzugefügte DVD-Laufwerk als erste Startoption festgelegt.

VM-Einstellungen: Firmware

VM-Einstellungen: Firmware

Alle anderen Optionen in den Einstellungen für die virtuelle Maschine können auf Standard-Werten belassen oder nach eigenem Ermessen eingestellt werden. Ebenfalls können sämtliche Einstellungen auch noch nach der Installation des Gast-Betriebssystems geändert werden (wenn man beispielsweise doch einmal mehr Arbeitsspeicher benötigen sollte).

Installation Ubuntu Server 18.04

Die Einrichtung der VM auf dem Host-System ist nun abgeschlossen. Bevor wir die virtuelle Maschine das erste Mal starten, sollte noch ein Prüfpunkt angelegt werden (Rechtsklick auf die VM > Prüfpunkt). Falls bei der Installation etwas schief gehen sollte, kann man die virtuelle Maschine wieder den Ursprungszustand versetzen (über Rechtsklick auf den Prüfpunkt > Anwenden).

Nach einem Rechtsklick auf die VM und Verbinden…, kann die virtuelle Maschine mit Aktion > Starten (oder STRG+S) zum ersten Mal gestartet werden.

Zunächst wird die Sprache des Betriebssystems gewählt – in diesem Fall Deutsch:

Ubuntu Server Setup: Sprache

Ubuntu Server Setup: Sprache

Das Tastatur-Layout wird leider nicht automatisch angepasst, so dass im nächsten Schritt das passende Tastatur-Layout gewählt werden muss:

Ubuntu Server Setup: Tastatur-Layout

Ubuntu Server Setup: Tastatur-Layout

Anschließend wird die Installations-Methode gewählt. Hier ist die erste Option (Install Ubuntu) die passende: