Nextcloud 17 + Nginx = Unable to upload files larger than unknown size

Hello,

I recently set up Nextcloud 17.0.2.1 with Nginx on Debian 10. It’s been a while since I’ve used Nginx, so it took a while, but I eventually got everything installed and set up so I could access the web application, log in, upload files, etc.

However, I only got as far as uploading some small test files, a couple 10s of KB at a time. Today, I tried to upload a 4.2 MB PDF from my phone, and it didn’t work. The upload page suggests it was a permission error. The Nginx log shows a 403 on the MOVE action:

2020/01/08 00:01:05 [error] 17030#17030: *141 access forbidden by rule, client: <redacted>, server: <redacted>, request: "MOVE /remote.php/dav/uploads/nic/96b64e14b647a8346ddab989100e2c9a/.file HTTP/1.1", host: "<redacted>"

I retried the PDF upload on the web application, and it worked absolutely fine, however a 46 MB file from my laptop uploaded via the web application also failed, with “Error when assembling chunks, status code 403” appearing on the top right.

There is no corresponding log in the Nextcloud log file, so I assume this is something to do with my Nginx config, pasted below:

server {
        server_name <redacted>;

        listen 443 ssl http2;

        ssl_certificate /var/lib/dehydrated/certs.d/nextcloud/fullchain.pem;
        ssl_certificate_key /var/lib/dehydrated/certs.d/nextcloud/privkey.pem;

#       add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;

        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;

        fastcgi_hide_header X-Powered-By;

        root /var/www/nextcloud;

        include conf.d/server/base.conf;

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

        client_max_body_size 1024m;
        fastcgi_buffers 64 4K;

        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;

        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;
                fastcgi_param modHeadersAvailable true;
                fastcgi_param front_controller_active true;
                fastcgi_pass unix:/run/php/nextcloud.sock;
#               fastcgi_pass unix:/run/php/php7.3-fpm.sock;
                fastcgi_intercept_errors on;
                fastcgi_request_buffering off;
        }

        location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
                try_files $uri/ =404;
                index index.php;
        }

        location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
                try_files $uri /index.php$request_uri;
                add_header Cache-Control "public, max-age=15778463";
#               add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
                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;

                access_log off;
        }

        location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
                try_files $uri /index.php$request_uri;
                access_log off;
        }
}

server {
        server_name <redacted>;

        listen 80;

        return 301 https://$host$request_uri;
}

Other than some site-specific changes, and some efforts to reduce repeated config sections (robots and favicon in the included base.conf), the config matches what is on the Nextcloud documentation, and similar to the config a friend uses (although I’m not sure what other changes he has made).

This is probably me doing something silly and just needing fresh eyes, but no-one I’ve asked so far has picked something up.

Thanks in advance.

B

Posible solution: read global configuration and find part which blocking files starting with dot, like for example this code:

    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

and comment it, or remove