Too many redirects error when using nginx reverse proxy

Hi there!

I’m using truenas and i’m running nextcloud in a jail of it’s own. Now, in a different jail I have an nginx proxy set up that is working well with radarr/sonarr, but keeps returning ERR_TOO_MANY_REDIRECTS with Nextcloud. Using curl -v https_domain_name shows an error 301 - moved permanentily.

Nextcloud version (eg, 20.0.5): 25.0
Operating system and version (eg, Ubuntu 20.04): TrueNas FreeBSD

Nextcloud config.php:

root@nc:/usr/local/www/nextcloud/config # cat config.php
<?php
$CONFIG = array (
  'apps_paths' =>
  array (
    0 =>
    array (
      'path' => '/usr/local/www/nextcloud/apps',
      'url' => '/apps',
      'writable' => true,
    ),
    1 =>
    array (
      'path' => '/usr/local/www/nextcloud/apps-pkg',
      'url' => '/apps-pkg',
      'writable' => false,
    ),
  ),
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'one-click-instance' => true,
  'one-click-instance.user-limit' => 100,
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => 'localhost',
  ),
  'passwordsalt' => 'deleted',
  'secret' => 'deleted/',
  'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => 'ip_of_my_truenas_instance',
    2 => 'nextcloud.domainname.com',
  ),
  'datadirectory' => '/usr/local/www/nextcloud/data',
  'dbtype' => 'mysql',
  'version' => '25.0.0.18',
  'overwrite.cli.url' => 'http://localhost',
  'dbname' => 'deleted',
  'dbhost' => 'deleted',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'deleted',
  'dbpassword' => 'deleted',
  'trusted_proxies' =>
  array (
	0 => 'ip_of_my_proxy',
	),
);

Nginx nextcloud config (on nextcloud jail)

root@nc:/usr/local/etc/nginx/conf.d # cat nextcloud.conf
upstream php-handler {
    server unix:/var/run/nextcloud-php-fpm.sock;
}

# Redirect to HTTPS
server {
    listen 80 default_server;
    listen [::]:80;

    location ^~ /.well-known/acme-challenge {
        # Path to the root of your installation
        root /usr/local/www/nextcloud/;
        try_files $uri $uri/ =404;
    }

    location / {
       return 301 https://$host:443$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name _;
	
	add_header Strict-Transport-Security "max-age=15768000; includeSubDomains;"
always;
	
	include conf.d/nextcloud.inc;
}

Nginx config (on nextcloud jail)

root@nc:/usr/local/etc/nginx # cat nginx.conf
load_module /usr/local/libexec/nginx/ngx_mail_module.so;
load_module /usr/local/libexec/nginx/ngx_stream_module.so;

user www;
worker_processes auto;

pid /var/run/nginx.pid;

events {
  use kqueue;
  worker_connections 1024;
  multi_accept on;
}
http {

  # Basic settings
  # ----------

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  reset_timedout_connection on;
  keepalive_timeout 65;
  keepalive_requests 1000;
  types_hash_max_size 2048;
  server_tokens off;
  send_timeout 30;
  server_names_hash_max_size 4096;

  # Common limits
  # ----------

  client_max_body_size 100m; # upload size
  client_body_buffer_size 1m;
  client_header_timeout 3m;
  client_body_timeout 3m;

  client_body_temp_path /var/tmp/nginx/client_body_temp;

  proxy_connect_timeout 5;
  proxy_send_timeout 10;
  proxy_read_timeout 10;

  proxy_buffer_size 4k;
  proxy_buffers 8 16k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;

  proxy_temp_path /var/tmp/nginx/proxy_temp;

  include mime.types;
  default_type application/octet-stream;

  # Logs format
  # ----------

  log_format main '$remote_addr - $host [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"'
                  'rt=$request_time ut=$upstream_response_time '
                  'cs=$upstream_cache_status';

  log_format cache '$remote_addr - $host [$time_local] "$request" $status '
                   '$body_bytes_sent "$http_referer" '
                   'rt=$request_time ut=$upstream_response_time '
                   'cs=$upstream_cache_status';

  access_log /var/log/nginx/access.log main;
  error_log /var/log/nginx/error.log warn;

  # GZip config
  # ----------

  gzip on;
  gzip_static on;
  gzip_types text/plain text/css text/javascript text/xml application/x-javascript application/javascript application/xml application/json image/x-icon;
  gzip_comp_level 9;
  gzip_buffers 16 8k;
  gzip_proxied expired no-cache no-store private auth;
  gzip_min_length 1000;
  gzip_disable "msie6"
  gzip_vary on;

  # Cache config
  # ----------

  proxy_cache_valid 1m;

  # Virtual host config
  # ----------

  # SSL
  # ----------

  ssl_certificate /usr/local/etc/letsencrypt/live/nextcloud.domainname.com/fullchain.pem;
  ssl_certificate_key /usr/local/etc/letsencrypt/live/nextcloud.domainname.com/privkey.pem;
  # Verify chain of trust of OCSP response using Root CA and Intermediate certs
  ssl_trusted_certificate /usr/local/etc/letsencrypt/live/nextcloud.domainname.com/chain.pem;

  ssl_session_timeout 1d;
  ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
  ssl_session_tickets off;

  # intermediate configuration
  # Keep only TLS 1.2 (+ TLS 1.3)
  ssl_protocols TLSv1.2 TLSv1.3;
  # Use only strong ciphers
  ssl_ciphers TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  # Use more secure ECDH Curve
  ssl_ecdh_curve X25519:P-521:P-384:P-256;
  # Defend against the BEAST attaack
  ssl_prefer_server_ciphers off;
  
  #OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  
  include /usr/local/etc/nginx/conf.d/*.conf;
 }

Nginx config (on reverse proxy)

root@reverseproxy:/usr/local/etc/nginx # cat nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    # Redirect all HTTP traffic to HTTPS
    server {
		listen 80 default_server;
		listen [::]:80 default_server;
		
		return 301 https://$host$request_uri;
	}
	
	# Import server blocks for all subdomains
	include "vdomains/*.conf";
}

Nginx domain config (on reverse proxy)

root@reverseproxy:/usr/local/etc/nginx # cat vdomains/nextcloud.domainname.com.conf
server {
        listen 443 ssl http2;

        server_name nextcloud.domainname.com;
        access_log /var/log/nginx/cloud.access.log;
        error_log /var/log/nginx/cloud.error.log;

        include snippets/nextcloud.domainname.com.cert.conf;
        include snippets/ssl-params.conf;

        location / {
                include snippets/proxy-params.conf;
				proxy_pass ip_of_my_nextcloud_jail;
		}
		location /.well-known/carddav {
			return 301 $scheme://$host/remote.php/dav;
		}
		location /.well-known/caldav {
			return 301 $scheme://$host/remote.php/dav;
		}		
}

Nginx proxy config (on reverse proxy)

koi-utf              nginx.conf.save      uwsgi_params-dist
koi-win              scgi_params          vdomains/
mime.types           scgi_params-dist     win-utf
mime.types-dist      sites_enabled/
nginx.conf           sites-enabled/
root@reverseproxy:/usr/local/etc/nginx # cat snippets/proxy-params.conf
add_header Front-End-Https    on;
add_header Strict-Transport-Security "max-age=2592000; includeSubdomains";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Upgrade %http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

To me it appears there is some conflict or some minor missmatch between the reverse-proxy nginx config and the nextcloud jail config, but I’ve been trying to find it for a couple of days now to no avail… Any suggestions are very much appreciated :slight_smile:

Seems like we both got the same error though with slightly different configurations…

I solved it by completely ignoring all certificates on the nextcloud jail and I do not redirect if the port is 80. I can look up my config if you need it

and I solved it because I had the settings in the nginx proxy manager wrong.
Of course it had to be https on port 443 to redirect on my other containers.