Unauthorized WOPI host - WAF + Nginx reverse proxy + dockerized Nextcloud & Collabora

Hey everyone,

I’ve been trying to troubleshoot an internal connection issue between Nextcloud and Collabora CODE, and I’m not completely sure if my architecture or configuration logic is correct — maybe I’m missing something small.

Setup Summary

We run both Nextcloud and Collabora CODE as Docker containers behind a corporate WAF (which performs SSL termination) and an internal NGINX reverse proxy that routes to the containers.

Externally, users access everything via HTTPS (https://nc.examplecloud.com, https://office.examplecloud.com), but internally the containers communicate via plain HTTP on a private Docker network.

Client (HTTPS)
   ↓
Corporate WAF (SSL termination)
   ↓
Internal NGINX reverse proxy
   ├─ Nextcloud container → http://172.23.0.5:80
   └─ Collabora container → http://172.23.0.6:9980

However, Collabora still seems to use the external HTTPS route when performing WOPI requests to Nextcloud, causing:

wsd-00001-00024   [ websrv_poll ] ERR  #31: Failed or timed-out CheckFileInfo
[https://nc.examplecloud.com/index.php/apps/richdocuments/wopi/files/3703_abcxyz?access_token=abc&permission=edit]
| wsd/wopi/CheckFileInfo.cpp:119

Nextcloud config.php (sanitized)

<?php
$CONFIG = array (
  'overwrite.cli.url' => 'http://nc.examplecloud.com',
  'overwritehost' => 'nc.examplecloud.com',
  'overwriteprotocol' => 'http',
  'overwritecondaddr' => '^172\\.23\\.0\\.',
  'trusted_proxies' => [
    '172.18.0.0/16',
    '172.22.23.90',
    '192.168.0.0/16',
    '172.23.0.0/24',
  ],
  'trusted_domains' => [
    'nc.examplecloud.com',
    'office.examplecloud.com',
    'collabora',
    '172.23.0.0/24',
  ],
  'richdocuments' => [
    'wopi_url' => 'http://collabora:9980',
    'wopi_allowlist' => ['0.0.0.0/0','::/0'],
  ],
  'allow_local_remote_servers' => true,
);

docker-compose.yml excerpt (simplified)

services:
  nextcloud:
    image: nextcloud:latest
    networks:
       nextcloud_net:
          ipv4_address: 172.23.0.5
    volumes:
      - ./config:/var/www/html/config
      - ./custom_apps:/var/www/html/custom_apps
    environment:
      - POSTGRES_HOST=ip-db
      - REDIS_HOST=redis

  collabora:
    image: collabora/code:latest
    networks:
      - nextcloud_net
    extra_hosts:
      - "nc.examplecloud.com:nginx-internal-ip"
      - "office.examplecloud.com:nginx-internal-ip"
    environment:
      - aliasgroup1=https://.*:443
      - aliasgroup2=http://office\.examplecloud\.com
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:net.proxy_disable=true
      - DONT_GEN_SSL_CERT=true
    ports:
      - "9980:9980"

  nginx:
    image: nginx:1.24-alpine
    networks:
      - nextcloud_net
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

networks:
  nextcloud_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.23.0.0/24

What I’m trying to figure out

  • Why is Collabora still calling the external HTTPS endpoint (handled by WAF) instead of the internal HTTP route?

  • Could overwriteprotocol and overwritecondaddr be ignored in this network chain (due to proxy headers)?

  • Or maybe the aliasgroup1 in Collabora isn’t rewriting URLs correctly behind NGINX and WAF?

If anyone has a similar setup (WAF + NGINX reverse proxy + dockerized Nextcloud & Collabora) and got internal WOPI HTTP working, I’d really appreciate your input.


I’m not even sure if this is the correct way to configure it at all — maybe I’ve taken the wrong approach from the beginning? Any insights or confirmation would really help. :)))

hi @geeknumber1

Very nice description Thanks :slight_smile:

So i see that Collabora is calling the external https URL because inside the Collabora container the hostname nc.examplecloud.com still resolves to the external WAF address. So Collabora thinks it must use the external https route. Nextcloud also sends back https URLs when the proxy headers don’t match your overwrite rules.

Fix in three short steps:

  1. Force internal resolution. In the Collabora container map nc.examplecloud.com to the internal Nextcloud IP so all WOPI calls stay inside the Docker network. For example: extra_hosts: “nc.examplecloud.com:172.23.0.5”.

  2. Add the real proxy IPs (WAF and internal nginx) to Nextcloud trusted_proxies so Nextcloud trusts the forwarding headers.

  3. Make sure nginx forwards correct headers like X-Forwarded-Proto and Host so Nextcloud knows the original protocol.

Once Collabora resolves the Nextcloud hostname internally and Nextcloud trusts the proxies, Collabora will stop calling the public https endpoint and use the internal http path correctly.

Thanks
Darshan

Hi @darshan

Thank you so much for your clear guidance and the logical three-step solution. I really appreciate you taking the time to help.

I have carefully implemented all three of your recommendations. Specifically:

  1. Forced Internal Resolution: I’ve added extra_hosts to the Collabora service to point nc.examplecloud.com directly to the Nextcloud container’s internal IP.

  2. Trusted Proxies: I’ve added the WAF’s IP and the internal proxy’s network to trusted_proxies in config.php and have commented out the conflicting overwritehost, overwriteprotocol, and overwritecondaddr parameters.

  3. Correct Headers: I’ve configured our Nginx reverse proxy to send the X-Forwarded-Proto: https header for all relevant traffic.

Unfortunately, despite these changes and a full restart of the stack, the problem still persists. The Collabora logs continue to show a timeout error when trying to perform the CheckFileInfo call, and it still seems to be attempting an external HTTPS connection.

Here is the latest error from the Collabora log:

wsd-00001-00023 [ websrv_poll ] ERR #30: Failed or timed-out CheckFileInfo [https://nc.examplecloud.com/index.php/apps/richdocuments/wopi/files/3703_occaei3x2ozd?access_token=…] | wsd/wopi/CheckFileInfo.cpp:119

wsd-00001-00023 [ websrv_poll ] ERR #30: CheckFileInfo failed for [https%3A%2F%2Fnc.examplecloud.com%3A443%2Findex.php%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F3703_occaei3x2ozd], State::Fail| wsd/RequestVettingStation.cpp:341

I am providing my complete, sanitized configuration files below for your review. Perhaps you might spot something I’ve missed.

docker-compose.yml

services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped
    networks:
       nextcloud_net:
          ipv4_address: 172.23.0.5
    volumes:
      - ./custom_apps:/var/www/html/custom_apps
      - ./config:/var/www/html/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=**********
      - POSTGRES_DB=db
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_HOST=IP
      - REDIS_HOST=redis

  collabora:
    image: collabora/code:latest
    container_name: collabora
    restart: unless-stopped
    networks:
       nextcloud_net:
          ipv4_address: 172.23.0.4
 container IP
      - "nc.examplecloud.com:172.23.0.5"
    cap_add:
      - MKNOD
    environment:
      - TZ=Asia/Tehran
      - aliasgroup1=https://.*:443
      - aliasgroup2=http://office\.examplecloud\.com
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:net.proxy_disable=true --o:net.listen=0.0.0.0
      - DONT_GEN_SSL_CERT=true
    ports:
      - "9980:9980"

  redis:
    image: redis:7-alpine
    container_name: redis
    restart: unless-stopped
    networks:
       nextcloud_net:
          ipv4_address: 172.23.0.3
    command: ["redis-server", "--save", "", "--appendonly", "no"]

  nginx:
    image: nginx:1.24-alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
       nextcloud_net:
          ipv4_address: 172.23.0.2

networks:
  nextcloud_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.23.0.0/24
          gateway: 172.23.0.1

nginx.conf

events {}

http {

    server {
        listen 80;
        server_name nc.examplecloud.com;

        location / {
            proxy_pass http://nextcloud:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # Key Fix: Tell Nextcloud the original protocol was https
            proxy_set_header X-Forwarded-Proto https;
            client_max_body_size 512M;
            proxy_buffering off;
            proxy_read_timeout 36000s;
        }
    }


    server {
        listen 80;
        server_name office.examplecloud.com;

        location / {
            proxy_pass http://collabora:9980;
            proxy_set_header Host $host;
            # Key Fix: Tell Collabora the original protocol was https
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            client_max_body_size 0;
            proxy_buffering off;
        }
    }
}

config.php

<?php
$CONFIG = array (
  'upgrade.disable-web' => true,
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',

  // public URL (external) should use https
  'overwrite.cli.url' => 'https://nc.examplecloud.com',

  'apps_paths' =>
  array (
    0 =>
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 =>
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),

  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => 'redis',
    'password' => '',
    'port' => 6379,
  ),

  'trusted_proxies' =>
  array (
    0 => '172.18.*.*/16',
    1 => '172.18.*.*',
    2 => '172.22.*.*/24',
    3 => '192.168.*.*/16',
    4 => '172.23.*.*/24',
  ),

  'instanceid' => 'sanitized-instance-id',
  'passwordsalt' => '************',
  'secret' => '************',

  'trusted_domains' =>
  array (
    0 => '172.18.*.*',
    1 => 'nc.examplecloud.com',
    2 => 'office.examplecloud.com',
    3 => 'collabora',
    4 => '172.23.*.*/24',
  ),

  'richdocuments' =>
  array (
    'wopi_url' => 'http://collabora:9980',
    'wopi_allowlist' =>
    array (
      0 => '0.0.0.0/0',
      1 => '::/0',
    ),
  ),

  'forwarded_for_headers' =>
  array (
    0 => 'HTTP_X_FORWARDED_FOR',
    1 => 'HTTP_X_REAL_IP',
  ),

  'dbtype' => 'pgsql',
  'version' => '32.0.1.2',
  //'overwritehost' => 'nc.examplecloud.com',
  //'overwriteprotocol' => 'https',
  //'overwritecondaddr' => '^172\\.23\\.0\\.',

  'dbname' => 'nextcloud',
  'dbhost' => '172.18.*.*',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'dbuser' => 'nextcloud',
  'dbpassword' => 'nextcloud',
  'installed' => true,

  'objectstore' =>
  array (
    'class' => '\\OC\\Files\\ObjectStore\\S3',
    'arguments' =>
    array (
      'bucket' => 'nextcloud',
      'autocreate' => true,
      'key' => '************',
      'secret' => '************',
      'hostname' => '172.18.*.*',
      'port' => 9000,
      'use_ssl' => false,
      'region' => 'us-east-1',
    ),
  ),

  'loglevel' => 0,
  'log_type' => 'file',
  'maintenance' => false,
  'allow_local_remote_servers' => true,

  'content_security_policy' =>
  array (
    'directives' =>
    array (
      'form-action' =>
      array (
        0 => '\'self\'',
        1 => 'office.examplecloud.com',
      ),
      'frame-src' =>
      array (
        0 => '\'self\'',
        1 => 'office.examplecloud.com',
      ),
    ),
  ),
);

:sweat_smile: Honestly, if you can help me fix this setup, I’d really appreciate it — it’s been messing with my head for days! I’m slowly reaching the point where I might just throw my laptop out the window :joy:

hi @geeknumber1 the easiest solution would be to forward public DNS to your WAF - usually it is fast enough and doesn’t require any config beside some DNS magic

more details in Probably DNS help with NC Docker + Collabora + Wireguard tunnel - #5 by wwe - ℹ️ Support - Nextcloud community

there is also a detailed discussion where a user insisted on forced internal connections Nextcloud Community and Collabora CODE in the same Docker network - ℹ️ Support - Nextcloud community

1 Like