Seafile CE + Collabora integration

I am interested in integration of Seafile CE with Collabora, but even i follow the tutorial, i get “Unauthorized WOPI host” error. So I would like to ask people who have successfully integrated Seafile CE and Collabora the following:

  • Do you use “real” or DynDNS domain names (mine are dyndns)?
  • What is the certificate used (mine is LetsEncrypt)?
  • Are you running Seafile and Collabora docker on the same server or on two machines?
  • Do you use Apache or nginx (I use nginx)?

Thanks in advance for the answers!

Hey,

I have seafile with collabora on a server at home using dynamic dns. Also I have a real domain were I set up two Subdomains with cname to the dyndnd entry. I also use certificates from let’s encrypt and have both services (seafile /collabora docker image) running on the same host behind nginx.

In the nginx configs I added a redirection from http to https for every request.
Regards

Thanks for the answer, Garfield. I will re-setup my test environment then and will try again.

Kind regards

Korry

Garfield, still struggling, would you please post your config (or email it to korry73@gmail.com)
Thanks!

Hey korry,
I have uploaded the config here
I use mysql (MariaDB) as backend and it’s Ubuntu 17.04.
Perhaps you can find any difference.

I’m running Seafile Server and CollaboraCODE behind Nginx on the same server using one domain for both. Certificate is from Let’s Encrypt.

My guess is, it has something to do with your 'add_header X-Frame-Options "allow-from ’ in collabora.conf because “Unauthorized WOPI host” points me in that direction.

When fetch https://server.my.domain/hosting/discovery even from a different location via internet, I get an xml docoment like this:

<wopi-discovery>
<net-zone name="external-http">
    <app name="application/vnd.lotus-wordpro">
        <action ext="lwp" name="view" urlsrc="https://server.my.domain/loleaflet/XXXXXXXX/loleaflet.html?"/>
    </app>
    <app name="image/svg+xml">
        <action ext="svg" name="view" urlsrc="https://server.my.domain/loleaflet/XXXXXXXX/loleaflet.html?"/>
    </app>

Thanks Garfield and Wolle for your support. Still not working :frowning:

My config (tried Wolle’s suggestion with one server for both)

server {

listen 80;
server_name seacloud.no-ip.info; #because of kseafile

rewrite ^ https://$http_host$request_uri? permanent; # force redirect http to https
server_tokens off;

}

server {
listen 443;
server_name seacloud.no-ip.info;
ssl on;

ssl_certificate /etc/letsencrypt/live/seacloud.no-ip.info/fullchain.pem; #with letsencrypt
ssl_certificate_key /etc/letsencrypt/live/seacloud.no-ip.info/privkey.pem; #with letsencrypt
ssl_session_timeout 120m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers “ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4”;

proxy_set_header X-Forwarded-For $remote_addr;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    server_tokens off;

###################
ssl_session_cache shared:SSL:128m;
add_header Strict-Transport-Security “max-age=31557600; includeSubDomains”;
ssl_stapling on;
ssl_stapling_verify on;

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "allow-from https://seacloud.no-ip.info:443, ALLOW-FROM https://seacloud.no-ip.info" always;
add_header X-Xss-Protection "1";

add_header Referrer-Policy same-origin;

###################

location / {

fastcgi_pass    127.0.0.1:8000;
fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
fastcgi_param   PATH_INFO           $fastcgi_script_name;

fastcgi_param   SERVER_PROTOCOL     $server_protocol;
fastcgi_param   QUERY_STRING        $query_string;
fastcgi_param   REQUEST_METHOD      $request_method;
fastcgi_param   CONTENT_TYPE        $content_type;
fastcgi_param   CONTENT_LENGTH      $content_length;
fastcgi_param   SERVER_ADDR         $server_addr;
fastcgi_param   SERVER_PORT         $server_port;
fastcgi_param   SERVER_NAME         $server_name;
fastcgi_param   HTTPS               on;
fastcgi_param   HTTP_SCHEME         https;

access_log      /var/log/nginx/seahub.access.log;
error_log       /var/log/nginx/seahub.error.log;

}

location /seafhttp {

rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://127.0.0.1:8082;
client_max_body_size 0;

proxy_read_timeout 300;

}
location /seafdav {
fastcgi_pass 127.0.0.1:8080;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;

  fastcgi_param   SERVER_PROTOCOL     $server_protocol;
  fastcgi_param   QUERY_STRING        $query_string;
  fastcgi_param   REQUEST_METHOD      $request_method;
  fastcgi_param   CONTENT_TYPE        $content_type;
  fastcgi_param   CONTENT_LENGTH      $content_length;
  fastcgi_param   SERVER_ADDR         $server_addr;
  fastcgi_param   SERVER_PORT         $server_port;
  fastcgi_param   SERVER_NAME         $server_name;

  fastcgi_param   HTTPS               on;

  access_log      /var/log/nginx/seafdav.access.log;
  error_log       /var/log/nginx/seafdav.error.log;

}

location /media {

root /home/sfuser/seafile-server-latest/seahub;

}

static files

location ^~ /loleaflet {
    proxy_pass https://localhost:9980;
    proxy_set_header Host $http_host;
}

# WOPI discovery URL
location ^~ /hosting/discovery {
    proxy_pass https://localhost:9980;
    proxy_set_header Host $http_host;
}

# websockets, download, presentation and image upload
location ^~ /lool {
    proxy_pass https://localhost:9980;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
}

}

##############################################

Now the error changed to “Well, this is embarrassing, we cannot connect to your document. Please try again.”

In docker i have:

wsd-00025-00033 10:09:51.945684 [ websrv_poll ] WRN Waking up dead poll thread [docbroker_00d], started: false, finished: true| ./net/Socket.hpp:507
wsd-00025-00033 10:09:51.946203 [ websrv_poll ] WRN Waking up dead poll thread [docbroker_00d], started: false, finished: true| ./net/Socket.hpp:507
wsd-00025-00087 10:09:51.962084 [ docbroker_00e ] ERR Cannot get file info from WOPI storage uri [http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit]. Error: SSL Exception: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol| wsd/Storage.cpp:476
wsd-00025-00087 10:09:51.962489 [ docbroker_00e ] ERR Failed to add session to [seacloud.no-ip.info:80/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56] with URI [http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit]: SSL Exception| wsd/DocumentBroker.cpp:801
wsd-00025-00087 10:09:51.962664 [ docbroker_00e ] ERR Error while loading : SSL Exception| wsd/LOOLWSD.cpp:2106
wsd-00025-00087 10:09:51.963262 [ docbroker_00e ] WRN Child session [0013] not found to forward message: load url=http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit readonly=0 lang=en-US| wsd/DocumentBroker.cpp:1278
wsd-00025-00087 10:09:51.963875 [ docbroker_00e ] WRN Child session [0013] not found to forward message: useractive| wsd/DocumentBroker.cpp:1278
wsd-00025-00087 10:09:52.970128 [ docbroker_00e ] ERR No socket associated with WebSocketHandler 0x0x7f9db8012bb0| ./net/WebSocketHandler.hpp:110
wsd-00025-00026 10:09:52.970631 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00e], started: true, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:09:52.970922 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00e], started: true, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:09:52.971142 [ prisoner_poll ] WRN Prisoner connection disconnected but without valid socket.| wsd/LOOLWSD.cpp:1363
wsd-00025-00026 10:09:52.971330 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00e], started: false, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:09:52.971542 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00e], started: false, finished: true| ./net/Socket.hpp:507
wsd-00025-00091 10:10:06.031223 [ docbroker_00f ] ERR Cannot get file info from WOPI storage uri [http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit]. Error: SSL Exception: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol| wsd/Storage.cpp:476
wsd-00025-00091 10:10:06.031844 [ docbroker_00f ] ERR Failed to add session to [seacloud.no-ip.info:80/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56] with URI [http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit]: SSL Exception| wsd/DocumentBroker.cpp:801
wsd-00025-00091 10:10:06.032086 [ docbroker_00f ] ERR Error while loading : SSL Exception| wsd/LOOLWSD.cpp:2106
wsd-00025-00091 10:10:06.032427 [ docbroker_00f ] WRN Child session [0014] not found to forward message: load url=http://seacloud.no-ip.info/api2/wopi/files/a93dca03d626a26bd8487ce8d294f886d6dcbb56?access_token=a2409a9d49aa4a5c975d4a600abfcf15&access_token_ttl=1501151989000&permission=edit readonly=0 lang=en-US| wsd/DocumentBroker.cpp:1278
wsd-00025-00091 10:10:06.032613 [ docbroker_00f ] WRN Child session [0014] not found to forward message: useractive| wsd/DocumentBroker.cpp:1278
wsd-00025-00091 10:10:07.038206 [ docbroker_00f ] ERR No socket associated with WebSocketHandler 0x0x7f9db80185d0| ./net/WebSocketHandler.hpp:110
wsd-00025-00026 10:10:08.708637 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00f], started: true, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:10:08.709374 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00f], started: true, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:10:08.709902 [ prisoner_poll ] WRN Prisoner connection disconnected but without valid socket.| wsd/LOOLWSD.cpp:1363
wsd-00025-00026 10:10:08.710244 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00f], started: false, finished: true| ./net/Socket.hpp:507
wsd-00025-00026 10:10:08.710617 [ prisoner_poll ] WRN Waking up dead poll thread [docbroker_00f], started: false, finished: true| ./net/Socket.hpp:507

and i start it with

sudo docker run -t -p 9980:9980 -e “domain=seacloud\.no-ip\.info” --restart always --cap-add MKNOD collabora/code

Seacloud is a test environment.

Does somebody have a clue what should be changed?

Kind regards

Korry

Instead of that I have:

add_header X-Content-Type-Options nosniff;
add_header Access-Control-Allow-Origin *;

Thanks, Wolle, tested it, same - “Well, this is embarassing…”

From outside your server:

wget --quiet -O- https://seacloud.no-ip.info/hosting/discovery | head

Do you get reasonable xml output?

Yes:

wget --quiet -O- https://seacloud.no-ip.info/hosting/discovery | head

The XML does not appear here, but it is correct. You can run it against my server too (or to open it in a browser)

Did you adjust your seahub_settings.py to the changed domain of Collabora? Restarted seafile and seahub? I remember I had similar problems and suddenly after a reboot it worked.

Yes:

From 6.1.0 CE version on, Seafile support viewing/editing doc, ppt, xls files via LibreOffice

Add this setting to view/edit doc, ppt, xls files

OFFICE_SERVER_TYPE = ‘CollaboraOffice’

Enable LibreOffice Online

ENABLE_OFFICE_WEB_APP = True

Url of LibreOffice Online’s discovery page

The discovery page tells Seafile how to interact with LibreOffice Online when view file online

You should change https://collabora-online.seafile.com/hosting/discovery to your actual LibreOffice Online server address

OFFICE_WEB_APP_BASE_URL = ‘https://seacloud.no-ip.info/hosting/discovery

Expiration of WOPI access token

WOPI access token is a string used by Seafile to determine the file’s

identity and permissions when use LibreOffice Online view it online

And for security reason, this token should expire after a set time period

WOPI_ACCESS_TOKEN_EXPIRATION = 30 * 60 # seconds

List of file formats that you want to view through LibreOffice Online

You can change this value according to your preferences

And of course you should make sure your LibreOffice Online supports to preview

the files with the specified extensions

OFFICE_WEB_APP_FILE_EXTENSION = (‘ods’, ‘xls’, ‘xlsb’, ‘xlsm’, ‘xlsx’,‘ppsx’, ‘ppt’, ‘pptm’, ‘pptx’, ‘doc’, ‘docm’, ‘docx’, ‘odt’)

Enable edit files through LibreOffice Online

ENABLE_OFFICE_WEB_APP_EDIT = True

types of files should be editable through LibreOffice Online

OFFICE_WEB_APP_EDIT_FILE_EXTENSION = (‘ods’, ‘xls’, ‘xlsb’, ‘xlsm’, ‘xlsx’,‘ppsx’, ‘ppt’, ‘pptm’, ‘pptx’, ‘doc’, ‘docm’, ‘docx’, ‘odt’)

Have restarted everything. Will restart the virtual machine again though.

This options allows or prevents the browser from loading a website within an iframe. In my configuration i only allow the browser to load my collabora-website if it is within the iframe of my seafile-website.

This looks like something is wrong with the ssl certificates or maybe something dns-related within your host.

I compared your nginx header informations with mine.
From your server i get the strict-transport-security header value two times:

strict-transport-security: max-age=31536000; includeSubDomains, max-age=31557600; includeSubDomains

On my server it looks like this:

strict-transport-security: max-age=31557600; includeSubDomains

I don’t think that this has any effect.

And i found out that your certificate used for collabora is for CN ‘bridge.no-ip.info’ - is this correct? It should be for collabora.mydomain.info

Hi,

I have reissued the certificate and now it is only and strictly for the Seafile CE & Collabora domain, which in my case is seacloud.no-ip.info. No change though.

I have expected what the X-Frame-Option is for, have reverted to Garfield’s config and retested - same behaviour.

When I try to access https://bridge.no-ip.info I get the certificate for seacloud.no-ip.info - I guess bridge is your domain for collabora?
When I test with my server there is the correct certificate presented for both domains by nginx.

Well, initially my intention was to use seacloud.no-ip.info for Seafile CE and bridge.no-ip.info for Collabora.
But after Wolle mentioned, that it works for him with same domain, i have changed it to seacloud,no-ip.info only for both. Both domains share same ip . Now only seacloud.no-ip,info will open, you will get

bridge.no-ip.info uses an invalid security certificate. The certificate is only valid for seacloud.no-ip.info Error code: SSL_ERROR_BAD_CERT_DOMAIN

if you try to open brdge.no-ip.info and it is not used in the test environment anymore.

So now my setup should be correct, but anyway i get “unable to connect” still

If you want to use one domain for both services, I think you need to use different ports or at least different directories.

On my server seafile and collabora are running on different domains and therefore I have two nginx-configs with different certificates.
Please check your nginx configuration carefully to really have the names, ports, certificates and paths correct.

Garfield, not sure what you mean.
Seafile CE is running fine except the Collabora integration, Collabora is a docker container, so what directories and ports do you mean?
I understand your setup is bit different, but i cannot make cname records or use subdomains with the noip.com service. That’s why i have tried Wolle’s setup. Failed with same error though. Still do not get why.

I mean the virtual directories you (maybe) need to set up within your nginx configuration. I am not sure what you need if you want to use only one domain.
Are you forced to use no-ip or can you use another dyndns-provider?
Maybe you can create hosts-entries for testing with different domains and if that is working, you can merge it to use only one domain.