Diese ownCloud Installationsanleitung beschreibt die Installation, Konfiguration und Härtung, das Monitoring sowie einige Erweiterungsmöglichkeiten von ownCloud auf einem Ubuntu Server 20.04.x LTS Focal Fossa bzw. Debian Server 11 bullseye. Die Installation basiert dabei auf den Komponenten nginx 1.21.x mainline, Let’s Encrypt TLS 1.3, MariaDB 10.6.x, PHP 7.4.x, Redis, Fail2ban, ufw sowie Netdata und erhält abschließend von Qualys SSL Labs eine A+ Sicherheitsbewertung. Im Verlauf dieser Anleitung müssen Sie nur die rot markierten Werte wie bspw. ihre.domain.de oder 192.168.2.x mit den entsprechenden Werten Ihres Systems ersetzen.
Inhaltsverzeichnis
- Vorbereitungen und Installation des nginx Webservers
- Installation und Konfiguration von PHP 7.4
- Installation und Konfiguration des Datenbankservers MariaDB 10.6
- Installation des Redis-server („in-memory-Datenbank“)
- Installation und Optimierung der ownCloud (inkl. SSL)
- Systemhärtung (fail2ban und ufw)
- optional: bash_alias für php occ und empfohlene Settings (config.php)
Systemvorausetzungen seitens ownCloud
https://doc.owncloud.com/server/10.9/admin_manual/installation/system_requirements.html
1. Vorbereitungen und Installation des nginx Webserver
Aktuelle Installationsmedien für den zugrundeliegenden Linux-Server erhalten Sie hier:
Ubuntu 20.04.x LTS:Voraussetzungen Download-Installationsmedium - SSH wird vorausgesetzt (s. Bild zuvor)
Debian 11.x: Voraussetzungen Download-Installationsmedium - Standardsystemwerkzeuge u. SSH werden vorausgesetzt (s. Bild zuvor) su - apt install -y sudo usermod -aG sudo <aktueller Benutzer> exit
Debian und Ubuntu Server:
Wechseln Sie in den privilegierten Benutzermodus
sudo -s
um die folgenden Softwarepakete, als notwendige Grundlage des Serverbetriebs, zu installieren:
apt update -q4 && apt install -y curl gnupg2 git lsb-release ssl-cert ca-certificates apt-transport-https tree locate software-properties-common dirmngr screen htop net-tools zip unzip bzip2 ffmpeg ghostscript libfile-fcntllock-perl libfontconfig1 libfuse2 socat
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:
127.0.0.1 localhost 127.0.1.1 ihre.domain.de ihre # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters <externe IP>ihre.domain.de
Geben Sie den korrekten 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
Überprüfen Sie, ob der Zeitserverdienst mit mindestens einem Endpunkt konfiguriert ist.
nano /etc/systemd/timesyncd.conf
Ist die Zeile NTP auskommentiert (#NTP=), so entfernen Sie das ‚#‘-Zeichen vor NTP und fügen Sie bspw. diese zwei Zeitserver hinzu:
NTP=ntp1.dismail.de ntp2.dismail.de
Speichern Sie diese Datei und starten den Zeitserver neu:
systemctl restart systemd-timesyncd
Starten Sie den Server neu
reboot now
und melden sich dann erneut mit priviligierten Benutzerrechten am Server an:
sudo -s
Fügen Sie dem System weitere Software-Repositories (Softwarequellen) hinzu, um die aktuellen Releases der jeweiligen Pakete installieren zu können. Wechseln Sie in das folgende Verzeichnis:
cd /etc/apt/sources.list.d
Nur Ubuntu Server (AMD64 und ARM64):
Korrigieren Sie, sofern notwendig, zuerst die DNS-Auflösung:
rm -f /etc/resolv.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf systemctl restart systemd-resolved.service
Tragen Sie die Softwarequellen für nginx und PHP ein:
echo "deb http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | tee nginx.list
echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu $(lsb_release -cs) main" | tee php.list
Um diesen Quellen vertrauen zu können nutzen wir die entsprechenden Schlüssel:
PHP-Key:
apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 4F4EA0AAE5267A6C
Nur Debian Server (AMD64):
Ergänzen Sie die Softwarequellen für nginx und PHP:
echo "deb [arch=amd64] http://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" | tee nginx.list
echo "deb [arch=amd64] https://packages.sury.org/php/ $(lsb_release -cs) main" | tee php.list
Um den jeweiligen Quellen vertrauen zu können nutzen wir die entsprechenden Schlüssel:
PHP-Key:
wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add -
Ab hier geht es wieder für beide Server-Betriebssysteme (Ubuntu und Debian) weiter:
Wir ergänzen die noch fehlenden Schlüssel für nginx und fügen die Quellen und den Key von MariaDB hinzu, aktualisieren das System und generieren im Anschluß daran sogenannte self-signed-Zertifikate, die im weiteren Verlauf durch vollwertige Zertifikate von Let’s Encrypt ersetzt werden.
NGINX-Key:
curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
MariaDB Repository und Key:
cd ~ wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup chmod +x mariadb_repo_setup ./mariadb_repo_setup --mariadb-server-version="mariadb-10.6"
Aktualisieren wir nun die Softwarequellen des Systems
apt update
make-ssl-cert generate-default-snakeoil -y
Um sicherzustellen, dass keine Relikte früherer Installationen den Betrieb des Webserver stören, entfernen wir diese:
apt remove nginx nginx-extras nginx-common nginx-full -y --allow-change-held-packages
Zudem stellen wir sicher, dass das Pendant (Apache2) zum nginx Webserver weder aktiv noch installiert ist.
systemctl stop apache2.service && systemctl disable apache2.service
Nun sind die Vorbereitungen zur Installation des Webservers abgeschlossen und wir können diesen mit dem nachfolgenden Befehl installieren
apt install -y nginx
und den Dienst zum automatischen Start nach einem Systemneustart mittels
systemctl enable nginx.service
einrichten. Mit Blick auf die späteren Anpassungen wird die Standardkonfiguration gesichert und eine neue Konfigurationsdatei geöffnet:
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 und ersetzen die rot markierten Werte entsprechend Ihres Systems:
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on; use epoll;
}
http {
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;
#optional, Sie können das eigene Subnetz ergänzen, bspw.:
# set_real_ip_from 192.168.2.0/24;
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 valid=30s;
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}
Speichern Sie die Datei und schließen Sie diese, um im Anschluß den Webserver neu zu starten:
service nginx restart
Vorbereitend für die SSL Zertifikate und die Webverzeichnisse legen wir vier Ordner an und setzen die korrekten Berechtigungen:
mkdir -p /var/oc_data /var/www/letsencrypt/.well-known/acme-challenge /etc/letsencrypt/rsa-certs /etc/letsencrypt/ecc-certs
chown -R www-data:www-data /var/oc_data /var/www
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 7.4 (fpm)
Das PHP Repository wurde bereits im vorherigen Kapitel eingerichtet und aktiviert, so dass wir direkt mit der Installation beginnen können.
apt update -q4 && apt install -y php7.4-{fpm,gd,mysql,curl,xml,zip,intl,mbstring,bz2,ldap,apcu,bcmath,gmp,imagick,igbinary,redis,smbclient,cli,common,opcache,readline} imagemagick
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/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/www.conf.bak cp /etc/php/7.4/fpm/php-fpm.conf /etc/php/7.4/fpm/php-fpm.conf.bak cp /etc/php/7.4/cli/php.ini /etc/php/7.4/cli/php.ini.bak cp /etc/php/7.4/fpm/php.ini /etc/php/7.4/fpm/php.ini.bak cp /etc/php/7.4/fpm/php-fpm.conf /etc/php/7.4/fpm/php-fpm.conf.bak cp /etc/php/7.4/mods-available/apcu.ini /etc/php/7.4/mods-available/apcu.ini.bak cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak
Um PHP an ihr System anzupassen werden einige Patameter berechnet, führen Sie die nachfolgenden Zeilen einfach aus:
AvailableRAM=$(awk '/MemAvailable/ {printf "%d", $2/1024}' /proc/meminfo)
AverageFPM=$(ps --no-headers -o 'rss,cmd' -C php-fpm7.4 | awk '{ sum+=$1 } END { printf ("%d\n", sum/NR/1024,"M") }')
FPMS=$((AvailableRAM/AverageFPM))
PMaxSS=$((FPMS*2/3))
PMinSS=$((PMaxSS/2))
PStartS=$(((PMaxSS+PMinSS)/2))
Führen Sie nun alle nachfolgenden Optimierungen durch:
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.4/fpm/pool.d/www.conf sed -i 's/pm.max_children =.*/pm.max_children = '$FPMS'/' /etc/php/7.4/fpm/pool.d/www.conf sed -i 's/pm.start_servers =.*/pm.start_servers = '$PStartS'/' /etc/php/7.4/fpm/pool.d/www.conf sed -i 's/pm.min_spare_servers =.*/pm.min_spare_servers = '$PMinSS'/' /etc/php/7.4/fpm/pool.d/www.conf sed -i 's/pm.max_spare_servers =.*/pm.max_spare_servers = '$PMaxSS'/' /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/;pm.max_requests =.*/pm.max_requests = 1000/" /etc/php/7.4/fpm/pool.d/www.conf sed -i "s/allow_url_fopen =.*/allow_url_fopen = 1/" /etc/php/7.4/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/cli/php.ini sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/cli/php.ini sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/cli/php.ini sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/cli/php.ini sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/cli/php.ini sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/7.4/fpm/php.ini sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/7.4/fpm/php.ini sed -i "s/max_execution_time =.*/max_execution_time = 3600/" /etc/php/7.4/fpm/php.ini sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.4/fpm/php.ini sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.4/fpm/php.ini sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.4/fpm/php.ini sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.4/fpm/php.ini sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.4/fpm/php.ini sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.4/fpm/php.ini
sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/7.4/fpm/php-fpm.conf sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/7.4/fpm/php-fpm.conf sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/7.4/fpm/php-fpm.conf
sed -i '$aapc.enable_cli=1' /etc/php/7.4/mods-available/apcu.ini
sed -i "s/rights=\"none\" pattern=\"PS\"/rights=\"read|write\" pattern=\"PS\"/" /etc/ImageMagick-6/policy.xml sed -i "s/rights=\"none\" pattern=\"EPS\"/rights=\"read|write\" pattern=\"EPS\"/" /etc/ImageMagick-6/policy.xml sed -i "s/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/" /etc/ImageMagick-6/policy.xml sed -i "s/rights=\"none\" pattern=\"XPS\"/rights=\"read|write\" pattern=\"XPS\"/" /etc/ImageMagick-6/policy.xml
Starten Sie nun beide Dienste, nginx und PHP, neu:
service php7.4-fpm restart
service nginx restart
Auch PHP ist nun bereits installiert und für ownCloud optimiert. Für weitere PHP-Optimierungen finden Sie in diesem Artikel weitere Tuningmöglichkeiten. Starten wir nun mit der Installation und konfiguration des Datenbankserver MariaDB.
3. Installation und Konfiguration von MariaDB 10.6
Die Installation von MariaDB erfolgt mit diesem befehl:
apt update -q4 && apt install -y mariadb-server
Wie erfolgt ein Upgrade von MariaDB v. 10.5 zu v. 10.6
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:
mysql_secure_installation
Enter current password for root (enter for none): <ENTER> or type the password
Switch to unix_socket authentication [Y/n] Y
Set 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 und sichern dann die Standardkonfiguration, um unmittelbar danach Anpassungen vornehmen zu können:
service mysql stop
mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak
nano /etc/mysql/my.cnf
Kopieren Sie alle nachfolgenden Zeilen in die leere Datei:
# MariaDB 10.6 [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] basedir = /usr bind-address = 127.0.0.1 binlog_format = ROW bulk_insert_buffer_size = 16M character-set-server = utf8mb4 collation-server = utf8mb4_general_ci concurrent_insert = 2 connect_timeout = 5 datadir = /var/lib/mysql default_storage_engine = InnoDB expire_logs_days = 2 general_log_file = /var/log/mysql/mysql.log general_log = 0 innodb_buffer_pool_size = 1024M innodb_buffer_pool_instances = 1 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 32M innodb_max_dirty_pages_pct = 90 innodb_file_per_table = 1 innodb_open_files = 400 innodb_io_capacity = 4000 innodb_flush_method = O_DIRECT # innodb_read_only_compressed=OFF # ab MariaDB v. 10.6 erforderlich key_buffer_size = 128M 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_error = /var/log/mysql/mysql_error.log log_slow_verbosity = query_plan log_warnings = 2 long_query_time = 1 max_allowed_packet = 16M max_binlog_size = 100M max_connections = 200 max_heap_table_size = 64M myisam_recover_options = BACKUP myisam_sort_buffer_size = 512M port = 3306 pid-file = /var/run/mysqld/mysqld.pid query_cache_limit = 2M query_cache_size = 64M query_cache_type = 1 query_cache_min_res_unit = 2k read_buffer_size = 2M read_rnd_buffer_size = 1M skip-external-locking skip-name-resolve slow_query_log_file = /var/log/mysql/mariadb-slow.log slow-query-log = 1 socket = /var/run/mysqld/mysqld.sock sort_buffer_size = 4M table_open_cache = 400 thread_cache_size = 128 tmp_table_size = 64M tmpdir = /tmp transaction_isolation = READ-COMMITTED #unix_socket=OFF user = mysql wait_timeout = 600 [mysqldump] max_allowed_packet = 16M quick quote-names [isamchk] key_buffer = 16M
Speichern und schließen Sie die Datei und starten dann den Datenbankserver neu, um die ownCloud Datenbank, den ownCloud Benutzer und sein Passworts einzurichten:
service mysql restart mysql -uroot -p
CREATE DATABASE ownclouddb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER ownclouddbuser@localhost identified by 'ownclouddbpassword'; GRANT ALL PRIVILEGES on ownclouddb.* to ownclouddbuser@localhost; FLUSH privileges; quit;
Erläuterung:
Datenbankname: ownclouddb
Datenbankbenutzer: ownclouddbuser
Datenbankbenutzerpaßwort: ownclouddbpassword
Überprüfen Sie, ob das Isolation-Level (read commit) und das Charset (utf8mb4) korrekt gesetzt wurden:
mysql -h localhost -uroot -p -e "SELECT @@TX_ISOLATION; SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='ownclouddb'"
Erscheint in der Ausgabe (resultset) „READ-COMMITTED“ und „utf8mb4_general_ci“ wurde alles korrekt eingerichtet und wir können mit der Installation von Redis fortfahren.
4. Installation und Konfiguration von Redis
Wir installieren den Redis-Server um die ownCloud Performance zu steigern, da durch Redis die Last auf der ownCloud Datenbank reduziert wird:
apt update -q4 && apt install -y redis-server
Passen Sie die Rediskonfiguration durch das Sichern und Anpassen der Konfiguration mittels Ausführen der nachfolgenden Befehle an:
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/g /etc/redis/redis.conf sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf sed -i "s/# maxclients 10000/maxclients 10240/" /etc/redis/redis.conf usermod -aG redis www-data
cp /etc/sysctl.conf /etc/sysctl.conf.bak sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf
Aus hinreichender Installationserfahrung heraus empfehle ich Ihnen, den gesamten Server einmalig neu zu starten:
reboot now
Gratulation, der Server ist bereits Installiert und eingerichtet, so dass nun mit der Einrichtung der ownCloud begonnen werden kann.
5. Installation und Optimierung der ownCloud (inkl. SSL)
Wir richten nun verschiedene vhost, also Serverkonfigurationsdateien, ein und modifizieren die Standard vhost-Datei persistent. Da das System zuvor neu gestartet wurde wechseln wir erneut in den privilegierten Benutzermodus, sichern die Standard vhost-Datei namens default.conf und legen leere vHost-Dateien zum Konfigurieren an.
sudo -s
[ -f /etc/nginx/conf.d/default.conf ] && 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/owncloud.conf
Somit ist durch die leere „default.conf“ Datei auch bei späteren Aktualisierungen des Webservers sichergestellt, dass diese Standardkonfiguration den ownCloud Betrieb nicht beeinflußt.
Erstellen Sie die globale vhost-Datei, um die http-Standardanfragen permanent auf https umzuleiten und zudem die SSL-Zertifikatskommunikation mit Let’sEncrypt zu ermöglichen.
nano /etc/nginx/conf.d/http.conf
Kopieren Sie alle nachfolgenden Zeilen in die Datei http.conf und passen die rot markierten Werte entsprechend Ihres Systems an:
upstream php-handler {
server unix:/run/php/php7.4-fpm.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 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;
}
}
Speichern und schließen Sie diese Datei. Bearbeiten Sie nun die eigentliche ownCloud vHost-Datei owncloud.conf, die sämtliche Konfigurationen für den Betrieb der ownCloud enthält.
nano /etc/nginx/conf.d/owncloud.conf
Kopieren Sie alle nachfolgenden Zeilen in die Datei owncloud.conf und passen den rot markierten Werte entsprechend Ihres Systems an:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 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/rsa-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/rsa-certs/privkey.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;
ssl_stapling on;
ssl_stapling_verify on;
client_max_body_size 10G;
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 application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
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 "none" always;
add_header X-XSS-Protection "1; mode=block" always;
root /var/www/owncloud/;
fastcgi_hide_header X-Powered-By;
fastcgi_ignore_headers X-Accel-Buffering;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
return 404;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
return 404;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri $uri/ =404;
index index.php;
}
location ~ \.(?:css|js)$ {
add_header Cache-Control "max-age=15778463";
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
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 "none" always;
add_header X-XSS-Protection "1; mode=block" always;
try_files $uri /index.php$uri$is_args$args;
access_log off;
}
location ~ \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg|map)$ {
add_header Cache-Control "public, max-age=7200";
try_files $uri /index.php$uri$is_args$args;
access_log off;
}
}
Speichern und schließen Sie diese Datei und erweitern dann die Server- und Systemsicherheit durch die Möglichkeit des sicheren Schlüsselaustauschs mittels eines Diffie-Hellman Schlüssels (dhparam.pem):
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.
service nginx restart
Wir beginnen nun die ‚eigentliche‘ Installation der ownCloud 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 aktuelle ownCloud Release herunter:
wget https://download.owncloud.org/community/owncloud-complete-20210721.zip
Entpacken Sie die owncloud Software in das Webverzeichnis (var/www), setzen dann die Berechtigung adäquat und Löschen die Download-Datei:
unzip owncloud-complete-20210721.zip && mv owncloud /var/www/ && chown -R www-data:www-data /var/www/ && rm -f latest.tar.bz2
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 zwingend über http und Port 80! Für das Zertifikatshandling erstellen wir nun einen dedizierten Benutzer und fügen diesen der www-data Gruppe hinzu:
adduser --disabled-login acmeuser
usermod -a -G www-data acmeuser
Diesem technischen Benutzer erteilen wir noch die notwendigen Berechtigungen, um bei einer Zertifikatserneuerung den notwendigen Webserverstart initiieren zu können.
visudo
In der Mitte der Datei, unterhalb von
[..] User privilege specification root ALL=(ALL:ALL) ALL [...]
tragen Sie die folgende Zeile ein:
acmeuser ALL=NOPASSWD: /bin/systemctl reload nginx.service
Mit STRG+X gefolgt von einem y speichern und verlassen Sie diese Datei.
Wechseln Sie in die Shell des neuen Benutzers (acmeuser) um die Zertifikatssoftware zu installieren und verlassen diese Shell danach wieder:
su - acmeuser
curl https://get.acme.sh | sh
exit
Passen Sie die entsprechenden Berechtigungen 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
Setzen Sie Let’s Encrypt als Standard CA für Ihren Server
su - acmeuser -c ".acme.sh/acme.sh --set-default-ca --server letsencrypt"
und wechseln dann erneut in die Shell des neuen Benutzers
su - acmeuser
Requestieren (beantragen) Sie nun die SSL-Zertifikate von Let’s Encrypt und ersetzen dabei ihre.domain.de mit Ihrer eigenen Domain :
acme.sh --issue -d ihre.domain.de --server letsencrypt --keylength 4096 -w /var/www/letsencrypt --key-file /etc/letsencrypt/rsa-certs/privkey.pem --ca-file /etc/letsencrypt/rsa-certs/chain.pem --cert-file /etc/letsencrypt/rsa-certs/cert.pem --fullchain-file /etc/letsencrypt/rsa-certs/fullchain.pem --reloadcmd "sudo /bin/systemctl reload nginx.service"
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 neuen Benutzers
exit
und legen sich dann ein Skript an, dass 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 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/oc_data chmod 0644 /var/www/owncloud/.htaccess chmod 0644 /var/www/owncloud/.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/owncloud.conf sed -i s/#\ssl/\ssl/g /etc/nginx/conf.d/owncloud.conf service nginx restart
Um sowohl die SSL-Zertifikate automatisch zu erneuern, als auch den notwendigen Webserverneustart zu initiieren, wurde automatisch ein Cronjob angelegt.
crontab -l -u acmeuser
Wir können nun mit der Einrichtung der ownCloud fortfahren. Dazu rufen wir den Browser auf
https://ihre.domain.de
und tragen die nachfolgenden Werte aus den vorherigen Kapiteln ein:
database-name „ownclouddb“ : Datenbankname aus Kapitel 3
database-user “ownclouddbuser” : Datenbankbenutzer aus Kapitel 3
database-pass “ownclouddbpassword” : Datenbankbenutzerpasswort aus Kapitel 3
admin-user “YourowncloudAdmin” : frei wählbar von Ihnen
admin-pass “YourowncloudAdminPasssword” : frei wählbar von Ihnen
Warten Sie bis die Installation der ownCloud abgeschlossen wurde und passen dann die zentrale Konfigurationsdatei der ownCloud „config.php“ in der Konsole als Benutzerwww-data weiter an:
1. Fügen Sie Ihre Domain als trusted domain hinzu, ergänzen Sie dabei ihre.domain.de mit Ihrer dedizierten Domain:
sudo -u www-data php /var/www/owncloud/occ config:system:set trusted_domains 0 --value=ihre.domain.de
2. Setzen Sie Ihre Domain als overwrite.cli.url, ergänzen Sie dabei ihre.domain.de mit Ihrer dedizierten Domain:
sudo -u www-data php /var/www/owncloud/occ config:system:set overwrite.cli.url --value=https://ihre.domain.de
Nun erweitern wir abschließend die ownCloud Konfiguration. Sichern Sie dazu zuerst die bestehende config.php und führen dann die nachfolgenden Zeilen in einem Block aus:
sudo -u www-data cp /var/www/owncloud/config/config.php /var/www/owncloud/config/config.php.bak
sudo -u www-data sed -i 's/^[ ]*//' /var/www/owncloud/config/config.php
sudo -u www-data sed -i '/);/d' /var/www/owncloud/config/config.php
sudo -u www-data cat <<EOF >>/var/www/owncloud/config/config.php 'filelocking.enabled' => 'true', 'logtimezone' => 'Europe/Berlin', 'log_rotate_size' => 104857600, 'maintenance' => false, 'memcache.local' => '\OC\Memcache\APCu', 'memcache.locking' => '\OC\Memcache\Redis', 'overwriteprotocol' => 'https', 'redis' => array ( 'host' => '/var/run/redis/redis-server.sock', 'port' => 0, 'timeout' => 0.5, ), ); EOF
Ihre ownCloud ist ab sofort voll einsatzfähig, optimiert und abgesichert. Starten Sie alle relevanten Services neu:
service nginx stop service php7.4-fpm stop service mysql restart service php7.4-fpm restart service redis-server restart service nginx restart
Richten Sie einen Cronjob für ownCloud als „www-data“ – Benutzer ein:
crontab -u www-data -e
Fügen Sie diese Zeile ein
*/5 * * * * php -f /var/www/owncloud/occ system:cron > /dev/null 2>&1
Speichern und schließen Sie dann die Datei und konfigurieren Sie den ownCloud-Job von „Ajax“ zu „Cron“ mittels der ownClouds CLI um:
sudo -u www-data php /var/www/owncloud/occ background:cron
Bitte nehmen Sie sich etwas Zeit und überprüfen den Sicherheitsstatus Ihres Servers.
Die Warnung basiert auf einem bewußt getroffenen Settings in der owncloud.conf.
[...]add_header X-XSS-Protection "1; mode=block" always;[...]
Nähere Informationen finden Sie hier. Ziel sollte stets sein, mindestens das nachfolgend dargestellte „A+“-Ergebnis in den Tests zu erzielen:
Mit diesen Ergebnissen (A+) haben wir die notwendigen Maßnahmen erfolgreich umgesetzt und härten das ownCloud System weiter mittels fail2ban und der ufw Firewall.
6. Härtung (fail2ban and ufw)
Zuerst installieren wir fail2ban um den Server gegen Brute-force-Attacken und fehlerhafte Loginversuche zu schützen:
apt update -q4 && apt install -y fail2ban
Erstellen Sie eine neue Filterdatei und befüllen diese wie nachfolgend beschrieben:
touch /etc/fail2ban/filter.d/owncloud.conf
Kopieren Sie alles von „cat …“ bis „… EOF“ in Ihre Zwischenablage und fügen es dann in die Shell ein:
cat <<EOF >/etc/fail2ban/filter.d/owncloud.conf [Definition] _daemon = owncloud failregex = {"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":"--","app":"core","method":".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)"} ignoreregex = EOF
Bestätigen Sie mit <ENTER> um die Datei zu befüllen und legen dann die neue Jail-Datei an:
nano /etc/fail2ban/jail.d/owncloud.local
Kopieren Sie alle nachfolgenden Zeilen hinein:
[owncloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = owncloud
maxretry = 5
bantime = 3600
findtime = 36000
logpath = /var/oc_data/owncloud.log
Mit den zuvor dargestellten Parameteren wird nach 5 fehlerhaften Anmeldeversuchen (maxretry) innerhalb der letzten 36000 Sekunden (findtime, das entspricht 10h) die IP des potentiellen Angreifers für einen Zeitraum von 3600 Sekunden (bantime, enspricht 1h) gesperrt.
Starten Sie fail2ban neu und überprüfen den fail2ban-status:
service fail2ban restart
fail2ban-client status owncloud
Ab sofort werden IP-Adressen, von denen 5 oder mehr fehlerhafte Anmeldeversuche innerhalb der letzten 10h ausgegangen sind für 1h gesperrt und Ihr Server somit vor weiteren Attacken geschützt. Wenn Sie die Sperre manuell testen wollen und die resultierende Sperre Ihrer IP respektive bereits gesperrte IPs entsperren wollen, so führen Sie zuerst diesen Befehl aus,
fail2ban-client status owncloud
um sich die gesperrten IP-Adressen anzeigen zu lassen. Die dargestellte(n) IP(s) können Sie mittels des nachfolgenden Befehls entsperrren:
fail2ban-client set owncloud unbanip <ip-adresse>
Abschließend installieren wir noch eine Firewall, die sogenannte uncomplicated firewall (ufw):
Sofern Sie zuvor den SSH-Port von 22 auf einen anderen Port geändert haben, so müssen Sie die 22 entsprechend ersetzen!
apt install -y ufw
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp
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:
ufw allow proto tcp from 192.168.2.0/24 to any port 22
Ersetzen Sie das exemplarische Netz (192.168.2.0/24) durch das bei Ihnen genutzte Netz!
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
service ufw restart
7. bash_aliases und empfohlene Settings (config.php)
Passen Sie die Datei /root/bash_aliases an, um das ownCloud Toolset occ direkt mittels mocc starten zu können
if [ ! -f /root/.bash_aliases ]; then touch /root/.bash_aliases; fi
cat <<EOF >> /root/.bash_aliases
alias mocc="sudo -u www-data php /var/www/owncloud/occ"
EOF
Melden Sie sich von der aktuellen Sitzung ab und wieder neu an. Ab sofort können Sie als priviligierter Benutzer (sudo -s) die ownCloud occ-Tools direkt per „mocc … “ ausführen, bspw:
mocc app:list --enabled
um sich 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="1800"
mocc config:system:set log_rotate_size --value="104857600"
mocc config:system:set trashbin_retention_obligation --value="auto, 7"
mocc config:system:set versions_retention_obligation --value="auto, 365"
mocc config:system:set simpleSignUpLink.shown --type=bool --value=false
mocc config:system:set upgrade.disable-web --type=bool --value=true
mocc config:system:set loglevel --value="2"
Mit mocc erhalten Sie die Übersicht aller Befehle.
Die Installation und Absicherung Ihres ownCloud Servers wurde erfolgreich abgeschlossen und so wünsche ich Ihnen viel Spaß mit Ihren Daten in Ihrer privaten Cloud. Über Ihre Unterstützung (diese wird ordnungsgemäß versteuert!) würden sich meine Frau, meine Zwillinge und ich sehr freuen!