Nextcloud 15, NGINX 1.15.7, OpenSSL 1.1.1 and TLS 1.3

This guide based on the initial Nextcloud installation guide. Following this guide you will harden your Nextcloud server (AMD64/ARM64) even more using NGINX 1.15.7 and OpenSSL 1.1.1 by  adding TLS 1.3 encryption to your SSL configuration as simple as follows:


sudo -s
cd /usr/local/src
wget && apt-key add nginx_signing.key
vi /etc/apt/sources.list

Add the folowing two rows:

deb bionic nginx
deb-src bionic nginx

deb stretch nginx
deb-src stretch nginx


Then update your system repositories and go ahead with the OpenSSL configuration:

apt update
mkdir /usr/local/src/nginx && cd /usr/local/src/nginx/
apt install dpkg-dev -y && apt source nginx
cd /usr/local/src && apt install git -y
git clone
cd openssl && git branch -a

git checkout OpenSSL_1_1_1-stable


Now prepare your NGINX binaries. Open the rules file

vi /usr/local/src/nginx/nginx-1.15.7/debian/rules

a) add the following statement two times


b) change

dh_shlibdeps -a


dh_shlibdeps -a --dpkg-shlibdeps-params=--ignore-missing-info

To prevent further warnings edit the gcc:

vi /usr/local/src/nginx/nginx-1.15.7/auto/cc/gcc

Change your directory back and start compiling NGINX:

cd /usr/local/src/nginx/nginx-1.15.7/
apt build-dep nginx -y && dpkg-buildpackage -b

To be ignored:

“dpkg-buildpackage: error: failed to sign .buildinfo file”

Remove any existing NGINX installations/instances:

apt remove nginx nginx-common nginx-full -y --allow-change-held-packages
cd /usr/local/src/nginx/

Install the new built NGINX

dpkg -i nginx_1.15.7*.deb

If the service will be masked please unmask it:

systemctl unmask nginx


service nginx restart

and prevent NGINX from being updated automatically:

apt-mark hold nginx


nginx -V

and you will find information about your new NGINX

TLS 1.3

Now open your Nextcloud ssl.conf and enhance this configuration for TLS 1.3 purposes:

vi /etc/nginx/ssl.conf

Change the ssl_protocols to

ssl_protocols TLSv1.2 TLSv1.3;

and add “TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:” to your current ciphers:

ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:...

More secure but less compatible:

ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:...

Restart your NGINX

service nginx restart

and test your Nextcloud server regarding TLS 1.3

in Firefrox ≥ v. 63.0.

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.

22 Responses

  1. miklor says:

    Hi Carsten and thank you for this awesome guide 😀
    I have some issues with fail2ban, which does not detect failed logins..

    The day before the release of Nextcloud 15 I followed your guide with Nextcloud 14 and I got everything working as it should. I tested fail2ban with wrong username and password 3 times in a row and got banned for 10 hours. So version 14 and fail2ban was a success.
    I have now tried with Nextcloud 15 and also tried to do a reinstall 4 times, but fail2ban does not react on “brute-force” attempts.

    The output from: fail2ban-regex /var/nc_data/nextcloud.log /etc/fail2ban/filter.d/nextcloud.conf looks correct and it seems like the regex is working.

    Use failregex filter file : nextcloud, basedir: /etc/fail2ban
    Use log file : /var/nc_data/nextcloud.log
    Use encoding : UTF-8


    Failregex: 6 total
    |- #) [# of hits] regular expression
    | 2) [6] ^{“reqId”:”.*”,”level”:2,”time”:”.*”,”remoteAddr”:”.*”,”app”:”core”.*”,”message”:”Login failed: ‘.*’ \(Remote IP: ”\)”.*}$

    Ignoreregex: 0 total

    Date template hits:
    |- [# of hits] date format
    | [10] Year-Month-Day[T ]24hour:Minute:Second(?:\.Microseconds)?(?:Zone offset)?

    Lines: 10 lines, 0 ignored, 6 matched, 4 missed
    [processed in 0.02 sec]

    When I test fail2ban on SSH, it works fine. In /var/log/fail2ban.log I can see the SSH attempts, but none from Nextcloud.
    Am I missing something or doing something wrong or has anyone had a similar experience?

  2. Dirk says:

    Hello Carsten,
    first of all: thank you very much for your tutorials, I find them very helpful!

    I have tried to solve my problem for many hours: I’m trying to set up TLS 1.3 with nginx on Debian, I followed your tutorial and set up everything correctly (built nginx with openssl 1.1.1b-dev, set TLSv1.3, and ciphers (just like you) in my nginx vhost and restarted nginx, but still Firefox 63 and Chrome 71 display TLSv1.2 and not TLSv1.3, also running the openssl command with tls_1_3 gives me an error, and ssllabs also only says YES for TLSv1.2…
    It’s quite annoying…

    Do you know what the problem might be?

    Thanks for your help!

    • Please post your output: nginx -V

      • Dirk says:

        Here it is:

        nginx version: nginx/1.15.7
        built by gcc 8.2.0 (Debian 8.2.0-9)
        built with OpenSSL 1.1.1b-dev xx XXX xxxx
        TLS SNI support enabled
        configure arguments: –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/ –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-compat –with-file-aio –with-threads –with-http_addition_module –with-http_auth_request_module –with-http_dav_module –with-http_flv_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_mp4_module –with-http_random_index_module –with-http_realip_module –with-http_secure_link_module –with-http_slice_module –with-http_ssl_module –with-http_stub_status_module –with-http_sub_module –with-http_v2_module –with-mail –with-mail_ssl_module –with-stream –with-stream_realip_module –with-stream_ssl_module –with-stream_ssl_preread_module –with-cc-opt=’-g -O2 -fdebug-prefix-map=/usr/local/src/nginx/nginx-1.15.7=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC’ –with-ld-opt=’-specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,–as-needed -pie’ –with-openssl=/usr/local/src/openssl –with-openssl-opt=enable-tls1_3

        • The last statement (–with-openssl-opt=enable-tls1_3) points to differences according to my instructions. Please double check your nginx rules file.

          • Dirk says:

            I compiled it using your statements first and it also didn’t work, then I found this “enable-tls_1_3) and compiled nginx with that, but no luck. I also amended the nginx-options-ssl file in /etc/letsencrypt…

            Is it necessary to reissue the ssl certificate my for domain?

          • no, it isn’t necessary. find the diff’s between your rules-file and mine and follow this guide again step by step – that will solve your issue.
            What errors are thrown while compiling NGINX as i described?

        • Dirk says:

          I recompiled nginx strictly following your tutorial. This is my output of nginx -V now:

          nginx version: nginx/1.15.7
          built by gcc 8.2.0 (Debian 8.2.0-9)
          built with OpenSSL 1.1.1b-dev xx XXX xxxx
          TLS SNI support enabled
          configure arguments: –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/ –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-compat –with-file-aio –with-threads –with-http_addition_module –with-http_auth_request_module –with-http_dav_module –with-http_flv_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_mp4_module –with-http_random_index_module –with-http_realip_module –with-http_secure_link_module –with-http_slice_module –with-http_ssl_module –with-http_stub_status_module –with-http_sub_module –with-http_v2_module –with-mail –with-mail_ssl_module –with-stream –with-stream_realip_module –with-stream_ssl_module –with-stream_ssl_preread_module –with-cc-opt=’-g -O2 -fdebug-prefix-map=/usr/local/src/nginx/nginx-1.15.7=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC’ –with-ld-opt=’-specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,–as-needed -pie’ –with-openssl=/usr/local/src/openssl

          This is the error output after compiling nginx:

          dpkg-genchanges: info: binary-only upload (no source code included)
          dpkg-source –after-build .
          dpkg-buildpackage: info: binary-only upload (no source included)
          signfile nginx_1.15.7-1~stretch_amd64.buildinfo
          gpg: skipped “Konstantin Pavlov “: No secret key
          gpg: dpkg-sign.hMnxXkSw/nginx_1.15.7-1~stretch_amd64.buildinfo: clear-sign failed: No secret key

          dpkg-buildpackage: error: failed to sign .buildinfo file

          Nothing out of the ordinary, right?

          But after restarting nginx, chrome says for my nextcloud still:

          Connection – secure (strong TLS 1.2)
          The connection to this site is encrypted and authenticated using TLS 1.2 (a strong protocol), ECDHE_RSA with X25519 (a strong key exchange), and AES_256_GCM (a strong cipher).

          It really doesn’t make any sense…

          • Please send me your URL – i will double check this. Did you ammend your ssl.con either?

          • Thank you for your URL: you forgot to add the new cipher etc. as mentioned “TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:” to your current ciphers”

          • Dirk says:

            … I did that but still no luck. I tried to put the ssl settings (cipher, TLSv.13,… everywhere, in the /etc/letsencrypt/options-ssl-nginx.conf, in /etc/nginx/nginx.conf and in my vhost in /etc/nginx/sites-enabled/

            And it still does not work… It’s crazy. Do you have any hint?

          • Dirk, please follow my guide in every little step and it will work or provide me your conf-files. For sure, you forgot to change few things!

  3. isaac says:

    hello Carsten,

    how do we upgrade nginx with this guide, nginx version is now 1.15.6 previously i built it with 1.15.5

    thanks very much

  4. Alex says:

    I like your posts! You help is very appreciated! All the best for you.


  5. Lars van Ravenzwaaij says:

    Hi Carsten,
    First, many thanks for all of your helpfull guides on setting up nextcloud!
    This guide for implementing openssl 1.1.1 is based on your ubuntu-setup. Can it also be used on your debian-setup?



  6. isaac says:

    Hi Carsten,

    I tried to compile nginx 1.15.5 with openssl 1.1.1 but added the nginx-cahce purge module with it based on your previous guide
    … it successfully compiled, any reason why you did not include anymore with the new tutorial?

    Problem is, upon testing with ssl labs, I get an orange warning of HTTP server test failed due to HTTP forwarded— too many redirection!
    does the nginx cache purge module have anything to do with this?

    thanks very much

    • from time to time i recognized it either on different systems. it is related to Nextclouds database. Please doublecheck it very simple:
      move your current config.php
      mv /var/www/nextcloud/config.php /var/www/nextcloud/config.php.bak
      then re-run the check. The warnings will disappear. Don’t forget to copy the config back
      cp /var/www/nextcloud/config.php.bak /var/www/nextcloud/config.php
      If your Nextcloud DB is still empty/not productive you may also create an empty new Nextcloud db and re-run the check successfully.
      Regarding the ngx_cache_purge-module – i do not maintain the previous guide any longer … but feel free to compile nginx containing this module!

  7. isaac says:

    Hi Carsten,
    Thank you for this wonderful guide. Using TLS 1.3 and openssl 1.1.1 seem to reduce the score we get with SSL labs. It weakens the key exchange and cipher strength
    score only to 90%. I just thought you should know and the problem seem to be related to this …..

    thanks again

Leave a Reply

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