Tomaz Leopold
Tomaz Leopold

Reputation: 73

Nextcloud delivers error too many redirects when using nginx reverse proxy

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 # 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)

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 weeks now to no avail. Any suggestions are very much appreciated, I've tried asking this on the Nextcloud community forum and their discord, but there were sadly no responses.

Upvotes: 0

Views: 1100

Answers (1)

Buffoonism
Buffoonism

Reputation: 1858

Too many redirects is generally a redirect loop somewhere. URI A redirects to itself, or to URI B which redirects back to URI A in a never-ending loop.

A quick way of finding out is to open the developer tools from the menu in your browser, select the network tab, refresh, and have a look at what actually ends up in the location header.

Upvotes: 1

Related Questions