Nextcloud Office can't connect to CODE behind reverse proxy: Requesting address is denied

Hello everybody,

I’m having a lot of trouble with setting up the docker image: collabora/code:latest behind my reverse proxy. My nextcloud instance (which has a similar setup and is working fine) can’t connect to the server. However inside admin settings of Nextcloud Office I get Collabora Online server is reachable. when I connect through https://code.foo.tld. The first docker log shows the error I get inside my code docker container. If I try to create/open any files with Nextcloud Office I just get the error: Document loading failed - Failed to load Nextcloud Office - please try again later.
I already did a lot of research and found multiple related topics stating exactly the same problem. Most of them however are multiple years old and I couldn’t find a solution that worked for me, which is why I am opening a new topic on this.
All relevant logs, configs and docker files should be listed below.
If you have any additional questions, feel free to let me know! I would be glad if someone could help me with this because I’ve been struggling setting it up for 2 days now!

I can reach https://code.foo.tld/hosting/discovery and https://code.foo.tld/hosting/capabilities, but https://code.foo.tld/cool or https://code.foo.tld/cool/adminws show me a blank page (it is reachable tho).
https://code.foo.tld shows me a 404 as expected.

Unnecessary/Private information in the following snippets is either left out or replaced with random words/letters.

docker log (code)

Ready to accept connections on port 9980.
dateTtime.num0Z
wsd-num1-num2 date time.num3 +0000 [ websrv_poll ] WRN  convert-to: Requesting address is denied: z.z.z.z| wsd/COOLWSD.cpp:3507
wsd-num1-num1 date time.num4 +0000 [ coolwsd ] WRN  Waking up dead poll thread [HttpSynReqPoll], started: false, finished: false| net/Socket.hpp:727

docker-compose.yml

version: "3.9"

services:
  reverse-proxy:
    image: "nginx:stable-alpine"
    container_name: "reverse-proxy"
    networks:
      frontend:
        ipv4_address: "x.x.x.x"
      backend:
        ipv4_address: "y.y.y.y"
    hostname: "reverse-proxy"
    "..."
  nextcloud-webserver:
    image: "nginx:stable-alpine"
    "..."
  nextcloud:
    image: "nextcloud:stable-fpm-alpine"
    "..."
    networks:
      frontend:
        ipv4_address: "x.x.x.x"
      backend:
        ipv4_address: "y.y.y.y"
    "..."
  nextcloud-database:
    image: "yobasystems/alpine-mariadb"
    "..."
  code-web:
    image: "nginx:stable-alpine"
    container_name: "code-web"
    networks:
      backend:
        ipv4_address: "y.y.y.y"
    hostname: "code-web"
    depends_on:
      - "code"
    "..."
  code:
    image: "collabora/code:latest"
    container_name: "code"
    networks:
      frontend:
        ipv4_address: "x.x.x.x"
      backend:
        ipv4_address: "y.y.y.y"
    hostname: "code"
    restart: "always"
    env_file:
      - "~/dock/code/code.env"

networks:
  frontend:
    internal: false
    ipam:
      config:
        - subnet: "x.x.x.x/x"
          gateway: "x.x.x.x"
  backend:
    internal: true
    ipam:
      config:
        - subnet: "y.y.y.y/y"
          gateway: "y.y.y.y"

~/dock/code/code.env

aliasgroup1="https://nextcloud.foo.tld:443"
DONT_GEN_SSL_CERT="true"
extra_params="--o:ssl.enable=false --o:ssl.termination=true"
password='password'
server_name="hostname-app"
username="username"

These are the relevant nginx configs. A lot of stuff is left out and any include statements are replaced with the files that they include.

reverse-proxy.conf

# https://nginx.org/en/docs/ngx_core_module.html#worker_processes
worker_processes auto;
# https://nginx.org/en/docs/ngx_core_module.html#error_log
error_log /var/log/nginx/error.log;
# https://nginx.org/en/docs/ngx_core_module.html#pid
pid /run/nginx.pid;
# https://nginx.org/en/docs/ngx_core_module.html#include
include /usr/share/nginx/modules/*.conf;

# https://nginx.org/en/docs/ngx_core_module.html#events
events {
    # https://nginx.org/en/docs/ngx_core_module.html#worker_connections
    worker_connections 1024;
}

# https://nginx.org/en/docs/http/ngx_http_core_module.html#http
http {
    # https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log
    access_log /var/log/nginx/access.log combined;
    # https://nginx.org/en/docs/ngx_core_module.html#include
    include /etc/nginx/mime.types;
    # https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type
    default_type application/octet-stream;
    # https://nginx.org/en/docs/http/ngx_http_core_module.html#server
    server {
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols
        ssl_protocols TLSv1.3;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM';
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve
        ssl_ecdh_curve secp384r1;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers
        ssl_prefer_server_ciphers on;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
        ssl_dhparam /etc/nginx/certs/dhparam.pem;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache
        ssl_session_cache shared:SSL:10m;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout
        ssl_session_timeout 10m;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets
        ssl_session_tickets off;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
        ssl_stapling on;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling_verify
        ssl_stapling_verify on;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client
        ssl_verify_client on;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate
        ssl_client_certificate /etc/nginx/certs/authenticated_origin_pull_ca.pem;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate
        ssl_trusted_certificate /etc/nginx/certs/origin_ca_ecc_root.pem;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate
        ssl_certificate /etc/nginx/certs/foo.tld.pem;
        # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key
        ssl_certificate_key /etc/nginx/certs/foo.tld.key;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
        server_name code.foo.tld;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location / {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
            proxy_http_version 1.1;
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_bypass
            proxy_cache_bypass $http_upgrade;
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
            proxy_read_timeout 90;
            # https://docs.oracle.com/en-us/iaas/Content/Balance/Reference/httpheaders.htm
            proxy_set_header X-Real-IP $remote_addr;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
            proxy_set_header X-Forwarded-Proto $scheme;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $host;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
            proxy_set_header X-Forwarded-Host $host;
            # https://docs.oracle.com/en-us/iaas/Content/Balance/Reference/httpheaders.htm
            proxy_set_header X-Forwarded-Port $server_port;
            # https://nginx.org/en/docs/http/websocket.html
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
            proxy_set_header Upgrade $http_upgrade;
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
            proxy_set_header Connection 'upgrade';
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-web:80/;
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
            proxy_redirect http://hostname-web:80 https://code.foo.tld;
        }
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
        add_header Strict-Transport-Security "max-age=15780000; includeSubDomains; preload" always;
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
        add_header X-Frame-Options SAMEORIGIN;
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
        add_header X-XSS-Protection "1; mode=block";
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
        add_header X-Content-Type-Options nosniff;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
        server_tokens off;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip
        gzip off;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile
        sendfile on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nopush
        tcp_nopush on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelay
        tcp_nodelay on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
        keepalive_timeout 65;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#types_hash_max_size
        types_hash_max_size 4096;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
        client_max_body_size 0;
    }
    # https://nginx.org/en/docs/http/ngx_http_core_module.html#server
    server {
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
        listen 80;
        listen [::]:80;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
        server_name _;
        # https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return
        return 301 https://$host$request_uri;
    }
}

web-server.conf

# https://nginx.org/en/docs/ngx_core_module.html#worker_processes
worker_processes auto;
# https://nginx.org/en/docs/ngx_core_module.html#error_log
error_log /var/log/nginx/error.log;
# https://nginx.org/en/docs/ngx_core_module.html#pid
pid /run/nginx.pid;
# https://nginx.org/en/docs/ngx_core_module.html#include
include /usr/share/nginx/modules/*.conf;

# https://nginx.org/en/docs/ngx_core_module.html#events
events {
    # https://nginx.org/en/docs/ngx_core_module.html#worker_connections
    worker_connections 1024;
}

# https://nginx.org/en/docs/http/ngx_http_core_module.html#http
http {
    # https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log
    access_log /var/log/nginx/access.log combined;
    # https://nginx.org/en/docs/ngx_core_module.html#include
    include /etc/nginx/mime.types;
    # https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type
    default_type application/octet-stream;
    #https://sdk.collaboraonline.com/docs/installation/Proxy_settings.html#reverse-proxy-settings-in-nginx-config-ssl-termination
    ########## START collabora ##########
    # https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server
    server {
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
        listen 80 default_server;
        listen [::]:80 default_server;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
        server_name sub.foo.tld;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        ## STATIC FILES ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ^~ /browser {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
        }
        ## WOPI DISCOVERY URL ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ^~ /hosting/discovery {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
        }
        ## CAPABILITIES ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ^~ /hosting/capabilities {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
        }
        ## DOWNLOAD, PRESENTATION & IMAGE UPLOAD ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ~ ^/(c|l)ool {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
        }
        ## MAIN WEBSOCKET ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ~ ^/cool/(.*)/ws$ {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
            # https://nginx.org/en/docs/http/websocket.html
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
            proxy_set_header Upgrade $http_upgrade;
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
            proxy_set_header Connection "Upgrade";
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
            proxy_read_timeout 36000s;
        }
        ## ADMIN CONSOLE WEBSOCKET ##
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#location
        location ^~ /cool/adminws {
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
            proxy_pass http://hostname-app:9980;
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
            proxy_set_header Host $http_host;
            # https://nginx.org/en/docs/http/websocket.html
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
            proxy_set_header Upgrade $http_upgrade;
            ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
            proxy_set_header Connection "Upgrade";
            # https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
            proxy_read_timeout 36000s;
        }
    ########## END collabora ##########
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
        add_header X-Frame-Options SAMEORIGIN;
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
        add_header X-XSS-Protection "1; mode=block";
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
        add_header X-Content-Type-Options nosniff;
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
        add_header Referrer-Policy "no-referrer";
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
        add_header X-Download-Options "noopen";
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
        add_header X-Permitted-Cross-Domain-Policies none;
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
        add_header X-Robots-Tag none;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
        server_tokens off;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip
        gzip on;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_vary
        gzip_vary on;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_comp_level
        gzip_comp_level 4;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_min_length
        gzip_min_length 256;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_proxied
        gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
        # https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types
        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;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile
        sendfile on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nopush
        tcp_nopush on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelay
        tcp_nodelay on;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
        keepalive_timeout 65;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#types_hash_max_size
        types_hash_max_size 4096;
        # https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
        client_max_body_size 512M;
        # https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers
        fastcgi_buffers 64 4K;
        # https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_hide_header
        fastcgi_hide_header X-Powered-By;
    }
}
1 Like

After adding regex expressions for around 10 IP addresses… I gave up. I’m really not sure how, but originally I only got the error for the host ip (when setting the server as admin), then for similar looking ips(when opening a document from here on), then for probably cloudflare ips(but not my cloudflare ips), then finally the local ip that my docker clients are connected to and then just random seeming extra ips… Therefore I can only guess that the approach with --o:net.post_allow.host[x]=z\.z\.z\.z is either flawed or just incorrect.

(this is copied from stackoverflow, for context: I looked at this and figured that using net.post_allow.host[x] would be the correct approach.

I do not use docker so I am not sure if there are any additional settings necessary there, but with the follow nginx locatons reverse proxying works in my setup:

  # static files
  location ^~ /browser {
    proxy_pass http://10.0.0.3;
    proxy_set_header Host $http_host;
  }

  # WOPI discovery URL
  location ^~ /hosting/discovery {
    proxy_pass http://10.0.0.3;
    proxy_set_header Host $http_host;
  }

  # main websocket
  location ~ ^/cool/(.*)/ws$ {
    proxy_pass http://10.0.0.3;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $http_host;
    proxy_read_timeout 36000s;
  }

  # download, presentation and image upload
  location ~ ^/cool {
    proxy_pass http://10.0.0.3;
    proxy_set_header Host $http_host;
  }

  # Admin Console websocket
  location ^~ /cool/adminws {
    proxy_pass http://10.0.0.3;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $http_host;
    proxy_read_timeout 36000s;
  }

  #capabilities check
  location ^~ /hosting/capabilities {
    proxy_pass http://10.0.0.3;
    proxy_set_header Host $http_host;
  }

I hope this helps

3 Likes

Thank you very much for the reply, I’ll try the config you have suggested and see how it goes.
It may take a few days until I can give you feedback however.

1 Like

Ensure that your reverse proxy is configured correctly. Verify that the reverse proxy is correctly forwarding requests to your Collabora CODE container. Make sure you have the necessary SSL certificates configured for the Collabora domain. Check if CORS is properly configured. Buy proxies isn’t a problem either, there are quite a few companies you can trust nowadays. Collabora CODE needs to be able to communicate with your Nextcloud instance, and this involves proper CORS setup. Double-check your Nextcloud configuration to ensure that it’s set up to use Collabora CODE. This includes the server URL and any other relevant settings in the Nextcloud admin panel related to Collabora integration.

1 Like

take a look at this article it helps to find or even resolve 99% of the issues

Nextcloud Collabora integration

1 Like

Thank you very much for trying to answer my question.

(from stackoverflow):
I gave up on this topic more than half a year ago. I’d assume that it’s some issue with my configuration.

If you want me to close this, please let me know. I’d leave this open for now since someone might find this useful in the future and since there isn’t any clear solution that I have confirmed to be working.

1 Like

Hey @leomeinel. Thanks for the update. :slight_smile:

Is this still an issue on the latest versions though? A lot has changed and been fixed in Collabora / Nextcloud (richdocuments) in the last year or two.

I just installed the docker versions for Collabora+Nextcloud a few weeks ago, and it went smooth… so perhaps the same will happen to you too. :slight_smile:

I’m facing a similar issue. I’m trying to set up NextCloud and Collabora on the same domain, but using two different ports.

NextCloud indicates that the Collabora Online server is reachable, and I can successfully curl from the client to NextCloud, as well as from NextCloud to Collabora and vice versa.

Despite this, I’m unable to edit files. The Collabora logs show the following error:
[ websrv_poll ] WRN convert-to: Requesting address is denied: NextCloudIP| wsd/ClientRequestDispatcher.cpp:493

I’m unsure of the root cause, but suspect it may be related to the reverse proxy configuration, NextCloud settings, or Collabora settings.

Here’s an overview of my setup. I’m using Caddy as a reverse proxy.
In docker-compose.yaml, I have the following configuration for Caddy and Collabora:

caddy:
    container_name: reverse-proxy
    image: caddy:2
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
      - 9985:9985
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_v2_data:/data
      - ./caddy_v2_config:/config
    networks:
      - nextcloud_network
collabora: 
    image: collabora/code
    container_name: collabora_app
    environment:
      - domain=NEXTCLOUDDOMAIN\\.dedyn\\.io
      - aliasgroup1=NEXTCLOUDDOMAIN.dedyn.io
      - server_name=https://NEXTCLOUDDOMAIN.dedyn.io:9985
      - username=${COLLABORA_USERNAME}
      - password=${COLLABORA_PASSWORD}
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:net.proto=IPv4
    cap_add: 
      - MKNOD
    ports:
      - "9980:9980"
    volumes:
      - ./collabora_setup/coolwsd/coolwsd.xml:/etc/coolwsd/coolwsd.xml
    networks:
      - nextcloud_network
    restart: always

My Caddyfile is as follows:

https://NEXTCLOUDDOMAIN.dedyn.io:443 {
        reverse_proxy nextcloud-web:80

        # Set headers
        header /* {
                Strict-Transport-Security "max-age=15552000;"
        }

        # Rewrite rules
        rewrite /.well-known/carddav /remote.php/dav
        rewrite /.well-known/caldav /remote.php/dav
        rewrite /.well-known/webfinger /index.php/.well-known/webfinger
        rewrite /.well-known/nodeinfo /index.php/.well-known/nodeinfo
}

https://NEXTCLOUDDOMAIN.dedyn.io:9985 {
        reverse_proxy collabora_app:9980
        reverse_proxy /cool/* http://127.0.0.1:9980 {
                header_up Host {host}
                header_up X-Real-IP {remote}
                header_up Connection "Upgrade"
                header_up Upgrade websocket
        }
}

And in coolwsd.xml file, I’ve modified the server_name:
<server_name desc=“External hostname:port of the server running coolwsd. If empty, it’s derived from the request (please set it if this doesn’t work). May be specified when behind a reverse-proxy or when the hostname is not reachable directly.” type=“string” default=“”>NEXTCLOUDDOMAIN.dedyn.io:9985</server_name>

I also adjusted the SSL settings:

<enable type="bool" desc="Controls whether SSL encryption between coolwsd and the network is enabled (do not disable for production deployment). If default is false, must first be compiled with SSL support to enable." default="true">false</enable>
<termination desc="Connection via proxy where coolwsd acts as working via https, but actually uses http." type="bool" default="true">true</termination>
And the username and password for the admin console.

I would appreciate any suggestions or guidance on how to resolve this issue. Thanks in advance!

So I kind of found the issue and multiple fixes to it.

The problem is that the Collabora and Nextcloud-Servers are being proxied by Cloudflare. Specifying the Nextcloud-Server in aliasgroup1 therefore doesn’t allow the actual requesting IP.

Meaning

a1.a2.a3.a4 maps to example.com, which is listed in aliasgroup1.

The outgoing requests from that server are coming from b1.b2.b3.b4, which is not mapped to example.com, and is also not allowed to make WOPI requests, just like any Cloudflare IPs aren’t allowed, except the one that maps to example.com.

Probably insecure solution

This, especially configuring the Allow list for WOPI requests, did solve my problem.

Just adding all Cloudflare IP-Ranges to Allow list for WOPI requests in the Nextcloud-Web-UI fixed the problem for me. I am not sure if this is secure (at all).

@Red’s answer (stackoverflow.com) is still kind of correct and would work for static IPs. And I would consider it (more) secure depending on the resulting Allow list for WOPI requests in the Nextcloud-Web-UI.

A more secure solution would be following this

Things you have to change regardless of Full (strict) Cloudflare ssl configuration

As stated here, you would then specify in the Allow list for WOPI requests, which can be found in the Nextcloud-Web-UI:

<Docker-hostname-that-both-Nextcloud-and-Collabora-share-as-IPv4,Docker-hostname-that-both-Nextcloud-and-Collabora-share-as-IPv6>

So for example:

10.1.0.1/16,fe80::.../64

You will also have to select Disable certificate verification (insecure). Since requests will be made locally, this shouldn’t be a problem.

Things to consider when using Full (strict) Cloudflare ssl configuration - Adding a local nginx server block

The local server block can’t contain the following:

server {
    ...
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_verify_client on;
    ssl_client_certificate [...];
    ssl_trusted_certificate [...];
    ...
}

Your Cloudflare configuration can stay the same, since requests from Nextcloud to Collabora and vice versa will be made locally

Other things I have changed for the local server block:

server {
    listen 127.0.0.1:443 ssl;
    listen [::1]:443 ssl;
    listen <Docker-hostname-that-both-Nextcloud-and-Collabora-share>:443 ssl;
    ...
}

Other than that both the local and the public server blocks are exactly the same.

The public server block however only listens on the following:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    ...
}

You might have to add the following to other server blocks that aren’t your public Collabora or Nextcloud blocks if they are also on <Docker-hostname-that-both-Nextcloud-and-Collabora-share>:

server {
    ...
    listen <Docker-hostname-that-both-Nextcloud-and-Collabora-share>:443 ssl;
    ...
}

Things to consider when using Podman

This also works if all the services concerned are in the same Podman pod, and you are using Podman, NOT Docker:

You would then have to specify as flags for podman pod create:

--network-alias=collabora.example.com --network-alias=nextcloud.example.com

I also removed the extra Web-Server from my original configuration and just moved it to the reverse proxy for anyone trying to follow that.

NOTE: I did a lot of edits and hope that this is finally done and at least kind of well-structured. NOTE2: Read your edits before submitting :slight_smile:

2 Likes

Thanks a lot @leomeinel for the update.

1 Like