Hello Nextcloudcomunity,
iām new here and only recently started working on Linux, servers, nextcloud and more.
But I am very curious and want to host my own cloud. Iāve been working on that for many days and weeks now, but Iām having some problems that make me delete my LXCs again and again and have to start from scratch.
I would like to run my Nextcloud on an LEMP stack (i.e. with Nginx) behind a reverse proxy (also with Nginx).
But I seem to have a problem of understanding, because it just does not want to work. So first my simple question:
If I have Letās Encrypt with certbot on my reverse proxy (LXC 1), i.e. the communication up to my reverse proxy in my local network is SSL encrypted, how important is it to set this up on my Nextcloud LXC (2) as well? Or can the communication between Reverse Proxy and Nextcloud be unencrypted ? What are the advantages and disadvantages ?
Otherwise I obviously have some problem to set up the nginx configuration of the virtual host correctly.
Iām pretty desperate because I donāt know where the error is.
It would be great if you could help me.
Most examples youāll see deal with #1 where the reverse proxy terminates the SSL connection and then uses http to the backend. This technically is going to be the fastest way to server many users. The backend connection however will be unencrypted. (Just for reference ā nginx calls the backend āupstreamā so if googling for examples from the nginx documentation ā use the word āupstreamā). If you donāt trust your internal LAN ā or there are potential weakness in your LAN then this might be a problem.
SSL terminating and re-encrypting can also be performed. Usually the backend certificates are self-signed, however there is no reason you couldnāt use LE certs for backend communication as well. Since you control the reverse proxy and the nextcloud server ā if you really wanted to get fancy/smancy with the encryption you could use client SSL certificates as well as server-side SSL certificates (LE certs are exclusively server-side SSL certificates). Computationally having to decrypt/re-encrypt is more expensive and itās likely slower if you are serving a lot of users. Iāve seen however some debate about this theory particularly if using CPUs (Intelās) that have AES-NI built-in (which are most modern processors). I havenāt run any tests which would demonstrate the speed or computational cost of this setup, however if you are only going to serve a handful of users, youāll likely not notice any difference. This setup could be used if you donāt really trust your LAN or if itās required by law ā for example dealing with HIPPA-compliant data or banking data.
To take things a step farther you could also setup a collabora docker or native installation that is also protected by SSL certificates ā so itās always possible to do a triple-SSL connected stream -->reverse proxyā>nextcloudā>collabora (or open office).
Iāve implemented both #1 and #3 in my setup and usually just do #3 for security purposes ā itās likely overkill but I just wanted to see if I could set everything up.
Hello, kevdog,
Thank you for your explanation.
Option #3 sounds like what I actually want to do. It sounds more straightforward and if Iām going for SSL encryption, Iād like to go all the way. Overkill or not.
The thing with the certificates is not quite clear to me yet.
To be a bit more concrete, I had the following setup:
First I secured my Nextcloud LXC with LE and created SSL certificates for my Nextcloud subdomain with certbot. This worked so far.
After that I tried to connect the reverse proxy, created again a SSL certificate for my Nextcloud subdomain with certbot and tried to forward the traffic to the internal IP address of my Nextcloud LXC. In this case I always got a redirection error when I tried to access the Nextcloud URL.
Can, must, should the certificates be identical on both the reverse proxy (LXC1) and on the Nextcloud (LXC2) and go to my subdomain both times ?
Those were my configs:
Sorry if the formatting of my Configs is not perfect
On nextcloud-LXC
/etc/nginx/sites-enabled/nextcloud
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/var/run/php/php7.4-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name subdomain.domain.tld;
# enforce https
return 301 https://$server_name:443$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name subdomain.domain.tld;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# NOTE: some settings below might be redundant
ssl_certificate /etc/letsencrypt/live/subdomain.domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.tld/privkey.pem;
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/nextcloud;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
# The following rule is only needed for the Social app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
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 ap>
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
And here is the config on my reverse proxy:
server {
server_name subdomain.domain.tld;
location / {
proxy_pass https://192.168.1.120/; #internal IP address of the LXC where my Nextcloud runs
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/subdomain.domain.tld/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.tld/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = subdomain.domain.tld) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name subdomain.domain.tld;
return 404; # managed by Certbot
}
Nobody but kevdog uses a reverse proxy and full SSL encryption and can help me with this problem ?
I would never have thought that my problem was so unique and difficult. How did you solve it alternatively, so that such problems donāt arise at all ?
Have you tried #1 as an interim solution to verify that you can get it working without SSL? I have the same setup (but with FAMP stacks) and it has worked without any trouble for years. I canāt help specifically since I donāt knwo nginx, but I have a general tip. It can be problematic to have two things that can fail as a novice. Try to get the simple working and then add complexity. So I would do the following if I where you
Try to get #1 working, so you know that the reverse proxy part works
Check your logs. There should be clues in the error logs for nginx, on either the proxy or nextcloud container. Set the log level to debug, try to load the site and look in the logs for clues what went wrong.
Hello, Kebba,
a good suggestion. I tried it once. But I donāt even have the possibility to get the IP address via http
Whenever I type http://IP-Adresse of my Nextcloud installation in my browser, it automatically changes it to https and I get the message āConnection failedā.
I still think your idea is good to start with the simple things, but obviously nothing works without SSL already here.
Iām getting desperate about all these problems
I can help you but not until next week. Traveling however I have a reverse re-encrypting proxy with SSL server certs for my setup. I donāt have access to my setup till then. Looking at setup quickly it doesnāt seem you have headers setup correctly. Take a look at this post as this was my starting point:
Hi kevdog,
nice to hear from you and thanks for your help. That would be great.
You seem to know a lot about the subject
Parallel to your link I found a āsolutionā which is obviously not quite clean yet, but at least it works.
I have now encrypted both my Nextcloud LXC and my Reverse Proxy -LXC with my subdomain SSL, and I have concocted a reverse proxy configuration that runs on a warning, but otherwise works.
Outside of my network everything seems to work by calling my URI and the access via reverse proxy to my nextcloud works as well.
But if I call the same URI from my internal network, I can access my Nextcloud as well, but my internal IP address will be displayed.
I have also just configured fail2ban. If I logged in incorrectly in the past (before the reverse proxy setting), my external router IP was displayed as the banned IP address. Now the internal IP address of my end device. So -why- the internal access seems to work only internally. Very confusing the whole thing
I also tried to add the headers from your link in my Reverse Proxy Config, but then I get a ā500 Internal Server Errorā message.
Iām not sure what you mean by this: āBut if I call the same URI from my internal network, I can access my Nextcloud as well, but my internal IP address will be displayedā
Is this what you are doing:
externalā>Rv proxyā>nextcloud
And also attempting this:
internalā>Rv proxyā>nextcloud
Hi kevdog,
yes, thatās exactly what I meant. I would have expected that the way is the same (no matter if internal or external) when I call my subdomain.
If I change the proxy_redirect from the current config to your suggested one, I get the following error message during the syntax check:
nginx: [warn] the āsslā directive is deprecated, use the ālisten ā¦ sslā directive instead in /etc/nginx/sites-enabled/subdomain.domain.tld.conf:23
nginx: [emerg] invalid parameter āhttps://subdomain.domain.tldā in /etc/nginx/sites-enabled/subdomain.domain.tld.conf:40
nginx: configuration file /etc/nginx/nginx.conf test failed
I usually get the warning message, but it still works. With the error I now get when I remove the ip-address from the config, it doesnāt work anymore.
About DNS: I use the DynDNS service of my domain operator. In addition, my router has the function that I can connect the DynDNS service of my domain operator directly with it.
Option 1 for your first post is exactly what I am looking for. I would like to use http within my LAN but https from outside. Is this possible? Could you point me at a tutorial? Thanks in advance.
I can point you in right direction for sure. Whatās your nextcloud setup looking like ā OS host, is it docker, native, etc? What reverse proxy were you thinking about using?
Ok I donāt know anything about the RPi, however I donāt think that really is too important. You have a base Nextcloud installation with Nginx Webserver using fpm. Was there a particular reverse proxy you were looking at? Would the reverse proxy be located on the same machine or different location?
The reverse proxy would be on the same machine. I have my Pi open to the world on ports 80 and 443. Port 80 automatically redirects to 443 on https and is currently serving a Wordpress site. I have the nextcloud on a different port that is only available on the LAN. I used the nginx reverse proxy example config file from the Nextcloud documenation but with all the ssl parts removed.
That worked fine for initial installation, but then I couldnāt log in as the login page was trying to return the form using https, which violated the content security policy.
I changed overwrite.cli.url to http instead of https and added a line:
āoverwriteprotocolā => āhttpā in the config.php file.
Since doing that (and installing php.intl) everything has worked fine on the LAN, but was that the most efficient and safe way of doing things?
As for the reverse proxy, I was going to add a ālocation ^nextcloud/ {}ā block to my port 443 server. I presume I will have to change the host to match the LAN host before the proxy pass (or add a new trusted host to Nextcloud), but do I have to do anything on the way back? Iāve not tried yet, as Iāve spent the last couple of days checking that my LAN installation was actually working properly.
Iād ideally have an indendent reverse proxy. This could be on the same machine or different machine. Yes you could repurpose your nginx webserver running your nextcloud to be both a webserver and reverse proxy ā however I kind of like the modular concept that you have one tool do one job ā its easier to debug, and its easier to replace or move to a different machine in the future. Youāre on a RPie. Can that do docker?
Depending on your situation you are going to have to pick a reverse proxy ā either nginx (or nginx proxy manager ā which provides GUI and will do Letsencrypt renewals automatically but requires docker), traefik (which I think it also requires docker ā I run it in docker but there maybe a native option), or caddy. All these products will do automated LetsEncrypt renewals (not nginx without npm).
Iād recommend using subdomains rather than subdirectories if possible. So for example nextcloud.domain.com rather than domain.com/nextcloud. Reverse proxies in general seem to function better and less prone to error with subdomains rather than subdirectories.
Hey guys
Just saw this thread and Iām hoping kevdog is still listening to it and willing to give further advice.
So, I have a Nextcloud server up on Apache and I can get to it with a separate Nginx reverse proxy server via http. Nextcloud really balks though in the system status check, and some things arenāt even useable like passwords, if youāre not using https.
That said, I think I need to do option #3 (https to Nginx-reencrypt and forward to Nextcloud) Barring an issue I think Iām having with Letsencrypt not downloading certs to the āLiveā directory what is the proper way to set this up?
First, Can I use the same Subdomain that I get to use from NoIP or Dynu from LetsEncrypt on both machines? If not, what the alternative (self signed? - and if self signed which machine should that go on?). I think I read something that Letsencrypt doesnāt let you download multiple certs for the same subdomain/domain. Also, if itās self signed how can I set it up to be nonexpiring?
Second, I want to do this in pieces to reduce the troubleshooting variables of where it may not be working. So first I want to bring it up on the reverse proxy default html. Actually I donāt even care if it goes to Apacheās default http html as long as I can see that the Nginx certs are working correctly. Than Iād like to know the ācodeā and where to put it to do the reencryption and forward to Apacheās https (that way I limit it to either something being wrong with the reencryption and forward code or something wrong with the Apache cert setup).
Any help is greatly appreciated.
I think I have it from what Iām reading from the Nextcloud documentation. I think I need to use X-FORWARD and config my reverse proxy machine in Nextcloud as a ātrusted proxyā. Weāll see how it goes