Some HTTP links not rewritten to HTTPS despite `'overwriteprotocol' => 'https'`

Setup:

Official docker image + official nginx image as reverse proxy/TLS terminator

Nextcloud version: 18.0.2 (from official Docker image)
Operating system and version: Ubuntu 16.04
Apache: whatever is in the official Docker image
Nginx version: 1.17.9
PHP version: whatever is in the official Docker image

The issue:

Some HTTP links not rewritten to HTTPS.

The first point where I am experiencing this are the contact images that should be shown in the list when clicking on the contact icon in the top right:

Content Security Policy: The page’s settings blocked the loading of a resource at http://cloud.example.com/remote.php/dav/addressbooks/system/system/system/Database:name.vcf?photo&size=32 (“img-src”).

The second one is the OnlyOffice document server:

  1. Install as described in [1]

  2. OnlyOffice settings field Document Editing Service Location is prepopulated with https://cloud.example.com/apps/documentserver_community/ and opening docs gets me a popup “ONLYOFFICE not reachable. Contact your Administrator.” (similar to what someones describes in this Github issue [2])

  3. If I change the prefix to https it loads more of OnlyOffice but then is stuck at
    Content Security Policy: The page’s settings blocked the loading of a resource at http://cloud.example.com/apps/documentserver_community/open/1234567890/Editor.bin (“connect-src”). Similar to this issue [3] but unlike the reporter who seems to be experiencing this for CSVs only I have it for any docfiles I try.

I already have

'overwrite.cli.url' => 'https://cloud.example.com',
'overwriteprotocol' => 'https',

in my config.php as well

proxy_set_header X-Forwarded-Proto $scheme;

in my nginx.conf :frowning:

So now I’m kinda clueless; these are the only two sources of error for other people that I have found on Github or in this forum.

Is this the first time you’ve seen this error? (Y/N):
Contacts: no, but I kinda lived with it. OnlyOffice: yes, and now it annoys be enough to ask here.

The output of your Nextcloud log in Admin > Logging:

OMITTED FOR NOW

config.php:

'overwrite.cli.url' => 'https://cloud.example.com',
'overwriteprotocol' => 'https',

The output of your Apache/nginx/system log in /var/log/:

OMITTED FOR NOW

Reverse proxy nginx config:

server {
    listen 80;
    listen [::]:80;
    server_name cloud.example.com;

    server_name_in_redirect off;

    access_log  /var/log/nginx/nextcloud.access.log  main;

    location /.well-known {
        root   /usr/share/nginx/html;
        allow all;
    }

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

server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name cloud.example.com;

    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/cloud.example.com/privkey.pem;

    include /etc/nginx/conf.d/ssl.conf;
    
    location /robots.txt {
        root /usr/share/nginx/html;
        try_files $uri 404.html;
        access_log off;
    }

    location = /.well-known/carddav {
      return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;
    }

    # Raise file upload size
    client_max_body_size 512m;

    # Limit download size
    proxy_max_temp_file_size 4096m;

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }

    location / {
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_pass_request_headers on;
        proxy_pass  http://nextcloud;
    }
}

[1] https://nextcloud.com/blog/how-to-install-onlyoffice-in-nextcloud-hub-and-new-integration-feature/
[2] https://github.com/nextcloud/documentserver_community/issues/35
[3] https://github.com/nextcloud/documentserver_community/issues/70

Not tested

Sure, nginx already is redirecting everything to HTTPS. I initally omitted that but have now added it to the paste of my config above.

I don’t think this is related to the issue though. The browser is blocking the requests because of the CSP, so the request never reach my nginx proxy and have no chance of being redirected.
The issue is rather that Nextcloud is not requesting the https:// version of the resources.

Perhaps you can use in Firefox / Chrome Developer Tools (F12 -> Network) and post lines with problems.

The Firefox dev console errors are already posted above. Chrome is slightly more verbose (as in it gives what part of Nextcloud’s CSP triggered the block):

Refused to load the image 'http://cloud.example.com/remote.php/dav/addressbooks/system/system/system/Database:test.vcf?photo&size=32' because it violates the following Content Security Policy directive: "img-src 'self' data: blob:".

Refused to connect to 'http://cloud.example.com/apps/documentserver_community/open/997792175/Editor.bin' because it violates the following Content Security Policy directive: "connect-src 'self'".

(and those are exactly the URLs that are shown with status (blocked:CSP) in Chrome dev tool’s network tab)

Yes. But which request start the load of the image? Is there perhaps a configuraton error?

If I click on the contact image in the top left, the following requests fire:

https://cloud.example.com/contactsmenu/contacts
http://cloud.example.com/remote.php/dav/addressbooks/system/system/system/Database:test.vcf?photo&size=32

So I guess the first one to /contactsmenu/contacts gets the contact list and then their details (i.e. the image)?
My understanding is that because the call to remote.php/dav/addressbooks/system/system/system/Database:test.vcf?photo&size=32 is not https: the CSP causes the browser to block it. So somehow I need to get Nextcloud to use the right scheme there :confused:

The config.sample.php reads:

/**
 * When generating URLs, Nextcloud attempts to detect whether the server is
 * accessed via ``https`` or ``http``. However, if Nextcloud is behind a proxy
 * and the proxy handles the ``https`` calls, Nextcloud would not know that
 * ``ssl`` is in use, which would result in incorrect URLs being generated.
 * Valid values are ``http`` and ``https``.
 */
'overwriteprotocol' => '',

My understanding from that is that Nextcloud should rewrite those URLs to https: itself.

So I am wondering whether there is any way for Nextcloud to ignore my config.php's

'overwrite.cli.url' => 'https://cloud.example.com',
'overwriteprotocol' => 'https',

settings.

The permissions on that are

-rw-r-----  1 www-data www-data  1735 Mar 17 14:12 config.php

a) Is that what they should be?

b) Is there any other way that would cause Nextcloud to not rewrite URLs to https if behind a reverse proxy but being told to do so through overwriteprotocol?

Nextcloud seems to be able to read the the config.php, because if I comment out the entries of trusted_proxies I get a warning in the admin panel:

“The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the documentation.”

So that can’t be it either. So annoying.

Try without overwriteprotocol

I’ve also now chimed in here to get clarification under what circumstances Nextcloud is designed to read/use that setting.

EDIT: I renamed the title of this thread to make it more obvious what the core of the issue appears to be.
EDIT 2: I’m so sorry @Gatak, I misread your comment :grimacing:. Didn’t catch the “out” of “without”. Thus I now tried without overwriteprotocol (deleting the entry from the config.php), but unfortunately with the same result. Nvertheless, I really appreciate suggestions such as yours on what else to try (I’m running out of ideas), so thanks a lot!

I use Apache and rewrite to https:// rule I have on my :80 instance is

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} !^/.well-known
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NC,NE,R=permanent,L]

config.php

  'datadirectory' => '/var/www/domains/mydom.net/htdocs/nextcloud/data',
  'overwrite.cli.url' => 'https://mydom.net/',
  'htaccess.RewriteBase' => '/',
  'dbtype' => 'mysql',
  'version' => '19.0.0.12',

So, I finally found time for setting up a test instance, slowly step-by-step. And, oh god, there it worked! (after I set just the overwriteprotocol to https, none of the other overwriteXYs.

So I compared the config.php of the fresh test instance with that of my production instance (which was much longer).
Then I started removing the extra lines in the prod’s config.php one-by-one, and I found the culprit!

Removing the 'overwritecondaddr' => '^172\\.20\\.X\\.X$', line from the config.php fixed it!

It seemed to clash with the 'overwriteprotocol' => 'https', line.
Since the proxy’s IP is not fixed in Docker it was wrong anyway (you can assign it a fixed IP, but I didn’t do that).

(of course, the Xs in ^172\\.20\\.X\\.X$ where numerical values, I redacted them)

Nothing above worked for me.
So, I found that I can hard-code it to use HTTPS

Edit html\custom_apps\richdocumentscode\proxy.php
And on line 2 add this:
$_SERVER['HTTPS']='on';

Basically, Nextcloud can’t correctly determine HTTPS requests and by doing $_SERVER['HTTPS']='on'; you are telling it to stop guessing…