I host Nextcloud on my home network. It isn’t the fastest network out there (80/20 on a good day) which makes the website very slow because the browser has to download about 40MB of resources. I was running everything behind the Cloudflare CDN but started facing timeout issues when uploading files using the website (tl;dr Cloudflare has a timeout which uploading large files causes).
My solution was to use a separate domain, nc-static.example.com
, to serve the static resources through the CDN and turn off Cloudflare on the nc.example.com
site and pass it straight to the origin.
I assume this is a very unusual way of doing things and I’d like some input on the security aspect of this. Does everything look alright?
I did this on my reverse proxy server. My Nextcloud server’s nginx is configured according to the documentation.
To move the static resources over to nc-static.example.com
I used nginx’s sub_filter
to edit the HTML:
sub_filter_once off;
proxy_set_header Accept-Encoding "";
sub_filter_types text/html;
sub_filter 'href="/' 'href="https://nc-static.example.com/';
sub_filter 'src="/' 'src="https://nc-static.example.com/';
sub_filter 'content="/' 'content="https://nc-static.example.com/';
To make CSP happy, I used Openresty’s Lua module to append nc-static.example.com
to the values in the Content-Security-Policy
header:
header_filter_by_lua_block {
local csp = ngx.var.upstream_http_content_security_policy
if csp then
csp = csp:gsub("script%-src", "script-src https://nc-static.example.com")
csp = csp:gsub("style%-src", "style-src https://nc-static.example.com")
csp = csp:gsub("img%-src", "img-src https://nc-static.example.com")
csp = csp:gsub("font%-src", "font-src https://nc-static.example.com")
csp = csp:gsub("media%-src", "media-src data: https://nc-static.example.com")
ngx.header["Content-Security-Policy"] = csp
end
}
The nc-static.example.com
server is configured like this:
server
{
# ...
server_name nc-static.example.com;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# ...
location ~* ^/(core|apps|js|dist)/(.+)(\?v=[a-f0-9]+)?
{
expires 12h;
add_header Cache-Control "public, max-age=43200";
proxy_pass https://nxcld_backend;
}
location /
{
return 404;
}
# ...
}
Is this a brilliant or dumb idea?