Diese Nextcloud Installationsanleitung für Ubuntu 26.04 LTS (x86_64) mit nginx, MariaDB 11.8, PHP8.5, LetsEncrypt, Redis, crowdsec, ufw u.v.m. beschreibt die Installation, Konfiguration und Härtung sowie einige Erweiterungsmöglichkeiten von Nextcloud auf ihren Servern.




Aktualisierungen
» 2 0 2 6 «
28. April 2026:
» Neue Nextcloud Installationsanleitung für Ubuntu 26.04 LTS (Nextcloud Installationsanleitung)
27. April 2026:
» Neues Nextcloud Installationsskript für Ubuntu 26 (Nextcloud Installationsskript)
25. Februar 2026:
» Anpassung für Nextcloud HUB 26 Winter (php 8.4 und Mariadb 11.8)
11. Januar 2026:
» Anpassung für PHP 8.3 unter Debian 13
04. Januar 2026:
» Anpassung für PHP 8.3 und Redis unter Debian 13
» 2 0 2 5 «
23. November 2025:
» Anpassung bzgl. Netdata
13. November 2025:
» Anpassungen bzgl. Debian 13 und „software-properties-common„
09. November 2025:
» Changes bzgl. MariaDB-Repos für Ubuntu undDebian, http/3 entfernt, da nach Angaben der Nextcloud GmbH die Software derzeit nicht http/3 kompatibel ist.
05. November 2025:
» Die Update-Skripte wurden aktualisiert
26. Oktober 2025:
» minimum./maximum.supported.desktop.version ergänzt.
26. September 2025:
» Anpassungen bzgl. CrowdsEC:
» Nextcloud Installationsanleitung
» Nextcloud Installationsskript
» Fail2ban » Crowdsec
27. August 2025:
» Enabled http/3 « optional
(aufgrund von bekannten und anerkannten Problemen der Nextcloud-Software mit http/3 raten wir in produktiven Umgebungen davon ab!)
10. August 2025:
» Anpassung des Nextcloud Installationsskriptes für Debian 13
08. August 2025:
» Anpassung der PostgreSQL 16 Parameter (/var/lib/postgresql/16/main/postgresql.auto.conf)
02. JuLi 2025:
» Anpassung der php-GC-Werte und Nextcloud-SessionWerte
– PHP: php.ini
– Nextcloud: config.php
30. Juni 2025:
» Anpassung der my.cnf (slave_connections_needed_for_purge = 0)
03. Juni 2025:
» SSL Stapling wurde entfernt (Let’s Encrypt)
25. Mai 2025:
» Lock data and shares of disabled users
16. Mai 2025:
» SSL Stapling wurde auskommentiert (Let’s Encrypt)
03. Mai 2025:
» Wechsel zu Redis v.8.0 (OpenSource)
20. April 2025:
» Nextcloud Installationsanleitung für Debian 12 (MariaDB 11.4) angepasst
01. März 2025:
» Nextcloud Installationsanleitung für Hub 10 freigegeben
25. Februar 2025:
» Nextcloud Installationsanleitung angepasst: md5 check
05. Februar 2025:
» Nextcloud Installationsanleitung angepasst: Crowdsec und Session-/Anmeldeverhalten
09. Januar 2025:
» ACME – Autoupgrade
Systemvoraussetzungen
Nextcloud Systemrequirements:
» https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server
Nextcloud Remote access:
» https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#connections-to-remote-servers
Die Installation basiert auf nginx (http/2), Let’s Encrypt TLS 1.3, MariaDB 11.8, PHP 8.5 (php-fpm), Redis, crowdsec, fail2ban, ufw und erhält abschließend sowohl von Nextcloud, als auch von Qualys SSL Labs eine A+ Sicherheitsbewertung. Die anzupassenden Parameter sind im Artikel rot markiert und müssen durch Ihre spezifischen Systemwerte (bspw. ihre.domain.de, 192.168.2.x, /var/nc_data, Redispassword) ersetzt werden.
Möchten Sie hingegen lieber alles mit nur einem einzigen Skript installieren? Dann nutzen Sie unser Nextcloud-Installationsskript zero26.sh, welches Ihnen hier zur Verfügung steht.
Inhaltsverzeichnis
- Systemvorbereitungen und Installation des nginx Webservers
- Installation und Konfiguration von PHP 8.5
- Installation und Konfiguration des Datenbankservers MariaDB 11.8
- Installation des Redis-Server („in-memory-Datenbank“)
- Installation und Optimierung der Nextcloud (inkl. SSL)
- Systemhärtung (crowdsec IPS, fail2ban und ufw)
- Optimieren und aktualisieren der Nextcloud per Skript
- optional: Nextcloud (HPB) High Performance Backend für Dateien
- optional: bash_alias für php occ, empfohlene Settings (config.php), logrotating
- optional: Verbesserung der Sicherheit und Performance des TCP-Stacks
Weiterführende Herstellerinformationen finden Sie hier.
1. Vorbereitungen und Installation des nginx Webserver
Aktuelle Installationsmedien für den zugrundeliegenden Linux-Server erhalten Sie hier:
Ubuntu 26.04.x LTS: Download-Installationsmedium
Starten Sie mit der Installation und verbinden sich anschließend per SSH mit Ihrem Server – bspw.:
ssh <benutzer>@<IP-Adresse>
Wechseln Sie in den privilegierten Benutzermodus
sudo -s
und aktualisieren zuerst das System.
apt update && apt upgrade -y
Bereiten Sie den Server vor, indem Sie die notwendigen Basissoftwarepakete installieren:
apt update && apt upgrade -y
apt install -y \
apt-transport-https bash-completion bzip2 ca-certificates cron curl dialog dirmngr \
ffmpeg ghostscript git gpg gnupg gnupg2 htop jq libfile-fcntllock-perl libfontconfig1 \
libfuse2 locate lsb-release nano nodejs net-tools npm rsyslog screen smbclient socat \
ssl-cert tree unzip vim wget zip software-properties-common ubuntu-keyring
mkdir -p /etc/apt/keyrings
Tragen Sie den zukünftigen Servernamen sowohl in die hosts-Datei, als auch in die hostname-Datei ein:
nano /etc/hosts
Passen Sie die roten Werte an Ihre Umgebung an, im Beispiel gehen wir davon aus, dass die Domäne „ihre.domain.de“ heißt:
127.0.0.1 localhost
127.0.1.1 ihre ihre.domain.de
::1 ihre ihre.domain.de ip6-localhost ip6-loopback
[...]
Geben Sie den vollständigen Servername in der hostname-Datei an und ersetzen den roten Wert durch Ihren:
nano /etc/hostname
Der Servername muss als FQDN, also vollqualifiziert angegeben werden:
ihre.domain.de
Sorgen Sie nun dafür, dass der Server nicht in einen „Energiesparmodus“ wechseln kann:
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
Starten Sie abschließend den Server neu
reboot now
und melden sich dann erneut mit priviligierten Benutzerrechten am Server an:
sudo -s
Fügen Sie dem System das nginx-Software-Repositoriey (Softwarequelle) hinzu, um die aktuellen Releases des jeweiligen Pakets installieren zu können
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
Um das hinzugefügte Repository einzulesen und das System damit zu präparieren aktualisieren wir das System abermals und generieren temporäre „self-signed“-Zertifikate, die im späteren Verlauf durch vollwertige ECC-Zertifikate von Let’s Encrypt ersetzt werden.
apt update && make-ssl-cert generate-default-snakeoil -y
Nun sind die Vorbereitungen bereits abgeschlossen und wir können mit der Installation des Webservers nginx beginnen.
apt install -y nginx
Den automatischen Start des Dienstes setzen wir wie folgt:
systemctl enable nginx.service
Mit Blick auf die späteren Anpassungen wird die Standardkonfiguration gesichert und eine neue Konfigurationsdatei erstellt:
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak touch /etc/nginx/nginx.conf && nano /etc/nginx/nginx.conf
Kopieren Sie den gesamten nachfolgenden Inhalt in die Datei:
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
ssl_early_data on;
server_names_hash_bucket_size 64;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
send_timeout 3600;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=500 inactive=10m;
open_file_cache_errors on;
keepalive_timeout 65;
reset_timedout_connection on;
server_tokens off;
resolver 127.0.0.53 176.9.93.198 176.9.1.117 valid=30s;
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}
Betreiben Sie Ihre Nextcloud hinter einem Reverse Proxy, so ersetzen Sie die IP des Parameteres „set_real_ip_from 127.0.0.1“ mit der IP des Reverse Proxys („set_real_ip_from w.x.y.z„).
Speichern Sie die Datei und schließen Sie diese, um im Anschluß den Webserver neu zu starten:
systemctl restart nginx.service
Vorbereitend für die SSL Zertifikate und die Webverzeichnisse legen wir vier Ordner an und setzen die korrekten Berechtigungen:
mkdir -p /var/log/nextcloud /var/nc_data /var/www/letsencrypt/.well-known/acme-challenge /etc/letsencrypt/rsa-certs /etc/letsencrypt/ecc-certs
chown -R www-data:www-data /var/nc_data /var/www /var/log/nextcloud
Die Installation des Webservers ist somit bereits abgeschlossen und wir fahren mit der Installation und den Anpassungen von PHP fort.
2. Installation und Konfiguration von PHP 8.5 (fpm)
Wir verwenden das seitens Ubuntu 26 bereitgestellte PHP 8.5 und können direkt mit der Installation beginnen.
apt update
apt install -y php-common \
php8.5-{fpm,gd,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,mysql,redis,smbclient,sqlite3,cli,common,readline} imagemagick libmagickcore-7.q16-10-extra --allow-change-held-packages
apt install -y ldap-utils nfs-common cifs-utils --allow-change-held-packages
Optional (bei einem geplanten Einsatz von Samba- und/oder cifs-Shares oder einer LDAP(s)-Anbindung):
apt install -y ldap-utils nfs-common cifs-utils
Setzen Sie das richtige Datumsformat, um auch ein korrektes Logging zu ermöglichen:
timedatectl set-timezone Europe/Berlin
Bevor wir mit den Optimierungen von PHP beginnen sichern wir die Konfigurationsdateien,
cp /etc/php/8.5/fpm/pool.d/www.conf /etc/php/8.5/fpm/pool.d/www.conf.bak
cp /etc/php/8.5/fpm/php-fpm.conf /etc/php/8.5/fpm/php-fpm.conf.bak
cp /etc/php/8.5/cli/php.ini /etc/php/8.5/cli/php.ini.bak
cp /etc/php/8.5/fpm/php.ini /etc/php/8.5/fpm/php.ini.bak
cp /etc/php/8.5/mods-available/apcu.ini /etc/php/8.5/mods-available/apcu.ini.bak
cp /etc/ImageMagick-7/policy.xml /etc/ImageMagick-7/policy.xml.bak
optimieren dann PHP für den Betrieb Ihrer Nextcloud
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/8.5/fpm/pool.d/www.conf
sed -i 's/pm = dynamic/pm = ondemand/' /etc/php/8.5/fpm/pool.d/www.conf
sed -i 's/pm.max_children =.*/pm.max_children = 200/' /etc/php/8.5/fpm/pool.d/www.conf
sed -i 's/pm.start_servers =.*/pm.start_servers = 100/' /etc/php/8.5/fpm/pool.d/www.conf
sed -i 's/pm.min_spare_servers =.*/pm.min_spare_servers = 60/' /etc/php/8.5/fpm/pool.d/www.conf
sed -i 's/pm.max_spare_servers =.*/pm.max_spare_servers = 140/' /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/8.5/fpm/pool.d/www.conf
sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/8.5/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = Off/" /etc/php/8.5/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.5/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.5/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/8.5/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/8.5/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.5/cli/php.ini
sed -i "s/;cgi.fix_pathinfo.*/cgi.fix_pathinfo=0/" /etc/php/8.5/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 1G/" /etc/php/8.5/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = Off/" /etc/php/8.5/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/8.5/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/8.5/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10G/" /etc/php/8.5/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10G/" /etc/php/8.5/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/8.5/fpm/php.ini
sed -i "s/;cgi.fix_pathinfo.*/cgi.fix_pathinfo=0/" /etc/php/8.5/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.validate_timestamps=.*/opcache.validate_timestamps=1/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=256/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=64/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=100000/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=0/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/8.5/fpm/php.ini
sed -i "s/;opcache.huge_code_pages=.*/opcache.huge_code_pages=0/" /etc/php/8.5/fpm/php.ini
sed -i "s/session.gc_maxlifetime =.*/session.gc_maxlifetime = 36000/" /etc/php/8.5/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/8.5/fpm/php-fpm.conf
sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/8.5/fpm/php-fpm.conf
sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/8.5/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/8.5/mods-available/apcu.ini
# sed -i 's/opcache.jit=off/opcache.jit=on/' /etc/php/8.5/mods-available/opcache.ini
# sed -i '$aopcache.jit=1255' /etc/php/8.5/mods-available/opcache.ini
# sed -i '$aopcache.jit_buffer_size=256M' /etc/php/8.5/mods-available/opcache.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-7/policy.xml
sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-7/policy.xml
sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-7/policy.xml
sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-7/policy.xml
sed -i '$a[mysql]' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.allow_local_infile=On' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.allow_persistent=On' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.cache_size=2000' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.max_persistent=-1' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.max_links=-1' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.default_port=3306' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.connect_timeout=60' /etc/php/8.5/mods-available/mysqli.ini
sed -i '$amysql.trace_mode=Off' /etc/php/8.5/mods-available/mysqli.ini
und starten PHP sowie den Webserver nginx neu:
systemctl restart php8.5-fpm.service nginx.service
Auch PHP ist nun bereits installiert und für den Betrieb der Nextcloud optimiert. Starten wir nun mit der Installation und konfiguration des Datenbankserver MariaDB.
3. Installation und Konfiguration von MariaDB 11.8
Die Installation von MariaDB erfolgt mit diesem Befehl:
apt update && apt install -y mariadb-server
Härten wir nun den Datenbankserver mittels des mitgelieferten Tools „mysql_secure_installation“. Bei einer Erstinstallation besteht kein Rootpasswort, so dass Sie die Abfrage mit ENTER bestätigen könne. Es wird empfohlen, ein Passwort direkt zu setzen, der entsprechende Dialog erscheint automatisch:
mariadb-secure-installation
Enter current password for root (enter for none): <ENTER> or type the password
Switch to unix_socket authentication [Y/n] Y
Change the root password? [Y/n] Y
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
Stoppen Sie nun den Datenbankserver, sichern dann die Standardkonfiguration, um unmittelbar danach Anpassungen vornehmen zu können:
systemctl stop mariadb-server cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak cat <<EOF >/etc/mysql/my.cnf [client] default-character-set = utf8mb4 port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld_safe] log_error=/var/log/mysql/mysql_error.log nice = 0 socket = /var/run/mysqld/mysqld.sock [mysqld] # performance_schema=ON basedir = /usr bind-address = 127.0.0.1 binlog_format = ROW character-set-server = utf8mb4 collation-server = utf8mb4_general_ci datadir = /var/lib/mariadb default_storage_engine = InnoDB expire_logs_days = 2 slave_connections_needed_for_purge = 0 general_log_file = /var/log/mysql/mysql.log innodb_buffer_pool_size = 1G innodb_log_buffer_size = 32M innodb_log_file_size = 512M innodb_read_only_compressed=OFF join_buffer_size = 2M key_buffer_size = 512M lc_messages_dir = /usr/share/mysql lc_messages = en_US log_bin = /var/log/mysql/mariadb-bin log_bin_index = /var/log/mysql/mariadb-bin.index log_bin_trust_function_creators = true log_error = /var/log/mysql/mysql_error.log log_slow_verbosity = query_plan log_warnings = 2 long_query_time = 1 max_connections = 100 max_heap_table_size = 64M max_allowed_packet = 512M max-binlog-size = 512M max_binlog_total_size = 2G myisam_sort_buffer_size = 512M port = 3306 pid-file = /var/run/mysqld/mysqld.pid query_cache_limit = 0 query_cache_size = 0 read_buffer_size = 2M read_rnd_buffer_size = 2M skip-name-resolve socket = /var/run/mysqld/mysqld.sock sort_buffer_size = 2M table_open_cache = 400 table_definition_cache = 800 tmp_table_size = 32M tmpdir = /tmp transaction_isolation = READ-COMMITTED user = mysql wait_timeout = 600 [mariadb-dump] max_allowed_packet = 512M quick quote-names [isamchk] key_buffer = 16M EOF mkdir -p /var/log/mysql chown -R mysql:mysql /var/log/mysql systemctl restart mariadb.service
Erstellen Sie nun die Nextcloud-Datenbank, den Nextcloud-Benutzer und sein Passwort:
mariadb -uroot -p -e "CREATE DATABASE nextclouddb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER nextclouddbuser@localhost identified by 'nextclouddbpassword'; GRANT ALL PRIVILEGES on nextclouddb.* to nextclouddbuser@localhost; FLUSH privileges;"
Erläuterung (bitte frei nach Ihren Wünschen anpassen):
Datenbankname: nextclouddb
Datenbankbenutzer: nextclouddbuser
Datenbankbenutzerpaßwort: nextclouddbpassword
Überprüfen Sie die neue Datenbank:
mariadb -e "SELECT @@TX_ISOLATION; SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='nextclouddb'"
Erscheint in der Ausgabe (resultset) „READ-COMMITTED“ und „utf8mb4_general_ci“ so wurde alles korrekt eingerichtet und wir können mit der Installation von Redis fortfahren.
4. Installation und Konfiguration von Redis v. 8
Wir installieren und optimieren den Redis-Server um die Nextcloudperformance zu steigern, da durch Redis die Last auf der MariaDB-Nextclouddatenbank signifikant reduziert wird:
apt update && apt install -y redis-server redis-tools --allow-change-held-packages
cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sed -i 's/port 6379/port 0/' /etc/redis/redis.conf
sed -i 's/\# unixsocket\ .*$/unixsocket \/var\/run\/redis\/redis-server.sock/' /etc/redis/redis.conf
sed -i 's/\#\ unixsocketperm\ .*$/unixsocketperm 770/g' /etc/redis/redis.conf
sed -i 's/# maxclients\ .*$/maxclients 10240/' /etc/redis/redis.conf
sed -i "s/\# requirepass foobared/requirepass REDISPASSWORD/" /etc/redis/redis.conf
usermod -aG redis www-data
touch /etc/sysctl.d/99-redis.conf
cat <<EOF >/etc/sysctl.d/99-redis.conf
vm.overcommit_memory = 1
EOF
Stellen wir nun abschließend sicher, dass alle zuvor installierten Dienste auch bei einem Serverneustart automatisch gestartet werden:
systemctl enable mariadb.service redis-server.service php8.5-fpm.service nginx.service && systemctl restart mariadb.service redis-server.service php8.5-fpm.service nginx.service
Gratulation, der Server ist bereits vollständig mit nginx, PHP8.5, MariaDB und Redis installiert, eingerichtet und optimiert! Wir können nun mit der Einrichtung der Nextcloud beginnen.
5. Installation und Optimierung der Nextcloud (inkl. SSL)
Wir richten nun verschiedene vHosts, also Webserverkonfigurationsdateien, ein und modifizieren die Standard vHost-Datei (default.conf) so, dass diese auch durch spätere Systemupdates nicht automatisch verändert werden kann. Sichern Sie die Standard vhost-Datei namens default.conf und legen zuerst leere vHost-Dateien zum Konfigurieren an.
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
touch /etc/nginx/conf.d/default.conf
touch /etc/nginx/conf.d/http.conf
touch /etc/nginx/conf.d/nextcloud.conf
cat <<EOF >/etc/nginx/conf.d/http.conf
upstream php-handler {
server unix:/run/php/php8.5-fpm.sock;
}
map \$arg_v \$asset_immutable {
"" "";
default "immutable";
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 192.168.30.198 ihre.domain.de;
root /var/www;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
location / {
return 301 https://\$host\$request_uri;
}
}
EOF
cat <<EOF >/etc/nginx/conf.d/nextcloud.conf
limit_req_zone \$binary_remote_addr zone=NextcloudRateLimit:10m rate=2r/s;
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name 192.168.30.198 ihre.domain.de;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_trusted_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
#ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve X448:secp521r1:secp384r1;
ssl_prefer_server_ciphers on;
client_max_body_size 10G;
client_body_timeout 3600s;
client_body_buffer_size 512k;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
add_header Permissions-Policy "interest-cohort=()";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
include mime.types;
types {
text/javascript mjs;
}
root /var/www/nextcloud;
index index.php index.html /index.php\$request_uri;
location = / {
if ( \$http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/\$is_args\$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files \$uri \$uri/ =404; }
location /.well-known/pki-validation { try_files \$uri \$uri/ =404; }
return 301 /index.php\$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:\$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location ~ \.php(?:\$|/) {
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php\$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)\$;
set \$path_info \$fastcgi_path_info;
try_files \$fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
fastcgi_param PATH_INFO \$path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering on;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ {
try_files \$uri /index.php\$request_uri;
add_header Cache-Control "public, max-age=15778463, \$asset_immutable";
add_header Permissions-Policy "interest-cohort=()";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header X-XSS-Protection "1; mode=block" always;
expires 6M;
access_log off;
location ~ \.wasm\$ {
default_type application/wasm;
}
}
location ~ \.(otf|woff2?)$ {
try_files \$uri /index.php\$request_uri;
expires 7d;
access_log off;
}
location /remote {
return 301 /remote.php\$request_uri;
}
location /login {
limit_req zone=NextcloudRateLimit burst=5 nodelay;
limit_req_status 429;
try_files \$uri \$uri/ /index.php\$request_uri;
}
location / {
try_files \$uri \$uri/ /index.php\$request_uri;
}
}
EOF
HINWEIS: Nur für Cyberduck- bzw. Mountain Duck – Nutzer
Bitte diese Anpassungen vornehmen
nano /etc/nginx/conf.d/nextcloud.conf
[...]
# fastcgi_max_temp_file_size 0;
fastcgi_max_temp_file_size 10240M;
[...]
Quelle: https://docs.cyberduck.io/mountainduck/issues/fastcgi/#nginx
HINWEIS – ENDE
Erweitern Sie die Server- und Systemsicherheit durch die Möglichkeit des sicheren Schlüsselaustauschs mittels eines Diffie-Hellman Schlüssels:
openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Bitte haben Sie nun Geduld! Das Generieren kann – in Abhängigkeit von der Systemleistung – einige Minuten dauern. Erst wenn das Generieren abgeschlossen ist, starten wir den Webserver erneut durch.
systemctl restart nginx.service
Wir beginnen nun die ‚eigentliche‘ Installation der Nextcloud Software und richten dafür die SSL Zertifikate von Let’s Encrypt mittels acme ein. Wechseln Sie dafür in das Arbeitsverzeichnis
cd /usr/local/src
und laden das aktuellste Nextcloud-Release
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
wget https://download.nextcloud.com/server/releases/latest.tar.bz2.md5
Überpüfen Sie die Dateien:
md5sum --ignore-missing -c latest.tar.bz2.md5 < latest.tar.bz2
Nur wenn Ihnen der Test mit
latest.tar.bz2: OK
bestätigt wird, fahren wir fort. Entpacken Sie dann die Nextcloud Software in das Webverzeichnis (/var/www), setzen dann die notwendigen Berechtigung und Löschen die heruntergeladenen Dateien:
tar -xjf latest.tar.bz2 -C /var/www && chown -R www-data:www-data /var/www/ && rm -f latest.tar.bz2 latest.tar.bz2.md5
Bitte stellen Sie sicher, dass Ihr Server sowohl über Port 80/TCP als auch über Port 443/TCP von außen erreichbar ist. Das Erstellen und Aktualisieren von Let’s Encryptzertifikaten erfolgt im Zuge dieser Anleitung zwingend über http und Port 80. Andere Möglichkeiten werden von uns im Artikel (Let’s Encrypt Zertifikate (RSA 4096 oder EC 384) ohne offene TCP-Ports 80 und 443 beantragen und erstellen beschrieben. Für das Zertifikatshandling erstellen wir nun einen dedizierten Benutzer und fügen diesen der www-data Gruppe hinzu:
adduser acmeuser --gecos "" --disabled-password
usermod -aG www-data acmeuser
Diesem technischen Benutzer erteilen wir noch die notwendigen Berechtigungen, um bei einer Zertifikatserneuerung den notwendigen Webserverstart initiieren zu können.
touch /etc/sudoers.d/acmeuser
cat <<EOF >/etc/sudoers.d/acmeuser
acmeuser ALL=NOPASSWD: /bin/systemctl reload nginx.service
EOF
Installieren Sie nun für den Benutzer acmeuser das acme.sh-Tool und aktivieren zudem das automatische Upgrade:
su - acmeuser -c "/usr/bin/curl https://get.acme.sh | sh"
su - acmeuser -c ".acme.sh/acme.sh --set-default-ca --server letsencrypt"
su - acmeuser -c ".acme.sh/acme.sh --upgrade --auto-upgrade"
Passen Sie die entsprechenden Datei- und Verzeichnisberechtigungen an, um die neuen Zertifikate darin speichern zu können:
chmod -R 775 /var/www/letsencrypt && chmod -R 770 /etc/letsencrypt && chown -R www-data:www-data /var/www/ /etc/letsencrypt
Wechseln Sie in die Shell des neuen acme-Benutzers
su - acmeuser
und beantragen dann die SSL-Zertifikate von Let’s Encrypt. Ersetzen Sie dafür bitte ihre.domain.de mit Ihrer „echten“ Domain:
acme.sh --issue -d ihre.domain.de --server letsencrypt --keylength ec-384 -w /var/www/letsencrypt --key-file /etc/letsencrypt/ecc-certs/privkey.pem --ca-file /etc/letsencrypt/ecc-certs/chain.pem --cert-file /etc/letsencrypt/ecc-certs/cert.pem --fullchain-file /etc/letsencrypt/ecc-certs/fullchain.pem --reloadcmd "sudo /bin/systemctl reload nginx.service"
Verlassen Sie die Shell des acme-Benutzers
exit
und legen sich dann ein Skript an, das zukünftig die Berechtigungen überprüft und korrigiert (permissions.sh):
nano /root/permissions.sh
Kopieren Sie alle Zeilen in die Datei:
#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
if [ -d "/var/www/nextcloud/apps/notify_push" ]; then
chmod ug+x /var/www/nextcloud/apps/notify_push/bin/x86_64/notify_push
fi
chmod -R 775 /var/www/letsencrypt
chmod -R 770 /etc/letsencrypt
chown -R www-data:www-data /var/www /etc/letsencrypt
chown -R www-data:www-data /var/nc_data
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
exit 0
Markieren Sie das Skript als ausführbar und führen es dann direkt aus:
chmod +x /root/permissions.sh
/root/permissions.sh
Entfernen Sie Ihre bisher verwendeten Self-Signed-Zertifikate aus nginx und aktivieren Sie die neuen, vollwertigen und bereits gültigen SSL Zertifikate von Let’s Encrypt. Starten Sie dann den Webserver neu:
sed -i '/ssl-cert-snakeoil/d' /etc/nginx/conf.d/nextcloud.conf
sed -i s/#\ssl/\ssl/g /etc/nginx/conf.d/nextcloud.conf
systemctl restart nginx.service
Um sowohl die SSL-Zertifikate automatisch zu erneuern, als auch den notwendigen Webserverneustart zu initiieren, wurde automatisch ein Cronjob angelegt, den Sie nachfolgend einsehen können:
crontab -l -u acmeuser
Wir können nun mit der Einrichtung der Nextcloud selbst fortfahren. Dazu verwenden Sie den nachfolgenden „silent“ Installationsbefehl:
sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextclouddb" --database-user "nextclouddbuser" --database-pass "nextclouddbpassword" --admin-user "YourNextcloudAdmin" --admin-pass "YourNextcloudAdminPasssword" --data-dir "/var/nc_data"
Erläuterungen:
database-name „nextclouddb“ : Datenbankname aus Kapitel 3
database-user “nextclouddbuser” : Datenbankbenutzer aus Kapitel 3
database-pass “nextclouddbpassword” : Datenbankbenutzerpasswort aus Kapitel 3
admin-user “YourNextcloudAdmin” : frei wählbar von Ihnen
admin-pass “YourNextcloudAdminPasssword” : frei wählbar von Ihnen
Warten Sie bis die Installation der Nextcloud abgeschlossen wurde und passen dann die zentrale Konfigurationsdatei der Nextcloud „config.php“ als Webuser www-data an:
1. Fügen Sie Ihre Domain und die IP des Servers als „trusted domain“ hinzu, ergänzen Sie dabei ihre.domain.de und y.x.y.z mit Ihrer dedizierten Domain:
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value=w.x.y.z
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=ihre.domain.de
2. Setzen Sie Ihre Domain als overwrite.cli.url und overwritehost, ergänzen Sie dabei ihre.domain.de mit Ihrer dedizierten Domain:
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://ihre.domain.de
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwritehost --value=ihre.domain.de
Nun erweitern wir abschließend die Nextcloud Konfiguration. Sichern Sie dazu zuerst die bestehende config.php
sudo -u www-data cp /var/www/nextcloud/config/config.php /var/www/nextcloud/config/config.php.bak
und führen dann die nachfolgenden Zeilen in einem Block aus:
sed -i '/);/d' /var/www/nextcloud/config/config.php
cat <<EOF >>/var/www/nextcloud/config/config.php
'activity_expire_days' => 14,
'allow_local_remote_servers' => true,
'auth.bruteforce.protection.enabled' => true,
'forbidden_filenames' =>
array (
0 => '.htaccess',
1 => 'Thumbs.db',
2 => 'thumbs.db',
),
'cron_log' => true,
'default_phone_region' => 'DE',
'enable_previews' => true,
'enabledPreviewProviders' =>
array (
0 => 'OC\\Preview\\PNG',
1 => 'OC\\Preview\\JPEG',
2 => 'OC\\Preview\\GIF',
3 => 'OC\\Preview\\BMP',
4 => 'OC\\Preview\\XBitmap',
5 => 'OC\\Preview\\Movie',
6 => 'OC\\Preview\\PDF',
7 => 'OC\\Preview\\MP3',
8 => 'OC\\Preview\\TXT',
9 => 'OC\\Preview\\MarkDown',
10 => 'OC\\Preview\\HEIC',
11 => 'OC\\Preview\\Movie',
12 => 'OC\\Preview\\MKV',
13 => 'OC\\Preview\\MP4',
14 => 'OC\\Preview\\AVI',
),
'filesystem_check_changes' => 0,
'filelocking.enabled' => 'true',
'htaccess.RewriteBase' => '/',
'integrity.check.disabled' => false,
'knowledgebaseenabled' => false,
'log_rotate_size' => '104857600',
'logfile' => '/var/log/nextcloud/nextcloud.log',
'loglevel' => 2,
'logtimezone' => 'Europe/Berlin',
'remember_login_cookie_lifetime' => 36000,
'session_lifetime' => 36000,
'session_keepalive' => true,
'auto_logout' => true,
'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu',
'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',
'minimum.supported.desktop.version' => '33.0.2',
'overwriteprotocol' => 'https',
'preview_max_x' => 1024,
'preview_max_y' => 768,
'preview_max_scale_factor' => 1,
'profile.enabled' => false,
'redis' =>
array (
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'password' => 'REDISPASSWORD',
'timeout' => 0.5,
'dbindex' => 1,
),
'quota_include_external_storage' => false,
'share_folder' => '/Freigaben',
'skeletondirectory' => '',
'trashbin_retention_obligation' => 'auto, 7',
'maintenance_window_start' => 1,
'serverid' => '1',
);
EOF
sed -i 's/^[ ]*//' /var/www/nextcloud/config/config.php
Modifizieren Sie die „.user.ini“
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering=0/" /var/www/nextcloud/.user.ini
und passen die Nextcloud sowie die Nextcloud-Apps als user www-data an
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair --include-expensive
sudo -u www-data php /var/www/nextcloud/occ app:disable survey_client
sudo -u www-data php /var/www/nextcloud/occ app:disable firstrunwizard
sudo -u www-data php /var/www/nextcloud/occ app:disable app_api
sudo -u www-data php /var/www/nextcloud/occ app:disable logreader
sudo -u www-data php /var/www/nextcloud/occ config:app:set files_sharing hide_disabled_user_shares --value yes
Nextcloud ist ab sofort voll einsatzfähig, optimiert und abgesichert. Starten Sie alle relevanten Services neu:
systemctl restart mariadb.service redis-server.service php8.5-fpm.service nginx.service
Richten Sie einen Cronjob für Nextcloud als „www-data“ – Benutzer ein:
crontab -u www-data -e
Fügen Sie diese Zeile am Ende ein
*/5 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1
Speichern und schließen Sie dann die Datei und konfigurieren Sie den Nextcloud-Job von „Ajax“ zu „Cron“ mittels der Nextclouds CLI um:
sudo -u www-data php /var/www/nextcloud/occ background:cron
Bitte nehmen Sie sich etwas Zeit und überprüfen den Sicherheitsstatus Ihres Servers. Das Ziel sollte sein, mindestens die nachfolgend dargestellten „A+“-Ergebnisse in den Tests zu erzielen:
https://www.ssllabs.com/ssltest/index.html

und https://observatory.mozilla.org/

Um Schwierigkeiten zu vermeiden, die aus Aktualisierungen der verwendeten Komponenten resultieren können, lassen sich die relevanten Pakete mittels „apt-mark hold“ vom turnusmäßigen Aktualisieren ausschließen:
apt-mark hold nginx* nginx-*
apt-mark hold redis-*
apt-mark hold mariadb-* mariadb* mysql-* mysql* galera-*
apt-mark hold php-* php8.5-*
Um diese Pakete im Rahmen von Aktualisierungen wieder zu berücksichtigen muss nur das „hold“ aufgehoben werden:
apt-mark unhold nginx* nginx-*
apt-mark unhold redis-*
apt-mark unhold mariadb-* mariadb* mysql-* mysql* galera-*
apt-mark unhold php-* php8.5-*
Nach der Aktualisierung empfehlen wir ein erneutes setzen auf ‚hold‘.
6. Systemhärtung (crowdsec IPS, fail2ban und ufw)
Zuerst installieren wir crowdsec um den Server gegen Brute-force-Attacken und fehlerhafte Loginversuche zu schützen. Richten Sie dafür das Repository ein:
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
Da für Ubuntu 26 zum Zeitpunkt der Erstellung des Artikels noch kein Repository zur Verfügung steht, passen wir das source-File an:
sed -i 's/resolute/noble/' /etc/apt/sources.list.d/crowdsec_crowdsec.list
DIese Anpassung kann nach Bereitstellung des Repositorys umgehend rückgängig gemacht werden. Führen wir nun die Installation aus
apt update && install -y crowdsec crowdsec-firewall-bouncer
und stellen anschließend den „Autostart“ der CrowdSec-Software sicher:
systemctl enable --now crowdsec.service crowdsec-firewall-bouncer.service
Überprüfen wir nun, ob CrowdSec gestartet und auf Autostart („enabled“) steht:
systemctl status crowdsec.service crowdsec-firewall-bouncer.service
Um Ihren Cloudserver hinsichtlich NGINX- und Nextcloud-Attacken abzusichern fügen wir sowohl eine NGINX-, als auch Nextcloud- und SSH-Collections hinzu:
cscli collections install crowdsecurity/nginx
cscli parsers install crowdsecurity/nginx-logs
cscli scenarios install crowdsecurity/nginx-req-limit-exceeded
cscli collections install crowdsecurity/nextcloud
cscli collections install crowdsecurity/nextcloud
cscli scenarios install crowdsecurity/nextcloud-bf
cscli parsers install crowdsecurity/nextcloud-logs
cscli parsers install crowdsecurity/nextcloud-whitelist
cscli collections install crowdsecurity/sshd
cscli scenarios install crowdsecurity/ssh-bf
cscli scenarios install crowdsecurity/ssh-slow-bf
cscli parsers install crowdsecurity/sshd-success-logs
cscli parsers install crowdsecurity/sshd-logs
Passen Sie nun den Pfad des Nextcloud-Logfiles für crowdsec an:
touch /etc/crowdsec/acquis.d/setup.nextcloud.yaml
cat <<EOF >>/etc/crowdsec/acquis.d/setup.nextcloud.yaml
#Nextcloud by c-rieger.de
filenames:
- /var/log/nextcloud/nextcloud.log
labels:
type: Nextcloud
---
EOF
Um diese Erweiterungen wirksam werden zu lassen, führen wir noch diesen Befehl zum aktualisieren der Dienste aus:
systemctl daemon-reload && systemctl restart crowdsec.service crowdsec-firewall-bouncer.service
Lassen Sie sich nun die Collections anzeigen und prüfen, ob Nextcloud (Name: nextcloud), NGINX (Name: nginx) und SSH (Name: sshd) mit dem Status „enabled“ dargestellt werden. Ein Blick auf die Szenarien und Parser zeigt uns u.a. die neuen Erweiterungen an:
cscli collections list && cscli scenarios list && cscli parser list
Ab sofort ist Ihr System auf Angriffe wie bspw. Bruteforce-, DDOS- und ähnliche Szenarien vorbereitet und sperrt „kritisch aufgefallene“ IP’s automatisch für bspw. 4 Stunden für ihren Server. Dabei werden u.a. Angriffe auf Nextcloud (logins, Bruteforce u.v.m.), SSH und NGINX analysiert und interpretiert!
Ergänzend zu CrowdSec installieren wir fail2ban.
apt install -y fail2ban --allow-change-held-packages
touch /etc/fail2ban/filter.d/nextcloud.conf
touch /etc/fail2ban/jail.d/nextcloud.local
cat <<EOF >/etc/fail2ban/filter.d/nextcloud.conf
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
EOF
cat <<EOF >/etc/fail2ban/jail.d/nextcloud.local
[DEFAULT]
maxretry=3
bantime=1800
findtime = 1800
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 5
logpath = /var/log/nextcloud/nextcloud.log
[nginx-http-auth]
enabled = true
EOF
touch /var/log/nextcloud/nextcloud.log
chown -R www-data:www-data /var/log/nextcloud/$NEXTCLOUDDNS.log
systemctl enable --now fail2ban && systemctl restart fail2ban.service
Mittels der Befehle
fail2ban-client status
bzw. konkret
fail2ban-client status sshd && fail2ban-client status nextcloud
lassen sich die Zustände der fail2ban-Jails betrachten.
Installieren wir im Anschluß die serverseitige Firewall namens uncomplicated firewall (ufw). Sofern Sie zuvor den SSH-Port von 22 auf einen anderen Port geändert haben, so müssen Sie die 22 zwingend entsprechend ersetzen!
apt install -y ufw
ufw allow 80/tcp comment "LetsEncrypt (http)"
ufw allow 443/tcp comment "LetsEncrypt (https)"
ufw allow 22/tcp comment "SSH"
Möchten Sie SSH nicht nach außen freigeben (empfohlen!) und nur aus dem internen Netz nutzen, so ersetzen Sie den letzten ufw-Befehl (ufw allow 22/tcp) durch diesen und ersetzen das exemplarische Subnetz durch ihr Subnetz :
ufw allow proto tcp from w.x.y.0/24 to any port 22 comment "SSH nur aus dem LAN"
Setzen Sie das Firewall-Logging auf „medium“ und verhindern nicht definierte eingehende Verbindungen.
ufw logging medium
ufw default deny incoming
Aktivieren Sie die Firewall und starten diese neu:
ufw enable
systemctl restart ufw.service
ufw status verbose
Nextcloud kommuniziert mit verschiedenen Remote-Servern, um gewisse Information verarbeiten, austauschen und bereitstellen zu können:
- www.nextcloud.com, www.startpage.com, www.eff.org, www.edri.org for checking the internet connection
- apps.nextcloud.com for the available apps
- updates.nextcloud.com for Nextcloud updates
- lookup.nextcloud.com For updating and lookup in the federated sharing addressbook
- push-notifications.nextcloud.com for sending push notifications to mobile clients
- surveyserver.nextcloud.com if the admin has agreed to share anonymized data
- Any remote Nextcloud server that is connected with federated sharing
- …
Quelle: Nextcloud
7. Optimieren & aktualisieren der Nextcloud per Skript
Erstellen Sie ein Skript um den Server, die Nextcloud sowie die aktivierten Apps zu aktualisieren und zu optimieren:
cd /root
wget -O update.sh -q https://codeberg.org/criegerde/nextcloud/raw/branch/master/skripte/update.sh
Alternativ steht Ihnen auch ein Updateskript inklusive der Nextcloud-Office-Docker-Aktualisierung zur Verfügung.
wget -O update.sh -q https://codeberg.org/criegerde/nextcloud/raw/branch/master/skripte/update-nc-office.sh
Markieren Sie das Skript als ausführbar und führen Sie es als privilegierter Benutzer regelmäßig aus.
chmod +x /root/update.sh
Sofern Sie bei der Installation abweichende Pfade oder Softwareversionen verwendet haben, so passen Sie das Skript bitte noch an:
/root/update.sh
Weiterführende Herstellerinformationen:
- Nextcloud Webseite
- Nextcloud Dokumentation
- Nextcloud app store
- Nextcloud Vergleichsmatrix
- Nextcloud Installationsquellen
- Nextcloud Changelog und Archiv
- nginx Webseite
- PHP time zones
- MariaDB Server Documentation
- Certbot
- Lets Encrypt
- ISO Alpha-2 country codes (‚default_phone_region‘ => ‚DE‘,)
8. (optional) Nextcloud High Performance Backend für Dateien
Wir beginnen mit der Einrichtung des High Performance Backends für Dateien und wechseln dafür in den Nextcloud App Store. In der Kategorie Werkzeuge findet man die App Client Push.
Alternativ können Sie die App auch über die Kommandozeile installieren:
sudo -u www-data php /var/www/nextcloud/occ app:enable notify_push
Nach der Installation und Aktivierung über den App Store sind die Tätigkeiten in der Nextcloud-Oberfläche bereits abgeschlossen. Weiter geht es hier auf der Kommandozeile des Servers.Als erstes braucht der virtuelle Host für Nextcloud eine kleine Erweiterung
nano /etc/nginx/conf.d/nextcloud.conf
Am Ende der Datei fügen wir die roten Zeilen hinzu:
[...]
location / {
try_files $uri $uri/ /index.php$request_uri;
add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400' always;
}
location ^~ /push/ {
proxy_pass http://127.0.0.1:7867/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Starten Sie den Webserver neu:
systemctl restart nginx.service
Das Setup des High Performance Backends für Dateien wird dann über OCC aufgerufen:
cd /var/www/nextcloud
sudo -u www-data php occ notify_push:setup
Sofern die die Konfiguration valide ist, werden weitere Anweisungen angezeigt, um eine systemd Unit für das Nextcloud High Performance Backend für Dateien anzulegen. Dazu öffnen wir eine weitere, zusätzliche SSH-Session und erstellen den Service:
nano /etc/systemd/system/notify_push.service
[Unit]
Description = Push daemon for Nextcloud clients
After=nginx.service php8.3-fpm.service mariadb.service redis-server.service
[Service]
Environment=PORT=7867
Environment=NEXTCLOUD_URL=https://ihre.domain.de
ExecStart=/var/www/nextcloud/apps/notify_push/bin/x86_64/notify_push /var/www/nextcloud/config/config.php
User=www-data
[Install]
WantedBy = multi-user.target
Der Service wird anschließend aktiviert und gestartet:
systemctl daemon-reload
systemctl enable --now notify_push
Sofern der Dienst korrekt gestartet wurde wechseln wir in die erste SSH Session zurück und bestätigen den Dialog mit ENTER. Sollten app-Updates kommen, so wird ein Serviceneustart benötigt.
systemctl restart notify_push.service
Die Konfiguration können Sie wie folgt verifizieren:
sudo -u www-data php occ notify_push:setup https://ihre.domain.de/push
Um die Funktionalität des Nextcloud HPB für Dateien zu überprüfen, laden Sie sich den Nextcloud-„test_client“ herunter
wget -O test_client -q https://github.com/nextcloud/notify_push/releases/download/v0.6.11/test_client-x86_64-unknown-linux-musl
und starten diesen gefolgt von Ihrer Domain, dem Benutzer und dem dazugehörigen Passwort. Ist bereits 2FA aktiv, so nutzen Sie ein App-Passwort.
chmod +x test_client
./test_client https://<ihre.domain.de> <Nextcloud-Benutzername> <(App-)Passwort>
und laden bspw. eine Datei in Ihre Cloud hoch. Sehen Sie dann im Nextcloud test_client-Tool Aktivitäten, so funktioniert das Nextcloud HPB für Dateien. Löschen Sie im Anschluß an Ihre Tests den Client, um spätere Probleme beim Aktualisieren der Nextcloud zu vermeiden.
rm -f test_client
Die Einrichtung des High Performance Backends für Dateien ist somit erfolgreich abgeschlossen.
9. (optional) bash_aliases und empfohlene Settings (config.php)
Passen Sie die Datei /root/bash_aliases an, um das Nextcloud Toolset occ direkt mittels nocc starten zu können
if [ ! -f /root/.bash_aliases ]; then touch /root/.bash_aliases; fi
cat <<EOF >> /root/.bash_aliases
alias nocc="sudo -u www-data php /var/www/nextcloud/occ"
EOF
source /root/.bash_aliases
Ab sofort können Sie als priviligierter Benutzer (sudo -s) die Nextcloud occ-Tools direkt per „nocc … “ ausführen, bspw:
nocc app:list
um sich bspw. alle aktivierten und deaktivierten Apps Ihrer Nexctloud anzeigen zu lassen. Wir empfehlen folgende Settings zu setzen:
nocc config:system:set remember_login_cookie_lifetime --value="3600"
nocc config:system:set log_rotate_size --value="104857600"
nocc config:system:set trashbin_retention_obligation --value="auto, 7"
nocc config:system:set versions_retention_obligation --value="auto, 365"
nocc config:system:set simpleSignUpLink.shown --type=bool --value=false
nocc config:system:set upgrade.disable-web --type=bool --value=true
nocc config:app:set text workspace_available --value=0
nocc config:system:set loglevel --value="2"
nocc config:app:set settings profile_enabled_by_default --value="0"
#nocc app:enable admin_audit
#nocc config:app:set admin_audit logfile --value="/var/log/nextcloud/audit.log"
#nocc config:system:set log.condition apps 0 --value admin_audit
Chunk-Größe setzen oder mit ‚0‘ deaktivieren
nocc config:app:set files max_chunk_size --value="104857600"
oder
nocc config:app:set files max_chunk_size --value 0
Um das Session-/Anmeldeverhalten zu verändern, können Sie diese Einstellungen in der config.php und php.ini wie exemplarisch gezeigt anpassen. Die Berechnung erfolgt bspw. so: 60s*60m*2h = 7200
nano /var/www/nextcloud/config/config.php
[...]
'remember_login_cookie_lifetime' => 7200,
'session_lifetime' => 7200,
'session_keepalive' => true,
'auto_logout' => true,
[...]
nano /etc/php/8.5/fpm/php.ini
[...]
session.gc_maxlifetime = 7200
[...]
Starten Sie die Dienste neu, um das Logoutverhalten zu aktivieren
systemctl restart php8.5-fpm.service nginx.service
Eine weiterführende Übersicht an Nextcloud-Einstellungen finden Sie hier.
Um die manuelle Logrotation einzurichten, bspw. für die nextcloud.log und audit.log Dateien, gehen Sie wie folgt vor:
sed -i '/log_rotate_size/d' /var/www/nextcloud/config/config.php
nocc config:system:set log_rotate_size --value="0"
nano /etc/logrotate.d/nextcloud-audit
Fügen Sie alles Nachfolgende hinzu, speichern und verlassen dann diese Datei:
/var/log/nextcloud/*.log {
su root adm
size 100M
missingok
rotate 30
compress
delaycompress
notifempty
sharedscripts
}
Um das Logrotating zu testen bzw. initial zu starten und auszuführen können Sie folgende Befehle nutzen:
logrotate -d /etc/logrotate.d/nextcloud-audit
logrotate --force /etc/logrotate.d/nextcloud-audit
Das Logrotating wurde somit systemseitig eingestellt und Nextcloud-seitig deaktiviert.
10. (optional): Verbesserung der Sicherheit und Performance des TCP-Stacks
Die empfohlene Anpassungen sind nachfolgend aufgelistet. Wie sie diese Werte auf einmal setzen, das wird im Anschluß beschrieben:
# Schutz gegen IP-Spoofing (IPv4 und IPv6)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
# Schutz gegen TCP-SYN-Flooding (IPv4)
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2
net.core.somaxconn = 1024
# ICMP Echo Ignore Broadcasts (IPv4)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# ICMP Redirects deaktivieren (IPv4 und IPv6)
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Sourcen-Routing deaktivieren (IPv4 und IPv6)
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
# TCP-Timestamps deaktivieren (IPv4)
net.ipv4.tcp_timestamps = 0
# Loggen von Martian-Paketen (IPv4 und IPv6)
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv6.conf.all.log_martians = 1
net.ipv6.conf.default.log_martians = 1
# Maximale Anzahl von halb offenen Verbindungen (IPv4)
net.ipv4.tcp_max_syn_backlog = 4096
# Netzwerkspeichergrößen erhöhen (IPv4 und IPv6)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.optmem_max = 40960
# Maximale Anzahl von Verbindungstrackings erhöhen (IPv4 und IPv6)
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_tcp_timeout_established = 1800
# Maximaler Backlog für Netzwerkgeräte erhöhen (IPv4 und IPv6)
net.core.netdev_max_backlog = 5000
# TCP-Verbindungseinstellungen optimieren (IPv4)
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15
# Datei-Deskriptor-Limits erhöhen
fs.file-max = 2097152
# TCP-Warteschlangen (Read/Write Queues) erhöhen (IPv4)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP-Window-Scaling aktivieren (IPv4)
net.ipv4.tcp_window_scaling = 1
# TCP-Memory-Management optimieren (IPv4)
net.ipv4.tcp_mem = 50576 64768 98152
# Reverse Path Filtering aktivieren (IPv4 und IPv6)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv6.conf.all.rp_filter = 1
net.ipv6.conf.default.rp_filter = 1
# TCP Fast Open aktivieren (optional, IPv4)
net.ipv4.tcp_fastopen = 3
# ARP-Caching verbessern (IPv4)
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 2048
net.ipv4.neigh.default.gc_thresh3 = 4096
Um die zuvor beschriebenen Einstellungen zur Härtung und Optimierung des TCP-Stacks umzusetzen können führen Sie folgenden Befehl aus:
wget -O /etc/sysctl.d/100-nextcloud.conf -q https://codeberg.org/criegerde/nextcloud/raw/branch/master/etc/sysctl.d/100-nextcloud.conf
Nachdem die Datei heruntergeladen wurde starten Sie den Server einmalig neu.
reboot now
Sie können nach dem Neustart alle Werte wie folgt überprüfen:
sudo -s
sysctl -A
Möchten Sie diese Einstellungen rückgängig machen, so benennen Sie die Datei bspw. in disabled um
mv /etc/sysctl.d/100-nextcloud.conf /etc/sysctl.d/100-nextcloud.conf.disabled
und starten anschleßend den Server neu.
Über Ihre Unterstützung würden wir uns sehr freuen – vorab vielen und herzlichen Dank dafür.
