Nextcloud 13 (Apache2) installation guide


Following this guide you will be able to install and configure Nextcloud 13 based on Ubuntu 16.04.4 LTS, Apache 2.4.29 (mpm_event, http2), PHP 7.2 (php7.2-fpm), MariaDB, Redis, fail2ban, firewall (ufw) and achieve an A+ rating from both: Nextcloud and Qualys SSL Labs. We will request and implement the ssl certificate from Let’s Encrypt in this guide. You only have to ammend the red marked values (YOUR.DEDYN.IO, 192.168.2.x, 22) regarding your environment!


Updated: April, 10th, 2018:
– added two statements regarding php sessionclean
sed -i “s/09,39.*/# &/” /etc/cron.d/php
(crontab -l ; echo “09,39 * * * * /usr/lib/php/sessionclean 2>&1”) | crontab -u root –

earlier changes


Pre-Requirements:

sudo -s
apt install software-properties-common && apt install -y python-software-properties && apt install -y zip unzip screen curl ffmpeg
add-apt-repository -y ppa:ondrej/php && add-apt-repository -y ppa:ondrej/apache2 && add-apt-repository -y ppa:certbot/certbot
apt update && apt upgrade -y

Determine the uid of your www-data user by issuing

id www-data

and only if it differs from ‘uid=33‘ replace the ‘uid=33‘ in the following rows properly before executing them!

sed -i '$atmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /var/tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /usr/local/tmp/apc tmpfs defaults,uid=33,size=300M,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /usr/local/tmp/cache tmpfs defaults,uid=33,size=300M,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
sed -i '$atmpfs /usr/local/tmp/sessions tmpfs defaults,uid=33,size=300M,noatime,nosuid,nodev,noexec,mode=1777 0 0' /etc/fstab
mkdir -p /var/www /var/nc_data /usr/local/tmp/cache /usr/local/tmp/sessions /usr/local/tmp/apc /upload_tmp
chown -R www-data:www-data /upload_tmp /var/nc_data /var/www
chown -R www-data:root /usr/local/tmp/sessions /usr/local/tmp/cache /usr/local/tmp/apc
mount -a

Install Maria-DB:

apt install mariadb-server -y

Harden your Database server:

mysql_secure_installation

If you already set the db-password for the <root>-User you can skip the first question. All the other following questions should be answered with ‘Yes’ (Y).

mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak && vi /etc/mysql/my.cnf

Past all the following rows:

[server]
 skip-name-resolve
 innodb_buffer_pool_size = 128M
 innodb_buffer_pool_instances = 1
 innodb_flush_log_at_trx_commit = 2
 innodb_log_buffer_size = 32M
 innodb_max_dirty_pages_pct = 90
 query_cache_type = 1
 query_cache_limit = 2M
 query_cache_min_res_unit = 2k
 query_cache_size = 64M
 tmp_table_size= 64M
 max_heap_table_size= 64M
 slow-query-log = 1
 slow-query-log-file = /var/log/mysql/slow.log
 long_query_time = 1

[client-server]
 !includedir /etc/mysql/conf.d/
 !includedir /etc/mysql/mariadb.conf.d/

[client]
 default-character-set = utf8mb4

[mysqld]
 character-set-server = utf8mb4
 collation-server = utf8mb4_general_ci
 binlog_format = MIXED
 innodb_large_prefix=on
 innodb_file_format=barracuda
 innodb_file_per_table=1

Restart the database server and log into it:

service mysql restart && mysql -uroot

Create the requiered database and user:

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER nextcloud@localhost identified by 'nextcloud';
GRANT ALL PRIVILEGES on nextcloud.* to nextcloud@localhost;
FLUSH privileges;
quit;

Install Apache2, PHP and Redis-Server:

apt install libapache2-mod-php7.2 php7.2-cli php7.2-common php7.2-mbstring php7.2-gd php7.2-intl php7.2-xml php7.2-mysql php7.2-zip php7.2-dev php7.2-curl php7.2-fpm php7.2-json php7.2-bz2 php7.2-ldap php-dompdf php-apcu imagemagick php-imagick php-smbclient redis-server php-redis unzip -y

Disable PHP 7.2 and mpm_prefork and enable php7.2-fpm with mpm_event:

a2dismod php7.2 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart
a2enconf php7.2-fpm && service apache2 restart

Download and extract the latest Nextcloud Release:

wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip && mv nextcloud/ /var/www/html/ && chown -R www-data:www-data /var/www/html/nextcloud && rm latest.zip

Modify Redis-Server:

Backup the configuration and modify it with regard to Nextcloud:

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 512/" /etc/redis/redis.conf
usermod -a -G redis www-data

Create a password hash

Issue the following statement (replace the red one to your need)

echo "yourPassWord2BHashed" | sha256sum

and note down the result without the final ‘‘:

d98c51c882960945f49fe8127cb0eb97dbf435b3532bd58c846bd85c2282c4af -

Edit the redis.conf

vi /etc/redis/redis.conf

and paste:

requirepass d98c51c882960945f49fe8127cb0eb97dbf435b3532bd58c846bd85c2282c4af

Enable further Apache modules:

a2enmod rewrite headers env dir mime && service apache2 restart

Prepare your server for Let’s Encrypt:

apt install python-certbot-apache -y
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/001-nextcloud.conf
rm /etc/apache2/sites-available/000-default.conf && rm /etc/apache2/sites-enabled/000-default.conf

Modify the initial Nextcloud vhost:

vi /etc/apache2/sites-available/001-nextcloud.conf

Make ammendments to the following rows:

ServerName your.dedyn.io
ServerAdmin webmaster@dedyn.io
DocumentRoot /var/www/html/nextcloud

Request your certificates by issuing

a2ensite 001-nextcloud.conf && service apache2 restart && certbot --apache

Choose ‘1’, then ‘2’ as shown in the screenshot:

Make further adjustements to the intial vhost:

mv /etc/apache2/sites-available/001-nextcloud.conf /etc/apache2/sites-available/001-nextcloud.conf.le-bak
vi /etc/apache2/sites-available/001-nextcloud.conf

Paste all the following rows and replace the red ones:

<VirtualHost *:80>
Servername your.dedyn.io
ServerAdmin mail@dedyn.io
DocumentRoot /var/www/html/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =your.dedyn.io
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Make further adjustements to the intial vhost:

cp /etc/apache2/sites-available/001-nextcloud-le-ssl.conf /etc/apache2/sites-available/001-nextcloud-le-ssl.conf.bak
vi /etc/apache2/sites-available/001-nextcloud-le-ssl.conf

Paste all the following rows and replace the red ones:

<IfModule mod_ssl.c>
<VirtualHost *:443>
SSLEngine on
SSLOptions +StrictRequire
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
ServerAdmin mail@dedyn.io
DocumentRoot /var/www/html/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ServerName your.dedyn.io
SSLCertificateFile /etc/letsencrypt/live/your.dedyn.io/fullchain.pem
SSLCACertificateFile /etc/letsencrypt/live/your.dedyn.io/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your.dedyn.io/privkey.pem
<Directory /var/www/html/nextcloud/>
Options +FollowSymlinks
AllowOverride All
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud
</Directory>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000; preload"
</IfModule>
</VirtualHost>
SSLProtocol TLSv1.2
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:!AES128
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
SSLOpenSSLConfCmd Curves secp384r1
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
</IfModule>

Androider’s: if you run in troubles e.g. using CalDAV/CardDAV please decrease the eliptic curve and cipher strength to:

SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLOpenSSLConfCmd Curves prime256v1

Enhance security:

screen -S dhparam
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

To leave screen press STRG+A following by ‘d’ – to resume run screen -r. Please be patient, it will take a while. When dhparam was generated just modify the apache.conf:

vi /etc/apache2/apache2.conf

At the beginning of this file add the following new row

ServerName your.dedyn.io

and replace ‘AllowOverride None‘ to ‘All‘ as follows in the shown section:

...
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
...

Restart apache by issuing

service apache2 restart

Tune your PHP:

cp /etc/php/7.2/fpm/pool.d/www.conf /etc/php/7.2/fpm/pool.d/www.conf.bak
cp /etc/php/7.2/cli/php.ini /etc/php/7.2/cli/php.ini.bak
cp /etc/php/7.2/fpm/php.ini /etc/php/7.2/fpm/php.ini.bak
cp /etc/php/7.2/apache2/php.ini /etc/php/7.2/apache2/php.ini.bak
cp /etc/php/7.2/fpm/php-fpm.conf /etc/php/7.2/fpm/php-fpm.conf.bak
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/pm.max_children = .*/pm.max_children = 240/" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/pm.start_servers = .*/pm.start_servers = 20/" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers = .*/pm.min_spare_servers = 10/" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers = .*/pm.max_spare_servers = 20/" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests = 500/pm.max_requests = 500/" /etc/php/7.2/fpm/pool.d/www.conf
sed -i "s/output_buffering =.*/output_buffering = Off/" /etc/php/7.2/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.2/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.2/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.2/cli/php.ini
sed -i "s/;upload_tmp_dir =.*/upload_tmp_dir = \/upload_tmp/" /etc/php/7.2/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.2/cli/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.2/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.2/cli/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.2/cli/php.ini
sed -i "s/;session.save_path =.*/session.save_path = \"N;700;\/usr\/local\/tmp\/sessions\"/" /etc/php/7.2/cli/php.ini
sed -i '$aapc.enable_cli = 1' /etc/php/7.2/cli/php.ini
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/7.2/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = Off/" /etc/php/7.2/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.2/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.2/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.2/fpm/php.ini
sed -i "s/;upload_tmp_dir =.*/upload_tmp_dir = \/upload_tmp/" /etc/php/7.2/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.2/fpm/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.2/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.2/fpm/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.2/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.2/fpm/php.ini
sed -i "s/;session.save_path =.*/session.save_path = \"N;700;\/usr\/local\/tmp\/sessions\"/" /etc/php/7.2/fpm/php.ini
sed -i "s/;emergency_restart_threshold =.*/emergency_restart_threshold = 10/" /etc/php/7.2/fpm/php-fpm.conf
sed -i "s/;emergency_restart_interval =.*/emergency_restart_interval = 1m/" /etc/php/7.2/fpm/php-fpm.conf
sed -i "s/;process_control_timeout =.*/process_control_timeout = 10s/" /etc/php/7.2/fpm/php-fpm.conf
sed -i "s/output_buffering =.*/output_buffering = Off/" /etc/php/7.2/apache2/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/7.2/apache2/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/7.2/apache2/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/7.2/apache2/php.ini
sed -i "s/;upload_tmp_dir =.*/upload_tmp_dir = \/upload_tmp/" /etc/php/7.2/apache2/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/7.2/apache2/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/7.2/apache2/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Berlin/" /etc/php/7.2/apache2/php.ini
sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/7.2/apache2/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/7.2/apache2/php.ini 
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/7.2/apache2/php.ini
sed -i '$aapc.enabled=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.file_update_protection=2' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.optimization=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.shm_size=256M' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.include_once_override=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.shm_segments=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.ttl=7200' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.user_ttl=7200' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.gc_ttl=3600' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.num_files_hint=1024' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.enable_cli=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.max_file_size=5M' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.cache_by_default=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.use_request_time=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.slam_defense=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.mmap_file_mask=/usr/local/tmp/apc/apc.XXXXXX' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.stat_ctime=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.canonicalize=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.write_lock=1' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.report_autofilter=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.rfc1867=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.rfc1867_prefix =upload_' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.rfc1867_name=APC_UPLOAD_PROGRESS' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.rfc1867_freq=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.rfc1867_ttl=3600' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.lazy_classes=0' /etc/php/7.2/apache2/php.ini
sed -i '$aapc.lazy_functions=0' /etc/php/7.2/apache2/php.ini
sed -i "s/09,39.*/# &/" /etc/cron.d/php
(crontab -l ; echo "09,39 * * * * /usr/lib/php/sessionclean 2>&1") | crontab -u root -

Nextcloud Installation:

Open your browser and call to configure Nextcloud. Enter the following values:

https://your.dedyn.io

Username: cloudroot
Password*: Your-NC_Password!

Data folder: /var/nc_data

Datenbankuser: nextcloud
DB-Passwort*: nextcloud
Datenbank-Name: nextcloud
Host: localhost

After a few seconds Nexcloud will be installed and you will be redirected to Nextclouds file app. Please log out directly and make further ammendments.

sudo -u www-data vi /var/www/html/nextcloud/.htaccess

Replace the red ones to your requirements:

...
<IfModule mod_php7.c>
php_value upload_max_filesize 10240M
php_value post_max_size 10240M
php_value memory_limit 512M
php_value mbstring.func_overload 0
php_value default_charset 'UTF-8'
php_value output_buffering 'Off'
<IfModule mod_env.c>
...

Then adjust Nextclouds config.php. First have a look at the new generated values:

egrep "'instanceid' =>.*|'passwordsalt' => '.*|'secret' => '.*" /var/www/html/nextcloud/config/config.php
'instanceid' => 'ofg69hjknlor0',
'passwordsalt' => 'RrRjXeEeEdddBmJbRnqlnVK7e6R5T3hRX',
'secret' => 'HjKlIz9i8J7G6F5DuGQrqV1L9D8HFj6J8YedSVnTD9d',
sudo -u www-data cp /var/www/html/nextcloud/config/config.php /var/www/html/nextcloud/config/config.php.bak
sudo -u www-data vi /var/www/html/nextcloud/config/config.php

examplarily as follows:

<?php
$CONFIG = array (
 'activity_expire_days' => 14,
 'auth.bruteforce.protection.enabled' => true,
 'blacklisted_files' => 
 array (
 0 => '.htaccess',
 1 => 'Thumbs.db',
 2 => 'thumbs.db',
 ),
 'cron_log' => true,
 'datadirectory' => '/var/nc_data',
 'dbtype' => 'mysql',
 'dbname' => 'nextcloud',
 'dbhost' => 'localhost',
 'dbport' => '',
 'dbtableprefix' => 'oc_',
 'dbuser' => 'nextcloud',
 'dbpassword' => 'nextcloud',
 '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',
 ),
 'filesystem_check_changes' => 0,
 'filelocking.enabled' => 'true',
 'htaccess.RewriteBase' => '/',
 'installed' => true,
 'instanceid' => '*KeepYourSettings: ofg69hjknlor0*',
 'integrity.check.disabled' => false,
 'knowledgebaseenabled' => false,
 'logfile' => '/var/nc_data/nextcloud.log',
 'loglevel' => 2,
 'logtimezone' => 'Europe/Berlin',
 'log_rotate_size' => 104857600,
 'maintenance' => false,
 'memcache.local' => '\\OC\\Memcache\\APCu',
 'memcache.locking' => '\\OC\\Memcache\\Redis',
 'mysql.utf8mb4' => true,
 'overwriteprotocol' => 'https',
 'overwrite.cli.url' => 'https://your.dedyn.io',
 'passwordsalt' => '*KeepYourSettings: RrRjXeEeEdddBmJbRnqlnVK7e6R5T3hRX*',
 'preview_max_x' => 1024,
 'preview_max_y' => 768,
 'preview_max_scale_factor' => 1,
 'redis' => 
 array (
 'host' => '/var/run/redis/redis.sock',
 'password' => 'd98c51c882960945f49fe8127cb0eb97dbf435b3532bd58c846bd85c2282c4af',
 'port' => 0,
 'timeout' => 0.0,
 ),
 'quota_include_external_storage' => false,
 'secret' => '*KeepYourSettings: HjKlIz9i8J7G6F5DuGQrqV1L9D8HFj6J8YedSVnTD9d*',
 'share_folder' => '/Shares',
 'skeletondirectory' => '',
 'theme' => '',
 'trashbin_retention_obligation' => 'auto, 7',
 'trusted_domains' => 
 array (
 0 => 'your.dedyn.io',
 ),
 'updater.release.channel' => 'stable',
 'version' => '13.0.2.1',
);

Configure and enable a Nextcloud cron-job:

crontab -u www-data -e

Paste the following row:

*/15 * * * * php -f /var/www/html/nextcloud/cron.php > /dev/null 2>&1
5 1 * * * php -f /var/www/html/nextcloud/occ files:scan-app-data  > /dev/null 2>&1

Switch from Ajax to Cron using Nextcloud CLI:

sudo -u www-data php /var/www/html/nextcloud/occ background:cron

Then we will issue Nextclouds CLI again to update Nextclouds configuration and restart all services:

sudo -u www-data php /var/www/html/nextcloud/occ maintenance:update:htaccess
service redis-server restart && service php7.2-fpm restart && service apache2 restart

From now, Nextcloud is reachable without the ‘index.php’ string and no warnings should appear anymore in the admin panel.


If the integrity check will fail, try to change the config.php

sudo -u www-data vi /var/www/html/nextcloud/config/config.php

and set :

'integrity.check.disabled' => true,

Then restart all services:

service php7.2-fpm restart && service redis-server restart && service apache2 restart

Re-run the integrity check and set the value back to ‘false’:

sudo -u www-data vi /var/www/html/nextcloud/config/config.php
'integrity.check.disabled' => false,

Restart all services again.

service php7.2-fpm restart && service redis-server restart && service apache2 restart

and the message should disappear!


Modify the mpm_event.conf

vi /etc/apache2/mods-available/mpm_event.conf

Change the “MaxConnectionsPerChild” value to 1000:

StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 1000

At least we will enable http2 by issuing

a2enmod http2 && service php7.2-fpm restart && service apache2 restart

and create a http2.conf with few settings:

vi /etc/apache2/conf-available/http2.conf

Paste all the following rows:

<IfModule http2_module>
Protocols h2 h2c http/1.1
H2Direct on
H2StreamMaxMemSize 5120000000
</IfModule>

and enable this configuration by issuing

a2enconf http2 && service apache2 restart

Finally we will secure Apache to a minimum level by diasbaling Apaches status module (as long as you won’t need it in particular) and altering the security.conf:

a2dismod status && vi /etc/apache2/conf-available/security.conf

Change the values to the red ones:

ServerTokens Prod
ServerSignature Off
TraceEnable Off

and restart PHP, Apache2 and Redis one last time.

service php7.2-fpm restart && service redis-server restart && service apache2 restart

Nextcloud is now already up and running!

We will now harden the system using fail2ban and ufw. First we install and configure fail2ban and finally we will configure the firewall (ufw).

Install and configure fail2ban:

sudo -s
apt update && apt install fail2ban -y

Create the Nextcloud-filter:

vi /etc/fail2ban/filter.d/nextcloud.conf

Paste the following lines:

[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","app":"core".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
^.*\"remoteAddr\":\"<HOST>\".*Trusted domain error.*$

Create a new jail:

vi /etc/fail2ban/jail.d/nextcloud.local

Paste the following rows:

[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 36000
findtime = 36000
logpath = /var/nc_data/nextcloud.log

Re-start the fail2ban-service:

service fail2ban restart

Configure your ufw (uncomplicated firewall):

ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 22/tcp

Enable and restart ufw by running

ufw enable && service ufw restart

and enjoy your personal data in your secured and hardened Nextcloud-Server!

Don’t forget to Backup your Nextcloud

Find more instructions here: Nextcloud Backup and Restore


Carsten Rieger

26 Responses

  1. Matthias says:

    Hi Carsten, ich habe meine Nextcloud Installation nach deinem Beispiel durchgeführt. Respekt und vielen Dank für die tolle Anleitung. Heute habe ich das Update auf die Version 13.0.2 über die CLI eingespielt. Das einspielen hat ohne Probleme funktioniert. Auch kann ich über meinen Client der auf meinem Notebook läuft meine Daten wieder sauber synchronisieren. Allerdings kann ich die Weboberfläche nicht mehr erreichen. Als Fehlermeldung erschein
    “Forbidden You don’t have permission to access /index.php on this server.”

    Hattest du schon mal ein ähnliches Problem?
    VG

  2. dongha28 says:

    When trying to enable php7.2-fpm, a2enmod says it does not exist
    root@ubuntu01:~# a2enmod php7.2-fpm
    ERROR: Module php7.2-fpm does not exist!

    How do I enable php7.2-fpm?

    • First you have to install it as simple as i wrote in the guide:
      apt install libapache2-mod-php7.2 php7.2-cli php7.2-common php7.2-mbstring php7.2-gd php7.2-intl php7.2-xml php7.2-mysql php7.2-zip php7.2-dev php7.2-curl php7.2-fpm php7.2-json php7.2-bz2 php7.2-ldap php-dompdf php-apcu imagemagick php-imagick php-smbclient redis-server php-redis unzip -y
      Then you will be able to disable PHP 7.2 and mpm_prefork and enable php7.2-fpm with mpm_event by issuing
      a2dismod php7.2 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart
      a2enconf php7.2-fpm && service apache2 restart

      • dongha28 says:

        I already have php7.2-fpm installed
        php7.2-fpm is already the newest version (7.2.5-1+ubuntu16.04.1+deb.sury.org+1).

        But there is no conf OR load file in the /etc/apache2/mods-enabled directory.
        The funny thing is, php7.2-fpm has its own directory at /etc/php/7.2/fpm
        root@ubuntu01:/etc/php/7.2/fpm# ls
        conf.d php-fpm.conf php-fpm.conf.bak php.ini php.ini.bak pool.d

        Will I be ablate enable php7.2-fpm by copying over the php-fpm.conf file to the /mods-enabled/ directory?
        I already executed the previous step ‘a2dismod php7.2 && a2dismod mpm_prefork && a2enmod proxy_fcgi setenvif mpm_event && service apache2 restart’ and everything went ok, including apache2 restart. I keep getting stuck at the php7.2-fpm part.

  3. Michael says:

    Bravo!

  4. steffen says:

    Hallo,

    Ich habe alles soweit hinbekommen, nun habe ich meine PiDrive Platte von WD eingebunden und diese wird auch in nextcloud angezeigt.
    Das einzige Problem das ich hab ist, ich kann auf die Platte keine Datein hochladen? Was mach ich falsch.

  5. aytac says:

    hello again
    i am following your tutorial it is genius !
    my nextcloud instalation has problem when i try to send test mail it say A problem occurred while sending the email. Please revise your settings. (Error: Connection could not be established with host mail.xysysy.com [ #0])
    do you know how to resolve it ?
    my instalation is on the ubuntu 17.10 and pgsl with php7.2
    thank you for all !

  6. aytac says:

    hello many many thanks for your best tutorial
    i would like to ask you somethings about nextcloud installations
    1) nextcloud web server for the 100 users which is your prefer ? (apache or nginx )
    2) database postgres or Mariadb
    3) is it ok ubuntu 17.10 server ?
    many thanks for your answer

  7. stefano says:

    thank you, you are the best

  8. Claes says:

    Hi,
    I followed your guide and everything i setup and working, except for mounting shares using “SMB / CIFS” under “External storages” in Nextcloud from my file server running Windows…
    How do I configure it?

    • Hi Claes, do you have php-smbclient installed? Check: php -m
      If yes, you may choose it in Nextclouds external storage app as your preferred storage provider and configure the necessary credentials.
      If not please install php-smbclient by issuing
      sudo -s
      apt install php-smbclient -y

      Cheers, Carsten
      Cheers, Carsten

  9. ErAzOr says:

    @Carsten
    Hi Carsten. Vielen Dank für die Anleitung.

    Haben mal ne generelle Frage zu Apache:
    Nginx bietet ja das Modul ngx_cache_purge, welches die Generierung von Thumbnails beschleunigen soll.
    Gibt es analog dazu auch ein entsprechendes Modul für Apache? Oder ist es mit Apache nicht erforderlich, da entsprechende Funktion bereits Bestandteil ist?.
    Grüße ErAzOr

    • Vielen Dank! Ein explizites Modul ist mir nicht bekannt – ich bin auf diesem Gebiet leider noch “blank”. Über Informationen dazu wäre ich dankbar 😉 Viele Grüße, Casten

  10. Nextclouder says:

    Thanks for the fast response and update, I delete 000-default in sites-enabled and default-ssl in sites-available, the only file left is /etc/apache2/sites-available/001-nextcloud.conf which has my name.dedyn.io, the domain is working, I get the Apache2 welcome page on port 80.

    Certbot is unhappy and doesn’t pick up the vhost in /etc/apache2/sites-available/001-nextcloud.conf:

    # certbot –apache
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator apache, Installer apache
    No names were found in your configuration files. Please enter in your domain
    name(s) (comma and/or space separated) (Enter ‘c’ to cancel):

    This is my 001-nextcloud.conf:

    ServerName .dedyn.io

    ServerAdmin webmaster@dedyn.io
    DocumentRoot /var/www/html/nextcloud

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Thanks again for your fantastic blog, just trying to follow along and running in little hiccups ..

    • Hi, did you change the vhost (001-nextcloud.conf) properly? LE would pick up the ServerName from the vhost – this is definitivley wrong: ServerName .dedyn.io
      You have to substitute the hostname and mail:
      your.dedyn.io to e.g. nextcloud.yourdomain.com
      webmaster@dedyn.io to e.g. webmaster@yourdomain.com

      assuming your dyndns would be “yourdomain.com”.

      Certbot is unhappy and doesn’t pick up the vhost in /etc/apache2/sites-available/001-nextcloud.conf:
      You have to create a link (e.g. ln -s) or a2ensite 001-nextcloud.conf first. Apache2 won’t use vhosts in sites-available.
      Cheers, Carsten

  11. Nextclouder says:

    I made it to “certbot –apache” then I get the error apache2: Syntax error on line 225 of /etc/apache2/apache2.conf: Could not open configuration file /etc/apache2/sites-enabled/000-default.conf: No such file or directory

    Do we first need to enabled the 001-nextcloud.conf from sites-available to the sites-enabled folder? Also is it possible that the apache2 package is missing in the apt install commands above? I had to manually install it in addition to copy & pasting ..

    • Hi.
      No, it isn’t missised, it will be installed by issuing “libapache2-mod-php7.2” …
      Please remove the defaults vhosts:
      rm /etc/apache2/sites-available/000-default.conf
      rm /etc/apache2/sites-enabled/000-default.conf
      service apache2 restart

      and before issuing certbot aou have to a2ensite 000-nextcloud.conf.
      Thank you very much for your feedback and your hint! I already updated the guide Cheers, Carsten

  12. mzk says:

    THX!