Nextcloud

Nextcloud ist eine Open-Source-Groupware für Cloud-Dienste und Datensynchronisation auf eigenen Servern. Kern-Feature ist die verteilte Zusammenarbeit an Dateien - verwaltet per Web-GUI, WebDAV oder dem Nextcloud-Desktop-Client. Apps erweitern das System: Kalender und Adressbuch (Standard), Office-Integration, Videokonferenz, Mail, Deck, LDAP- und OIDC-Anbindung.

Nextcloud ging 2016 aus ownCloud hervor. Release-Zyklus (Stand NC 33): etwa alle 16 Wochen eine neue Major-Version, jede Major wird ein Jahr lang mit Maintenance-Releases versorgt. Die aktuell unterstützten Majors und ihre PHP-Anforderungen stehen im Releases-and-PHP-versions-Wiki.

Begriffe

App

Erweiterung der Nextcloud-Kernfunktionen. Apps werden vom App Store oder per Hand installiert und liegen in apps/ bzw. custom_apps/. Verwaltung per Web-UI oder occ app:*.

Background Job

Ein wiederkehrender Job, den der Nextcloud-Scheduler abarbeitet (File-Scans, Cleanup, Federations-Sync etc.). Läuft entweder per Cron (cron.php, empfohlen), AJAX (im Browser des eingeloggten Users, nur für Test) oder Webcron (externer Dienst pollt regelmässig). Konfigurierbar per occ background:cron|background:ajax|background:webcron.

Federation

Nextcloud-zu-Nextcloud-Freigabe über mehrere Instanzen hinweg. Nutzt das Open Cloud Mesh Protocol.

HPB (High Performance Backend)

Sammelbegriff aus der Nextcloud-Doku für den Verbund aus Signaling-Server, Janus und NATS, der das PHP-basierte Signaling für Nextcloud Talk durch eine performante Standalone-Lösung ersetzt. Details in Nextcloud Talk, STUN & TURN.

OCC (ownCloud Console)

Das Kommandozeilen-Interface. Aufruf stets als PHP-User (Apache/www-data): sudo -u apache php /var/www/html/nextcloud/occ .... Komplette Kommandoliste mit occ list, Hilfe pro Kommando mit occ help <command>.

OCS-API

OpenCollaborationServices-API. REST-artige HTTP-API für Mobile-Apps, Desktop-Clients und externe Integrationen. Erreichbar unter /ocs/v1.php/… bzw. /ocs/v2.php/….

ODF

OpenDocument Format (ISO 26300). Von LibreOffice und Collabora präferiertes Dokumentenformat, Endungen .odt, .ods, .odp. Siehe Collabora vs. LibreOffice.

OOXML

Office Open XML (ISO 29500). Microsoft-Office-präferiertes Format, Endungen .docx, .xlsx, .pptx. OnlyOffice bevorzugt OOXML, Collabora bevorzugt ODF.

Preview-Generator

Hintergrund-App, die für Dateien Vorschau-Bilder in mehreren Grössen erzeugt und cached. Ohne Preview-Generator erzeugt Nextcloud Previews on demand, was bei grossen Ordnern den ersten Aufruf spürbar verzögert.

Primary Storage

Der Ort, an dem Nextcloud Datei-Inhalte ablegt. Default ist das Filesystem unter data-dir; alternativ Object Storage (siehe Nextcloud Object Storage).

Talk

Videokonferenz-, Chat- und Audio-App (Paketname spreed). Für kleine Calls reicht die integrierte PHP-Signaling-Variante; ab fünf Teilnehmern lohnt sich das HPB. Details in Nextcloud Talk, STUN & TURN.

WebDAV

Das HTTP-basierte Protokoll, über das Nextcloud Dateien ausliefert. Endpunkt: /remote.php/dav/files/<username>/. Der Nextcloud-Desktop- und Mobile-Client sprechen WebDAV.

Funktionsübersicht der Nextcloud-Produkte

Feature

Files

Groupware

Office

Talk

Flow

Assistant

File Sync

File Sharing

Calendar

Contacts

Mail

Deck

Document Editing

Real-time Collaboration

Chat & Audio Calls

Video Conferencing

Screen Sharing

Workflow Automation

AI Assistant

Installation

Linuxfabrik-Setups werden über die Ansible-Rolle linuxfabrik.lfops.nextcloud aufgesetzt. Die Rolle kümmert sich um Paketquellen, Apache, PHP-FPM, MariaDB, Redis, Systemd-Timer und die SELinux-Booleans. Für manuelle Setups beschreibt das Admin Manual (Installation) den Weg Schritt für Schritt.

Archiv-Downloads: https://download.nextcloud.com/server/releases/ (aktuellstes Release: https://download.nextcloud.com/server/releases/latest.tar.bz2).

Tipp

Auf Instanzen mit mehreren Benutzern, die sich untereinander nicht kennen, die App „User status“ abschalten - das Nextcloud-Dashboard zeigt sonst die Liste der letzten Anmeldungen inkl. E-Mail-Adressen anderer Benutzer an.

Den Subscription-Key für Enterprise-Installationen aus https://portal.nextcloud.com/subscription hinterlegen:

sudo -u apache /var/www/html/nextcloud/occ app:install support
sudo -u apache /var/www/html/nextcloud/occ config:app:set support subscription_key --value='1Q2W-3E4R-5T6Z-7U8I'
# optional hard cap on user count:
sudo -u apache /var/www/html/nextcloud/occ config:app:set support user-limit --value='10'

Update und Upgrade

Standardweg ist das CLI-Upgrade per occ upgrade. Das Web-Upgrade bleibt als Fallback für Setups ohne Shell-Zugang. Linuxfabrik setzt das CLI-Upgrade über das nextcloud-update-Skript aus der LFOps-Rolle ein.

sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --on
# ... pull new release tarball, replace files, keep config/ and data/ ...
sudo -u apache php /var/www/html/nextcloud/occ upgrade
sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --off

Nach dem Upgrade zusätzlich occ db:add-missing-indices, occ db:add-missing-columns und occ db:add-missing-primary-keys ausführen - die Nextcloud-Weboberfläche zeigt explizit an, wenn diese Schritte offen sind.

Konfiguration

Die Haupt-Konfiguration liegt in /var/www/html/nextcloud/config/config.php. Einzelne Parameter lassen sich auch per occ config:system:set setzen, was für Automatisierung und Idempotenz einfacher ist.

Alle Optionen und ihre Defaults: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html.

Loglevel

  • 0 DEBUG - alle Aktivitäten, sehr detailliert.

  • 1 INFO - User-Logins und Dateiaktivitäten plus Warnings, Errors, Fatal Errors.

  • 2 WARN - Operationen gelingen, aber mit Warnings.

  • 3 ERROR - Operation schlägt fehl, andere Dienste laufen weiter (Standard für Produktion).

  • 4 FATAL - Server stoppt.

sudo -u apache /var/www/html/nextcloud/occ config:system:set loglevel --value=3 --type=integer

Unerlaubte Zeichen in Dateinamen

Die vier zusammengehörigen Optionen forbidden_filenames, forbidden_filename_basenames, forbidden_filename_characters und forbidden_filename_extensions legen fest, welche Namen Nextcloud in der Web-UI und auf WebDAV ablehnt. Standardverbote umfassen \ / : ? * " < > | sowie führende und nachgestellte Leerzeichen.

sudo -u apache /var/www/html/nextcloud/occ config:system:get forbidden_filename_characters

Für Dateien, die bereits im Bestand sind und ungültige Zeichen tragen, hilft ab Nextcloud 30 das Kommando occ files:sanitize-filenames (benennt sie gemäss den konfigurierten Regeln um). Für ältere Installationen muss manuell umbenannt oder gelöscht werden.

Siehe auch unseren Blog-Beitrag RewriteRule vs. ProxyPass - für Nextcloud entscheidend.

Maintenance-Mode

Sperrt alle Benutzer aus (ausser Admin via CLI). Für Upgrades, Wartung und konsistenzsensitive Eingriffe zwingend:

sudo -u apache /var/www/html/nextcloud/occ maintenance:mode --on
sudo -u apache /var/www/html/nextcloud/occ maintenance:mode --off
sudo -u apache /var/www/html/nextcloud/occ maintenance:mode

Cron-Backend

Für Background-Jobs drei Varianten - für produktive Setups ist cron (systemd-Timer oder klassisches cron mit cron.php) der Standard:

sudo -u apache /var/www/html/nextcloud/occ background:cron
sudo -u apache /var/www/html/nextcloud/occ background:ajax
sudo -u apache /var/www/html/nextcloud/occ background:webcron

OCC - das Admin-Interface

occ ist das zentrale Kommandozeilen-Werkzeug. Es muss als PHP-User (Apache, www-data) ausgeführt werden, damit Dateisystemrechte stimmen:

sudo -u apache /var/www/html/nextcloud/occ <command> [options]
sudo -u apache /var/www/html/nextcloud/occ list
sudo -u apache /var/www/html/nextcloud/occ help <command>

Eine Auswahl der Kommandos, die im Admin-Alltag immer wieder gebraucht werden:

Kommando

Zweck

status

Instanz-Status (Version, Edition, Maintenance)

upgrade

CLI-Upgrade nach Austausch des Release-Tarballs

maintenance:mode

Maintenance-Mode an/aus/abfragen

maintenance:repair

Reparatur-Pass nach Upgrades

db:add-missing-indices

fehlende Indizes anlegen (nach Upgrades)

db:add-missing-columns

fehlende Spalten anlegen (nach Upgrades)

db:add-missing-primary-keys

fehlende Primary Keys anlegen (nach Upgrades)

files:scan --all

Dateisystem erneut einlesen

files:cleanup

verwaiste oc_filecache- und Mount-Einträge

files:sanitize-filenames

NC 30+: ungültige Dateinamen bereinigen

user:add|list|delete|disable

Benutzerverwaltung

group:adduser|removeuser

Gruppenzuweisungen

config:system:get|set|delete

Systemweite Konfiguration (config.php)

config:app:get|set|delete

App-spezifische Konfiguration

app:install|enable|disable

Apps installieren, aktivieren, deaktivieren

background-job:execute <id>

einzelnen Background-Job manuell ausführen

log:tail -f

Live-Follow des Nextcloud-Logs

ldap:*

LDAP-Konfiguration und -Tests

notify_push:setup

High-Performance-Client-Push einrichten

trashbin:expire|cleanup

Papierkorb aufräumen

versions:expire|cleanup

Datei-Versionen aufräumen

Die vollständige Liste liefert occ list. Kommandos aus installierten Apps (Talk: talk:*, Mail: mail:*, Deck: deck:* etc.) tauchen dort ebenfalls auf.

Storage

Nextcloud kennt drei Arten von Storage:

Primary Storage (Local)

Filesystem unter dem in config.php konfigurierten datadirectory. Default, funktioniert ohne zusätzliche Software.

Primary Storage (Object)

S3, Swift oder Azure Blob als Primary Storage. Siehe Nextcloud Object Storage für Setup und Migration.

External Storage

Zusätzliche Storages, die pro User oder global gemountet werden (SMB/CIFS, SFTP, FTP, WebDAV, weitere S3-Buckets, Nextcloud-Federation). Konfigurierbar per App Files External (files_external).

External Storage: SMB/CIFS

Aktuelle Voraussetzungen laut Admin Manual (External Storage SMB):

  • PHP-Modul libsmbclient-php (native Integration, bevorzugt). Auf RHEL 9+ aus dem remi-Repo bzw. direkt mit php-smbclient, unter Debian/Ubuntu php-smbclient.

  • Binary smbclient (Samba-Client, ab Version 4.x) für Push-Notifications über occ files_external:notify.

# RHEL 9+
dnf --assumeyes install cifs-utils php-smbclient
# Debian / Ubuntu
apt-get --assume-yes install cifs-utils php-smbclient smbclient

Für jedes External-Storage-Mount mit Push-Notification-Unterstützung läuft pro Mount ein occ files_external:notify-Prozess. Linuxfabrik-Setups packen diese in je einen systemd-Service (nc-external-files-notify@.service) plus Timer, beide ins Monitoring aufgenommen.

Upload grosser Dateien

Der Upload einer 10-GB-Datei gegen einen langsamen Storage braucht tolerant eingestellte Timeouts, sonst bricht das Assembling der Chunks mit Error when assembling chunks. status code 504 ab. Zusätzlich sollte PHP memory_limit mindestens 1 GiB haben, sonst kommen OOM-Fehler. post_max_size wirkt auf die Chunk-Grösse und darf klein bleiben - je grösser der Wert, desto länger das Assembling.

Apache App-Server (/etc/httpd/conf/httpd.conf oder im VirtualHost):

Timeout 600                    # default 60

Apache als Reverse-Proxy:

ProxyTimeout 600               # same as app-server Timeout

PHP (/etc/php.ini bzw. /etc/php.d/90-nextcloud.ini):

max_execution_time  = 3600     ; default 30
memory_limit        = 1024M    ; default 128M
post_max_size       = 16M      ; default 8M
upload_max_filesize = 10000M   ; default 2M

Chunk-Grösse (Web-UI-Client, Desktop-Client), Default 100 MiB:

sudo -u apache /var/www/html/nextcloud/occ config:system:set files.chunked_upload.max_size --value=104857600 --type=integer

/tmp braucht genug freien Platz für die parallelen Chunk-Uploads. Vollständige Parameterliste: https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/big_file_upload_configuration.html.

Integration

LDAP

Die App user_ldap ist Kern-Bestandteil und bringt einen Setup-Wizard in den Nextcloud-Admin-Settings mit. Die wichtigsten Wizard-Tabs: Server, Users, Login, Groups. Für Automatisierung und Audits läuft die LDAP-Konfiguration auch über occ:

ldap:create-empty-config    # neue LDAP-Config anlegen (IDs: s01, s02, ...)
ldap:set-config             # einzelne Config-Werte setzen
ldap:show-config            # aktive Configs anzeigen
ldap:test-config            # Verbindung testen
ldap:test-user-settings     # Suche/Filter gegen einen konkreten User
ldap:check-user             # prüft, ob ein User im LDAP existiert
ldap:check-group            # analog für Gruppen
ldap:search                 # Such-Query ausführen
ldap:delete-config          # Config löschen
ldap:show-remnants          # User, die aus LDAP verschwunden sind, aber noch in Nextcloud
ldap:promote-group          # Admin-Gruppe für einen LDAP-Admin promoten

Konkrete Referenz: https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html.

Tipp

Bekanntes Verhalten seit 2017: nach der Erst-Konfiguration tauchen neu im LDAP angelegte Benutzer nicht automatisch in der Nextcloud-Benutzerliste auf - ein Login funktioniert trotzdem, und über die Nextcloud-Suche (Benutzerliste → Suche) werden sie sichtbar. Danach lassen sich ihre Eigenschaften (Gruppenzugehörigkeit, Quota) normal bearbeiten.

Wer sich parallel noch mit einem lokalen Nextcloud-Account anmelden möchte (z.B. Admin in einer LDAP-gebundenen Instanz), hängt ?direct=1 an die Login-URL: https://cloud.example.com/index.php/login?direct=1.

Beispiel einer LDAP-Query mit ldapsearch gegen FreeIPA (Gruppe nextcloud als Filter):

dnf --assumeyes install openldap-clients
# single quotes around -D and the filter are important
ldapsearch -v \
    -H ldap://freeipa \
    -D 'uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=example,dc=com' \
    -W -b \
    'dc=example,dc=com' \
    '(&(objectClass=inetorgperson)(memberOf=cn=nextcloud,cn=groups,cn=accounts,dc=example,dc=com))'

In Nextcloud entspricht das unter Users → LDAP Query dem Filter (&(objectclass=inetorgperson)(memberof=cn=nextcloud,cn=groups,cn=accounts,dc=example,dc=com)) und Advanced → User Display Name Field dem Wert uid.

Um Remnants (User aus ldap:show-remnants) zu löschen, vor dem occ user:delete die Dateien des Benutzers an einen anderen Account übertragen - sonst werden die Dateien mitgelöscht:

sudo -u apache /var/www/html/nextcloud/occ files:transfer-ownership <olduser> <newuser>
sudo -u apache /var/www/html/nextcloud/occ user:delete <olduser>

Keycloak (OIDC, SAML)

Für neue Integrationen die offizielle App user_oidc (von Nextcloud gepflegt, verfügbar über den App Store). Sie unterstützt OpenID Connect inkl. Discovery-Endpoint, Gruppen-Mapping, Token-Exchange und automatischem Benutzer-Provisioning. Die beiden Community-Apps Social Login und OpenID Connect Login existieren weiterhin, sind aber nicht mehr erste Wahl.

SAML bleibt der Sonderfall für Umgebungen, in denen OIDC nicht verfügbar ist - dafür gibt es die App SSO & SAML authentication.

Groblay-Out einer user_oidc-Integration gegen Keycloak:

  1. In Keycloak einen Client nextcloud vom Typ openid-connect mit Access Type confidential anlegen. Valid-Redirect-URI: https://cloud.example.com/apps/user_oidc/code.

  2. In Keycloak einen Group Membership Mapper anlegen (Token Claim Name groups), damit Gruppen über das ID-Token durchgereicht werden.

  3. In Nextcloud die App user_oidc installieren, im Web-Admin unter Settings → OpenID Connect einen Provider hinzufügen: Discovery Endpoint https://keycloak.example.com/realms/<realm>/.well-known/openid-configuration, Client ID und Client Secret aus dem Keycloak-Client, Gruppen-Claim groups.

  4. Auto-Provisioning in user_oidc aktivieren, damit neue SSO-User automatisch angelegt werden.

Details zur Keycloak-Seite im Keycloak-Artikel. Die Linuxfabrik-Rolle linuxfabrik.lfops.nextcloud setzt user_oidc optional mit auf.

Encryption

Nextcloud kennt zwei unabhängige Verschlüsselungsebenen auf Dateiebene - Transportverschlüsselung via TLS wird hier als selbstverständlich vorausgesetzt.

Server-Side Encryption (SSE)

Optional aktivierbares Modul, das jede Datei vor dem Speichern verschlüsselt. Seit Nextcloud 9.0 mit authenticated Encryption; seit Nextcloud 25 ist der Overhead gegenüber Klartext bei etwa einem Prozent (früher bis zu einem Drittel).

SSE verschlüsselt ausschliesslich Datei-Inhalte, nicht Dateinamen oder Verzeichnisstruktur. Schlüssel liegen entweder serverweit (Default) oder pro Benutzer. Den serverweiten Schlüssel schützt das in config.php hinterlegte Secret.

Sinnvoll ist SSE vor allem dann, wenn Daten ausserhalb des eigenen Standorts gespeichert werden - über External Storage gegen Dropbox, S3 bei einem Provider, einen NAS in einem weniger vertrauenswürdigen Netzsegment. Auf dem lokalen Filesystem neben der Nextcloud-Instanz bringt SSE kaum Schutz, weil der Schlüssel zusammen mit den Daten liegt.

Einmal aktiviert, verhindert serverweite SSE zudem die sinnvolle Nutzung von Online-Office (Collabora, OnlyOffice), sobald die Variante Benutzerverzeichnis mit User-Passwort verschlüsseln aktiv ist.

Aktivieren:

sudo -u apache /var/www/html/nextcloud/occ app:enable encryption
sudo -u apache /var/www/html/nextcloud/occ encryption:enable
sudo -u apache /var/www/html/nextcloud/occ encryption:list-modules
sudo -u apache /var/www/html/nextcloud/occ encryption:set-default-module OC_DEFAULT_MODULE
sudo -u apache /var/www/html/nextcloud/occ encryption:encrypt-all

End-to-End Encryption (E2EE)

Getrennt von SSE: eine reine Client-Funktion der Desktop- und Mobile-Clients (App end_to_end_encryption). Der Server sieht weder Klartext noch Schlüssel. Markierte Ordner werden vollständig vor dem Server verborgen - inklusive Dateinamen und Verzeichnisstruktur.

Trade-offs:

  • Web-UI zeigt den Inhalt der Ordner nicht an, der Sync-Client ist Pflicht.

  • Kein Public Share, keine Gruppen-Freigabe, keine serverseitige Suche, kein Collabora/OnlyOffice auf verschlüsselten Dateien.

  • Kein serverseitiger Papierkorb, keine Versionierung für E2E-Ordner.

Für den Zugriff von mehreren Geräten erzeugt der Client eine Mnemonic Passphrase (zwölf zufällige englische Wörter). Diese Passphrase muss gesichert werden - ohne sie sind die Daten verloren. Die Passphrase liefert der Client unter Account → Show E2E mnemonic erneut an, solange der Client aktiv gekoppelt ist.

Details: https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html.

Bemerkung

SSE und E2E sind unabhängig und greifen unterschiedliche Bedrohungsmodelle ab. SSE schützt gegen kompromittierte Storage-Systeme, E2E gegen kompromittierte Server. Kein Modus verschlüsselt Kalender, Kontakte, ToDo-Listen oder Chat-Verläufe - für diese Datentypen fehlen standardisierte Clients mit E2E-Unterstützung.

Office-Integration

Zur Einordnung von Collabora, OnlyOffice und LibreOffice siehe Collabora vs. LibreOffice. Nextcloud integriert beide Office-Suiten parallel:

  • Wird beim Klick auf ein Dokument automatisch eine Suite geöffnet, ist das Collabora (solange dort die Dateiendung als unterstützt markiert ist).

  • OnlyOffice steht über das Kontextmenü (drei Punkte → „Open in OnlyOffice“) zur Verfügung.

  • In der mobilen Nextcloud-App wird standardmässig OnlyOffice verwendet.

Die Web-Office-Apps sind Nextcloud Office (Collabora-Technologie; App-ID richdocuments) und ONLYOFFICE (App-ID onlyoffice).

Notify Push

Notify Push ist Nextclouds High-Performance-Client-Push-Dienst. Ohne ihn pollen Desktop- und Mobile-Clients den Server in Sekundentakten ab; mit ihm hält der Client eine persistente WebSocket-Verbindung, und Änderungen (neue Files, Shares, Kalendertermine) werden innerhalb von Sekundenbruchteilen zugestellt.

Setup

Voraussetzungen laut Upstream (https://github.com/nextcloud/notify_push):

  • Redis-Server, Nextcloud muss Redis über config.php eingebunden haben.

  • Das Binary notify_push läuft als systemd-Service (Default-Port 7867; Unix-Socket via SOCKET_PATH alternativ).

  • Die App notify_push ist installiert.

  • Der Reverse-Proxy leitet /push an das Notify-Push-Binary weiter (WebSocket-Upgrade!).

Setup-Wizard:

sudo -u apache /var/www/html/nextcloud/occ notify_push:setup https://cloud.example.com/push

Der Wizard meldet bei erfolgreichem Setup:

✓ redis is configured
✓ push server is receiving redis messages
✓ push server can load mount info from database
✓ push server can connect to the Nextcloud server
✓ push server is a trusted proxy by Nextcloud

Trusted Proxies

Der häufigste Fehler im Notify-Push-Setup betrifft die Einstellung trusted_proxies. Der Wizard schickt einen Test-Request mit X-Forwarded-For: 1.2.3.4 und prüft, ob Nextcloud tatsächlich 1.2.3.4 als Client-IP zurückerhält. Falls nicht, meldet er z.B.:

✗ push server is not a trusted proxy by Nextcloud or another proxy in the chain.
Nextcloud resolved the following client address for the test request: "198.51.100.89" instead of the expected "1.2.3.4" test value.

Was dabei im Hintergrund passiert:

┌────────────────┐
│      WAN       │
└───────┬────────┘
┌───────┴────────┐
│     proxy      │
│   192.0.2.3    │
└───────┬────────┘
┌───────┴────────┐
│   nextcloud    │
│   192.0.2.4    │
└────────────────┘

Der Notify-Push-Server schickt:

src=192.0.2.4, dest=192.0.2.3
GET /test/remote/1.2.3.4
X-Forwarded-For: 1.2.3.4

Der Reverse-Proxy hängt seine eigene Source-IP hinten an (mod_proxy-Verhalten, siehe https://httpd.apache.org/docs/current/mod/mod_proxy.html#x-headers):

src=192.0.2.3, dest=192.0.2.4
GET /test/remote/1.2.3.4
X-Forwarded-For: 1.2.3.4, 192.0.2.4

Nextcloud arbeitet den Header von rechts nach links ab:

  1. Source-IP 192.0.2.3 → in trusted_proxies? → ja → Client-IP wird zu 192.0.2.4.

  2. Neue Source-IP 192.0.2.4 → in trusted_proxies? → nein → abgebrochen, Client-IP bleibt 192.0.2.4.

Ergebnis: Nextcloud hält 192.0.2.4 für den Client, der Wizard erwartete aber 1.2.3.4. Auflösung: die interne IP des Nextcloud-Servers selbst muss ebenfalls in trusted_proxies.

Bei komplexeren Setups (z.B. Cloudflare vor der Firewall) müssen sämtliche Glieder der Proxy-Kette eingetragen sein:

┌────────────────┐
│      WAN       │
└───────┬────────┘
┌───────┴────────┐
│  Cloudflare    │
│ 203.0.113.0/13 │
└───────┬────────┘
┌───────┴────────┐
│      fw        │
│   192.0.2.3    │
│  198.51.100.89 │
└───────┬────────┘
┌───────┴────────┐
│     proxy      │
│   192.0.2.3    │
└───────┬────────┘
┌───────┴────────┐
│   nextcloud    │
│   192.0.2.4    │
└────────────────┘

Ohne /etc/hosts-Override sieht Nextcloud nun den Pfad über die öffentliche Firewall-IP: der Notify-Push-Request landet per NAT von 192.0.2.4 auf Cloudflare, Cloudflare weiter auf die Public-IP der Firewall, von dort über den Proxy ins interne Netz zurück. Nextcloud sieht am Ende im Header 1.2.3.4, 198.51.100.89, 203.0.113.110.

Damit der Wizard erfolgreich ist, gehören in diesem Szenario die öffentliche IP des gesamten vDC sowie der Cloudflare-Range in trusted_proxies, nicht die interne IP des Nextcloud-Servers. Konkret:

sudo -u apache /var/www/html/nextcloud/occ config:system:set trusted_proxies 0 --value=192.0.2.3
sudo -u apache /var/www/html/nextcloud/occ config:system:set trusted_proxies 1 --value=203.0.113.0/13

Nextcloud Talk

Für das Chat-, Audio- und Video-Feature siehe den eigenen Artikel Nextcloud Talk, STUN & TURN. Dort sind STUN, TURN, Signaling-Server, Janus und NATS im Detail beschrieben, inkl. Firewall-Setup und Apache-WebSocket-Proxy.

Nextcloud-Clients

Desktop-Sync

Der native Client (nextcloud-desktop) identifiziert sich im User-Agent als mirall und spricht WebDAV gegen die Nextcloud-Instanz. Seine Abfragesequenz beim Verbindungsaufbau:

# first contact - fails the client wholesale if not reachable:
GET /status.php

# afterwards, roughly every 30 seconds:
PROPFIND /remote.php/dav/files/username/
GET      /ocs/v1.php/cloud/user?format=json
GET      /remote.php/dav/avatars/username/128.png

Mit aktivem Notify Push hält der Client zusätzlich eine WebSocket-Verbindung gegen /push offen, was die Polling-Frequenz und damit die Latenz drastisch reduziert.

curl gegen Nextcloud

Nextcloud spricht WebDAV für authentifizierte Nutzer unter /remote.php/dav/… und für öffentliche Share-Links unter /public.php/webdav/….

Upload in einen Share mit Edit-Rechten:

SHARE_LINK='https://cloud.example.com/index.php/s/nT8Dkq6G4pWQabc'
LOCAL_FILE='/path/to/my/file'

curl \
    --connect-timeout 5 \
    --progress-bar \
    --upload-file "$LOCAL_FILE" \
    --user "$(basename "$SHARE_LINK"):" \
    "https://cloud.example.com/public.php/webdav/$(basename "$LOCAL_FILE")"

Download einer Datei aus einem Share-Link:

SHARE_LINK='https://cloud.example.com/index.php/s/nT8Dkq6G4pWQabc'

curl \
    --location \
    --progress-bar \
    --remote-header-name \
    --remote-name \
    "${SHARE_LINK}/download"

Nextcloud API

OCS-API: die User-Credentials werden Base64-codiert im Authorization: Basic-Header mitgeschickt, dazu muss OCS-APIRequest: true gesetzt sein. In Python:

import base64

credentials = base64.b64encode(b'api-user:api-password').decode()
headers = {
    'Authorization': f'Basic {credentials}',
    'OCS-APIRequest': 'true',
}

Grundlegende Server-Statistiken (Server-Info-App):

curl \
    --header 'Authorization: Basic bmV4dGNsbp3d0NIVQ==' \
    --header 'OCS-APIRequest: true' \
    https://cloud.example.com/ocs/v2.php/apps/serverinfo/api/v1/info?format=json

Security Scan

Der Dienst https://scan.nextcloud.com prüft eine öffentliche Nextcloud-Instanz auf bekannte Schwachstellen. Intern testet er eine Reihe üblicher Pfade auf Nextcloud-Metadaten:

  • /status.php

  • /nextcloud/status.php

  • /oc/status.php

  • /oc-shib/status.php

  • /owncloud/status.php

Scan per API ohne Web-UI:

# queue a scan
curl --silent --request POST \
    --header 'Content-type: application/x-www-form-urlencoded' \
    --header 'X-CSRF: true' \
    --data 'url=cloud.example.com' \
    https://scan.nextcloud.com/api/queue | jq

# fetch result (UUID from the queue response)
curl --silent https://scan.nextcloud.com/api/result/558eccce-8aba-4717-850b-28d47cb84a16 | jq

DB-Snippets

Nützliche Ad-hoc-Queries für MariaDB/MySQL. Alle Abfragen sind read-only, sollten sich aber nie in automatisierte Skripte einklinken - die interne Schema-Struktur ist Nextcloud-Version-abhängig.

Benutzer-Informationen

-- E-Mail-Adressen aller Benutzer
SELECT JSON_EXTRACT(data, '$.email.value') FROM oc_accounts;

-- alle deaktivierten (lokalen) Benutzer
SELECT userid
FROM oc_preferences AS p
LEFT JOIN oc_users AS u ON p.userid = u.uid
WHERE p.appid = 'core'
  AND p.configkey = 'enabled'
  AND p.configvalue = 'false';

-- E-Mails aller aktiven Benutzer (LDAP ausgenommen, weil dort kein oc_users-Eintrag besteht)
SELECT JSON_EXTRACT(data, '$.email.value')
FROM oc_accounts
WHERE uid NOT IN (
    SELECT userid
    FROM oc_preferences AS p
    LEFT JOIN oc_users AS u ON p.userid = u.uid
    WHERE p.appid = 'core'
      AND p.configkey = 'enabled'
      AND p.configvalue = 'false'
);

-- Storage-Verbrauch inkl. Versionen und Papierkorb
SELECT s.id, size
FROM oc_filecache AS f
INNER JOIN oc_storages AS s ON f.storage = s.numeric_id
WHERE s.id = 'object::user:admin'
  AND f.parent = -1;

-- Storage-Verbrauch ohne Versionen und Papierkorb
SELECT s.id, size
FROM oc_filecache AS f
INNER JOIN oc_storages AS s ON f.storage = s.numeric_id
WHERE s.id = 'object::user:admin'
  AND path = 'files';

Server-Informationen

-- Datenbank-Version
SELECT VERSION() AS version;

-- Datenbank-Grösse
SHOW TABLE STATUS FROM `nextcloud`;

-- aktive Benutzer der letzten 5 Minuten
SELECT COUNT(*) AS num_entries FROM oc_authtoken
WHERE last_activity > UNIX_TIMESTAMP() - 300;

-- Benutzer mit je einem lastLogin-Eintrag
SELECT COUNT(*) AS num_entries FROM oc_preferences
WHERE configkey = 'lastLogin';

-- Storage-Zählungen
SELECT COUNT(*) AS num_entries FROM oc_storages WHERE id LIKE 'home::%';
SELECT COUNT(*) AS num_entries FROM oc_storages WHERE id LIKE 'local::%';
SELECT COUNT(*) AS num_entries FROM oc_storages
WHERE id NOT LIKE 'home::%' AND id NOT LIKE 'local::%';

-- Share-Statistiken nach Typ und Rechten
SELECT COUNT(*) AS num_entries, permissions, share_type
FROM oc_share GROUP BY permissions, share_type;

Dateien mit unerlaubten Zeichen

Eine einzige Query statt einer Query pro Zeichen - und ab Nextcloud 30 ohnehin ersetzbar durch occ files:sanitize-filenames:

SELECT s.id, path
FROM oc_filecache AS f
LEFT JOIN oc_storages AS s ON f.storage = s.numeric_id
WHERE path LIKE 'files/%'
  AND (
      name REGEXP '[\\\\/:?*"<>|]'
      OR name LIKE ' %'
      OR name LIKE '% '
  );

Best Practices

  • Background-Jobs laufen per cron (systemd-Timer oder klassischer cron) alle 5 Minuten. Ausfall des Cron-Backends macht sich nur zeitverzögert bemerkbar - per Icinga-Check auf last_cron_job_run (Feld aus oc_appconfig) oder den Serverinfo-Endpoint prüfen.

  • Preview-Generator (App previewgenerator) proaktiv aktivieren, sobald ein Bestand > 100’000 Dateien existiert. Ohne ihn erzeugt Nextcloud Previews on demand, was den ersten Aufruf eines grossen Verzeichnisses spürbar verzögert.

  • Redis als Memory-Cache und als Backend für File-Locking konfigurieren, sobald mehr als ein paar gleichzeitige Nutzer aktiv sind. Für High-Performance-Client-Push (siehe oben) ist Redis ohnehin Pflicht.

  • Backups müssen Dateisystem (datadirectory, custom_apps, config) und Datenbank zeitnah zusammen sichern. Bei Object-Storage-Setups zusätzlich den Bucket-Zustand einfrieren.

  • Subscription-Key nach Ablauf zeitnah erneuern - die Support-App prüft das Ablaufdatum und meldet im Admin-Panel. Linuxfabrik-Monitoring erkennt abgelaufene Keys über den nextcloud-version-Check.

  • Update-Kadenz: NC bringt etwa alle 16 Wochen eine neue Major, jede Major wird ein Jahr lang gepflegt. Bei langsamem Rollout lohnt es sich, immer N-1 zu fahren (aktuell N-1 = NC 32), um Migrations-Bugs anderer vorab zu sehen.

Unterschiede RHEL / Debian

  • Apache-Pfade: RHEL /etc/httpd/, VHost-Verzeichnis /etc/httpd/conf.d/ oder Linuxfabrik-Standard /etc/httpd/sites-available/. Debian/Ubuntu /etc/apache2/, VHosts in /etc/apache2/sites-available/ aktiviert über a2ensite.

  • Apache-User: RHEL apache, Debian/Ubuntu www-data. Unsere Beispiele verwenden apache - unter Debian entsprechend anpassen.

  • PHP-Module und -Pfade: RHEL standard-installiert unter /etc/php.d/ mit php-fpm als Default-Sapi; Debian/Ubuntu installiert parallel mehrere PHP-Versionen unter /etc/php/<version>/ und aktiviert diese über update-alternatives.

  • SELinux vs. AppArmor: RHEL läuft mit SELinux in enforcing-Mode. Nextcloud benötigt die Booleans httpd_can_network_connect, httpd_can_sendmail und ggf. httpd_unified. Debian und Ubuntu haben AppArmor; Profile liegen unter /etc/apparmor.d/ und können pro Dienst angepasst werden.

  • Redis- und MariaDB-Paketnamen: RHEL redis / mariadb-server aus AppStream; Debian redis-server / mariadb-server. Die LFOps-Rolle abstrahiert das.

Troubleshooting

Your web server is not properly set up to resolve "/.well-known/nodeinfo" / Your web server is not properly set up to resolve "/.well-known/webfinger"

404 muss durch Nextcloud gehandhabt werden, nicht durch den Webserver. Falls Nextcloud hinter einem Apache-Reverse-Proxy läuft, die Direktive ProxyErrorOverride Off verwenden.

Background-Job sofort laufen lassen

Der Nextcloud-Scheduler entscheidet anhand der Spalten last_run und last_checked in oc_jobs, wann ein Job wieder dran ist. Setzt man beide Werte für den gewünschten Job auf 0, wird er beim nächsten cron.php-Lauf sofort ausgeführt, ohne auf sein reguläres Intervall zu warten.

Incorrect row format found in your database. ROW_FORMAT=Dynamic offers the best database performances for Nextcloud

Folgende Befehle schaffen Abhilfe:

sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --on

mariadb --user=mariadb-admin --password --silent nextcloud --execute "
SELECT CONCAT('ALTER TABLE \`', TABLE_NAME, '\` ROW_FORMAT=DYNAMIC;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'nextcloud'
AND ENGINE = 'InnoDB';" | mariadb --user=mariadb-admin --password nextcloud

sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --off
Failed to fetch capabilities: GET https://office.example.com/hosting/capabilities resulted in a 502 Proxy Error

Race-Condition zwischen dem Apache-Reverse-Proxy und Collabora Online (CODE). Apache hält die Verbindung zu Collabora als Idle-Connection offen; sobald Collabora diese serverseitig schliesst, versucht Apache im selben Moment den nächsten Request über die bereits geschlossene Verbindung zuzustellen und antwortet mit 502.

Abhilfe: im ProxyPass für das Collabora-Backend einen ttl-Wert setzen, der deutlich kleiner ist als der Idle-Timeout des Collabora-Backends (in Collabora-Online konfigurierbar über net.idle_timeout_secs in coolwsd.xml). Apache baut die Verbindung dann nach Ablauf der TTL proaktiv neu auf, statt auf eine vom Backend bereits geschlossene Verbindung zu schreiben.

/etc/httpd/sites-available/collabora.conf
ProxyPass / http://127.0.0.1:9980/ ttl=60
ProxyPassReverse / http://127.0.0.1:9980/
Exception HMAC does not match: Could not decrypt or decode encrypted session data

Nextcloud kann die serverseitig abgelegten, verschlüsselten Session-Daten nicht entschlüsseln. Ursache ist ein vom Client geschicktes Session-Cookie, dessen zugehöriger Schlüssel (oc_sessionPassphrase) fehlt oder nicht zur verschlüsselten Session passt. Tritt regelmässig durch Bots auf, die einen vermuteten Session-Cookie-Namen mitschicken, aber kein gültiges Schlüssel-Cookie.

Gültige Nextcloud-Sessions bringen zwei zusammengehörige Cookies mit:

  • Das eigentliche Session-Cookie mit dem Namen oc<instanceid> - die instanceid steht pro Instanz in /var/www/html/nextcloud/config/config.php.

  • Das Schlüssel-Cookie oc_sessionPassphrase - daraus leitet Nextcloud den Schlüssel zum Entschlüsseln der Session-Daten ab.

Beispiel-Cookies für eine Instanz mit instanceid = d3n3w8rdc3:

__Host-nc_sameSiteCookielax=true
__Host-nc_sameSiteCookiestrict=true
ocd3n3w8rdc3=<session-id>
oc_sessionPassphrase=<base64-passphrase>

Requests, die nur das Session-Cookie mitschicken, aber kein oc_sessionPassphrase, lassen sich per Apache-RewriteRule mit 403 abweisen (oc<instanceid> mit dem konkreten Wert aus der eigenen config.php ersetzen):

/etc/httpd/sites-available/nextcloud.conf
RewriteCond %{HTTP_COOKIE} ocd3n3w8rdc3=
RewriteCond %{HTTP_COOKIE} !oc_sessionPassphrase=
RewriteRule .* - [R=403,L]
InvalidPathException: Invalid path, " " is not allowed

Der Job files:scan stösst auf einen Dateinamen mit ungültigen Zeichen (führende oder nachgestellte Leerzeichen, Steuerzeichen, unter Windows reservierte Zeichen). Ab Nextcloud 30 bereinigt occ files:sanitize-filenames die gesamte Instanz in einem Zug. Ältere Versionen benötigen manuelles Umbenennen oder Löschen auf Dateisystem-Ebene.

Error during scan: Couldn't stat smb://example.com/home: Permission denied

Ein SMB-External-Storage in oc_storages ist nicht mehr erreichbar - entweder weil der Share nicht mehr existiert oder weil die hinterlegten Credentials abgelaufen sind. Beispielhafter verwaister Eintrag:

153,smb::@example.com//home//,1,

Vorgehen: zuerst den Storage in der Nextcloud-Weboberfläche unter Administration Settings → External Storage entfernen. Verwaiste Metadaten räumt danach occ files:cleanup auf - das ist der offizielle Weg und sollte immer der direkten DB-Manipulation vorgezogen werden.

Lässt sich der Eintrag aus oc_storages nur noch per DB entfernen (etwa weil die Web-UI die Referenz nicht mehr auflöst), vorher mit SELECT prüfen, ob die numeric_id noch aktiv referenziert wird:

SELECT * FROM oc_mounts    WHERE storage_id = <numeric_id>;
SELECT COUNT(*) FROM oc_filecache WHERE storage = <numeric_id>;

Fehlen Treffer in oc_mounts, lässt sich der oc_storages-Eintrag entfernen; verbleibende oc_filecache-Zeilen räumt occ files:cleanup im Anschluss auf.