nextcloud / documentserver_community

Document server for onlyoffice
https://apps.nextcloud.com/apps/documentserver_community
129 stars 29 forks source link

Multi domain #75

Open ToneLune opened 4 years ago

ToneLune commented 4 years ago

Hello,

Congratulations for this integration of OnlyOffice to NextCloud, no more complications with Docker and Vhosts!

I use the same instance of NextCloud on several domains, OnlyOffice works very well on the configured domain (https://cloud.domain1.fr/index.php/apps/documentserver_community/ in Document editing service adress), but how can I integrate others domains?

Thanks you!

nobooody commented 4 years ago

My Nextcloud is also accessible from other domains, unfortunately it only works from the main domain. I would also be interested if and how it is possible to use multiple domains.

sOUTHX1337 commented 4 years ago

same problem/wish here.

WhilelM commented 4 years ago

same problem/wish here.

dbeniamine commented 4 years ago

I have the same problem and there is a discussion on Nextcloud forum.

From my understanding the issue is due to the only office frame coming from another domain than the main page, thus blocked by the X-FRAME-OPTION header which is set by Nextcloud to SAMEORIGIN. We should not remove this header for security reason.

Therefore the best solution would be to have a setting in onlyoffice : "use app documentserver` that construct the url of the documentserver depending on Nextcloud url.

Does that make sense ?

systemofapwne commented 4 years ago

I just ran into similar issues as mentioned by @dbeniamine. My nextcloud runs in a docker container and a nginx reverse proxy serves the content via TLS to two domains with very strict TLS settings. DomainA.tld works fine, since ONLYOFFICE uses DomainA.tld as service address. DomainB.tld on the other hand will not work due to X-FRAME-OPTION sameorigin, which I really do not want to give up. The error I do experience in chrome is

Refused to display 'https://DomainA.tld/apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/documenteditor/main/index.html?_dc=5.4.2-46&lang=de-DE&customer=ONLYOFFICE&frameEditorId=iframeEditor' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".

My first idea was to tell nginx to filter the transmitted HTML in oder to rewrite "DomainA.tld" to "DomainB.tld", when accessed via DomainB.tld via a sub_filter

    #Disable gzip so sub_filter works
    gunzip on;
    gzip_disable ".";

    sub_filter 'DomainA.tld' '$host';
    sub_filter_once off;
    sub_filter_types text/xml text/css text/javascript;

Yet, this did not help 100%: Now, the "sameorigin" error for the iframe disappears but now it fails on another location.

Refused to frame 'https://DomainB.tld/apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/documenteditor/main/index.html?_dc=5.4.2-46&lang=de-DE&customer=ONLYOFFICE&frameEditorId=iframeEditor' because it violates the following Content Security Policy directive: "frame-src https://DomainA.tld/apps/documentserver_community/".

Nc2020-1 commented 4 years ago

I have the same problem. It would be great to integrate that multi domain feature.

eliwap commented 4 years ago

I would like to add my vote to this request

ramenpepe commented 4 years ago

its not pretty but i did a quick patch to load the conflicting iframe and javascript from the same hostname by tweaking. :

nextcloud/apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/api/documents/api.js function createIframe(config) { var iframe = document.createElement("iframe"); url = window.location.protocol+"//"+window.location.hostname+"/apps/documentserver"+getAppPath(config).split("/apps/documentserver")[1]+getAppParameters(config); iframe.src = url;

nextcloud/apps/onlyoffice/templates/editor.php if (!empty($_["directToken"])) { script("onlyoffice", "directeditor"); } $u=explode("/",$_['documentServerUrl']); $_['documentServerUrl']=$u[0]."//".$_SERVER['HTTP_HOST']."/".$u[3]."/".$u[4]."/$ ?>

dbeniamine commented 4 years ago

I tested @kwangwei modifications, I had to change them a bit (see below) as I have nextcloud installed in /nextcloud, but it still di do not work for the second hostname:

Content Security Policy: The page’s settings blocked the loading of a resource at https://sub2.fqdn/nextcloud/apps/documentserver_commu….2-46&lang=en&customer=ONLYOFFICE&frameEditorId=iframeEditor (“frame-src”).

Where sub2 is the second subdomain. I do not understand why it is still block, sub2.fqdn is the right host now ...

My version of the patch:

first point is replacing line 768 of nextcloud/apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/api/documents/api.js by

iframe.src = window.location.protocol+"//"+window.location.hostname+'/'+getAppPath(config).split('/').slice(3).join('/')+getAppParameters(config);

Second is adding line 36 of nextcloud/apps/onlyoffice/templates/editor.php :

$u=explode("/",$_['documentServerUrl']);                                    
$path = implode('/', array_slice($u, 3));                                   
$_['documentServerUrl']=$u[0]."//".$_SERVER['HTTP_HOST']."/".$path;   
Orhideous commented 4 years ago

Even after @kwangwei's patch still doesn't works due strict CSP for base page. For example, https://cloud.second.domain/apps/onlyoffice/337682?filePath=test.xlsx has CSP with frame-src https://cloud.FIRST.DOMAIN/apps/documentserver_community/, so frame with relative url /apps/documentserver_community/… (that means https://cloud.second.domain/apps/documentserver_community/…) can't be loaded.

P.S. Changing iframe's address to absolute didn't help either, because request with absolute address turns to 302 response with relative location.

yihanwu1024 commented 4 years ago

My Nextcloud is also accessible from other domains, unfortunately it only works from the main domain. I would also be interested if and how it is possible to use multiple domains.

Just to be more accurate, it only works for the domain that is set in ONLYOFFICE connector settings.

LeeteqXV commented 4 years ago

This is an important feature. Many projects cannot even get started using NC without this.

heikar commented 3 years ago

Any news?

I have here a nextcloud instance which is reachable through two domains. In the first domain Only Office works perfect but in in the second domain i cannot open office documents.

In the js console i get the following exception:

because it violates the following Content Security Policy directive: "frame-src

@dbeniamine Unfortunately your patch does not work :( I have installed the following apps: Community Document Server with version 0.1.8 and ONLYOFFICE with version 6.2.0.

terafirmanz commented 3 years ago

I have this issue too.

NC is on sub1.domain.com OO is on sub2.doamin.com (installed as part of OnlyOffice Groups)

I have a workaround in place thanks to running a reverse proxy for SSL offloading etc. I use HAProxy but this could be adapted for others.

I solved this by updating my HAProxy config to like so: frontend acl nextcloud hdr_beg(host) -i sub1.domain.com acl onlyoffice hdr_beg(host) -i sub2.domain.com acl onlyoffice_docs path_beg /ds-vpath/ use_backend onlyoffice if nextcloud onlyoffice_docs use_backend nextcloud if nextcloud

In short I forward requests for onlyoffice to the onlyoffice server and then on the nextcloud domain I detect if the URL path begins with teh onlyoffice path (groups installs it into /ds-vpath/ if you have it in the root of a domain this won't work.

Then in Nextcloud I set the Onlyoffice URL to be the nextcloud domain to /ds-vpath/ so https://sub1.domain.com/ds-vpath/ put in my key and perfect it works.

All this excludes all the usual Auth token setup and config.php stuff you have to do anyway.

idolpx commented 3 years ago

Now working as expected with tweaks suggested by @dbeniamine.

Thanks!

heikar commented 3 years ago

Hi @idolpx please can you provide the two files? In my environment, the changes dont affect the behavior.

idolpx commented 3 years ago

Hi @idolpx please can you provide the two files? In my environment, the changes dont affect the behavior.

You will have to copy "api.js" to "nextcloud/custom_apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/api/documents" and copy "editor.js" to "nextcloud/custom_apps/onlyoffice/templates". They are both contained in the following archive with @dbeniamine's changes.

https://ultra.idolpx.com/ncoo/ncoo_multidomain.zip

Pilzinsel64 commented 3 years ago

Hello. I have a similar problem.

I have two Nextcloud instances running (on seperated server with own domains). The second one is on a Raspberry Pi 4 (using snap) and can't host a document server instance. On the first Nextcloud instance (manual installation) I use this App as document server.

The first I tried is to copy the document server address from NC instance one to instance two. I also added instance two to the trusted domains to config.php of instance one. Of course, that didn't work. I got the X-Frame-Error.

Then I found this issue and applied the modifications of @kwangwei and then of @dbeniamine on the two instances. But it didn't wok and also the files provided by @idolpx didn't work.

Does that requie more modifications if I want to use this app on multiple NC instances? I would assume that it's very similar to having multiple domains.

If not, I would like to suggest a sub-feature to allow also this, if possible.

Nasjoe commented 3 years ago

Hi !

On our side, we use Docker + Traefik + Nextcloud + Onlyoffice with multi DNS. Example here : https://github.com/Nasjoe/nextcloud-onlyoffice-traefik-docker

All is okay with this docker-compose.yml :

version: '3'

services:
  nextcloud_db:
    image: mariadb:10.4
    volumes:
      - ../data/mysql:/var/lib/mysql
    restart: always

    environment:
      - MYSQL_ROOT_PASSWORD=YOYOYO
      - MYSQL_PASSWORD=YEYEYE
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
    networks:
      - nextcloud_db

  nextcloud_app:  
    image: nextcloud:21
    restart: always
    depends_on:
      - nextcloud_db
    volumes:
      - ../data/www/html:/var/www/html
    hostname: nextcloud
    networks:
      - nextcloud_db
      - frontend

    labels:
      - traefik.enable=true
      - traefik.docker.network=frontend

      - traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud_redirect
      - traefik.http.routers.nextcloud.tls.certresolver=myresolver
      - traefik.http.routers.nextcloud.rule=Host(`nextcloud.host1.re`) || Host(`cloud.host2.re`)

      - traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue=ALLOW
      - traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy=frame-ancestors 'self' host1.re *.host1.re host2.re *.host2.re
      - traefik.http.middlewares.nextcloud.headers.stsSeconds=155520011
      - traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.nextcloud.headers.stsPreload=true
      - traefik.http.middlewares.nextcloud.headers.accesscontrolalloworigin=*
      - traefik.http.middlewares.nextcloud.headers.customresponseheaders.X-Frame-Options=SAMEORIGIN

      - traefik.http.middlewares.nextcloud_redirect.redirectregex.regex=/.well-known/(card|cal)dav
      - traefik.http.middlewares.nextcloud_redirect.redirectregex.replacement=/remote.php/dav/
    deploy:
      resources:
          limits:
            cpus: 4
            memory: 1024M

  onlyoffice:
    container_name: onlyoffice
    restart: always
    hostname: onlyoffice
    depends_on:
      - nextcloud_app
    image: onlyoffice/documentserver:6.3
    restart: always
    networks:
      - frontend
    labels:
      - traefik.enable=true
      - traefik.docker.network=frontend

      - traefik.http.routers.onlyoffice.middlewares=onlyoffice
      - traefik.http.routers.onlyoffice.tls.certresolver=myresolver
      - traefik.http.routers.onlyoffice.rule=Host(`onlyoffice.host1.re`)

      - traefik.http.middlewares.onlyoffice.headers.customFrameOptionsValue=ALLOW-FROM https://host1.re
      - traefik.http.middlewares.onlyoffice.headers.contentSecurityPolicy=frame-ancestors 'self' host1.re *.host1.re host2.re *.host2.re
      - traefik.http.middlewares.onlyoffice.headers.stsSeconds=155520011
      - traefik.http.middlewares.onlyoffice.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.onlyoffice.headers.stsPreload=true

      ## Extra headers for onlyoffice
      - traefik.http.routers.onlyoffice.tls=true
      - traefik.http.middlewares.cors-headers.headers.accessControlAllowOrigin=*
      - traefik.http.middlewares.onlyoffice.headers.customRequestHeaders.X-Forwarded-Proto=https
      - traefik.http.middlewares.onlyoffice.headers.accesscontrolalloworigin=*

    deploy:
      resources:
          limits:
            cpus: 3
            memory: 1024M

networks:
  frontend:
    external:
      name: frontend
  nextcloud_db:
    external:
      name: nextcloud_db

Enjoy !

LouisOuellet commented 2 years ago

To update @dbeniamine response with the current version :

In apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/api/documents/api.js Replace : iframe.src = getAppPath(config) + getAppParameters(config); With : iframe.src = window.location.protocol+"//"+window.location.hostname+'/'+getAppPath(config).split('/').slice(3).join('/')+getAppParameters(config);

In apps/onlyoffice/templates/editor.php Add : <?php $u=explode("/",$_['documentServerUrl']);$path = implode('/', array_slice($u, 3));$_['documentServerUrl']=$u[0]."//".$_SERVER['HTTP_HOST']."/".$path; ?> After : <?php if (!empty($_["documentServerUrl"])) { ?>

Hopefully someone will update the repository with this fix. As a nextcloud instance with multiple domain aliases can surely exist. At least it does in my setup.

My version of the patch:

first point is replacing line 768 of nextcloud/apps/documentserver_community/3rdparty/onlyoffice/documentserver/web-apps/apps/api/documents/api.js by

iframe.src = window.location.protocol+"//"+window.location.hostname+'/'+getAppPath(config).split('/').slice(3).join('/')+getAppParameters(config);

Second is adding line 36 of nextcloud/apps/onlyoffice/templates/editor.php :

$u=explode("/",$_['documentServerUrl']);                                    
$path = implode('/', array_slice($u, 3));                                   
$_['documentServerUrl']=$u[0]."//".$_SERVER['HTTP_HOST']."/".$path;   

I found it was much easier to find a piece of code then a line. Since line can and have changed since @dbeniamine's post.

lomon commented 2 years ago

In my case the patch from @dbeniamine or @LouisOuellet does not work anymore.

NextCloud 23 Community document server 0.1.11 NUROFFICE 7.3.0

Any ideas? I would prefer a stable solution and really hope that multidomain compatibility will come with the next update.

idolpx commented 2 years ago

It took me a lot of experimentation but I finally got everything working exactly the way I wanted with the following docker-compose.yml file. Everything is running on the same docker host system. I can access everything on my local network and from remote. Please try it out and let me know if you have any issues.

version: "3.3"

networks:
  proxy:
    ipam:
      driver: default
      config:
        - subnet: 17.100.0.0/16

services:

  traefik:
    image: traefik:v2.5
    container_name: traefik
    hostname: traefik
    networks:
      default:
      proxy:
        ipv4_address: 17.100.0.2
    command:
      #- "--log.level=DEBUG"
      #- "--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"

      - "--entrypoints.https.address=:443"
      - "--entrypoints.https.http.tls.certResolver=le"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.http.http.redirections.entryPoint.to=entrypoints-https"
      - "--entrypoints.http.http.redirections.entryPoint.scheme=https"

      - "--certificatesResolvers.le.acme.email=jjohnston@techknowpro.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesResolvers.le.acme.tlsChallenge=true"
      - "--certificatesResolvers.le.acme.httpChallenge=true"
      - "--certificatesResolvers.le.acme.httpChallenge.entryPoint=http"
    volumes:
      - /docker/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    restart: always

  mariadb:
    image: jc21/mariadb-aria:10.4
    container_name: mariadb
    hostname: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: 'XXXX'
      MYSQL_DATABASE: 'nextcloud'
      MYSQL_USER: 'nextcloud'
      MYSQL_PASSWORD: 'XXXX'
    ports:
      - 3307:3306
    volumes:
      - /docker/mariadb:/var/lib/mysql
    restart: unless-stopped

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    hostname: nextcloud
    networks:
      default:
      proxy:
    extra_hosts:
#       Add entry to /etc/hosts in container to Traefik proxy for OnlyOffice domain
      - "onlyoffice.domain.com:17.100.0.2"
    labels:

      - traefik.enable=true

      - traefik.http.routers.nextcloud.rule=Host(`nextcloud1.domain.com`, `nextcloud2.domain.com`)
      - traefik.http.routers.nextcloud.tls=true
      - traefik.http.routers.nextcloud.tls.certresolver=le

      - traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud_redirect

      - traefik.http.middlewares.nextcloud.headers.stsSeconds=155520011
      - traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.nextcloud.headers.stsPreload=true

      - traefik.http.middlewares.nextcloud.headers.accesscontrolalloworiginlist=*
      - traefik.http.middlewares.nextcloud.headers.customresponseheaders.X-Frame-Options=SAMEORIGIN

      - traefik.http.middlewares.nextcloud_redirect.redirectregex.permanent=true
      - traefik.http.middlewares.nextcloud_redirect.redirectregex.regex=/.well-known/(card|cal)dav
      - traefik.http.middlewares.nextcloud_redirect.redirectregex.replacement=/remote.php/dav/

    ports:
      - 8888:80
    volumes:
      - /docker/nextcloud:/var/www/html
      - /mnt/time-machine/nextcloud:/var/www/html/data
      - /mnt:/mnt
    restart: unless-stopped

  onlyoffice:
    image: alehoho/oo-ce-docker-license
    container_name: onlyoffice
    hostname: onlyoffice
    extra_hosts:
#       Add entry to /etc/hosts in container to Traefik proxy for OnlyOffice and NextCloud domains
      - "onlyoffice.domain.com:17.100.0.2"
      - "nextcloud1.domain.com:17.100.0.2"
      - "nextcloud2.domain.com:17.100.0.2"
    labels:
#       https://helpcenter.onlyoffice.com/de/installation/docs-community-proxy.aspx

      - traefik.enable=true

      - traefik.http.routers.onlyoffice.rule=Host(`onlyoffice.domain.com`)
      - traefik.http.routers.onlyoffice.tls=true
      - traefik.http.routers.onlyoffice.tls.certresolver=le

      - traefik.http.routers.onlyoffice.middlewares=onlyoffice

      - traefik.http.middlewares.onlyoffice.headers.customrequestheaders.X-Forwarded-Host=onlyoffice.domain.com
      - traefik.http.middlewares.onlyoffice.headers.customrequestheaders.X-Forwarded-Proto=https

    ports:
      - 9981:80
    restart: unless-stopped
idolpx commented 2 years ago

I posted a gist to share.

https://gist.github.com/idolpx/64cbc2b37218194e21413761e065d9fc

badsmoke commented 1 year ago

does anyone have a tutorial for nginx as a proxy?

ant0nwax commented 1 year ago

Please look at this thread, there is also trouble for other things in OnlyOffice 7.2 and 7.3 https://github.com/ONLYOFFICE/DocumentServer/issues/2083

robingroppe commented 5 months ago

+1 Fully agree with @dbeniamine We need multi-domain support out of the box, I am using a Hetzner Storage Share with 3 additional subdomains and only one will ever work with onlyoffice.

Please allow setting the onlyoffice domain to the same domain nextcloud i accessed with