Nextcloud 14 installation guide (NGINX/Ubuntu)



Following this guide you will be able to install and configure Nextcloud 14 new latest based on Ubuntu 18.04.x LTS, NGINX 1.15.6 new , TLSv1.2 or TLSv1.3, PHP 7.2.10, MariaDB 10.3.10, Redis, fail2ban, firewall (ufw) and will achieve an A+ rating from as well Nextcloud as Qualys SSL Labs. We will request and implement your ssl certificate(s) from Let’s Encrypt in chapter 5. You only have to ammend the red marked values (YOUR.DEDYN.IO, 192.168.2.x, ssh port 22) regarding your environment!


Pre-requirements

From my perspective the requirements for this guide may be rated as low: you only have to

  • provide a 64Bit Mini-Server (e.g. Intel NUC),
  • forward two ports (80 and 443) from internet (your router e.g. FritzBox or Speedport) to your internal Nextcloud server
  • and install the operating system Ubuntu 18.04 LTS (64Bit).

Table of content

  1. Prepare your server and install NGINX
  2. PHP
  3. MariaDB
  4. Redis
  5. Nextcloud (SSL enabled, A+, 100%)
  6. fail2ban and firewall (ufw)

Last Updates:

October, 25th 2018:
– added ssl early data directive to both: ssl.conf and proxy.conf

… the entire update history


1. Prepare your server and install NGINX

If you are interested in compiling NGINX and operate with OpenSSL 1.1.1 + TLS 1.3 you may find detailed instructions here.

sudo -s
cd /usr/local/src
mv /etc/apt/sources.list /etc/apt/sources.list.bak && touch /etc/apt/sources.list
cat <<EOF >>/etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu bionic main multiverse restricted universe
deb http://archive.ubuntu.com/ubuntu bionic-security main multiverse restricted universe
deb http://archive.ubuntu.com/ubuntu bionic-updates main multiverse restricted universe
deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ bionic nginx
deb [arch=amd64] http://mirror2.hs-esslingen.de/mariadb/repo/10.3/ubuntu bionic main
EOF
wget http://nginx.org/keys/nginx_signing.key && apt-key add nginx_signing.key
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
apt update && apt upgrade -y && apt install software-properties-common zip unzip screen curl ffmpeg libfile-fcntllock-perl -y
add-apt-repository ppa:certbot/certbot -y && apt update && apt upgrade -y && apt install letsencrypt ssl-cert -y
apt remove nginx nginx-common nginx-full -y --allow-change-held-packages
apt install nginx -y

Modify NGINX:

systemctl enable nginx.service && apt-mark hold nginx

To update NGINX in the future just issue the following statement:

apt-mark unhold nginx && apt upgrade -y && apt-mark hold nginx

Change NGINX configuration:

mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak && vi /etc/nginx/nginx.conf

to:

user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
server_names_hash_bucket_size 64;
upstream php-handler {
server unix:/run/php/php7.2-fpm.sock;
}
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
#include /etc/nginx/proxy.conf;
#include /etc/nginx/ssl.conf;
#include /etc/nginx/header.conf;
#include /etc/nginx/optimization.conf;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$host" sn="$server_name" '
'rt=$request_time '
'ua="$upstream_addr" us="$upstream_status" '
'ut="$upstream_response_time" ul="$upstream_response_length" '
'cs=$upstream_cache_status' ;
access_log /var/log/nginx/access.log main;
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 208.67.222.222 valid=30s;
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}

Start NGINX:

service nginx restart

Create folders and apply permissions:

mkdir -p /var/nc_data /var/www/letsencrypt /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

2. Install PHP

apt install php7.2-fpm php7.2-gd php7.2-mysql php7.2-curl php7.2-xml php7.2-zip php7.2-intl php7.2-mbstring php7.2-json php7.2-bz2 php7.2-ldap php-apcu imagemagick php-imagick php-smbclient -y

Awesome, PHP 7.2 is already installed. Verify your timezone settings

date

and if necessary set it properly

timedatectl set-timezone Europe/Berlin

Configure 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/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 '$aapc.enabled=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.file_update_protection=2' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.optimization=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.shm_size=256M' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.include_once_override=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.shm_segments=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.ttl=7200' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.user_ttl=7200' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.gc_ttl=3600' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.num_files_hint=1024' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.enable_cli=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.max_file_size=5M' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.cache_by_default=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.use_request_time=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.slam_defense=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.mmap_file_mask=/usr/local/tmp/apc.XXXXXX' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.stat_ctime=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.canonicalize=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.write_lock=1' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.report_autofilter=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.rfc1867=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.rfc1867_prefix =upload_' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.rfc1867_name=APC_UPLOAD_PROGRESS' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.rfc1867_freq=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.rfc1867_ttl=3600' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.lazy_classes=0' /etc/php/7.2/fpm/php.ini
sed -i '$aapc.lazy_functions=0' /etc/php/7.2/fpm/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 -

Modify /etc/fstab

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 /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

OPTIONAL:

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

Mount tmpfs and then restart both, PHP and NGINX:

mount -a && service php7.2-fpm restart && service nginx restart

3. MariaDB

If you are interested in Postgresql instead of MariaDB please have a look here. Update your system and install MariaDB:

apt update && apt install mariadb-server -y

Verify your database server version:

mysql --version

A version like …10.3.10-MariaDB… should appear.

Secure MariaDB:

mysql_secure_installation
Enter current password for root (enter for none): <ENTER> or type the password
Set root password? [Y/n] Y

If already set during the MariaDB installation you will be asked wether to change or keep the password

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

Configure MariaDB:

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

Paste the following rows:

[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
default-character-set = utf8mb4
[mysqld_safe]
log_error=/var/log/mysql/mysql_error.log
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
log_error=/var/log/mysql/mysql_error.log
general_log_file = /var/log/mysql/mysql.log
general_log = 0
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
skip-external-locking
skip-name-resolve
bind-address = 127.0.0.1
max_connections = 200
connect_timeout = 5
wait_timeout = 600
max_allowed_packet = 16M
thread_cache_size = 128
sort_buffer_size = 4M
bulk_insert_buffer_size = 16M
tmp_table_size = 64M
max_heap_table_size = 64M
myisam_recover_options = BACKUP
key_buffer_size = 128M
#open-files-limit = 2000
table_open_cache = 400
myisam_sort_buffer_size = 512M
concurrent_insert = 2
read_buffer_size = 2M
read_rnd_buffer_size = 1M
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
query_cache_min_res_unit = 2k
log_warnings = 2
slow_query_log_file = /var/log/mysql/mariadb-slow.log
long_query_time = 1
log_slow_verbosity = query_plan
slow-query-log = 1
slow-query-log-file = /var/log/mysql/slow.log
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
expire_logs_days = 10
max_binlog_size = 100M
default_storage_engine = InnoDB
innodb_buffer_pool_size = 256M
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 = 400
innodb_flush_method = O_DIRECT
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
transaction_isolation = READ-COMMITTED
binlog_format = ROW
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
#no-auto-rehash    # faster start of mysql but no tab completion
[isamchk]
key_buffer = 16M
!include /etc/mysql/mariadb.cnf
!includedir /etc/mysql/conf.d/

Restart MariaDB:

service mysql restart

Create the database and the user:

mysql -h localhost -uroot -p -e "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;"

Verify the transaction Isolation level was set to READ_Commit and the collation was set to UTF8MB4 properly:

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='nextcloud'"

If the resultset will be “READ-COMMITTED” and “utf8mb4_general_ci” as shown go ahead with the installation of redis.


4. Redis

apt update && apt install redis-server php-redis -y

Change configuration and group membership:

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
cp /etc/sysctl.conf /etc/sysctl.conf.bak && sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf

Reboot your server:

shutdown -r now

5. Create the nextcloud.conf:

sudo -s
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak && touch /etc/nginx/conf.d/default.conf && vi /etc/nginx/conf.d/nextcloud.conf

Paste the following rows:

server {
server_name YOUR.DEDYN.IO;
listen 80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name YOUR.DEDYN.IO;
listen 443 ssl http2 default_server;
root /var/www/nextcloud/;
access_log /var/log/nginx/nextcloud.access.log main;
error_log /var/log/nginx/nextcloud.error.log warn;
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;
}
client_max_body_size 10240M;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100m;
mp4_max_buffer_size 1024m;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:css|js|woff|svg|gif|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
access_log off;
expires 360d;
}
}

If you want your Nextcloud running in a subdir like https://your.dedyn.io/nextcloud use this nextcloud.conf instead:

server {
server_name your.dedyn.io;
listen 80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name your.dedyn.io;
listen 443 ssl http2 default_server;
root /var/www/;
access_log /var/log/nginx/nextcloud.access.log main;
error_log /var/log/nginx/nextcloud.error.log warn;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
client_max_body_size 10240M;
location ^~ /nextcloud {
location /nextcloud {
rewrite ^ /nextcloud/index.php$uri;
}
location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100m;
mp4_max_buffer_size 1024m;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^/nextcloud/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|css|js|woff|svg|gif)$ {
try_files $uri /nextcloud/index.php$uri$is_args$args;
access_log off;
expires 360d;
}
}
}

Create the letsencrypt.conf:

vi /etc/nginx/conf.d/letsencrypt.conf

Paste the following rows:

server {
server_name 127.0.0.1;
listen 127.0.0.1:81 default_server;
charset utf-8;
access_log /var/log/nginx/le.access.log main;
error_log /var/log/nginx/le.error.log warn;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
}

Create the ssl.conf:

vi /etc/nginx/ssl.conf

Paste the following rows:

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/live/YOUR.DEDYN.IO/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/YOUR.DEDYN.IO/privkey.pem;
#ssl_trusted_certificate /etc/letsencrypt/live/YOUR.DEDYN.IO/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.2;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;

OPTIONAL (If you compiled NGINX 1.15.6 with OpenSSL 1.1.1) add

ssl_protocols TLSv1.2 TLSv1.3;
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:ECDHE-RSA-AES256-SHA384';
ssl_early_data on;

Create the proxy.conf

vi /etc/nginx/proxy.conf

Paste the following rows:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_redirect off;

OPTIONAL (If you compiled NGINX 1.15.6 with OpenSSL 1.1.1) add:

proxy_set_header Early-Data $ssl_early_data;

Create the header.conf:

vi /etc/nginx/header.conf

Paste the following rows:

add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer" always;
add_header Feature-Policy "geolocation 'self'";

Create the optimization.conf:

vi /etc/nginx/optimization.conf

Paste the following rows:

fastcgi_read_timeout 3600;
fastcgi_buffers 64 64K;
fastcgi_buffer_size 256k;
fastcgi_busy_buffers_size 3840K;
fastcgi_cache_key $http_cookie$request_method$host$request_uri;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
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;
gzip_disable "MSIE [1-6]\.";

Create the php_optimization.conf:

vi /etc/nginx/php_optimization.conf

Paste the following rows:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_cache_valid 404 1m;
fastcgi_cache_valid any 1h;
fastcgi_cache_methods GET HEAD;

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.

Restart NGINX:

sed -i s/\#\include/\include/g /etc/nginx/nginx.conf && service nginx restart

Download and extract Nextcloud:

cd /usr/local/src
wget https://download.nextcloud.com/server/releases/latest.tar.bz2 && tar -xjf latest.tar.bz2 -C /var/www && chown -R www-data:www-data /var/www/ && rm latest.tar.bz2

Request your ssl-certificate(s):

letsencrypt certonly -a webroot --webroot-path=/var/www/letsencrypt --rsa-key-size 4096 -d YOUR.DEDYN.IO

Apply the permissions using a permissions.sh script:

vi /root/permissions.sh

Paste the following rows:

#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
chown -R www-data:www-data /var/www/
chown -R www-data:www-data /upload_tmp/
chown -R www-data:www-data /var/nc_data/
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
chmod 600 /etc/letsencrypt/live/YOUR.DEDYN.IO/fullchain.pem
chmod 600 /etc/letsencrypt/live/YOUR.DEDYN.IO/privkey.pem
chmod 600 /etc/letsencrypt/live/YOUR.DEDYN.IO/chain.pem
chmod 600 /etc/letsencrypt/live/YOUR.DEDYN.IO/cert.pem
chmod 600 /etc/ssl/certs/dhparam.pem
exit 0

Run the script:

chmod +x /root/permissions.sh && /root/permissions.sh

Modify the ssl.conf and restart NGINX:

sed -i '/ssl-cert-snakeoil/d' /etc/nginx/ssl.conf
sed -i s/\#\ssl/\ssl/g /etc/nginx/ssl.conf
service nginx restart

Create a certificate renewal automatism:

sed -i "s/SHELL=*/# &/" /etc/cron.d/certbot
sed -i "s/PATH=*/# &/" /etc/cron.d/certbot
sed -i "s/0 =*/# &/" /etc/cron.d/certbot
vi /root/renewal.sh

Paste the following rows

#!/bin/bash
cd /etc/letsencrypt
letsencrypt renew
result=$(find /etc/letsencrypt/live/ -type l -mtime -1 )
if [ -n "$result" ]; then
/usr/sbin/service nginx stop
/usr/sbin/service mysql restart
/usr/sbin/service redis-server restart
/usr/sbin/service php7.2-fpm restart
/usr/sbin/service nginx restart
fi
exit 0

Make it exectuable and create a cronjob

chmod +x /root/renewal.sh && crontab -e

Paste the red row below existing ones:

09,39 * * * * /usr/lib/php/sessionclean 2>&1
@monthly /root/renewal.sh 2>&1

Install Nextcloud silently

sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "nextcloud" --admin-user "YourNextcloudAdmin" --admin-pass "YourNextcloudAdminPasssword" --data-dir "/var/nc_data"

Information:

–database-user “nextcloud” : As set above while creating the database and user

–database-pass “nextcloud” : As set above while creating the database and user

–admin-user “YourNextcloudAdmin” : your free choice

–admin-pass “YourNextcloudAdminPasssword” : your free choice

Finish the installation, then make ammendments to your config.php as www-data:

sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=your.dedyn.io
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://your.dedyn.io
sudo -u www-data cp /var/www/nextcloud/config/config.php /var/www/nextcloud/config/config.php.bak

Expand your Nextcloud config.php:

sudo -u www-data sed -i 's/^[ ]*//' /var/www/nextcloud/config/config.php
sudo -u www-data sed -i '/);/d' /var/www/nextcloud/config/config.php
sudo -u www-data cat <<EOF >>/var/www/nextcloud/config/config.php
'activity_expire_days' => 14,
'auth.bruteforce.protection.enabled' => true,
'blacklisted_files' => 
array (
0 => '.htaccess',
1 => 'Thumbs.db',
2 => 'thumbs.db',
),
'cron_log' => true,
'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' => '/',
'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',
'overwriteprotocol' => 'https',
'preview_max_x' => 1024,
'preview_max_y' => 768,
'preview_max_scale_factor' => 1,
'redis' => 
array (
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'timeout' => 0.0,
),
'quota_include_external_storage' => false,
'share_folder' => '/Shares',
'skeletondirectory' => '',
'theme' => '',
'trashbin_retention_obligation' => 'auto, 7',
'updater.release.channel' => 'stable',
);
EOF

Edit the .user.ini:

sudo -u www-data sed -i "s/upload_max_filesize=.*/upload_max_filesize=10240M/" /var/www/nextcloud/.user.ini
sudo -u www-data sed -i "s/post_max_size=.*/post_max_size=10240M/" /var/www/nextcloud/.user.ini
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering='Off'/" /var/www/nextcloud/.user.ini
service php7.2-fpm restart && service redis-server restart && service nginx restart

Adjust Nextcloud

sudo -u www-data php /var/www/nextcloud/occ config:system:set 'auth.bruteforce.protection.enabled' --value=false
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:enable admin_audit
sudo -u www-data php /var/www/nextcloud/occ app:enable files_pdfviewer

Logon to your brandly new Nextcloud in your browser

https://your.dedyn.io/login

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

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

and set :

'integrity.check.disabled' => true,

Then restart all services:

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

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

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

Restart all services again.

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

and the message should disappear!


Optimize your Nextcloud once (a) and regulary (b) using a script

(a)

/usr/sbin/service nginx stop
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigint
/usr/sbin/service nginx start

(infos: BigInt, missing indices)

(b)

vi /root/optimize.sh
#!/bin/bash
redis-cli -s /var/run/redis/redis-server.sock <<EOF
FLUSHALL
quit
EOF
sudo -u www-data php /var/www/nextcloud/occ files:scan --all
sudo -u www-data php /var/www/nextcloud/occ files:scan-app-data
exit 0

Save the script and mark it as executable

chmod +x /root/optimize.sh

Issue the optimize.sh script initially:

/root/optimize.sh

Add Nextcloud cronjobs for www-data and root

For www-data:

crontab -u www-data -e

Paste the following rows

*/15 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1

For root:

crontab -e

Paste the follwoing rows:

5 1 * * * /root/optimize.sh > /dev/null 2>&1

Don’t forget to switch from Ajax to Cron in Nextclouds-Adminpanel or use Nextcloud CLI to switch immediately:

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

Finally verify your server security level

(1)

https://www.ssllabs.com/ssltest/analyze.html?d=your.dedyn.io

(2)

https://scan.nextcloud.com

(3)

https://observatory.mozilla.org/analyze/your.dedyn.io


6. Harden your System using fail2ban and ufw

First install and configure fail2ban and finally configure the firewall ufw to secure and harden Nextcloud.

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 rows to the fail2ban filter for Nextcloud (or download as txt file to avoid WordPress-code-issues!):

[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

[nginx-http-auth]
enabled = true

Re-start the fail2ban-service:

service fail2ban restart

Configure your ufw (uncomplicated firewall):

apt install ufw -y && ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 22/tcp

Enable and restart ufw by running

ufw logging medium && ufw default deny incoming && ufw enable && service ufw restart

6.1 Harden your Nextcloud using Spamhaus Project and UFW

If you’d like to prevent “unprivileged visitors” just create the script /root/ufw-spamhaus.sh and block them by ufw directly.

vi /root/ufw-spamhaus.sh

Paste the following rows:

#!/bin/bash
# Thanks to @ank0m
EXEC_DATE=`date +%Y-%m-%d`
SPAMHAUS_DROP="/usr/local/src/drop.txt"
SPAMHAUS_eDROP="/usr/local/src/edrop.txt"
URL="https://www.spamhaus.org/drop/drop.txt"
eURL="https://www.spamhaus.org/drop/edrop.txt"
DROP_ADD_TO_UFW="/usr/local/src/DROP2.txt"
eDROP_ADD_TO_UFW="/usr/local/src/eDROP2.txt"
DROP_ARCHIVE_FILE="/usr/local/src/DROP_$EXEC_DATE"
eDROP_ARCHIVE_FILE="/usr/local/src/eDROP_$EXEC_DATE"
# All credits for the following BLACKLISTS goes to "The Spamhaus Project" - https://www.spamhaus.org
echo "Start time: $(date)"
echo " "
echo "Download daily DROP file:"
wget -q -O - "$URL" > $SPAMHAUS_DROP
grep -v '^;' $SPAMHAUS_DROP | cut -d ' ' -f 1 > $DROP_ADD_TO_UFW
echo " "
echo "Extract DROP IP addresses and add to UFW:"
cat $DROP_ADD_TO_UFW | while read line
do
/usr/sbin/ufw insert 1 deny from "$line" comment 'DROP_Blacklisted_IPs'
done
echo " "
echo "Downloading eDROP list and import to UFW"
echo " "
echo "Download daily eDROP file:"
wget -q -O - "$eURL" > $SPAMHAUS_eDROP
grep -v '^;' $SPAMHAUS_eDROP | cut -d ' ' -f 1 > $eDROP_ADD_TO_UFW
echo " "
echo "Extract eDROP IP addresses and add to UFW:"
cat $eDROP_ADD_TO_UFW | while read line
do
/usr/sbin/ufw insert 1 deny from "$line" comment 'eDROP_Blacklisted_IPs'
done
echo " "
#####
## To remove or revert these rules, keep the list of IPs!
## Run a command like so to remove the rules:
# while read line; do ufw delete deny from $line; done < $ARCHIVE_FILE
#####
echo "Backup DROP IP address list:"
mv $DROP_ADD_TO_UFW $DROP_ARCHIVE_FILE
echo " "
echo "Backup eDROP IP address list:"
mv $eDROP_ADD_TO_UFW $eDROP_ARCHIVE_FILE
echo " "
echo End time: $(date)

Make the script exutable by issuing

chmod +x /root/ufw-spamhaus.sh

and configure it in your crontab to be issued automatically.

(crontab -l ; echo "10 2 * * * /root/ufw-spamhaus.sh 2>&1") | crontab -u root -

Finally perform an initial run

/root/ufw-spamhaus.sh

and many UFW rules will be applied immediately. Be patient, it may take a while.


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

Carsten Rieger

Carsten Rieger is a senior system engineer in full-time and also working as an IT freelancer. He is working with linux environments for more than 13 years, an Open Source enthusiast and highly motivated on linux installation and troubleshooting. Mostly working with Debian/Ubuntu Linux, Nginx and Apache web server, MariaDB/MySQL/PostgreSQL, PHP, Cloud infrastructure (e.g. Nextcloud) and other open source projects (e.g. Roundcube) and in voluntary work for the Dr. Michael & Angela Jacobi Stiftung for more than 6 years.

205 Responses

  1. Peter says:

    After an update, I had to add to my.cnf:

    [mysqld]
    default_authentication_plugin=mysql_native_password

  2. isaac says:

    Hi Carsten,,

    Should we still install postfix(smtp) based on you previous guide, if next cloud 14 asks us to configure smtp for the email service of our server?
    Thanks very much again

  3. Lars van Ravenzwaaij says:

    Hi Carsten,

    I finally got the time to secure my nextcloud with fail2ban as in your guide.

    But, … fail2ban refuses to restart ;-(

    The path for the nextcloud.log in your guide is /var/nc_data. In my installation the path is /var/data/nextcloud, so I made that amendment in the jail.d/nextcloud.local, but that doesn’t work.
    As soon as I remove the “logpath = “-statement completely, fail2ban can be started. Can you help me to solve this?

    Thanks Lars

    • Strange. Did you apply the proper permissions before and what error has been thrown if you changed the path? Does the nextcloud.log already exists while altering fail2ban?

  4. Vincent says:

    First, thank you for this write-up. I’m migrating from 16.04 and using this guide for a fresh install on a Hyper V environment with Ubuntu.

    I am however stuck at the step:

    Restart NGINX:

    sed -i s/\#\include/\include/g /etc/nginx/nginx.conf && service nginx restart

    After this command, it returns:

    Job for nginx.service failed because the control process exited with error code.
    See “systemctl status nginx.service” and “journalctl -xe” for details.

    and:

    ● nginx.service – nginx – high performance web server
    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
    Active: failed (Result: exit-code) since Thu 2018-11-01 03:30:20 EDT; 3min 10s ago
    Docs: http://nginx.org/en/docs/
    Process: 1962 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
    Process: 2043 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)
    Main PID: 892 (code=exited, status=0/SUCCESS)

    Nov 01 03:30:20 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance web server…
    Nov 01 03:30:20 Ubuntu-NextCloud nginx[2043]: nginx: [emerg] BIO_new_file(“/etc/ssl/certs/ssl-cert-snakeoil.pem”) failed (SSL: error:02001002:system library:
    Nov 01 03:30:20 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exited, code=exited status=1
    Nov 01 03:30:20 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘exit-code’.
    Nov 01 03:30:20 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high performance web server.

    and:

    — The result is RESULT.
    Nov 01 03:24:08 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance web server…
    — Subject: Unit nginx.service has begun start-up
    — Defined-By: systemd
    — Support: http://www.ubuntu.com/support

    — Unit nginx.service has begun starting up.
    Nov 01 03:24:08 Ubuntu-NextCloud nginx[1973]: nginx: [emerg] BIO_new_file(“/etc/ssl/certs/ssl-cert-snakeoil.pem”) failed (SSL: error:02001002:system library:
    Nov 01 03:24:08 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exited, code=exited status=1
    Nov 01 03:24:08 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘exit-code’.
    Nov 01 03:24:08 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high performance web server.
    — Subject: Unit nginx.service has failed
    — Defined-By: systemd
    — Support: http://www.ubuntu.com/support

    — Unit nginx.service has failed.

    — The result is RESULT.
    Nov 01 03:27:29 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance web server…
    — Subject: Unit nginx.service has begun start-up
    — Defined-By: systemd
    — Support: http://www.ubuntu.com/support

    — Unit nginx.service has begun starting up.
    Nov 01 03:27:29 Ubuntu-NextCloud nginx[1979]: nginx: [emerg] BIO_new_file(“/etc/ssl/certs/ssl-cert-snakeoil.pem”) failed (SSL: error:02001002:system library:
    Nov 01 03:27:29 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exited, code=exited status=1
    Nov 01 03:27:29 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘exit-code’.
    Nov 01 03:27:29 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high performance web server.
    — Subject: Unit nginx.service has failed
    — Defined-By: systemd
    — Support: http://www.ubuntu.com/support

    — Unit nginx.service has failed.

    I am not an Ubuntu expert and only really know my way around Windows. Any help is much appreciated!

    I’ve tried this several times from scratch already and I’ve read thru the thread and comment and I haven’t seen others with the same issue.

    • It seems you forgot to install ssl-cert as mentioned at the early beginning of this guide. Please verify the self signed certificates do exist, e.g.: ls /etc/ssl/certs/ssl-cert-snakeoil.pem – if not issue sudo apt install ssl-cert -y && service nginx restart. Cheers Carsten

      • Vincent says:

        Thank you for your quick reply.

        I did as you suggested. ls did not find the file.

        I then issues the second command and it returned:

        Building dependency tree
        Reading state information… Done
        ssl-cert is already the newest version (1.0.39).
        The following packages were automatically installed and are no longer required:
        app-install-data apt-clone archdetect-deb btrfs-tools cryptsetup-bin
        dmeventd dmraid dpkg-repack gir1.2-timezonemap-1.0 gir1.2-xkl-1.0
        grub-pc-bin kpartx kpartx-boot libdebian-installer4 libdevmapper-event1.02.1
        libdmraid1.0.0.rc16 libido3-0.1-0 liblvm2app2.2 liblvm2cmd2.02
        libtimezonemap-data libtimezonemap1 lvm2 python3-pam rdate u-boot-tools
        Use ‘sudo apt autoremove’ to remove them.
        0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
        ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
        Authentication is required to restart ‘nginx.service’.
        Authenticating as: vincent,,, (vincent)
        Password:
        ==== AUTHENTICATION COMPLETE ===
        Job for nginx.service failed because the control process exited with error code.
        See “systemctl status nginx.service” and “journalctl -xe” for details.

        and:

        ● nginx.service – nginx – high performance web server
        Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
        Active: failed (Result: exit-code) since Thu 2018-11-01 05:05:35 EDT; 1min 39s ago
        Docs: http://nginx.org/en/docs/
        Process: 2913 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)

        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance web server…
        Nov 01 05:05:35 Ubuntu-NextCloud nginx[2913]: nginx: [emerg] BIO_new_file(“/etc/ssl/certs/ssl-cert-snakeoil.pem”) failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen(‘/etc/ssl/certs/ssl-cert-snakeoil.pem’,’r’) error:2006D080:BIO routines:BIO_new_file:no such file)
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exited, code=exited status=1
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘exit-code’.
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high performance web server.

        and:

        Nov 01 05:05:26 Ubuntu-NextCloud sudo[2897]: pam_unix(sudo:session): session ope
        Nov 01 05:05:27 Ubuntu-NextCloud sudo[2897]: pam_unix(sudo:session): session clo
        Nov 01 05:05:27 Ubuntu-NextCloud polkitd(authority=local)[766]: Registered Authe
        Nov 01 05:05:35 Ubuntu-NextCloud polkitd(authority=local)[766]: Operator of unix
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance w
        — Subject: Unit nginx.service has begun start-up
        — Defined-By: systemd
        — Support: http://www.ubuntu.com/support

        — Unit nginx.service has begun starting up.
        Nov 01 05:05:35 Ubuntu-NextCloud nginx[2913]: nginx: [emerg] BIO_new_file(“/etc/
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exit
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high perfor
        — Subject: Unit nginx.service has failed
        — Defined-By: systemd
        — Support: http://www.ubuntu.com/support

        — Unit nginx.service has failed.

        — The result is RESULT.
        Nov 01 05:05:35 Ubuntu-NextCloud polkitd(authority=local)[766]: Unregistered Aut
        Nov 01 05:06:51 Ubuntu-NextCloud dmeventd[2965]: Cannot open lockfile [/run/dmev
        lines 2593-2615/2615 (END)
        Nov 01 05:05:26 Ubuntu-NextCloud sudo[2897]: pam_unix(sudo:session): session opened for user root by vincent(uid=0)
        Nov 01 05:05:27 Ubuntu-NextCloud sudo[2897]: pam_unix(sudo:session): session closed for user root
        Nov 01 05:05:27 Ubuntu-NextCloud polkitd(authority=local)[766]: Registered Authentication Agent for unix-process:2901:451994 (system bus name :1.72 [/usr/bin/pkttyagent –notify-fd 5 –fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_CA.UTF-8)
        Nov 01 05:05:35 Ubuntu-NextCloud polkitd(authority=local)[766]: Operator of unix-process:2901:451994 successfully authenticated as unix-user:vincent to gain ONE-SHOT authorization for action org.freedesktop.systemd1.manage-units for system-bus-name::1.73 [systemctl restart nginx.service] (owned by unix-user:vincent)
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Starting nginx – high performance web server…
        — Subject: Unit nginx.service has begun start-up
        — Defined-By: systemd
        — Support: http://www.ubuntu.com/support

        — Unit nginx.service has begun starting up.
        Nov 01 05:05:35 Ubuntu-NextCloud nginx[2913]: nginx: [emerg] BIO_new_file(“/etc/ssl/certs/ssl-cert-snakeoil.pem”) failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen(‘/etc/ssl/certs/ssl-cert-snakeoil.pem’,’r’) error:2006D080:BIO routines:BIO_new_file:no such file)
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Control process exited, code=exited status=1
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: nginx.service: Failed with result ‘exit-code’.
        Nov 01 05:05:35 Ubuntu-NextCloud systemd[1]: Failed to start nginx – high performance web server.
        — Subject: Unit nginx.service has failed
        — Defined-By: systemd
        — Support: http://www.ubuntu.com/support

        — Unit nginx.service has failed.

        — The result is RESULT.
        Nov 01 05:05:35 Ubuntu-NextCloud polkitd(authority=local)[766]: Unregistered Authentication Agent for unix-process:2901:451994 (system bus name :1.72, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_CA.UTF-8) (disconnected from bus)
        Nov 01 05:06:51 Ubuntu-NextCloud dmeventd[2965]: Cannot open lockfile [/run/dmeventd.pid], error was [Permission denied]

        Just a note. I had thought I followed every step, double checking along the way.

        • Something went wrong – what has been logged during the installation of ssl-certs? From my perspective the installation failed or your permissions are not properly applied.
          As long as the ssl-certs are not created nginx won’t start following my guide. Please first ensure your self signed certificates are installed properly following UBUNTU Howto.
          Please also verify the permissions on /etc/ssl.

  5. Hirsyandi says:

    Thx for your tutorial, now it perfectly running on my dedicated server. But now came some confusing trouble, my server use 7x Hdd, and formated with raid, total space available approx 7Tb at least, but i see in space available in nextcloud monitoring menu, the space remaing 600Mb, why nextcloud not use all my available storage space? And how to make nextcloud to use all space available? Raid controlled by server, i use ubuntu 18.04 with guided partition and lvm, thx for your help sir, i’m sory for my bad english sir

  6. Mario says:

    Hi,

    bei Punkt 1 sollte die Zeile
    “deb http://nginx.org/packages/mainline/ubuntu/ bionic nginx”

    besser

    “deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ bionic nginx”

    heissen, sonst bekommt man folgende Meldung beim update:
    “N: Skipping acquire of configured file ‘nginx/binary-i386/Packages’ as repository ‘http://nginx.org/packages/mainline/ubuntu bionic InRelease’ doesn’t support architecture ‘i386′”

    Gruss

  7. Marco says:

    Hi, kurze Frage zu deinen Guides. Ist es kein Risiko wenn alle das gleiche SQL DB Passwort „Nextcloud“ verwenden?
    Oder sollte dies geändert werden?
    Danke. Deine Guides sind wirklich klasse!

    • Danke! Ja, prinzipiell sollen Passwörter aus den Guides immer geändert werden, wobei die DB-Passwörter leider immer Klartext in der Nextcloud-Konfiguration stehen…Grüße, Carsten

  8. Stefan Seligmann says:

    Hi Carsten,
    my nextcloud actually is running on ubuntu 16.04. What would be the strategy tu upgrade to 18.04? Did you ever try an ‘in place’ upgrade (apt dist-upgrade)?
    Stefan

  9. Darek says:

    Great and complete tutorial. The first of those that I found on the Internet. Thank you.
    It would be useful to have information about the configuration of the case when the data folder is on an external disk (USB).

  10. Hartmut Funk says:

    Hallo Herr Rieger,

    vielen Dank für diese Anleitung. Habe es zusammen mit Ihrem Beitrag für Collabora installieren können, funktioniert alles prima.

    Nach vielen Versuchen der erste Beitrag, der auch funktioniert. SOllten wir es produktiv nutzen, würde ich gern Ihre Hilfe in Anspruch nehmen.

    Viele Grüße
    Hartmut Funk

  11. Thomas says:

    Hi I added the app circles to my nextcloud 14.
    I created some users in that circle and as described a fileshare should work.
    You can share files with that users from the circle but they never will get the share.
    There will be errormessages in nextcloud and I think it is about the configuration.
    I have made the configuration like you described here and tried a lot to solve it but without success.
    Maybe you can support me to solve my problem.

    Error message of nextcloud:

    Error index OC\User\NoUserException: 2018-10-01T16:35:05+0200
    Error PHP Undefined index: circle_owner at /var/www/domain/nextcloud/apps/circles/lib/ShareByCircleProvider.php#651 2018-10-01T16:35:05+0200
    Error PHP Undefined index: circle_type at /var/www/domain/nextcloud/apps/circles/lib/ShareByCircleProvider.php#650

  12. Robin Johansson says:

    Hi,
    The Spamhouse configuration in this guide, can I use it on my WordPress site also?
    And maybe also in my Proxy?

  13. Klaus says:

    Hallo Hr. Rieger, wie funktioniert denn die Installation auf einem Odroid HC-1 ? Es gab von Ihnen mal eine Anleitung, die das Kompilieren des Nginx zeigte. So läuft meine NC 13 derzeit.
    Binärpakete von nginx.org sind für armhf wohl nicht verfügbar. Ich scheitere bereits bei Schritt mit einer entsprechenden Fehlermeldung. Danke und viele Grüße.

  14. Olle says:

    All of the PHP-packets does not exist in the standard repo. Where do I get them?

    • sudo -s
      mv /etc/apt/sources.list /etc/apt/sources.list.bak && vi /etc/apt/sources.list


      deb http://archive.ubuntu.com/ubuntu bionic main multiverse restricted universe
      deb http://archive.ubuntu.com/ubuntu bionic-security main multiverse restricted universe
      deb http://archive.ubuntu.com/ubuntu bionic-updates main multiverse restricted universe

      apt update

  15. Malte says:

    Hallo Herr Rieger,

    ich habe Nextcloud 14 und Nextcloud Talk nach der Anleitung installiert.
    Es funktioniert auch alles bis auf eine Fehlermeldung bestens.

    Jedes mal, wenn ein Viedeo hochgeladen wird und das entsprechende Vorschaubild generiert wird, kommt folgende Fehlermeldung:

    unlink(/upload_tmp/oc_tmp_MtwwCC): No such file or directory at /var/www/nextcloud/lib/private/Preview/Movie.php#111

    In der Dateiansicht ist das Vorschaubild auch vorhanden, also alles gut.
    Was hat es mit der Fehlermeldung auf sich? Was habe ich übersehen?

    Vielen Dank im Voraus.

  16. Andreas says:

    Hallo Herr Rieger,

    ich bekomme immer folgende Fehlermeldung:

    Die folgenden Pakete haben unerfüllte Abhängigkeiten:
    letsencrypt : Hängt ab von: certbot soll aber nicht installiert werden
    E: Probleme können nicht korrigiert werden, Sie haben zurückgehaltene defekte Pakete.

    Es handelt sich um eine frisch installierte Ubuntu 18.04.1 LTS in einer VMware ESXi Umgebung.

    • Hallo Andreas, es lässt sich bei mir nicht reproduzieren. Hast Du alle Befehle ausgeführt?
      apt update && apt upgrade -y && apt install software-properties-common zip unzip screen curl ffmpeg libfile-fcntllock-perl -y
      add-apt-repository ppa:certbot/certbot -y && apt update && apt upgrade -y && apt install letsencrypt -y

      Gab es Fehler dabei (mit Ausnahme des von Dir geposteten)?

      • Andreas says:

        die Befehle habe ich ausgeführt, beim ersten kommt nur dass für das Paket ffmpeg kein Installationskandidat zur Verfügung steht.

  17. Robin says:

    Can’t see that 14 is released yet at Nextcloud page – latest stable release is 13.0.6 or do I miss something?

  18. Felix says:

    Hi, Mr. Rieger.

    Is there any workaround for an ISP blocking 443 port? Actually, can listen on 80 port. Asked DDNS provider (No-IP) if there’s any possibility of forwarding traffic from port 443 to 80, support ticket still open.

    Thanks in advance for all the great work. If ever on Chile, def could invite you a beer. 🙂

    • Wow…thanky you … unfortunately it depends on your ISP and forward 443 to 80 is not recommended.

      • Felix says:

        After some struggling, able to open 443. Works like a charm!

        However, need to point nc_data to a mirrored ZFS dataset, rather than the SSD where OS is running. Can nc_data path be changed during install, or should rather be using another approach?
        According to NC documentation, moving nc_data after install is unsupported, and according to users, it can be quite a bumpy road.

        Tried both to install and move /var/www to such dataset via rsync, but could not make it work. BTW: Have you considered, or is possible to select NC data folder during install instructions /script, or, it’s just me missing something here?

        Thank you, again.

  19. Damir says:

    Hello Carsten,

    thank you for the great guide! 🙂

    I followed your guide and installed all successfully at first try and also installed Collabora.

    At first day all running flawlessly, at second day i got the error that Collabora can not load the files from storage
    i tried to access with the Filesync App but got Authentication Header Baerer not found so i try to solve this issues.

    So i checked the /etc/nginx/nginx.conf and located this
    #include /etc/nginx/proxy.conf;
    #include /etc/nginx/ssl.conf;
    #include /etc/nginx/header.conf;
    #include /etc/nginx/optimization.conf;

    In the guide this files were created, but in the nginx.conf are these files disabled is therefor a reason ?

    Best,
    Damir

  20. Hdsee says:

    Hi is this guide work with raspberry pi 3 ?

  21. Jan says:

    …Ah, i answered it by myself. TLS 1.3 is only possible with OpenSSL 1.1.1, which is in “Beta” at the moment.

    Regards, Jan

  22. Jan says:

    Hi Carsten,

    why is SSLlabs and other sites like this only showing that TLS1.2 is working, but not v1.3? My browsers are connecting via 1.2 too.
    Is it not working at the moment or is there an error somewhere in the config? I can’t see any error messages in the logs.

    Best regards
    Jan

  23. Matthias says:

    That’s right. I’ve moved my logfile to /var/log/nextcloud/nextcloud log. The path in the jail is correct and the logfile is written correctly. Should that be a problem?

    • Chung says:

      I had the same problem with you, and after some research, I am able to fix it by add the tag to the failregex lines.

      According to Fail2ban’s wiki page (https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters), the tag has to be present in every line of failregex.

      My Nextcloud filter is now like following:

      ^{“reqId”:”.*”,”remoteAddr”:”.*”,”app”:”core”,”message”:”Login failed: ‘.*’ (Remote IP: ”)”,”level”:2,”time”:”.*”}$
      ^{“reqId”:”.*”,”level”:2,”time”:”.*”,”remoteAddr”:”.*”,”app”:”core”.*”,”message”:”Login failed: ‘.*’ (Remote IP: ”)”.*}$
      ^.*”remoteAddr”:””.*Trusted domain error.*$

  24. Daniel says:

    Great tutorial –> good job!

  25. Matthias Kern says:

    Hi,
    with fail2ban I get the following error message, when trying the regex:

    fail2ban-regex /var/log/nextcloud/ /etc/fail2ban/filter.d/nextcloud.conf

    ERROR: No failure-id group in ‘^{“reqId”:”.*”,”remoteAddr”:”.*”,”app”:”core”,”message”:”Login failed: ‘.*’ (Remote IP: ”)”,”level”:2,”time”:”.*”}$’

    I copied the jail from this website but fail2ban doesn’t seem to like it.
    It’s Ubuntu 18.04, fail2ban 0.10.2.

    Do you also get that error?

    • Please check the path to Nextclouds log. If you followed my guide the path would be /var/nc_data/nextcloud.log. But you pointed to /var/log/nextcloud, Or amend your files to your path/environment properly.

Leave a Reply

Your email address will not be published. Required fields are marked *