Nextcloud
Siehe auch
- Ansible-Rolle Nextcloud:
Überblick
Es spielt eine Rolle, welchem Anbieter man seine Daten (Dateien aller Art, Kalender-Einträge etc.) anvertraut: Unternehmen mit Sitz in den USA müssen laut US CLOUD Act nach Aufforderung der Behörden jederzeit Daten von ihren Servern liefern, auch wenn sie ausserhalb der USA stehen. Die National Security Letters verbieten ihnen unter Strafandrohung, ihre Kunden darüber zu informieren. Das kollidiert mit den Schweizer- und EU-Datenschutzregeln und/oder nationalem Recht. Der Einsatz solcher Lösungen kann daher beispielsweise in Deutschland zu massiven DSGVO-Strafen führen.
Nextcloud ist Open Source und bietet Cloud-Dienste und Datensynchronisation auf eigenen Servern, die zu 100% unter eigener Kontrolle stehen - also ganz im Gegensatz zu AWS, Azure und Office 365, Dropbox oder GCP. Nextcloud ging Mitte 2016 aus Owncloud hervor. Der Unternehmensgründer Frank Karlitschek selbst gab den Fork bekannt.
Kern-Feature ist die verteilte Zusammenarbeit an Dateien, die per Web-GUI, WebDAV oder dem Nextcloud-Client verwaltet und synchronisiert werden können.
Apps erweitern das System in beliebige Richtungen:
Kalender und Adressbuch (Standard)
Videokonferenz
Social-Media-Funktionen
Kartenintegration
alternative Benutzerdatenbanken (LDAP, OAuth)
etc.
Versionstabelle per https://nextcloud.com/changelog/ und https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html zusammengestellt:
Nextcloud Version |
Nextcloud Hub |
max. PHP-Version |
---|---|---|
Nextcloud 29 |
Hub 8 |
PHP 8.3 |
Nextcloud 28 |
Hub 7 |
PHP 8.2 |
Nextcloud 27.1 |
Hub 6 |
PHP 8.2 |
Nextcloud 27 |
Hub 5 |
PHP 8.2 |
Nextcloud 26 |
Hub 4 |
PHP 8.1 |
Nextcloud 25 |
Hub 3 |
PHP 8.1 |
Nextcloud 24 |
Hub 24 |
PHP 8.0 |
Nextcloud 23 |
Hub 23 / Hub II |
PHP 8.0 |
Nextcloud 22 |
Hub 22 |
PHP 8.0 |
Nextcloud 21 |
Hub 21 |
PHP 8.0 |
Nextcloud 20 |
Hub 20 |
PHP 7.4 |
Nextcloud 19 |
Hub 19 |
PHP 7.4 |
Nextcloud 18 |
als Hub 18 vermarktet |
PHP 7.4 |
Nextcloud 17 |
PHP 7.3 |
|
Nextcloud 16 |
PHP 7.3 |
|
Nextcloud 15 |
PHP 7.3 |
|
Nextcloud 14 |
PHP 7.2 |
|
Nextcloud 13 |
PHP 7.1 |
Installation
Siehe https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html. Download von https://download.nextcloud.com/server/releases/ (neueste Datei: https://download.nextcloud.com/server/releases/latest.tar.bz2).
Tipp
Wer eine Shared Instance betreibt, auf der sich die Benutzer untereinander nicht kennen, sollte die App „User status“ abschalten - sie ermöglicht im Nextcloud-Dashboard die Anzeige der „Recent statuses“, eine Liste der letzten Anmeldevorgänge der Benutzer (inkl. E-Mail-Adresse).
Update/Upgrade durchführen
- per OCC (bevorzugt)
Siehe nextcloud-update.
- per Web-Interface
setsebool httpd_unified on setsebool httpd_can_network_connect on
Jetzt das Update über das Webinterface durchführen. Anschliessend:
setsebool -P httpd_unified off # if we don't need any network connections setsebool -P httpd_can_network_connect off
Forbidden Chars
Liste invalid/ungültiger Zeichen in Verzeichnis- und Dateinamen (sogenannte „forbidden chars“):
\ / : ? * " < > |
plus: files/folders with leading and trailing spaces are also considered invalid
Man kann das Web-Interface dazu bringen, diese Zeichen gar nicht erst anzunehmen; die dazu passende Einstellung in der config.php
heisst forbidden_filename_characters.
Siehe dazu auch unseren Blog-Beitrag RewriteRule vs ProxyPass - für Nextcloud entscheidend.
Eine Liste aller Dateien, die ungültige Zeichen im Verzeichnis- oder Dateinamen enthalten, kann aus der Datenbank extrahiert werden:
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE ' %' INTO OUTFILE '/tmp/forbidden-chars-slash.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '% ' INTO OUTFILE '/tmp/forbidden-chars-slash.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%/%' INTO OUTFILE '/tmp/forbidden-chars-slash.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%\\%' INTO OUTFILE '/tmp/forbidden-chars-backslash.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%:%' INTO OUTFILE '/tmp/forbidden-chars-colon.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%?%' INTO OUTFILE '/tmp/forbidden-chars-question-mark.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%*%' INTO OUTFILE '/tmp/forbidden-chars-star.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%"%' INTO OUTFILE '/tmp/forbidden-chars-quote.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%<%' INTO OUTFILE '/tmp/forbidden-chars-less-than.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%>%' INTO OUTFILE '/tmp/forbidden-chars-greater-than.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
SELECT
oc_storages.id, path
FROM
oc_filecache
LEFT JOIN
oc_storages ON oc_filecache.storage = oc_storages.numeric_id
WHERE
path LIKE 'files/%' AND name LIKE '%|%' INTO OUTFILE '/tmp/forbidden-chars-pipe.csv' FIELDS TERMINATED BY ', ' ENCLOSED BY '"';
Nextcloud Loglevel
0: DEBUG: All activity; the most detailed logging.
1: INFO: Activity such as user logins and file activities, plus warnings, errors, and fatal errors.
2: WARN: Operations succeed, but with warnings of potential problems, plus errors and fatal errors.
3: ERROR: An operation fails, but other services and operations continue, plus fatal errors.
4: FATAL: The server stops.
<?php
$CONFIG = array (
'loglevel' => 3,
);
OCC
occ files:cleanup
Was macht ein sudo -u apache /var/www/html/nextcloud/occ files:cleanup
genau?
0 orphaned file cache entries deleted
0 orphaned mount entries deleted
occ maintenance:repair
Was macht ein sudo -u apache /var/www/html/nextcloud/occ maintenance:repair
genau?
- Repair MySQL collation
- All tables already have the correct collation -> nothing to do
- Clean tags and favorites
- 0 tags of deleted users have been removed.
- 0 tags for delete files have been removed.
- 0 tag entries for deleted tags have been removed.
- 0 tags with no entries have been removed.
- Repair invalid shares
- Move .step file of updater to backup location
- Add move avatar background job
- Repair step already executed
- Add preview cleanup background jobs
- Migrate oauth2_clients table to nextcloud schema
- Update the oauth2_access_tokens table schema.
- Update the oauth2_clients table schema.
- Delete clients (and their related access tokens) with the redirect_uri starting with oc:// or ending with *
- Fix potential broken mount points
- No mounts updated
- Repair language codes
- Add log rotate job
- Clear frontend caches
- Image cache cleared
- JS cache cleared
- Clear every generated avatar
- Add preview background cleanup job
- Queue a one-time job to cleanup old backups of the updater
- Cleanup invalid photocache files for carddav
- Add background job to cleanup login flow v2 tokens
- Remove potentially over exposing share links
- No need to remove link shares.
- Clear access cache of projects
- Reset generated avatar flag
- Keep legacy encryption enabled
- Check encryption key format
- Remove old dashboard app config data
- Add job to cleanup the bruteforce entries
- Queue a one-time job to check for user uploaded certificates
- Repair DAV shares
- Add background job to set the lookup server share state for users
- Add token cleanup job
- Clean up abandoned apps
- Add possibly missing system config
- Add AI tasks cleanup job
- Queue a job to generate metadata
- migrate lazy config values
- Update hook for Appointments app
- appointments UpdateHook finished
- Deduplicate shared bookmark folders
- Removed 0 duplicate shares
- Remove superfluous shared bookmark folders
- Removed 0 superfluous shares
- Remove orphaned bookmark shares
- Removed 0 orphaned shares
- Removed 0 orphaned public links
- Remove orphaned bookmark tree items
- Removed 0 orphaned bookmarks entries
- Removed 0 orphaned folders entries
- Reinserted 0 orphaned children entries
- Removed 0 orphaned bookmark folders
- Reinserted 0 orphaned bookmarks
- Update bookmark group shares
- Removed 0 users and added 0 users to 0 groups
- Removed 0 shares
- Upgrading Circles App
- Fix component of birthday calendars
- 3 birthday calendars updated.
- Regenerating birthday calendars to use new icons and fix old birthday events without year
- Repair step already executed
- Fix broken values of calendar objects
0 [->--------------------------]
- Registering building of calendar search index as background job
- Repair step already executed
- Register building of social profile search index as background job
- Repair step already executed
- Registering background jobs to update cache for webcal calendars
- Added 0 background jobs to update webcal calendars
- Registering building of calendar reminder index as background job
- Repair step already executed
- Clean up orphan event and contact data
- 0 events without a calendar have been cleaned up
- 0 properties without an events have been cleaned up
- 0 changes without a calendar have been cleaned up
- 0 cached events without a calendar subscription have been cleaned up
- 0 changes without a calendar subscription have been cleaned up
- 0 contacts without an addressbook have been cleaned up
- 0 properties without a contact have been cleaned up
- 0 changes without an addressbook have been cleaned up
- Remove activity entries of private events
- Removed 0 activity entries
- Clean up old calendar subscriptions from deleted users that were not cleaned-up
0 [----->----------------------]
- 0 calendar subscriptions without an user have been cleaned up
- Remove invalid object properties
- 0 invalid object properties removed.
- Copy default images to the app data directory
- Icon external.svg already exists
- Icon external-dark.svg already exists
- Icon settings.svg already exists
- Icon settings-dark.svg already exists
- Fix the share type of guest shares when migrating from ownCloud
- Copy the share password into the dedicated column
- Set existing shares as accepted
- Restore default tags that are missing
- Looking up default tags
- 0 accounts to check found
0 [--------->------------------]
- Add a generated message-id to all Mail messages that have none
- Looking up messages without a message-id
- Purify and migrate collected mail addresses
0 [------------->--------------]
- Insert background jobs for all accounts
0 [---------------->-----------]
- Make Mail itinerary extractor executable
- itinerary file doesn't exist
- Create or update provisioned Mail accounts
- 0 accounts provisioned
- Repair Broken Threads for all mail accounts
- Repaired threads, 0 messages updated
- Queue a job to delete duplicated cached messages
- Remove any playlist files mistakenly added to music_tracks table
- Combine multi-disk albums and store disk numbers per track
- Register Music background jobs and remove legacy registrations
- Set creation and update dates for the library entities without one
- Remove the unused News update job
- Job does not exist, all good
- Clean up meta table
- Show a hint about the new editor to existing users
- Update OAuth token expiration times
- Enabling server side encryption for passman
- Enabling Service Side Encryption for passman
- init metadata
- Polls - Drop orphaned tables
- No orphaned tables found
- Polls - Drop orphaned columns
- No orphaned columns found
- Polls - Create hashes for votes and options
- Updated 0 option hashes
- Updated 0 vote hashes
- Polls - Delete duplicates and orphaned records
- Polls - Create indices and foreign key constraints
- Added oc_polls_polls['poll_id'] <- oc_polls_comments['id']
- Added oc_polls_polls['poll_id'] <- oc_polls_log['id']
- Added oc_polls_polls['poll_id'] <- oc_polls_notif['id']
- Added oc_polls_polls['poll_id'] <- oc_polls_options['id']
- Added oc_polls_polls['poll_id'] <- oc_polls_share['id']
- Added oc_polls_polls['poll_id'] <- oc_polls_votes['id']
- Index UNIQ_options already exists in oc_polls_options
- Index UNIQ_unprocessed already exists in oc_polls_log
- Index UNIQ_subscription already exists in oc_polls_notif
- Index UNIQ_shares already exists in oc_polls_share
- Index UNIQ_votes already exists in oc_polls_votes
- Index UNIQ_preferences already exists in oc_polls_preferences
- Index UNIQ_watch already exists in oc_polls_watch
- Index polls_polls_owners_non_deleted already exists in oc_polls_polls
- Polls - Foreign key contraints created.
- Polls - Indices created.
- Create help command
- Invalidate access cache for projects conversation provider
- Invalidation not required
- Cache the user display names
- Switches from default updater server to the customer one if a valid subscription is available
- Repair step already executed
- Force-reset all Text document sessions
- Initialize migration of background images from dashboard to theming app
- Add background job to check for backup codes
- Populating added database structures for workflows
OCC Cheat Sheet
v24
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
--no-warnings Skip global warnings, show command output only
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
check check dependencies of the server environment
help Display help for a command
list List commands
status show some status information
upgrade run upgrade routines after installation of a new release. The release has to be installed before.
activity
activity:send-mails Sends the activity notification mails
app
app:check-code check code to be compliant
app:disable disable an app
app:enable enable an app
app:getpath Get an absolute path to the app directory
app:install install an app
app:list List all available apps
app:remove remove an app
app:update update an app or all apps
background
background:ajax Use ajax to run background jobs
background:cron Use cron to run background jobs
background:webcron Use webcron to run background jobs
background-job
background-job:execute Execute a single background job manually
broadcast
broadcast:test test the SSE broadcaster
circles
circles:check Checking your configuration
circles:maintenance Clean stuff, keeps the app running
circles:manage:config edit config/type of a Circle
circles:manage:create create a new circle
circles:manage:destroy destroy a circle by its ID
circles:manage:details get details about a circle by its ID
circles:manage:edit edit displayName or description of a Circle
circles:manage:join emulate a user joining a Circle
circles:manage:leave simulate a user joining a Circle
circles:manage:list listing current circles
circles:manage:setting edit setting for a Circle
circles:members:add Add a member to a Circle
circles:members:details get details about a member by its ID
circles:members:level Change the level of a member from a Circle
circles:members:list listing Members from a Circle
circles:members:remove remove a member from a circle
circles:members:search Change the level of a member from a Circle
circles:memberships index and display memberships for local and federated users
circles:remote remote features
circles:shares:files listing shares files
circles:sync Sync Circles and Members
circles:test testing some features
config
config:app:delete Delete an app config value
config:app:get Get an app config value
config:app:set Set an app config value
config:import Import a list of configs
config:list List all configs
config:system:delete Delete a system config value
config:system:get Get a system config value
config:system:set Set a system config value
dav
dav:create-addressbook Create a dav addressbook
dav:create-calendar Create a dav calendar
dav:delete-calendar Delete a dav calendar
dav:list-calendars List all calendars of a user
dav:move-calendar Move a calendar from an user to another
dav:remove-invalid-shares Remove invalid dav shares
dav:retention:clean-up
dav:send-event-reminders Sends event reminders
dav:sync-birthday-calendar Synchronizes the birthday calendar
dav:sync-system-addressbook Synchronizes users to the system addressbook
db
db:add-missing-columns Add missing optional columns to the database tables
db:add-missing-indices Add missing indices to the database tables
db:add-missing-primary-keys Add missing primary keys to the database tables
db:convert-filecache-bigint Convert the ID columns of the filecache to BigInt
db:convert-mysql-charset Convert charset of MySQL/MariaDB to use utf8mb4
db:convert-type Convert the Nextcloud database to the newly configured one
encryption
encryption:change-key-storage-root Change key storage root
encryption:decrypt-all Disable server-side encryption and decrypt all files
encryption:disable Disable encryption
encryption:enable Enable encryption
encryption:encrypt-all Encrypt all files for all users
encryption:list-modules List all available encryption modules
encryption:migrate-key-storage-format Migrate the format of the keystorage to a newer format
encryption:set-default-module Set the encryption default module
encryption:show-key-storage-root Show current key storage root
encryption:status Lists the current status of encryption
federation
federation:sync-addressbooks Synchronizes addressbooks of all federated clouds
files
files:cleanup cleanup filecache
files:recommendations:recommend
files:repair-tree Try and repair malformed filesystem tree structures
files:scan rescan filesystem
files:scan-app-data rescan the AppData folder
files:transfer-ownership All files and folders are moved to another user - outgoing shares and incoming user file shares (optionally) are moved as well.
group
group:add Add a group
group:adduser add a user to a group
group:delete Remove a group
group:info Show information about a group
group:list list configured groups
group:removeuser remove a user from a group
integrity
integrity:check-app Check integrity of an app using a signature.
integrity:check-core Check integrity of core code using a signature.
integrity:sign-app Signs an app using a private key.
integrity:sign-core Sign core using a private key.
l10n
l10n:createjs Create javascript translation files for a given app
log
log:file manipulate logging backend
log:manage manage logging configuration
log:tail Tail the nextcloud logfile
log:watch Watch the nextcloud logfile
maintenance
maintenance:data-fingerprint update the systems data-fingerprint after a backup is restored
maintenance:mimetype:update-db Update database mimetypes and update filecache
maintenance:mimetype:update-js Update mimetypelist.js
maintenance:mode set maintenance mode
maintenance:repair repair this installation
maintenance:theme:update Apply custom theme changes
maintenance:update:htaccess Updates the .htaccess file
notification
notification:generate Generate a notification for the given user
notification:test-push Generate a notification for the given user
preview
preview:repair distributes the existing previews into subfolders
preview:reset-rendered-texts Deletes all generated avatars and previews of text and md files
security
security:bruteforce:reset resets bruteforce attemps for given IP address
security:certificates list trusted certificates
security:certificates:import import trusted certificate in PEM format
security:certificates:remove remove trusted certificate
serverinfo
serverinfo:update-storage-statistics Triggers an update of the counts related to storages used in serverinfo
sharing
sharing:cleanup-remote-storages Cleanup shared storage entries that have no matching entry in the shares_external table
sharing:expiration-notification Notify share initiators when a share will expire the next day.
tag
tag:add Add new tag
tag:delete delete a tag
tag:edit edit tag attributes
tag:list list tags
text
text:reset Reset a text document
theming
theming:config Set theming app config values
trashbin
trashbin:cleanup Remove deleted files
trashbin:expire Expires the users trashbin
trashbin:restore Restore all deleted files
trashbin:size Configure the target trashbin size
twofactorauth
twofactorauth:cleanup Clean up the two-factor user-provider association of an uninstalled/removed provider
twofactorauth:disable Disable two-factor authentication for a user
twofactorauth:enable Enable two-factor authentication for a user
twofactorauth:enforce Enabled/disable enforced two-factor authentication
twofactorauth:state Get the two-factor authentication (2FA) state of a user
update
update:check Check for server and app updates
user
user:add adds a user
user:add-app-password Add app password for the named user
user:delete deletes the specified user
user:disable disables the specified user
user:enable enables the specified user
user:info show user info
user:lastseen shows when the user was logged in last time
user:list list configured users
user:report shows how many users have access
user:resetpassword Resets the password of the named user
user:setting Read and modify user settings
versions
versions:cleanup Delete versions
versions:expire Expires the users file versions
workflows
workflows:list Lists configured workflows
Storage: Object Storage Backend
Nextcloud von Beginn an mit Object Storage Backend aufsetzen
Der Trick: Vor der Ausführung des occ-Kommandos zur Installation die Konfigurationsdatei für den Objectstore erzeugen und direkt zur config.php
dazulegen. Der Installer führt die beiden Dateien zusammen, womit der Object-Store zum primären Storage wird. Im Beispiel mit S3:
$CONFIG = array (
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\S3',
'arguments' => [
'autocreate' => true,
'bucket' => 'bucket-name',
'hostname' => 's3.pub1.infomaniak.cloud',
'key' => '7ca40b8a-2572-4ff7-9a9a-57051bf33dc7',
'region' => 'us-east-1',
'secret' => '51c9d8b3-25f7-45dc-812f-2146e38d2167',
'use_ssl' => true,
'use_path_style' => true,
],
],
);
Dann:
sudo -u apache php occ maintenance:install
--admin-pass 'linuxfabrik'
--admin-user 'nextcloud-admin'
--data-dir '/data'
--database 'mysql'
--database-host 'localhost'
--database-name 'nextcloud'
--database-user 'nextcloud'
--database-pass 'linuxfabrik'
Migration Local Storage zu Object Storage
Die Anleitung zeigt den Umzug hin zu S3 oder alternativ Swift.
Bemerkung
Vorhandene Zeitangaben beziehen sich auf ein System mit knapp 90 Benutzern, etwas mehr als 2.1 Millionen Dateien und einer Gesamtgrösse von rund 4 TB.
So wird ein Block-basierter Nextcloud-Storage auf einen Object Store migriert. Mit welchen Tools die Inhalte vom Local Storage auf einen Object Storage kopiert werden, spielt keine Rolle. Die Anleitung behandelt zwei Tools, aws
und rclone
. Das Ergebnis ist bei beiden das gleiche.
Hier wird von folgenden Voraussetzungen ausgegangen:
Die Datenbank heisst
nextcloud
.Der lokale Nextcloud-Storage liegt auf
/var/www/html/nextcloud/data/
.Der Object-Storage läuft im Beispiel bei Infomaniak im Zürcher Datacenter.
S3-Bucket/Swift-Container namens
bucket-name
ist angelegt.
S3/Swift-Storage beim Provider einrichten und Credentials notieren:
Bucket-Name: bucket-name (als Bucket-Name beispielsweise den Hostnamen verwenden)
S3-URL: https://s3.pub1.infomaniak.cloud
Swift-URL: https://api.pub1.infomaniak.cloud/identity/v3 (OpenStack Swift)
Vorbereitende Massnahmen:
# 30 minutes
chown -R apache:apache /var/www/html/nextcloud/data/
# 30 minutes
sudo -u apache /var/www/html/nextcloud/occ files:scan --all
Maintenance-Mode aktivieren (Benutzer für die Zeit der Migration aus Konsistenzgründen aussperren):
sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --on
systemctl restart php-fpm
Datenbank abfragen, um eine Liste der Dateien aller Benutzer inkl. Metadaten zu erhalten. Die beiden resultierenden SQL-Dumps belegen auf dem beschriebenen System zusammengenommen 500 MB.
mysql_user='root'
# get the user files
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/user_file_list
select concat('urn:oid:', fileid, ' ', '/var/www/html/nextcloud/data/', substring(id from 7), '/', path)
from oc_filecache join oc_storages on storage = numeric_id
where id like 'home::%'
order by id;
EOF
# get the meta files
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/meta_file_list
select concat('urn:oid:', fileid, ' ', substring(id from 8), path)
from oc_filecache join oc_storages on storage = numeric_id
where id like 'local::%'
order by id;
EOF
Symbolischen Link für Block-Storage-Datei auf zukünftige Datei im Object Store-Bucket anlegen:
mkdir -p /var/www/html/nextcloud/data/objectstore_files
cd /var/www/html/nextcloud/data/objectstore_files
# count the files that have to be processed
# 3 minutes
find /var/www/html/nextcloud/data/ -type f | wc -l
# 50 minutes
while read -r target source ; do
if [ -f "$source" ] ; then
if ! ln -s "$source" "$target"; then
echo "Error: Failed to link $source to $target!"
fi
else
echo "Error: Could not find $source!"
fi
done < /tmp/user_file_list | tee /tmp/user_file.log
# 30 minutes
while read -r target source ; do
if [ -f "$source" ] ; then
if ! ln -s "$source" "$target"; then
echo "Error: Failed to link $source to $target!"
fi
else
echo "Error: Could not find $source!"
fi
done < /tmp/meta_file_list | tee /tmp/meta_file.log
grep '^Error: ' /tmp/*.log
Am Ende ergibt dies ein Verzeichnis mit (im Beispiel etwas über 2.3 Millionen) urn:oid:<nnnnn>
-Dateien.
- Kopiervorgang mit
aws
(gegen einen S3-fähigen Object Storage) Das Python-Programm AWS CLI per Download installieren und konfigurieren (die Version in den OS-Repos ist hoffnungslos veraltet):
cd /tmp dnf -y install unzip curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip ./aws/install --bin-dir /usr/local/bin mkdir /root/.aws cat > /root/.aws/config << EOF [default] region = us-east-1 s3 = max_concurrent_requests = 100 EOF cat > /root/.aws/credentials << EOF [default] aws_access_key_id = 7ca40b8a-2572-4ff7-9a9a-57051bf33dc7 aws_secret_access_key = 51c9d8b3-25f7-45dc-812f-2146e38d2167 EOF
Dateien der Nextcloud-Benutzer hin zu S3 syncen:
cd /var/www/html/nextcloud/data/objectstore_files # ~ 75 MiB/sec = 4.4 GiB/min = 263 GiB/h = 6.1 TiB/d # first sync takes 14h 40min; a second sync a day later takes 1h 08min aws s3 sync . s3://bucket-name --endpoint-url https://s3.pub1.infomaniak.cloud --color auto
- Kopiervorgang mit
rclone
(am Beispiel eines Swift-fähigen Object Storage) # from epel-repo dnf -y install rclone cd /var/www/html/nextcloud/data/objectstore_files export RCLONE_CONFIG_MYPROJECT_TYPE=swift export RCLONE_CONFIG_MYPROJECT_ENV_AUTH=true source path/to/openstack.rc # ca. 25 MB/sec rclone sync --copy-links --progress . myproject:mybucket
Danach:
cd
rm -rf /var/www/html/nextcloud/data/objectstore_files
Ging es bisher nur um den Sync, wird es ab hier ernst und die bestehende Nextcloud-Instanz tatsächlich geändert. Die einzelnen Schritte sollten vor der Ausführung unbedingt genau geprüft werden. Deshalb: Datenbank-Backup bereithalten.
- S3-Backend
Datenbank aktualisieren und die Storage-Einträge auf den S3 zeigen lassen (im Beispiel auf den Bucket „bucket-name“):
cat > /tmp/update-database.sql << 'EOF' update oc_storages set id = concat('object::user:', substring(id from 7)) where id like 'home::%'; update oc_storages set id = 'object::store:amazon::bucket-name' where id like 'local::%'; update oc_mounts set mount_provider_class = 'OC\\Files\\Mount\\ObjectHomeMountProvider' where mount_provider_class = 'OC\\Files\\Mount\\LocalHomeMountProvider'; EOF # a few milliseconds mysql --user root --password --database nextcloud < /tmp/update-database.sql
Nextcloud-Konfiguration im Storage-Bereich auf Object Storage umkonfigurieren:
cd /var/www/html/nextcloud/ sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --off systemctl restart php-fpm
sudo -u apache php occ config:system:set objectstore class --value=OC\\Files\\ObjectStore\\S3 sudo -u apache php occ config:system:set objectstore arguments autocreate --type=boolean --value=true sudo -u apache php occ config:system:set objectstore arguments bucket --value=bucket-name sudo -u apache php occ config:system:set objectstore arguments hostname --value=s3.pub1.infomaniak.cloud sudo -u apache php occ config:system:set objectstore arguments key --value=7ca40b8a-2572-4ff7-9a9a-57051bf33dc7 sudo -u apache php occ config:system:set objectstore arguments port --type=integer --value=443 sudo -u apache php occ config:system:set objectstore arguments region --value=us-east-1 sudo -u apache php occ config:system:set objectstore arguments secret --value=51c9d8b3-25f7-45dc-812f-2146e38d2167 sudo -u apache php occ config:system:set objectstore arguments use_path_style --type=boolean --value=true sudo -u apache php occ config:system:set objectstore arguments use_ssl --type=boolean --value=true
Inspiration war https://github.com/nextcloud/server/issues/25781.
- Swift-Backend
Datenbank aktualisieren und die Storage-Einträge auf den Swift zeigen lassen (im Beispiel auf den Bucket „bucket-name“):
cat > /tmp/update-database.sql << 'EOF' update oc_storages set id = concat('object::user:', substring(id from 7)) where id like 'home::%'; update oc_storages set id = 'object::store:bucket-name' where id like 'local::%'; update oc_mounts set mount_provider_class = 'OC\\Files\\Mount\\ObjectHomeMountProvider' where mount_provider_class = 'OC\\Files\\Mount\\LocalHomeMountProvider'; EOF # a few milliseconds mysql --user root --password --database nextcloud < /tmp/update-database.sql
Nextcloud-Konfiguration im Storage-Bereich auf Object Storage umkonfigurieren:
cd /var/www/html/nextcloud/ sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --off systemctl restart php-fpm
sudo -u apache php occ config:system:set objectstore class --value=OC\\Files\\ObjectStore\\Swift sudo -u apache php occ config:system:set objectstore arguments autocreate --type=boolean --value=true sudo -u apache php occ config:system:set objectstore arguments bucket --value=bucket-name sudo -u apache php occ config:system:set objectstore arguments region --value=dc3-a sudo -u apache php occ config:system:set objectstore arguments scope project domain name --value=Default sudo -u apache php occ config:system:set objectstore arguments scope project name --value=cabfeec2-ee88-4fba-8197-5bcae1ac96eb sudo -u apache php occ config:system:set objectstore arguments serviceName --value=swift sudo -u apache php occ config:system:set objectstore arguments url --value=https://api.pub1.infomaniak.cloud/identity/v3 sudo -u apache php occ config:system:set objectstore arguments user domain name --value=Default sudo -u apache php occ config:system:set objectstore arguments user name --value=f187e2b0-7d6c-419a-b5b0-9a5743677005 sudo -u apache php occ config:system:set objectstore arguments user password --value=linuxfabrik
Siehe auch https://docs.infomaniak.cloud/documentation/04.object-storage/third-party-integration/01.Nextcloud/
rm -f path/to/openstack.rc
Zum Schluss:
systemctl restart php-fpm
sudo -u apache /var/www/html/nextcloud/occ maintenance:repair
Fertig. Testen.
Achtung
Vorschau der Bilder funktioniert nicht? Bilder lassen sich nicht laden? Verschiedene Fehler im nextcloud.log zum Thema „Encryption“ bis hin zu „Seeking“?
Schauen, ob die Datenbank-Tabelle oc_mounts
wirklich aktualisiert und „LocalHomeMountProvider“ auf „ObjectHomeMountProvider“ umgestellt wurde.
Migration Object Storage zu Local Storage
Die Anleitung zeigt den Umzug von Object Storage wie S3 oder Swift hin zu Local Block Storage.
Hier wird von folgenden Voraussetzungen ausgegangen:
Die Datenbank heisst
nextcloud
.Die Nextcloud-Files liegen im Object Store in einem S3-Bucket/Swift-Container namens
bucket-name
.Der lokale Nextcloud-Storage liegt unter
$nextcloud_datadir
.
Vorbereitende Massnahmen:
nextcloud_datadir='/data'
chown -R apache:apache "$nextcloud_datadir"
sudo -u apache /var/www/html/nextcloud/occ files:scan --all
Maintenance-Mode aktivieren (Benutzer für die Zeit der Migration aus Konsistenzgründen aussperren):
sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --on
systemctl restart php-fpm
systemctl disable --now nextcloud-jobs.timer nextcloud-scan-files.timer
Datenbank abfragen, um eine Liste der Dateien aller Benutzer inkl. Metadaten zu erhalten.
mysql_user='root'
# get the user files
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/user_file_mkdir_list
select concat(substring(oc_storages.id from 14), '/', path)
from oc_filecache
left join oc_storages on oc_filecache.storage = oc_storages.numeric_id
left join oc_mimetypes on oc_filecache.mimetype = oc_mimetypes.id
where oc_storages.id like 'object::user:%'
and oc_mimetypes.mimetype = 'httpd/unix-directory'
order by oc_storages.id;
EOF
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/user_file_mv_list
select concat('urn:oid:', oc_filecache.fileid, ' ', substring(oc_storages.id from 14), '/', path)
from oc_filecache
left join oc_storages on oc_filecache.storage = oc_storages.numeric_id
left join oc_mimetypes on oc_filecache.mimetype = oc_mimetypes.id
where oc_storages.id like 'object::user:%'
and oc_mimetypes.mimetype != 'httpd/unix-directory'
order by oc_storages.id;
EOF
# get the meta files
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/meta_file_mkdir_list
select path
from oc_filecache
left join oc_storages on oc_filecache.storage = oc_storages.numeric_id
left join oc_mimetypes on oc_filecache.mimetype = oc_mimetypes.id
where oc_storages.id like 'object::store:%'
and oc_mimetypes.mimetype = 'httpd/unix-directory'
order by oc_storages.id;
EOF
mysql --user "$mysql_user" --password --batch --disable-column-names --database nextcloud << EOF > /tmp/meta_file_mv_list
select concat('urn:oid:', fileid, ' ', path)
from oc_filecache
left join oc_storages on oc_filecache.storage = oc_storages.numeric_id
left join oc_mimetypes on oc_filecache.mimetype = oc_mimetypes.id
where oc_storages.id like 'object::store:%'
and oc_mimetypes.mimetype != 'httpd/unix-directory'
order by oc_storages.id;
EOF
Nun müssen alle Files aus dem Object Store in einen temporären Ordner heruntergeladen werden:
# from epel-repo
dnf -y install rclone
nextcloud_datadir='/data'
mkdir -p "$nextcloud_datadir/objectstore_files"
cd "$nextcloud_datadir/objectstore_files"
export RCLONE_CONFIG_MYPROJECT_TYPE=swift
export RCLONE_CONFIG_MYPROJECT_ENV_AUTH=true
source path/to/openstack.rc
rclone sync --progress myproject:mybucket .
# for example:
# Transferred: 129.321 GiB / 129.321 GiB, 100%, 120.399 KiB/s, ETA 0s
# Checks: 101520 / 101520, 100%
# Transferred: 101537 / 101537, 100%
# Elapsed time: 2h30m56.7s
Am Ende ergibt dies ein Verzeichnis mit urn:oid:<nnnnn>
-Dateien.
Diese müssen nun an den richtigen Ort bewegt werden:
nextcloud_datadir='/data'
cd "$nextcloud_datadir/objectstore_files"
while read -r folder ; do
folder_path="$nextcloud_datadir/$folder"
if ! mkdir -p "$folder_path"; then
echo "Error: Failed to create $folder_path!"
fi
done < /tmp/user_file_mkdir_list | tee /tmp/user_file_mkdir.log
while read -r source target ; do
if [ -z "$target" ]; then
echo "Error: target for $source is empty!"
continue
fi
target_path="$nextcloud_datadir/$target"
if ! \mv "$source" "$target_path"; then
echo "Error: Failed to move $source to $target_path!"
fi
done < /tmp/user_file_mv_list | tee /tmp/user_file_mv.log
while read -r folder ; do
folder_path="$nextcloud_datadir/$folder"
if ! mkdir -p "$folder_path"; then
echo "Error: Failed to create $folder_path!"
fi
done < /tmp/meta_file_mkdir_list | tee /tmp/meta_file_mkdir.log
while read -r source target ; do
if [ -z "$target" ]; then
echo "Error: target for $source is empty!"
continue
fi
target_path="$nextcloud_datadir/$target"
if ! \mv "$source" "$target_path"; then
echo "Error: Failed to move $source to $target_path!"
fi
done < /tmp/meta_file_mv_list | tee /tmp/meta_file_mv.log
grep '^Error: ' /tmp/*.log
# should be empty now
ll /data/objectstore_files/
rmdir /data/objectstore_files/
chown -R apache:apache "$nextcloud_datadir"
restorecon -Fvr "$nextcloud_datadir"
Datenbank aktualisieren und die Storage-Einträge auf den Local Storage zeigen lassen:
old_objectstore_bucket_name='mybucket'
nextcloud_datadir='/data'
cat > /tmp/update-database.sql << EOF
update oc_storages
set id = concat('home::', substring(oc_storages.id from 14))
where id like 'object::user:%';
update oc_storages
set id = 'local::$nextcloud_datadir/'
where id = 'object::store:$old_objectstore_bucket_name';
update oc_mounts
set mount_provider_class = 'OC\\\\Files\\\\Mount\\\\LocalHomeMountProvider'
where mount_provider_class = 'OC\\\\Files\\\\Mount\\\\ObjectHomeMountProvider';
EOF
# takes a few milliseconds
mysql_user='root'
mysql --user="$mysql_user" --password --database=nextcloud < /tmp/update-database.sql
# double check oc_storages.
# there should only be one entry starting with `local::`.
# if that is not the case, manually fix the database before starting the nextcloud services
mysql --user="$mysql_user" --password --database=nextcloud --execute="SELECT * FROM nextcloud.oc_storages WHERE id like 'local::%';"
Nun muss man die alte Object Storage Konfiguration entfernen und den Maintenance-Mode deaktivieren:
$EDITOR /var/www/html/nextcloud/config/config.php
cd /var/www/html/nextcloud/
sudo -u apache php /var/www/html/nextcloud/occ maintenance:mode --off
systemctl restart php-fpm
systemctl enable --now nextcloud-jobs.timer nextcloud-scan-files.timer
Fertig. Testen.
Storage: External SMB/CIFS Storage
Siehe auch
Ein optimales Setup braucht sowohl smbclient
und libsmbclient-php
.
smbclient
wird von occ external_storage:notify
benötigt, libsmbclient-php
wird von Nextcloud direkt verwendet.
Unter CentOS:
yum install cifs-utils php-smbclient -y
Pro External Storage muss ein occ external_storage:notify
gestartet werden. Dazu verwenden wir die nc-external-files-notify Skripte.
nc-external-files-notify.timer
und nc-external-files-notify.service
sollten falls möglich in das Monitoring aufgenommen werden.
activestate: active
loadstate: loaded
substate: running, waiting
unitfilestate: enabled
activestate: active, inactive
loadstate: loaded
substate: running, dead
unitfilestate: disabled
Storage: Upload grosser Dateien
Im Beispiel wird der Upload von 10 GB grossen Dateien gegen einen langsamen Storage konfiguriert. Wichtig ist, dass die Webserver-Timeouts genügend tolerant gewählt werden, um das Assembling der Datei-Chunks auf Serverseite zu ermöglichen - ansonsten erhält man Fehler der Art Error when assembling chunks. status code 504
. PHP mit memory_limit
unter 1 GB ergibt regelmässig OOM-Fehler. Die post_max_size
spielt dagegen keine grosse Rolle - ausser dass sich in unseren Messungen die Upload-Zeit durch langsameres Assembling verlängert, je grösser die post_max_size
gewählt wird.
Apache App-Server:
Timeout 600 # Default: 60
Apache Reverse-Proxy:
ProxyTimeout 600 # same value as Timeout on Nextcloud App-Server
PHP:
max_execution_time = 3600 ; Default: 30
memory_limit = 1024M ; Default: 128M
post_max_size = 16M ; Default: 8M
upload_max_filesize = 10000M ; Default: 2M
Und darauf achten, dass /tmp
genügend Platz für den (parallelen) Upload solch grosser Dateien bietet.
LDAP
App LDAP user and group backend verwenden.
Tipp
Issue seit mind. 2017: wird ein LDAP-Zugang konfiguriert, werden wie erwartet die passenden Benutzer aus dem LDAP in der Nextcloud-Benutzerliste angezeigt. Später im AD/LDAP hinzugefügte Benutzer tauchen dann aber dort nicht mehr auf, obwohl sie bekannt sind und ein Login problemlos funktioniert. Möchte man jetzt die Eigenschaften der unauffindbaren/nicht gelisteten LDAP-Benutzer in Nextcloud anpassen, ruft man die Benutzerliste auf und nutzt die Nextcloud-Suche. Dabei erscheinen die bisher unsichtbaren Benutzer, und man kann wie gewohnt deren Eigenschaften wie beispielsweise deren Gruppenzugehörigkeit anpassen.
Wer sich nach wie vor mit einem lokalen Account anmelden möchte, verwendet die URL https://cloud.example.com/index.php/login?direct=1
- LDAP gegen FreeIPA konfigurieren
Server:
User DN: uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=myorg,dc=tld
Password: xxx
Base DN: dc=myorg,dc=tld
Users - nur Benutzer aus der FreeIPA-Gruppe „nextcloud“ zulassen:
LDAP-Query:
(&(objectclass=inetorgperson)(memberof=cn=nextcloud,cn=groups,cn=accounts,dc=myorg,dc=tld))
Advanced > Directory Settings > User Display Name Field: uid
Login Attributes:
LDAP / AD Username: yes
LDAP / AD Email Address: yes
LDAP Query:
(&(objectclass=inetorgperson)(|(mail=%uid)(uid=%uid)))
Test einer LDAP-Query mit ldapsearch
:
dnf -y install openldap-clients
# the single quotes are important
ldapsearch -v \
-H ldap://freeipa \
-D 'uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=myorg,dc=tld' \
-W -b \
'DC=myorg,DC=tld' \
'(&(objectClass=inetorgperson)(memberOf=cn=nextcloud,cn=groups,cn=accounts,dc=myorg,dc=tld))'
Umgang mit OCC und LDAP auf der Kommandozeile:
ldap:check-user checks whether a user exists on LDAP.
ldap:create-empty-config creates an empty LDAP configuration
ldap:delete-config deletes an existing LDAP configuration
ldap:search executes a user or group search
ldap:set-config modifies an LDAP configuration
ldap:show-config shows the LDAP configuration
ldap:show-remnants shows which users are not available on LDAP anymore, but have remnants in Nextcloud.
ldap:test-config tests an LDAP configuration
sudo -u apache /var/www/html/nextcloud/occ ldap:check-user "Markus Frei"
# user exists? then:
sudo -u apache /var/www/html/nextcloud/occ ldap:search "Markus Frei"
Um „remnant“-Benutzer zu löschen, regelmässig sudo -u apache php /var/www/html/nextcloud/occ user:delete <nextcloud name>
(erste Spalte aus show-remnants
) verwenden. Achtung: Man muss vor dem Löschen die Dateien einem anderen Benutzer zuweisen, sonst werden die Dateien des LDAP-Benutzers gelöscht.
Keycloak (oAuth, SAML)
- Nextcloud-Seite
Es gibt drei Möglichkeiten - in unseren Tests hat Stand 2021-03 keine davon funktioniert:
Nextcloud und Keycloak per SAML über die App SSO & SAML authentication verbinden (schon wegen SAML und dem Zertifikatshandling nicht zu empfehlen)
Nextcloud und Keycloak per OpenID-Connect über die App Social Login verbinden. Unterstützt Roles, aber keine benutzerspezifischen Attribute.
Nextcloud und Keycloak per OpenID-Connect über die App OpenID Connect Login verbinden. Unterstützt eigene User-Attribute wie „Quota“, aber keine Roles. Ist zudem nur über die
config.php
administrierbar.
- Für die Nextcloud-App Social Login:
Damit sich Nextcloud über Keycloak authentifizieren kann, wird im Keycloak-Realm ein Client (hier „nextcloud“) und in Nextcloud die App „Social Login“ benötigt, womit OpenID-Connect/OAuth verwendet wird. Wer SAML bevorzugt, muss die App „SSO & SAML authentication“ installieren.
Konfiguration der „Social Login“-App:
[x] Prevent creating an account if the email address exists in another account
[x] Update user profile every login
[x] Restrict login for users without mapped groups
> Save
„Custom OpenID Connect“-Button klicken.
Internal name: keycloak
Title: Keycloak
Authorize url: https://keycloak/auth/realms/$REALM/protocol/openid-connect/auth
Token url: https://keycloak/auth/realms/$REALM/protocol/openid-connect/token
User info URL (optional): https://keycloak/auth/realms/$REALM/protocol/openid-connect/userinfo
Logout URL (optional): https://keycloak/auth/realms/$REALM/protocol/openid-connect/logout
Client Id: nextcloud
Client Secret: e8d78053-fd47-4ec3-b6dc-87357f18f8d5
Scope: openid
Groups claim (optional): roles
Button style: Keycloak
„Add group mapping“ anklicken.
users / users
Save.
Benutzer wählen > Role Mappings > Client Roles: nextcloud > Rolle zuweisen.
Siehe auch
- Für die Nextcloud-App OpenID Connect Login
Siehe
- Keycloak-Seite
Die Keycloak-Konfiguration hängt von der verwendeten Nextcloud-App ab.
Für die Nextcloud-App Social Login:
Neuer Client „nextcloud“ mit „openid-connect“ und Root URL „https://nextcloud.example.com“.
Clients > „nextcloud“ > Settings
Client ID: nextcloud
Client Protocol: openid-connect
Access Type: confidential
Clients > „nextcloud“ > Roles > Add Role
Role name: users
Clients > „nextcloud“ > Mappers > Add Builtin
„client roles“ auswählen > Add selected
Clients > „nextcloud“ > Mappers > „client roles“
Client ID: nextcloud
Token Claim Name: roles
Add to userinfo: ON
Clients > „nextcloud“ > Scope
Full Scope Allowed: OFF (This will ensure that only the client roles are stored in the token)
Sollen keine kryptische Benutzernamen in der Form „04f21d18-6176-11eb-a904-525400b49b22“ erzeugt werden, muss das
sub
-Property der userinfo per Mapper überschrieben werden:Clients > „nextcloud“ > Mappers > Create
Name: sub
Mapper Type: User Prooperty
Property: username
Token Claim Name: sub
Siehe auch https://janikvonrotz.ch/2020/10/20/openid-connect-with-nextcloud-and-keycloak/.
Encryption in Nextcloud
Nextcloud bietet mehrere Verschlüsselungsebenen.
- Transportverschlüsselung (TLS)
Schützt vor Lauschangriffen. Schützt nicht vor kompromittierten Geräten oder Servern.
- Server Side Encryption (SSE) - Daten beim Speichern verschlüsseln
Optional. Jede Datei wird vor dem Speichern mit einem eindeutigen Schlüssel verschlüsselt - entweder serverweit (aus Funktions- und Leistungsgründen der Standard), oder einem Schlüssel pro Benutzer. SSE verschlüsselt nur den Inhalt der Dateien, nicht aber deren Namen oder Ordnerstruktur.
Server Side Encryption wurde ursprünglich eingeführt, um External Storage wie Dropbox und dergleichen sicher anbinden zu können: Nextcloud sorgt dann dafür, dass alle Daten ausserhalb des eigenen Standorts verschlüsselt gespeichert werden.
Der serverweite Schlüssel (technisch ein Passwort zum Entschlüsseln der Dateien) wird mit Hilfe des Secrets in der
config.php
verschlüsselt im Nextcloud-Datenverzeichnis abgelegt (und lässt sich im Desaster-Fall wiederherstellen).Benutzerschlüssel liegen in den Datenverzeichnissen der einzelnen Benutzer und werden mit deren Benutzerkennwort verschlüsselt. Wird dieses Feature aktiviert, ist der Einsatz eines Online-Office (Collabora, OnlyOffice) nicht mehr möglich.
SSE schützt Dateien, solange die Dateiablage nicht auf dem gleichen System wie Nextcloud selbst liegt - eine auf ein lokales Datenverzeichnis angwendete SSE bietet wenn überhaupt nur geringen Schutz, schliesslich wird hier der Schlüssel zusammen mit den Daten gespeichert.
Stand 2021-04 „lügt“ die Web-Oberfläche noch: ist „Serverseitige Verschlüsselung“ aktiviert, meldet das eigene Benutzerprofil unter „Datenschutz“ ein „Deine Dateien sind mittels der serverseitigen Verschlüsselung verschlüsselt“ - egal ob „Benutzerverzeichnis verschlüsseln“ aktiviert wurde.
Fazit:
SSE macht Sinn, wenn die App External Storage angeboten wird, oder das Datenverzeichnis nicht auf dem gleichen System wie die Nextcloud-Installation selbst liegt.
Die Anwendung von SSE auf ein lokales Datenverzeichnis bringt keinen Sicherheitsvorteil (trügerische Sicherheit, die durch Meldungen unter „Datenschutz“ noch verstärkt werden).
Sollen Dateiinhalte vor dem Serverbetreiber verborgen werden, muss End-to-End-Encryption (E2E) zum Einsatz kommen.
- End-to-End-Encryption (E2E, E2EE - Client-basierte Verschlüsselung)
Der ultimative Schutz der Benutzerdaten wird durch die Ende-zu-Ende-Verschlüsselung gewährleistet. Nur hier hat der Server niemals Zugriff auf Schlüssel oder unverschlüsselte Dateien. Der Sync-Client verschlüsselt die Daten vor dem Senden innerhalb des E2E-fähigen Ordners (jedoch nicht in darunterliegenden Ordnern).
Das geht nicht ohne Funktionsverlust: die Nextcloud-Weboberfläche kann die verschlüsselten Dateien nicht einsehen, der Sync-Client ist damit Pflicht. Eine öffentliche Freigabe oder Freigabe an Gruppen ist nicht möglich, die Suchmaschine kennt deren Inhalte nicht, und Collaboration per Online-Office funktioniert nicht.
E2E lässt sich für einen oder mehrere Ordner aktivieren. Der Inhalt jedes dieser Ordner wird vollständig vom Server ausgeblendet, einschließlich Dateinamen und Verzeichnisstruktur. Um die Daten mit anderen Geräten zu synchronisieren, müssen Benutzer eine vom ersten Gerät erstellte Mnemonic-Passphrase nutzen. Sobald dies erledigt ist, werden durchgängig verschlüsselte Ordner nahtlos zwischen Geräten synchronisiert. Nextcloud kann beispielsweise auch so konfiguriert werden, dass alle von der Finanzabteilung erstellten Dateien automatisch verschlüsselt werden.
Tipp
Die „Mnemonic-Passphrase“ ist ein aus 12 zufälligen, englischen Wörtern bestehendes Passwort. Die Mnemonic-Passphrase wird zur Verschlüsselung der Dateien verwendet - daher diese UNBEDINGT notieren und in einem Passwort-Manager speichern. Sollte man mehrere Nextcloud-Clients nutzen, wird man nach dieser Passphrase gefragt. Man kann sich die Passphrase im Client unter „Account > Show E2E mnemonic“ nochmals anzeigen lassen. Es wird ein Client >= v2.5.0 benötigt.
Kein Admin dieser Welt kann helfen, falls man die Passphrase vergessen oder nicht notiert hat.
So erhält man die Mnemonic-Passphrase:
Nextcloud-Client in der neuesten Version installieren oder updaten (>= 2.5.0).
Nextcloud-Client (erneut) mit dem Server verbinden. Es erscheint ein Popup mit der „Mnemonic Passphrase“. Passphrase notieren.
So verschlüsselt man einen Ordner:
Einen neuen, leeren Ordner im lokalen Nextcloud-Verzeichnis anlegen.
Nextcloud-Client öffnen, rechte Maustaste auf den Ordner und „Encrypt“ auswählen.
Das war’s. Dateien, die in diesen Ordnern landen, werden nur noch verschlüsselt auf einen Nextcloud-Server hochgeladen - uneinsehbar für den Rest der Welt. Es können beliebig viele Ordner verschlüsselt werden.
Das ist mit verschlüsselten Ordnern nicht mehr möglich:
Zugriff per Web-Interface
Freigabe an eine Gruppe
Freigabe auf Dateiebene
Serverseitige Suche oder Vorschau
Serverseitiger Papierkorb und Versionierung
E2E ist seit 2020-08 (NC19+) produktiv einsetzbar, davor galt E2E lange Jahre als „experimental“.
Die End-to-End-Verschlüsselung in Nextcloud schützt Benutzerdaten vor jedem Angriffsszenario, selbst im Falle einer unentdeckten Sicherheitslücke oder vor (nicht vertrauenswürdigen) Serverbetreibern.
Die Daten auf den Benutzergeräten selbst werden nicht geschützt, und der Diebstahl eines unverschlüsselten, entsperrten Benutzergeräts würde es einem Angreifer ermöglichen, auf private Schlüssel zuzugreifen.
Fazit:
E2E hat einen sehr spezifischen Anwendungsfall, die Einschränkungen sind nur bei sensiblen Daten sinnvoll.
Verliert ein Benutzer seine Mnemonic-Passphrase, sind auch die damit verschlüsselten Daten unweigerlich verloren.
Der gleichzeitige Betrieb von SSE mit lokal verschlüsseltem Benutzerverzeichnis und E2E ist zwar möglich, wird aber nicht unterstützt - beides zusammen wird zu technischen Problemen führen. Und egal welche der beiden Methoden zum Einsatz kommt: verschlüsselt werden nur Dateien. Kalender, ToDo-Listen und andere Daten werden nicht verschlüsselt, da es beispielsweise im Bereich CalDAV dafür an Clients fehlt, die dies unterstützen.
Hier finden sich noch einige Details: https://nextcloud.com/blog/encryption-in-nextcloud/.
Collabora und ODF vs OnlyOffice und OOXML
ODF vs OOXML
ODF ist das leichgewichtigere, offenere und von LibreOffice präferierte Format für Dokumente aller Art. Die Spezifikation für ODF 1.2 umfasst ca. 1’000 Seiten (ISO 26300). ODF-Spreadsheets werden beispielsweise als .ods
gespeichert, Textdokumente als .odt
. Einige Microsoft-Office-Funktionen lassen sich mit ODF nicht umsetzen, weshalb es durch die Redmonder nicht unterstützt wird.
Wenn die Microsoft-eigenen, mit Binärcode gespickten, XML-basierten Office-Formate .docx
& Co. nicht zum Einsatz kommen, ist Office Open XML (OOXML) das von Microsoft Office präferierte Dokumentenformat, welches 2008 als ISO-Norm 29500 verabschiedet wurde und einen Umfang von ca. 6’000 Seiten aufweist. Es ist daher nicht vollständig implementiert; der Umfang ist hauptsächlich der MS-Office Rückwärtskompatibilität geschuldet.
Collabora vs OnlyOffice
Collabora ist quasi eine auf dem Server ausgeführte LibreOffice-Installation, für die der Browser mehr oder weniger nur das GUI anzeigt. Collabora orientiert sich bei Look & Feel also an LibreOffice und verarbeitet die Dokumente auf dem Server.
OnlyOffice hat den gegenteiligen Ansatz - es orientiert sich vom Aussehen her an MS-Office und verlagert das Document Processing auf den Client. Deren Document-Server stellt den Speicherplatz zur Verfügung und ist hier mehr für die kollaborative Kommunikation zuständig, der Grossteil der Applikation läuft dagegen im Browser.
In Collabora lässt sich bei der Erstellung einer Datei das Dateiformat frei wählen (ODF vs. OOXML), ODF wird aber wie bei LibreOffice klar präferiert. OnlyOffice bevorzugt dagegen Dokumente im OOXML-Format. Siehe https://www.onlyoffice.com/blog/2018/09/onlyffice-makes-it-easier-to-work-with-odf-in-integrated-solutions/.
OnlyOffice beherrscht das Freezing von Zeilen und Spalten, was für Collabora erst ab v6 angekündigt ist.
In einer Nextcloud-Instanz lassen sich beide Office-Suiten parallel nutzen. In diesem Fall werden Dokumente On-Click sofort in Collabora geöffnet; im Web-GUI ist OnlyOffice per Kontext-Menu (3 Punkte) verfügbar. In der Smartphone-App von Nextcloud ist das nicht der Fall, das Dokument kann nur mit OnlyOffice geöffnet werden.
Kommt in Nextcloud ausschliesslich Collabora zum Einsatz, wird es als Standard-Editor für sämtliche durch Collabora unterstützen Dateiformate benutzt. Bei OnlyOffice lässt sich in den Einstellung anpassen, welche Formate damit geöffnet werden sollen; per Kontext-Menu lassen sich damit trotzdem abgewählte Formate öffnen.
Ab Nextcloud Hub v18 wird zum ersten Mal OnlyOffice während der Nextcloud-Installation on demand installiert und integriert. OnlyOffice findet sich nicht im Nextcloud tarball/zip. Collabora wird (wie bis dato auch) per separater App angeboten oder dediziert und losgelöst von Nextcloud installiert. Ein klares Bekenntnis der Nextcloud-Macher zu OnlyOffice also. Für Verwirrung sorgte dann die Pressemitteilung von Collabora auf https://www.collaboraoffice.com/press-releases/collabora-online-as-default-in-nextcloud-hub/, dass ab Nextcloud Hub v19 Collabora das neue Default Web-Office-Paket ist.
Wohl auch durch die neu gewonnene Popularität hat OnlyOffice im Nextcloud-Umfeld recht schnell mit einigen „Known Issues“ auf sich aufmerksam gemacht, die einen negativen Einfluss auf die Funktion haben, siehe zum Beispiel https://github.com/nextcloud/documentserver_community/issues/100 und https://api.onlyoffice.com/editors/nextcloud#issue.
Die Features in der Übersicht:
Produkt |
Preis |
Edit auf Mobile |
max. gleichz. geöffnete Dokumente |
max. gleichz. Verbindungen |
max. Benutzer |
---|---|---|---|---|---|
Collabora CODE |
kostenlos |
ja |
10 |
20 |
k.A. |
Collabora for SMBs |
17€/User/Jahr |
ja |
k.A. |
k.A. |
99 |
Collabora for Enterprises |
k.A. |
ja |
k.A. |
k.A. |
k.A. |
OnlyOffice CE |
kostenlos |
view only |
k.A. |
20 |
bis 20 |
OnlyOffice Integration Edition Start |
35€ pro Server-Lifetime, 1 Jahr Support & Updates |
ja |
k.A. |
50 |
bis 50 |
OnlyOffice Integration Edition Standard |
1870€ pro Server-Lifetime, 1 Jahr Support & Updates |
ja |
k.A. |
100 |
bis 100 |
OnlyOffice Integration Edition Standard+ |
3740€ pro Server-Lifetime, 1 Jahr Support & Updates |
ja |
k.A. |
200 |
bis 400 |
Siehe auch:
DB: Informationen zu Benutzern auslesen
Liste der E-Mail-Adressen aller Benutzer erhalten:
select json_extract(data, '$.email.value')
from oc_accounts;
Alle deaktivierten Benutzer auflisten (gilt nicht für LDAP):
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-Mail-Adressen aller aktivierten Benutzer auflisten (gilt nicht für LDAP):
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"
)
Wieviel Storage hat der Benutzer beansprucht, inkl. versionierten Dateien und Trash?
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
Wieviel Storage hat der Benutzer ohne versionierte Dateien und ohne Trash beansprucht?
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'
DB: Informationen zum Server auslesen
# databaseVersion
SELECT VERSION() AS version;
# databasePerfData
SHOW variables;
SHOW global status;
# databaseSize
SHOW databases;
SHOW TABLE STATUS FROM `databaseName`;
USE `databaseName`;
# getNumberOfActiveUsers in the last 5 minutes
SELECT count(*) as num_entries FROM oc_authtoken WHERE last_activity > UNIX_TIMESTAMP() - 300;
# countUserEntries
SELECT COUNT(*) as num_entries FROM oc_preferences WHERE configkey= "lastLogin";
# countHomeStorages
SELECT COUNT(*) as num_entries FROM oc_storages WHERE id like 'home::%';
# countLocalStorages
SELECT COUNT(*) as num_entries FROM oc_storages WHERE id like 'local::%';
# countOtherStorages
SELECT COUNT(*) as num_entries FROM oc_storages WHERE id not like 'home::%' and id not like 'local::%';
# getShareStatistics
SELECT COUNT(*) as num_entries, permissions, share_type FROM oc_share WHERE 1 GROUP BY permissions, share_type;
Nextcloud API
Das API verlangt, dass User-Credentials Base64-encoded werden. In python beispielsweise so:
credentials = base64.b64encode('api-user:api-password')
header = {
'Authorization' : "Basic %s" % credentials,
'OCS-APIRequest': 'true',
}
Grundlegende Statistiken ermitteln:
curl \
-H 'Authorization: Basic bmV4dGNsbp3d0NIVQ==' \
-H 'OCS-APIRequest: true' \
http://localhost/nextcloud/ocs/v2.php/apps/serverinfo/api/v1/info?format=json
Nextcloud Security Scan
Der externe Dienst https://scan.nextcloud.com sucht nach folgenden Dateien, um die Daten zur Nextcloud-Instanz abzurufen:
/nextcloud/status.php
/oc-shib/status.php
/oc/status.php
/owncloud/status.php
/status.php
Auf der Kommandozeile geht das ganze so:
# in "data", set what to scan
curl --silent --request POST \
--header 'Content-type: application/x-www-form-urlencoded' \
--header 'X-CSRF: true' \
--data 'url: cloud3.linuxfabrik.ch' \
https://scan.nextcloud.com/api/queue | jq
# search for the returned Nextcloud UUID
# e.g. 558eccce-8aba-4717-850b-28d47cb84a16
curl --silent https://scan.nextcloud.com/api/result/558eccce-8aba-4717-850b-28d47cb84a16 | jq
Nextcloud-Client
Was fragt der Nextcloud-Client (User-Agent „mirall“, nutzt HTTP/1.1) in welcher Reihenfolge mit welcher Methode ab?
# first contact - if this fails, the client won't work at all
GET /status.php
# after that and round about every 30 seconds at least this:
PROPFIND /remote.php/dav/files/username/
GET /ocs/v1.php/cloud/user?format=json
GET /remote.php/dav/avatars/username/128.png
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.
Um einen Nextcloud Background-Job manuell zu starten, kann man in der oc_jobs
-DB-Tabelle last_run
und last_checked
auf 0
setzen.
Built on 2024-11-18