0

I am trying to install Nextcloud on my Raspberry Pi.

  1. I have created an A record in Cloudflare with subdomain pointing to my Raspberry Pi IP address and configured the NGINX with certbot using the default configuration file in /etc/nginx/sites-available/nextcloud.
    1. I have created symlink in /etc/nginx/sites-enables and checked the NGINX configuration with sudo nginx -t and the configuration was all valid.
    2. I am getting successfully redirected to https but I am getting an error that I am getting too many redirects when I try to open the nextcloud.mydomain.com in a browser.

This is my nextcloud config:

upstream php-handler {
    server 127.0.0.1:9000;
    #server unix:/var/run/php/php7.3-fpm.sock;
}

server {
    listen 80;
    server_name nextcloud.domain.com;

    if ($host = nextcloud.domain.com) {
        return 301 https://$server_name:443$request_uri;
    } # managed by Certbot

    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/nextcloud.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/nextcloud.domain.com/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
    add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot
    ssl_trusted_certificate /etc/letsencrypt/live/nextcloud.domain.com/chain.pem; # managed by Certbot
    ssl_stapling on; # managed by Certbot
    ssl_stapling_verify on; # managed by Certbot

    # 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;";
    #
    # 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 X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;

    # 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/html/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 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;

    # 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;";
        #
        # 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 X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        add_header Referrer-Policy no-referrer;

        # 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;
    }
}

This is the curl output:

curl -i http://nextcloud.domain.com
HTTP/1.1 301 Moved Permanently
Date: Mon, 03 Feb 2020 20:54:01 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=3600
Expires: Mon, 03 Feb 2020 21:54:01 GMT
Location: https://nextcloud.domain.com/
X-Content-Type-Options: nosniff
Server: cloudflare
CF-RAY: 55f74c364a04d8d1-AMS

And when I try to access the https version:

curl -i https://nextcloud.domain.com 

HTTP/2 301 
date: Mon, 03 Feb 2020 20:55:45 GMT
content-type: text/html
set-cookie: __cfduid=d160f56e9986d2c7037ff81e233fcad0e1580763345; expires=Wed, 04-Mar-20 20:55:45 GMT; path=/; domain=.domain.com; HttpOnly; SameSite=Lax; Secure
location: https://nextcloud.domain.com:443/
strict-transport-security: max-age=15552000; includeSubDomains; preload
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-robots-tag: none
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: no-referrer
cf-cache-status: DYNAMIC
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 55f74ebf5ed62bfe-AMS

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>

I have replaced my domain name with domain.

In the /var/log/nginx/access.log I am getting a lot of lines with the redirect and HTTP codes: 301 and 185.

If I delete the redirect return 301 https://$server_name:443@request_uri; line I am still getting redirected to https and I don't have any idea why.

For the record, I used to have lighttpd in the past installed on the Raspberry Pi but I have uninstalled it before installing the NGINX.

1 Answer 1

1

You have a single server definition for both HTTP and HTTPS and, as you noticed, the lines:

if ($host = nextcloud.domain.com) {
    return 301 https://$server_name:443$request_uri;
} # managed by Certbot

are doing most of the damage. Since it is a 301 redirect, you browser will remember it until it is restarted.

Split the configuration of the two listening ports, so that the first lines are:

server {
    listen 80;
    server_name nextcloud.domain.com;

    return 301 https://$server_name$request_uri; # managed by Certbot
}

server {
    listen 443 ssl http2;
    server_name nextcloud.domain.com;
    # rest of the config

Edit: As you remarked, you can put both listen directives in one server block, however this will cause a redirect loop if your server is accessed directly using the nextcloud.domain.com. Cloudflare probably puts another proxy server between your clients and nginx and forwards requests using your IP instead of the domain name. So the loop remains hidden, but is is still there.

If you want to keep the single server block, you should consider changing the if condition to:

if ($scheme = http) {
    return 301 https://$server_name$request_uri;
} # managed by Certbot

However, in terms of clarity and performance, it is probably worse than two server blocks.

3
  • actually, I have just fixed my issue and it was related to the Cloudflare DNS configuration. There I have enabled re-write HTTP to HTTPS and this caused the problem. Additionally, I have enabled the DNS to be proxied. Since I fixed it I am not experiencing any more redirects. Plus listening on both ports in the same server block is also OK according to the official NGINX documentation: nginx.org/en/docs/http/… . If I check the output with curl I am seeing one 301 redirect HTTP->HTTPS and then 302 to the login page and 200 for login Feb 4, 2020 at 12:10
  • You can't configure a HTTP redirect with DNS so Cloudflare probably points your domain to their servers, which act as a reverse proxy. Is cloudflare.domain.com pointing to your IP? If that were the case your configuration would cause a redirect loop. I edited the answer with more details. Feb 4, 2020 at 21:05
  • This is exactly what happened, yes, they were proxying the requests to my domain through their IPs Feb 5, 2020 at 8:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.