Mit dem Begriff Cloud (eigentlich Cloud Computing) wird ein Funktionsprinzip umschrieben, bei dem über Internettechnologien Dienste und Ressourcen für Nutzer angeboten werden. Von zentraler Bedeutung ist dabei oftmals die Funktion des Datenspeichers zur Ablage und Austausch vielfältiger Datenformate, aber auch zu deren Ver- oder Bearbeitung „in der Cloud”.
Als Private Cloud werden dabei Infrastruktur- und Softwarelösungen einer Cloud-Umgebung bezeichnet, die für geschlossene Nutzergruppen - meist an eine Organisation gebunden - betrieben werden. Dies umfasst auch den Betrieb der erforderlichen Hardware in der jeweiligen Einrichtung (Hosting). Die Nutzung der Private Cloud Dienste sind dabei innerhalb, meist aber auch von außerhalb der Einrichtung über das Internet möglich.
Aufgrund der eigenständigen Verwahrung und Verarbeitung der Daten können die Anforderungen zum Schutz der Privatsphäre und des Datenschutzes erfüllt werden. Die Daten liegen im eigenen Verantwortungsbereich und die Dienste werden auf der eigenen Hardware betrieben. Man ist unabhängig von anderen Anbietern, deren Lizenzmodellen und Datenschutzbestimmungen - kein Vendor Lock. Persönliche Daten verbleiben im eigenen Einflussbereich. Die Erfassung personenbezogener Nutzungsdaten der Cloud-Dienste kann durch gezielte Auswahl der verwendete Software und Zusatzmodule verhindert werden, insbesondere kann die unkontrollierte Weitergabe an Dritte unterbunden werden.
Voraussetzung dafür sind Konzepte zum sicheren Betrieb der Cloud im eigenen Rechenzentrum. Dazu gehört die Absicherung gegen Missbrauch und Diebstahl der Daten (IT-Sicherheit) und Maßnahmen zur ungewollten Weitergabe von Metadaten.
Wenn keine eigenen Serverkapazitäten vorhanden sind, kann das Hosting auch durch Dritte in einem externen Rechenzentrum erfolgen. Dazu müssen Fragestellungen nach Sitz des Anbieters, dessen Datenschutzbestimmungen und deren Umsetzung u.v.m. geprüft werden. ToDo#
Diese Seite beschreibt den Aufbau einer private Cloud zum eigenständigen Betrieb unter Nutzung derzeitig weit verbreiteter Virtualisierungstechniken (KVM und Docker) auf Basis von Open-Source Software unter Lizenz für freie Software.
Auf den folgenden Seiten finden Sie Anleitungen zum Nachbau einer vergleichbaren Private Cloud Lösung.
Eine Übersicht der verwendeten und angebundenen Dienste zeigt die folgende Grafik.
Für die Nutzung der Dienste wird ein moderner Browser mit Unterstützung von HTML5 und WebRTC benötigt, z.B. Firefox oder Chromium.
Als zentrales Bindeglied wird Nextcloud verwendet, eine Software zur Speicherung von Daten auf einem Server und zu deren Austausch über den Server. Es stehen Clienten für das automatische Synchronisieren lokaler Verzeichnisse mit dem Server zur Verfügung. Darüber hinaus bietet Nextcloud viele Zusatzmodule, welche die Darstellung und Verarbeitung der Daten in der Cloud ermöglichen. Zusätzlich können weitere Dienste angebunden werden [1].
OnlyOffice und Collabora Online in der Development Edition (CODE) sind Online-Office Programme, welche das kollaborative Bearbeiten von in der NextCloud gespeicherten Office-Dokumentendienen gleichzeitig durch mehrere Personen erlauben. Beide Programme haben vergleichbare Office-Grundfuktionen, wobei OnlyOffice die Daten im Browser und CODE auf dem Server verarbeitet.
BigBlueButton (BBB) ist ist ein Webkonferenzsystem, welches on-premises als OpenSource-Lösung auf einem Linux-System betrieben werden kann. BBB eignet sich z.B für die Durchführung von Lehrveranstaltungen. Neben der Audio- und Video- und Chatkommunikation mehrerer Personen (Audio auch via Telefoneinwahl) erlaubt es die Anzeige von Dokumenten, Desktop-Sharing und besitzt eine Whiteboard-Funktionen.
Optional: Matrix und RocketChat sind Programme zum Chat und Instant Messaging, meist als Messenger bezeichnet. Matrix bezeichnet ein quelloffenes Protokoll, das von verschiedenen nutzerseitigen Clienten verwendet werden kann. Ein häufig verwendeter Client ist Elements (ehemals Riot). In der folgenden Beschreibung wird Elements-Web - ein Client für den Browser - gezeigt und mit dem Matrix-Server Synapse verbunden. Die Vernetzung (Federation) mit anderen Matrix-Servern ist ebenfalls möglich und erlaubt den Austausch über die Grenzen der Einrichtung hinaus.
Optional: GitLab ist eine umfangreiche Software zur Unterstützung von Softwareentwicklung und zur Versionsverwaltung mittels Git.
In diesem Fall dient GitLab als ein Beispiel für einen OAuth-Provider, welcher für die delegierte Nutzerverwaltung und Authentifizierung aus der Nextcloud heraus genutzt werden kann.
Optional: Contao und Wiki.js sind hier zwei Beispiele für Erstellung und Hosting von Webseiten.
Für den Aufbau dieses Systems wird eine KVM-Virtualisierung (Systemvirtualisierung mittels Hypervisor) als Basis genutzt, betrieben unter Debian-Linux. Alternativ kann auch eine andere Virtualisierungslösung und andere Linux-Systeme verwendet werden. Auch die direkte Installation auf dem Server ist möglich, hat allerdings Nachteile.
Durch die Systemvirtualisierung können schnell Backups (Snaphots) angelegt werden, was vor jedem Update empfehlenswert und bei einem Update-Problem auch sehr hilfreich ist. Ausfallzeit lassen sich dadurch minimieren.
Innerhalb des virtuellen Systems werden die Dienste als Container betrieben. Das erlaubt eine ressourcenschonenden Trennung einzelner Dienste. Außerdem vereinfacht es meist Installation und updates, also die notwendigen administrativen Arbeiten.
Folgende Grafik skizziert den Aufbau:
Die KVM-Maschine (im folgenden kurz als VMs bezeichnet) dienen als Basis für die Dienste. Man kann für jeden Dienst eigene VMs nutzen oder mehrere Dienste teilen sich eine VM. In diesem Fall muss geklärt werden, wie das Multiplexing der einzelnen Dienste erfolgt, da der Zugriff über einen Browser meist per HTTPS erfolgt und der zugehörige Port nur einmal pro Maschine zur Verfügung steht. Man kann dies über vorgeschaltete Webserver lösen, welche die verschiedenen Dienste auf unterschiedliche Ports der nachgelagerten VM verteilen. Das erhöht allerdings die Komplexität der Infrastruktur.
Einfacher geht es meist, innerhalb der Maschine durch Verwendung eines ReverseProxy-Webservers die einzelnen Dienste anhand des Domain- bzw. Subdomainnamens aufzuteilen. Wir nutzen diesen Aufbau mit einem Nginx-Server als Verteiler, welcher anhand von Subdomains für Chat, Wiki amn die Dienste weiterleitet, die jeweils in einem separaten Container betrieben werden. Es können auch mehrere VMs für die einzelnen Dienste betrieben werden und eine separate VM als vorgeschalteter Loadbalancer. Für den Betrieb der Container auf verschiedener Hardware. z.B. einem Cluster von Linux-Maschinen würde sich auch Kubernetes anbieten. Im hier getesteten Fall wird Proxmox verwendet. Proxmox erlaubt das Verwalten und Verteilen der VMs auf mehreren Rechnern.
Der Speicherplatz für die Datenablage in der Cloud wird über ein zugeschaltetes Storage-System bereitgestellt. Dadurch bleibt der erforderliche Speicherplatz innerhalb der VMs (block storage) und der Container übersichtlich, da die größeren Daten ausgelagert werden. Es sind verschiedene Storage-Konzepte möglich, z.B. die Verwendung von S3-, SAN- bzw. iSCSI-Speicherplatz, welcher dann als zusätzliche Festplatte im System zur Verfügung steht. Dieser Plattenspeicher kann mit ZFS- oder BTRFS-Filesystem eingebunden werden, so dass auch hier eine Snapshot-Funktion vor Updates genutzt werden kann. Viele Storage-Systeme erlauben auch selber das Anlegen von Snapshots.
Ebenfalls möglich ist die Verwendung von Netzwerk-Dateisystemen wie NFSv4, SMB oder SSHFS oder WebDAVs. Von letztgenannten wird aus Performancegründen abgeraten.
An das Storage-Systeme werden entsprechende Ansprüche an Ausfallsicherheit (z.B. RAID 5/6/10-Festplattenverbund) und Datendurchsatz gestellt. Auch eine Backuplösung sollte integriert werden.
Nach der obigen Abbildung läuft Nextcloud als Docker-Container in der VM. Die Netzwerkanbindung erfolgt über die HTTP-Weiterleitung von über 127.0.0.1
Port 8081. Zusätzlich wird noch eine Datenbank-Container benötigt. Folgendes docker-compose.yml
File zeigt eine Beispielkonfiguration beider Dienste unter Nutzung einer Postgres-Datenbank in der Major-Version 13. Für Nextcloud wird das aktuelle Image der Major-Version 22 verwendet.
docker-compose.yml
version: '3.2'
services:
nextcloud-db:
image: postgres:13
container_name: nextcloud-db
restart: always
volumes:
- ./data_db:/var/lib/postgresql/data
environment:
- POSTGRES_DB_FILE=/run/secrets/postgres_db
- POSTGRES_USER_FILE=/run/secrets/postgres_user
- POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
secrets:
- postgres_db
- postgres_password
- postgres_user
nextcloud:
image: nextcloud:22
container_name: nextcloud
ports:
- "127.0.0.1:8081:80"
depends_on:
- nextcloud-db
volumes:
- ./config:/var/www/html/config
- ./config/php.ini:/usr/local/etc/php/conf.d/zzz-custom.ini
- ./apps:/var/www/html/apps
- ./custom_apps:/var/www/html/custom_apps
- nfs-data:/var/www/html/data
environment:
- POSTGRES_HOST=nextcloud-db
- POSTGRES_DB_FILE=/run/secrets/postgres_db
- POSTGRES_USER_FILE=/run/secrets/postgres_user
- POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
- NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/nextcloud_admin_password
- NEXTCLOUD_ADMIN_USER_FILE=/run/secrets/nextcloud_admin_user
extra_hosts:
- "nas.example.com:192.168.1.5"
- "nas:192.168.1.5"
labels:
- com.centurylinklabs.watchtower.enable="false"
restart: always
volumes:
config:
apps:
custom_apps:
nfs-data:
driver: local
driver_opts:
type: nfs
o: nfsvers=4,addr=<IP Adresse des NFS-Storage>,rw
device: ":/pfad/auf/dem/NAS/zum/Nextcloud/datadir"
secrets:
nextcloud_admin_password:
file: ./nextcloud_admin_password.txt # put admin password to this file
nextcloud_admin_user:
file: ./nextcloud_admin_user.txt # put admin username to this file
postgres_db:
file: ./postgres_db.txt # put postgresql db name to this file
postgres_password:
file: ./postgres_password.txt # put postgresql password to this file
postgres_user:
file: ./postgres_user.txt # put postgresql username to this file
Die docker-compose.yml
sollte in einem Verzeichnis abgelegt werden, dass durch ein Backup erfasst wird. Da sich alle zugehörigen Dateien in diesem Verzeicnis und dessen Unterverzeichnissen liegen, werden Datenbank und die Metadaten gesichert. Die Nextcloud-Nutzer-Dateien liegen in diesem Fall auf einem NFS-Laufwerk, welches von einem NAS-System als volume nfs-data
eingebunden wird und separat über das NAS gesichert werden sollte.
Zusätzlich werden weitere Volumes benötigt, die als Unterverzeichnisse anzulegen sind und in dem die Datanbank und Konfig-Daten gespeichert sind.
mkdir config
mkdir apps
mkdir custom_apps
mkdir data_db
Die Zugangsdaten für einen administrativen Nextcloud- und Postgres-Nutzer, sowie den namen der Dantank sind in folgende Dateien einzutragen.
./nextcloud_admin_password.txt # put admin password to this file
./nextcloud_admin_user.txt # put admin username to this file
./postgres_db.txt # put postgresql db name to this file
./postgres_password.txt # put postgresql password to this file
./postgres_user.txt # put postgresql username to this file
Diese Dateien sollten sie nur Leserechte für Nutzer root
haben.
Starten der Containers:
Durch Aufruf von docker-compose pull
und docker compose up (-d)
aus dem Verzeichnis werden die Container gestartet. Die weitere Einrichtung erfolgt über die Weboberfläche.
Konfig-Datein werden im Verzeichnis ./config
abgelegt und können anschlißened veränderte werden. Die installierten Apps liegen persistend in den Verzeichnissen ./apps
bzw. ./custom_apps
, wo sie ggf. angepasst (Einspieln von Patches) werden können und auch nach einem Update weiterhin zur Verfügung stehen.
Der Nginx-Proxy übernimmt die Aufgabe der TLS-Termininierung und die Weiterleitung an die nachgelagerten Dienste. Dafür wird ein TLS-Zertifkat benötigt, welches entweder über die PKI der jewieligen Einrichtung oder über ein DV-validierenden Dienst, wie z.B. let's encrypt bezogen werden kann.
Nginx kann selber als Docker-Container betrieben werden. In diesem Beispiel ist NGinx aber als Debian-Linux Paket auf der VM installiert und ist dort der einzige Dienst der VM. Diese VM kann gecloned werden und auf jeder Kopie steht somit ein HTTP(S)-Basisservice zur Auslieferung statischer Seiten zur Verfügung. Dynamische Inhalte werden über die nachgelagerten Docker-Dienste eingebunden. Dazu muss nur die Docker-Konfigurtation angelegt und eine Include-Datei für die Nginx-Konfiguration bereitgestellt werden. Bei einem Ausfall, z.B eines aufgrund des Update der Docker-Container-Infrasturktur liefert der Webserver eine Maintenance-Seite aus.
Alternativ kann Nginx selber als Docker-Instanz ausgerollt werden. Dann sollten für die einzelnen Dienste (Nextcloud, Onlyoffice, Matrix, etc.) eigene nachgelagerte Docker-Netze mit unterschiedlichen privaten IP-Bereichen konfiguriert werden und der Reverse Proxy auf diese IPs verteilen. Das vereichfacht die Trennung der Netze und verhindert Konflikte, da z.B zwei Postgres-Datenbanken benötigt werden. Natürlich könnten die Dienste sich auch eine Postgres-Instanz teilen. Es entstehen jedoch wieder Abhängigkeiten der Dienste untereinander, was wir gern vermeiden wollen.
Für die Verwendung von Nexcloud mit Nginx empfiehlt es sich, eine separate Subdomain zu verwenden und sämtliche Aufrufe an diese Subdomain uzu leiten. Alternativ geht auch ein Unterverzeichnis, kann aber bei einigen Nextcloud-Apps zu Problem führen. Entsprechende Anfragen müssen in Nginx auf den passenden Pfad umgeschrieben werden. Die folgende Konfigurationsdatei, die von Nginx z.B. über den Ordner /etc/nginx/sites-enabled/
eingebinden werden kann, zeigt dies an einem Beispiel für die Domain beispiel.de
, bei der Nextcloud via https://beispiel.de/nextcloud
verlinkt ist.
beispiel.de.conf
# Erhöhe u.a. die maximale Upload-Größe bzw. Übertragungsmenge innerhalb einer Verbindung
client_max_body_size 10g;
# redirects needs to use X-Forwarded-Proto too
map $http_x_forwarded_proto $redirectscheme {
default $scheme;
https https;
}
server {
listen 443 ssl http2 default_server;
server_name _ beispiel.de www.beispiel.de;
# SSL-Einstellungen
include snippets/beispiel.de-tls.conf;
# hier können weitere Inhalte liegen
root /var/www/html;
index index.php index.nginx-debian.html index.html index.htm;
# lokale DNS-Resolver
resolver <eigener DNS-Sever>;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
# Reverse Proxy for Nextcloud
location /nextcloud {
rewrite ^/nextcloud$ /nextcloud/;
auth_basic off;
proxy_pass http://127.0.0.1:8081;
rewrite ^/nextcloud/(.*)$ /$1 break;
proxy_intercept_errors off;
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-Proto https;
client_max_body_size 0; # don't check
proxy_buffering off;
proxy_next_upstream off;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_max_temp_file_size 0;
}
location /.well-known/carddav {
return 301 https://$host/nextcloud/remote.php/dav;
}
location /.well-known/caldav {
return 301 https://$host/nextcloud/remote.php/dav;
}
# redirect wrong app links
location /index.php/apps/ {
return 301 https://$host/nextcloud/index.php/apps/;
}
location /index.php/settings/ {
return 301 https://$host/nextcloud/index.php/settings/;
}
# according to the documentation these two lines are not necessary, but version 21.0.0 will produce warnings in the overview setup check
location = /.well-known/webfinger { return 301 /nextcloud/index.php$uri; }
location = /.well-known/nodeinfo { return 301 /nextcloud/index.php$uri; }
}
# rewrite non SSL
server {
listen 80 default_server;
server_name _;
if ($host = www.beispiel.de) {
return 301 https://$host$request_uri;
}
if ($host = beispiel.de) {
return 301 https://$host$request_uri;
}
# otherwise
return 404;
}
Wir gehen von einem konfigurierten BBB-System aus, entweder aus einem BBB-Server oder einem Serververbund mit vorgeschaltetem Scalelite. Zur Integration wird das Secret (geheime Phrase) des Servers (Aufruf von bbb-conf --secret
) bzw. das LOADBALANCER_SECRET (Datei /etc/default/scalelite
) von Scalelite benötigt.
Die BBB-Anbindung erfolgt über die Nextcloud-App BigBlueButton Integration. Nach Installation ist in den Zusätzlichen Einstellungen in NextCloud die Eingabe der BigBlueButton-URL und des Secrets erforderlich. Anschließend können aus der Nextcloud hereaus BBB-Räume erstellt und verwaltet werden. Man kann den Zugriff auf Nextcloud-Nutzer und -Gruppen beschränken oder Gäste über eine Freigabe-URL ggf. mit PIN-Eingabe erlauben.
Die Verwaltung von Nutzeracounts, deren Zugangsdaten (Credentials), Berechtigungen (Autorisierung), das Gruppenmanagement u.v.m. sind von zentraler Bedeutung. In Nextcloud ist eine einfache Nutzer- udn Gruppenverwaltung enthalten. Über Zusatz-Apps ist die Intgration und das Erzwingen qualitätiv hochwertiger Authentisierungsverfahren, die über die Sicherheit passwortbasierter Authentisierung hinausgehen, möglich. Dazu gehört die Zwei-Faktor-Authentifizierung z.B. mit TOTP-Zugang oder U2F-Tokens sowie eID-Logins etc.
Allerdings ist das Nutzermanagement in Nextcloud beschränkt und kann bei größerer Nutzeranzahl fehlerträchtig und administrativ aufwendig sein. Insbesondere die Deaktiverung veralteter Accounts wird dabei gern übersehen.
Abhilfe schafft eine zentrale gepflegte Nutzerverwaltung (IdM Identitätsmanagment), welches in vielen Einrichtungen für andere Dienste, z.B. Workstation-Logins, schon verhanden ist. Zur Verwendung werden entsprechende API-Schnittstellen erforderlich.
So können die häufig vorhanden Schnittstellen zu LDAP oder ActiveDirectory eingebunden werden. Für Webapplikationen und Webservice kann es sich auch um Portal-Lösungen oder um die Einbindung verteilter Authentifizierungs- und Autorisierungssysteme handeln (Shibboleth oder CAS / Central Authentication Service, für föderiertes Identitätsmanagement). Als Portallösung wird häufig OAuth2 mit OpenID Connect für Autorisierung mit zentraler Identitätsschicht verwendet, meist erkennbar an den Buttons "Login with Service". Nextcloud unterstützt die genannten Dienste und noch einige mehr.
Als Beispiel wird die Verknüfung von Nextcloud (OAuth2-Client) mit GitLab (OAuth2-Provider) beschrieben. Die Nutzer- und Gruppenverwaltung zusammen mit den erfordelrichen Credentials kann somit an GitLab ausgelagert werden. Dazu wird die App Social Login verwendet.
In GitLab wird eine OAuth Application angelegt (Menu Admin / Applications) z.B. unter dem Namen "NextCloud Login". Die Redirect-URI lautet https://<Nextcloud-URL>/index.php/apps/sociallogin/custom_oidc/GitlabBeispielDe
wobei der letzte Pfadbestandteilt GitlabBeispielDe
aus der App Social Login zu ennehmen ist. Als Scopes sind openid, profile, email
zu aktivieren. Die angezeigte Application ID und das Secret sind in die parallel durchzührende Einstellung in Nextcloud für eine neue Custom OpenID Connect Verbindung zu übernehmen.
Dort muss auch ein entsprechender Title vergeben werden, z.B. Gitlab Beispiel.de
woraufhin der in Gitlab für die Redirect URL zu verwendende "Internal name" GitlabBeispielDe
angezeigt wird.
In der App sind drei URLs und zwei Felder auszufüllen:
https://<GitLab-URL>/oauth/authorize
https://<GitLab-URL>/oauth/token
https://<GitLab-URL>/oauth/userinfo
openid email
groups
Der ButtonStyle sollte auf GitLab gesetzt und eine Default-Gruppe ausgewählt werden. Anschließend kann man den Button "Login with Gitlab" für die Anmeldung mit einem bestehenden GitLab-Account verwenden. Ist man bereits in GitLab angemeldet, so ist man nach der Auswahl ebenfalls sofort in der Nextcloud angemeldet.
Folgende Einstellungen für Social Login können auch von Interesse sein:
TODO
Für die Integration einer kollaborativen Office-Umgebung bieten sich OnlyOffice (läuft im wesentlichen im Browser)
oder Collabora Online in der Development Edition (CODE, läuft über den Server) an.
Wir beschreiben hier die Installation von OnlyOffice auf Docker-basis und die Integration in Nextcloud.
Die Installation ist relativ einfach. Eine Beschreibung findet man unter https://helpcenter.onlyoffice.com/de/installation/docs-community-docker-compose.aspx
git clone https://github.com/ONLYOFFICE/Docker-DocumentServer docker-onlyoffice
cd docker-onlyoffice
Für die Vewendung mit vorgelagertem Reverse Proxy sollte diedocker-compose
Konfig-Datei etwas angepasst werden:
...
onlyoffice-documentserver:
...
environment:
...
# Empfehlenswert, hier aktivieren und entsprechendes Secret festlegen:
# Uncomment strings below to enable the JSON Web Token validation.
#- JWT_ENABLED=true
#- JWT_SECRET=secret
#- JWT_HEADER=Authorization
#- JWT_IN_BODY=true
ports:
- '8083:80'
...
Starten
docker-compose up -d
Bei Bedarf die entsprechenden Fonts installieren.
Die Reverse-Proxy-Konfiguration erfolgt analog den anderen Systemen. Der Server soll auch unter beispiel.de
hören. Demzufolge ist obige Nginx-Konfigration zu erweitern:
# redirects needs to use X-Forwarded-Proto too
map $http_x_forwarded_proto $redirectscheme {
default $scheme;
https https;
}
# Reverse Proxy Backend for OnlyOffice
upstream docservice {
server 127.0.0.1:8083;
}
# for OO
map $http_x_forwarded_proto $the_scheme {
default $http_x_forwarded_proto;
"" $scheme;
}
# for OO
map $http_x_forwarded_host $the_host {
default $http_x_forwarded_host;
"" $host;
}
# for OO.
map $http_upgrade $proxy_connection {
default upgrade;
"" close;
}
...
server {
...
# Reverse Proxy for nextcloud
location /nextcloud {
...
}
location /documentserver/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host/documentserver;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://docservice/;
proxy_http_version 1.1;
}
...
}
Matrix ist ein offenes Messenger-Protokoll, dessen Besonderheit in dem dezentralen Ansatz liegt. Matrix-Server können Daten untereinander austauchen. Über Bridges geht das (im begrenzten Maße) sogar mit anderen Messengern. Bots ermöglichen automatisch ausgeführte Aktionen, wie z.B. Benachrichtigungen bei bestimmten Ereignissen oder die automatische Reaktion auf bestimmte Anfragen.
Matrix ist ein Kommunikationsprotokoll für föderierte Echtzeitkommunikation und unterstützt dabei auch Ende-zu-Ende Verschüsselung für zwei Teilnehmern oder für Gruppen in Gruppenchats.
Es stehen sowohl freie Matrix-Server-Implementierungen, als auch Desktop-, Mobile- und Web-Clienten für verschiedende Betriebssysteme und Smartphones zur Verfügungen. Anwender können ihre eigenen Matrix-Server betreiben, darüber Nutzer anlegen und mti andren Matrix-Nutzern (auf anderen Servern) sicher kommunizieren. Das macht den Einsatz von Matrix auch in Verbindung mit einer Private-Cloud-Lösung interessant, da es neben dem Datenautausch auch Echtzeitkommunikation und Push-Benachrichtiung unterstützt.
Hier wird der Betrieb des Matrix-Server Synapse (https://github.com/matrix-org/synapse/) als Docker-Container und dessen SSO-Integration beschrieben. Als Client für die Verwendung im Browser wird Element/Web (https://github.com/vector-im/element-web) verwendet und ebenfalls als Container betrieben. Über den ReverseProxy stehen beide Systeme im Netz zur Verfügung. Zur Nutzerverwaltung wiurd außerdem Synapse-Admin eingesetzt (https://github.com/Awesome-Technologies/synapse-admin). Aus Sicherheitsgründen wird der Zugriff darauf jedoch nur über einen SSH-Tunnel erlaubt.
Alle Teile stehen als Docker-Container zur Verfügung. Die Einrichtung muss schrittweise erfolgen.
Aus Sicherheitsgründen sollten getrennte (Sub)Domains für Matrix und Element verwendet werden (siehe https://github.com/vector-im/element-web/issues/1977). In diesem Beispiel ist es matrix.beispiel.de
und element.beispiel.de
.
Auf dem VM sollte ein Unterverzeichnis für die Matrix-Docker-Maschien angelegt werden, z.B. matrix und darunter einige weitere Verzeichnisse für persistente Daten zum Backup.
mkdir matrix
cd matrix
mkdir -p data/matrix/synapse
mkdir -p data/matrix/element
mkdir -p data/postgres/data
chmod 777 data/postgres/data
Die zugehörige docker-compose.yml
# docker-compose.yml
version: "3.3"
services:
postgresql:
image: "postgres:latest"
restart: "unless-stopped"
environment:
POSTGRES_PASSWORD: <einsetzen>
POSTGRES_USER: synapse
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
volumes:
- "./data/postgres/data:/var/lib/postgresql/data"
redis:
image: "redis:latest"
restart: "unless-stopped"
synapse:
image: "matrixdotorg/synapse:latest"
restart: "unless-stopped"
ports:
- "127.0.0.1:8008:8008"
depends_on:
- postgresql
- redis
environment:
VIRTUAL_HOST: "matrix.beispiel.de"
VIRTUAL_PORT: 8008
SYNAPSE_CONFIG_DIR: "/data"
SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml"
SYNAPSE_SERVER_NAME: "matrix.cslsa.de"
SYNAPSE_REPORT_STATS: "no"
UID: "1000"
GID: "1000"
TZ: "Europe/Berlin"
volumes:
- "./data/matrix/synapse:/data"
# Verwendung über ssh-Tunnel mit
# ssh <KVM-Maschine> -L 8081:localhost:8081 -L 8008:localhost:8008
# dann als Heimeserver-URL: http://localhost:8008
synapse-admin:
hostname: synapse-admin
build:
context: https://github.com/Awesome-Technologies/synapse-admin.git
ports:
- "127.0.0.1:8081:80"
restart: unless-stopped
element:
image: "vectorim/element-web:latest"
restart: "unless-stopped"
ports:
- "127.0.0.1:8080:80"
volumes:
- "./data/matrix/element/config.json:/app/config.json:ro"
Bevor das System gestartet werden kann, müssen die Konfigurationsdateien angelegt werden. Für Synapse wird eine anzupassende Vorlage durch einen kurzen docker-Aufruf mit den richtigen Paramtern unter data/matrix/synapse/homeserver.yaml
erzeugt und muss im Anschluss angepasst werden:
docker run -it --rm \
-v $(pwd)/data/matrix/synapse:/data \
-e SYNAPSE_SERVER_NAME=matrix.beispiel.de \
-e SYNAPSE_REPORT_STATS=no \
-e UID=1000 \
-e GID=1000 \
matrixdotorg/synapse:latest generate
Dadurch wurden Schlüssel und Datei homeserver.yaml
im Ordner data/matrix/synapse/
erzeugt. Folgende Zeilen in data/matrix/synapse/homeserver.yaml
sollten angepasst werden:
# Auszug
## Server ##
server_name: "matrix.beispiel.de"
# The absolute URL to the web client which /_matrix/client will redirect
# to if 'webclient' is configured under the 'listeners' configuration.
web_client_location: https://element.beispiel.de/
listeners:
# Unsecure HTTP listener: for when matrix traffic passes through a reverse proxy
# that unwraps TLS.
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
## Database ##
database:
name: psycopg2
txn_limit: 10000
args:
user: synapse
password: <einsetzen>
database: synapse
host: postgresql
cp_min: 5
cp_max: 10
## Logging ##
log_config: "/data/matrix.beispiel.de.log.config"
## Media Store ##
# Enable the media store service in the Synapse master. Uncomment the
# following if you are using a separate media store worker.
#
#enable_media_repo: false
# Directory where uploaded images and attachments are stored.
# Für persistente Speicherung könnte hier ein Pfad gemountet werden
media_store_path: "/data/media_store"
# Whether or not to report anonymized homeserver usage statistics.
#
report_stats: false
# Configuration for Redis when using workers. This *must* be enabled when
# using workers (unless using old style direct TCP configuration).
redis:
enabled: true
host: redis
port: 6379
# Optional password if configured on the Redis instance
#
#password: <secret_password>
# Empfehlenswert
# Server Notices room configuration
server_notices:
system_mxid_localpart: notices
system_mxid_display_name: "Server Notices"
room_name: "Server Nachrichten"
#system_mxid_avatar_url: "mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ"
Neben der lokalen Nutzerverwaltung stehen mehrere zentrale und SSO-Authentifizierungsvarianten zur Verfügung. Dazu gehören u.a. OpenID-Connect / OAuth, SAML, CAS uvm. Siehe https://matrix-org.github.io/synapse/latest/usage/configuration/user_authentication/single_sign_on/index.html .
Als Beispiel wird hier die Einbindung von OAuth mit Gitlab als Provider gezeigt, wodurch auch die Nutzerverwaltung zentralisiert werden kann. Je nach Einrichtung sind entsprechende Möglichkeiten zu prüfen.
Folgende Ergänzungen in data/matrix/synapse/homeserver.yaml
für SSO über zentrale GitLab OAuth2-Anbindung (OIDC-Provilder):
# Additional settings to use with single-sign on systems such as OpenID Connect,
# SAML2 and CAS.
sso:
client_whitelist:
- https://element.beispiel.de/
update_profile_information: true
# GitLab als OAuth2-Provider
# see https://matrix-org.github.io/synapse/latest/openid.html
oidc_providers:
- idp_id: gitlab
idp_name: Gitlab
idp_brand: "gitlab" # optional: styling hint for clients
issuer: "https://<GitLab-Domain>"
client_id: "<von GitLab>"
client_secret: "<von GitLab>"
client_auth_method: "client_secret_post"
scopes: ["openid", "read_user"]
user_profile_method: "userinfo_endpoint"
allow_existing_users: true
user_mapping_provider:
config:
localpart_template: '{{ user.nickname }}'
display_name_template: '{{ user.name }}'
Parallel muss dazu in GitLab analog zum NextCloud-Zugang eine Application angelegt und die ID und Secets darais in die obige Konfig-Datei übertragen werden. Die Redirect URI in GitLab lautet: https://matrix.beispiel.de/_synapse/client/oidc/callback
und die Scopes openid
und read_user
müssen ausgewählt werden.
Der Server kann jetzt mit
docker-compose up -d synapse
aus dem matrix
-Verzeichnis heraus gestartet werden. Mögliche Fehler findet man vielleicht in der Ausgabe von docker-compose logs -f
.
Für bestimmte Zwecke wird später noch ein lokaler adminsitrativer Nutzer benötigt. Dieser kann bei laufendem Container wie folgt angelegt werden:
docker ps
# Name des Synapse-Conainers bestimmen
docker exec -it <Synapse-Container-Name> /bin/bash
# Nutzer anlegen
register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
# und Admin auswählen
Die Datenbank liegt im Verzeichnis ./data/postgres/data
welches mit offenen Schreibrechten angelegt wurde. Diese kann jetzt wieder eingeschränkt werden.
ls -aln ls -lan data/postgres/data/
# uid und gid der Dateien bestimmen, sollte 999:999 sein
chown <uid>:<gid> data/postgres/data/
chmod 700 data/postgres/data/
Nachdem der Reverse-Proxy (siehe unten) aktiviert wurde, kann die Funktion des Matrix-Servers z.B. durch Aufruf der Versionsabfrafge via API-Call im Browser geprüft werden https://matrix.beispiel.de/_matrix/federation/v1/version
und sollte z.B. folgende Ausgabe erzeugen:
{"server":{"name":"Synapse","version":"1.49.2"}}
Die API-Spezifikation findet man u.a. hier: https://spec.matrix.org/v1.1/server-server-api/
Für die einfache Verwendung des Servers bietet sich ein Webclient an. Wir beschreiben hier Element-Web.
Die Einrichtung ist relativ einfach.
Es wird lediglich eine Datei data/matrix/element/config.json
benötigt. Das folgende Beispiel kann dahingehend angepasst werden. Die SSO-Paramter sollten ggf, angepasst werden. Eine Beschreibung aller Parameter findet man unter https://github.com/vector-im/element-web/blob/develop/docs/config.md.
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.beispiel.de",
"server_name": "matrix.beispiel.de"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"sso_redirect_options": {
"immediate": false,
"on_welcome_page": false
},
"disable_custom_urls": true,
"disable_guests": true,
"disable_login_language_selector": false,
"disable_3pid_login": false,
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"defaultCountryCode": "DE",
"showLabsSettings": true,
"features": {
"feature_new_spinner": "labs",
"feature_pinning": "labs",
"feature_custom_status": "labs",
"feature_custom_tags": "labs",
"feature_state_counters": "labs"
},
"default_federate": true,
"default_theme": "light",
"roomDirectory": {
"servers": [
"matrix.org"
]
},
"welcomeUserId": "@riot-bot:matrix.org",
"embeddedPages":{
"loginForWelcome":true
},
"piwik": false,
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
},
"settingDefaults": {
"breadcrumbs": true
},
"jitsi": {
"preferredDomain": "jitsi.riot.im"
}
}
Der Server kann jetzt mit docker-compose up -d element
gestartet werden.
Für den externen Zugriff benötigt man noch einen Reverse Proxy, z.B. für HAProxy, Apache, etc. Im Folgenden wird es wieder mit Nginx beschrieben.
Die Reverse-Proxy-Konfiguration für Nginx erfolgt analog zu den Nextcloud.
# stuff for http block
client_max_body_size 1g;
# redirects needs to use X-Forwarded-Proto too
map $http_x_forwarded_proto $redirectscheme {
default $scheme;
https https;
}
# Matrix-Server Synapse
server {
listen 443 ssl http2;
#listen [::]:443 ssl http2;
# For the federation port
listen 8448 ssl http2 default_server;
#listen [::]:8448 ssl http2 default_server;
# TSL-Einstellungen
include snippets/beispiel.de-tls.conf;
server_name matrix.beispiel.de _;
root /var/www/html1;
index index.html;
resolver <DNS Server>; # lokalen DNS-Resolver eintragen
#resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
#resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
# other settings
client_max_body_size 65M;
# matrix container proxy
location ~* ^(\/_matrix|\/_synapse\/client) {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /.well-known/matrix/ {
root /var/www/html1;
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
}
# Elements and Riot or other Matrix-Webclients via elements.beispiel.de
server {
listen 443 ssl http2;
#listen [::]:443 ssl http2;
# TSL-Einstellungen
include snippets/beispiel.de-tls.conf;
server_name elements.beispiel.de;
root /var/www/html1;
index index.html;
resolver <DNS Server>; # lokalen DNS-Resolver eintragen
#resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
#resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
client_max_body_size 65M;
# elements container proxy
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Für die Abfrage der Delegation (Föderation) müssen unter https://<domain>/.well-known/matrix
passende Einträge abgerufen werden können. Das kann durch Synapse selber erfolgen (siehe https://matrix-org.github.io/synapse/latest/delegate.html) oder nretis durch den ReverseProxy ausgeliefert werden. Aufgrund des root-Pfades /var/www/html1
sind dazu folgende Dateien anzulegen:
/var/www/html1/.well-known/matrix/server
{
"m.server": "matrix.beispiel.de:443"
}
/var/www/html1/.well-known/matrix/client
{
"m.homeserver": {
"base_url": "https://elements.beispiel.de"
}
}
In den obigen Beispielen wurde die TLS-Konfiguation über eine Include-Datei eingebunden. Hier eine Beispiel-Kopfiguraituon, welche die aktuellen TLS-1.2 und 1.3 Standards konfiguriert und entsprechende Sicherungsmaßnahmen umsetzt.
Beispiel-TLS Konfiguration snippets/beispiel.de-tls.conf
;
ssl_certificate /etc/letsencrypt/live/beispiel.de/fullchain.pem; # Certkette eintragen
ssl_certificate_key /etc/letsencrypt/live/beispiel.de/privkey.pem; # Key eintragen
ssl_dhparam /etc/nginx/ssl/ssl-dhparams.pem; # ggf. generieren mit: openssl dhparam -out /etc/nginx/ssl/ssl-dhparams.pem 4096
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp521r1:secp384r1;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS_AES_256_GCM_SHA384:TLS-AES-256-GCM-SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA;
# If you want to use 0-RTT uncomment the following line.
# However read https://tools.ietf.org/html/rfc8470 first.
#ssl_early_data on;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
Abhängig von der verwendeten PKI sind weitere Einstellungen zu OCSP und DNS-CAA-Einträge sinnvoll. Auch die Nutzung von Certbot zusammen mit der let's encrypt PKI ist möglich. Dafür bieten sich verschiedene Docker-basierte Lösungen an.