I’m running a nextcloud 19.04 instance on plesk and set it up according to the documentation and this how-to https://cry-sys.de/article/2-nextcloud-17-unter-plesk-installieren/
It all works great except for downloads from external storages and federated shares. I can upload to them but I can’t download anything. It doesn’t matter if it is a federated share, a nextcloud external storage or an s3 external storage.
Every download attempt times out and throws Content Security Errors in the browser web console:
GEThttps://files.example.de/remote.php/webdav/Test/openttd-1.10.3-windows-win64(1).exe
[HTTP/1.1 500 Internal Server Error 30978ms]
GET
https://files.example.de/remote.php/webdav/Test/openttd-1.10.3-windows-win64(1).exe
Status500
Internal Server Error
VersionHTTP/1.1
Übertragen14,90 KB (14,08 KB Größe)
HTTP/1.1 500 Internal Server Error
Server: nginx
Date: Tue, 13 Oct 2020 15:56:08 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Robots-Tag: none
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'
Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding
gzip, deflate, br
Accept-Language
de,en-US;q=0.7,en;q=0.3
Connection
keep-alive
Cookie
__Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; oc7oszrtzdsr=rum16rouse7p5om5sta1gj33m8; oc_sessionPassphrase=%2B5UoEBVwpoZ63gHHtaVZaSD129izYGQ1FOT7gncVZm53dGB%2FG9SseKuePQCVUiIgVrgnkiFl4Qc%2BPk6JlHh9lB7bbzOuPq1WrXDm52NDTeKRBD%2BpHDEBx%2BhGzSbL3d29
DNT
1
Host
files.example.de
Upgrade-Insecure-Requests
1
User-Agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Content Security Policy: Die Einstellungen der Seite haben das Laden einer Ressource auf inline blockiert ("script-src"). openttd-1.10.3-windows-win64(1).exe:32:1
Content Security Policy: Die Einstellungen der Seite haben das Laden einer Ressource auf data: blockiert ("media-src").
JQMIGRATE: Migrate is installed, version 1.4.1 jquery-migrate.min.js:2:551
$ is deprecated: The global jQuery is deprecated. It will be updated to v2.4 in Nextcloud 20 and v3.x in Nextcloud 21. In later versions of Nextcloud it might be removed completely. Please ship your own. globals.js:61:15
session heartbeat polling started session-heartbeat.js:97:9
$ is deprecated: The global jQuery is deprecated. It will be updated to v2.4 in Nextcloud 20 and v3.x in Nextcloud 21. In later versions of Nextcloud it might be removed completely. Please ship your own. 2 globals.js:61:15
The response csp header looks actually good to me but somehow it still doesnt work.
Maybe related or unrelated, running curl -vvvv https://files.example.com answers with
[ssl/tls stuff removed]
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 13 Oct 2020 15:55:19 GMT
< Content-Type: text/html
< Content-Length: 156
< Last-Modified: Tue, 13 Oct 2020 15:26:00 GMT
< Connection: keep-alive
< ETag: "5f85c708-9c"
< X-Powered-By: PleskLin
< Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;
< Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<script> window.location.href="index.php"; </script>
<meta http-equiv="refresh" content="0; URL=index.php">
</head>
</html>
while running curl -vvvv https://files.example.com/index.php answers with:
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Server: nginx
< Date: Tue, 13 Oct 2020 16:06:24 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: oc7oszrtzdsr=tpu7ds3p69rs8do4ps52797l32; path=/; secure; HttpOnly; SameSite=Lax
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Set-Cookie: oc_sessionPassphrase=yio8JZP4Jj4ORoP1gpxmzwIb7Yz37tY8lBs5AnhH0d09iL8AGgfG5yhCGtCR9ylNFel1zNHJ04aDLage%2F%2F3S76SOjVx1mst%2FApwYLvQzGnOcg1Gn3Q7cL%2BAItsKDGxhw; path=/; secure; HttpOnly; SameSite=Lax
< Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-ME5UNTRDZmFrY3N4aHpva09NUXkvK2x1NDJUNWpQVnYvcGh5eFJUeWNNQT06aDd5bzFFNkszcElKMW5aTmE2SUJ5Sk1vdWpTOXpaUVdyZkZIalVPRkVZWT0='; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
< Referrer-Policy: no-referrer
< X-Content-Type-Options: nosniff
< X-Download-Options: noopen
< X-Frame-Options: SAMEORIGIN
< X-Permitted-Cross-Domain-Policies: none
< X-Robots-Tag: none
< X-XSS-Protection: 1; mode=block
< Set-Cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
< Set-Cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
< Location: https://files.example.com/index.php/login
< X-Powered-By: PleskLin
< Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;
< Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;
<
I would have expected that https://files.example.com would also answer with the correct csp header because that’s what my instance at home does.
Nginx additional configuration in plesk:
# 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.
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The following 6 rules are borrowed from `.htaccess`
rewrite ^/\.well-known/host-meta\.json /public.php?service=host-meta-json last;
rewrite ^/\.well-known/host-meta /public.php?service=host-meta last;
rewrite ^/\.well-known/webfinger /public.php?service=webfinger last;
rewrite ^/\.well-known/nodeinfo /public.php?service=nodeinfo last;
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
try_files $uri $uri/ =404;
}
# 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;
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
# 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.
# 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;
add_header X-Content-Type-Options nosniff;
add_header X-Download-Options noopen;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Robots-Tag none;
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;
}
Remaining nginx config from plesk in background:
#ATTENTION!
#
#DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,
#SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.
server {
listen <ip>:443 ssl;
server_name files.example.de;
server_name www.files.example.de;
server_name ipv4.files.example.de;
ssl_certificate /opt/psa/var/certificates/scf69MuUN;
ssl_certificate_key /opt/psa/var/certificates/scf69MuUN;
client_max_body_size 128m;
proxy_read_timeout 1200;
root "/var/www/vhosts/example.de/files.example.de";
access_log "/var/www/vhosts/system/files.example.de/logs/proxy_access_ssl_log";
error_log "/var/www/vhosts/system/files.example.de/logs/proxy_error_log";
#extension letsencrypt begin
location ^~ /.well-known/acme-challenge/ {
root /var/www/vhosts/default/htdocs;
types { }
default_type text/plain;
satisfy any;
auth_basic off;
allow all;
location ~ ^/\.well-known/acme-challenge.*/\. {
deny all;
}
}
#extension letsencrypt end
#extension sslit begin
#extension sslit end
location ~ /\.ht {
deny all;
}
location ~ ^/(plesk-stat|awstats-icon|webstat|webstat-ssl|ftpstat|anon_ftpstat) {
auth_basic "Domain statistics";
auth_basic_user_file "/var/www/vhosts/system/files.example.de/pd/d..httpdocs@plesk-stat";
autoindex on;
location ~ ^/plesk-stat(.*) {
alias /var/www/vhosts/system/files.example.de/statistics/$1;
}
location ~ ^/awstats-icon(.*) {
alias /usr/share/awstats/icon/$1;
}
location ~ ^/(.*) {
alias /var/www/vhosts/system/files.example.de/statistics/$1;
}
}
location ~ ^/~(.+?)(/.*?\.php)(/.*)?$ {
fastcgi_read_timeout 1200;
alias /var/www/vhosts/example.de/web_users/$1/$2;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:///var/www/vhosts/system/files.example.de/php-fpm.sock";
include /etc/nginx/fastcgi.conf;
}
location ~ \.php(/.*)?$ {
fastcgi_read_timeout 1200;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:///var/www/vhosts/system/files.example.de/php-fpm.sock";
include /etc/nginx/fastcgi.conf;
}
location ~ /$ {
index "index.html" "index.cgi" "index.pl" "index.php" "index.xhtml" "index.htm" "index.shtml";
}
add_header X-Powered-By PleskLin;
include "/var/www/vhosts/system/files.example.de/conf/vhost_nginx.conf";
}
server {
listen <ip>:80;
server_name files.example.de;
server_name www.files.example.de;
server_name ipv4.files.example.de;
client_max_body_size 128m;
proxy_read_timeout 1200;
location / {
return 301 https://$host$request_uri;
}
I’d be so greatful if anyone could help me with this!