Probably DNS help with NC Docker + Collabora + Wireguard tunnel

Hello, currently I am trying to set up Collabora Online for document editing but I am running into a wall. I run a dockerized instance of nextcloud and Collabora. For this, I referenced this awesome guide: Collabora integration guide

I went through the troubleshooting checklist and I can’t get my containers to see each other, ie verify access to collabora via nextcloud and vice versa is not available. From my host machine I can access them both.

My ISP does not grant me a static IP and I am behind a carrier-grade-NAT (CG-NAT). Therefore I rented a virtual private server (VPS) which hosts an Ubuntu VM with wireguard. My home server runs debian with openmediavault and docker. I connected my home-server and vps via a wireguard tunnel (forwarding all traffic exept ssh to my home-server). On my home server I use Nginx-Proxy-Manager to manage certificates and forwarding.

My nextcloud instance is forwarded to https://cloud.server.de
My Collabora instance is forwarded to https://office.server.de
From my separate computer I get all the results I exspect to be there. Ping works. Curl gives the outputs the guide sais it should.
From my homeserver I can ping the relevant urls, but curl throws an error. From each docker container same result.

That is why I believe it either has something to do with DNS, with firewall or wireguard. I’ve thrown my head against the wall but I don’t have the knowledge on how to further diagnose this issue.

root@nextcloud:/# ping -c2 office.server.de
PING office.server.de (212.xxx.xxx.xxx): 56 data bytes
64 bytes from 212.xxx.xxx.xxx: seq=0 ttl=63 time=14.913 ms
64 bytes from 212.xxx.xxx.xxx: seq=1 ttl=63 time=14.808 ms

--- office.server.de ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 14.808/14.860/14.913 ms



root@nextcloud:/# curl https://office.server.de/hosting/discovery
curl: (7) Failed to connect to office.server.de port 443 after 22 ms: Couldn't connect to server

If relevant, here would be my respective docker-compose files:

collabora

---
version: "2"
services:
  collabora:
    image: collabora/code:latest
    container_name: collabora
    cap_add:
      - MKNOD
    ports:
      - "9980:9980"
    environment:
      - aliasgroup1=https://nextcloud.server.de
      - username=admin
      - password=admin
      - "extra_params=--o:ssl.enable=false --o:ssl.termination=true"
    volumes:
      - /etc/localtime:/etc/localtime:ro

nextcloud

version: "2"
services:
  nextcloud:
    image: lscr.io/linuxserver/nextcloud:27.1.1
    container_name: nextcloud
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
    volumes:
      - ./nextcloud-config/nextcloud:/config
      - ./nextcloud-data/data:/data
    ports:
      - 42351:443
    restart: unless-stopped
    depends_on:
      - nextcloud_db
  nextcloud_db:
    image: linuxserver/mariadb:latest
    container_name: nextcloud_db
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=root_pw
      - TZ=Europe/Berlin
      - MYSQL_DATABASE=nextcloud_db
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=db_pass
    volumes:
      - ./nextcloud-config/db:/config
    restart: unless-stopped

wireguard config - vps

[Interface]
PrivateKey = somethingsomethingsomethingprivate
ListenPort = 51280
Address = 10.0.0.1/24
MTU = 1500

PostUp = iptables -t nat -A PREROUTING -p tcp -i ens192 '!' --dport 22 -j DNAT --to-destination 10.0.0.2; iptables -t nat -A POSTROUTING -o ens192 -j SNAT --to-source 212.xxx.xxx.xxx
PostUp = iptables -t nat -A PREROUTING -p udp -i ens192 '!' --dport 51280 -j DNAT --to-destination 10.0.0.2;


PostDown = iptables -t nat -D PREROUTING -p tcp -i ens192 '!' --dport 22 -j DNAT --to-destination 10.0.0.2; iptables -t nat -D POSTROUTING -o ens192 -j SNAT --to-source 212.xxx.xxx.xxx
PostDown = iptables -t nat -D PREROUTING -p udp -i ens192 '!' --dport 51280 -j DNAT --to-destination 10.0.0.2;

#NAS
[Peer]
PublicKey = somethingsomethingsomethingpublic
AllowedIPs = 10.0.0.2/32

wireguard config - homeserver

[Interface]
PrivateKey = privatekey
Address = 10.0.0.2/24
MTU = 1500
DNS = fritz.box

[Peer]
PublicKey = publickey
AllowedIPs = 0.0.0.0/0
Endpoint = server.de:51280
PersistentKeepalive = 25

hi @PeaaZee welcome to the forum :handshake:

very good first post!

you are using a linuxserver image - this might be not an issue here but they do special customization’s - it’s worth to ask in their forum as well.

you are likely right. I would start with DNS - I see an issue in my installation as well - for some reason I don’t understand containers inside docker don’t user local DNS server (the host does) and always connect through public IP. in my case this works - maybe slower than direct connection but it works - so I don’t really care.

In your case I would

  1. check which IP is used for ping -c2 office.server.de - first octet looks like a public IP - is this your VPS public IP? In my eyes it’s supposed to be your VPS.
  2. as next step try curl https://office.server.de/hosting/discovery -v this will show you more details like
docker exec -ti nextcloud curl https://office.server.de -v
*   Trying 212.xxx.xxx.xxx:443...
* Connected to office.server.de (212.xxx.xxx.xxx) port 443 (#0)

maybe it tells you more already.

Hey, thanks! I am baffled! The man himself!

Yes, the ping IP adress is the static, public IP of my VPS.

As per your request this would be the output of the verbose curl, from homeserver and the containers:

root@homeserver:/# curl -vvv https://office.server.de/hosting/discovery
*   Trying 212.xxx.xxx.xxx:443...
* connect to 212.xxx.xxx.xxx port 443 failed: Connection refused
* Failed to connect to office.server.de port 443 after 23 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to office.server.de port 443 after 23 ms: Couldn't connect to server

whereas the verbose output from my main machine looks like this:

user@privatepc:~> curl -v https://nextcloud.server.de/status.php
*   Trying 212.xxx.xxx.xxx:443...
* Connected to nextcloud.server.de (212.xxx.xxx.xxx) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=nextcloud.server.de
*  start date: Dec 13 10:56:37 2023 GMT
*  expire date: Mar 12 10:56:36 2024 GMT
*  subjectAltName: host "nextcloud.server.de" matched cert's "nextcloud.server.de"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://nextcloud.server.de/status.php
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: nextcloud.server.de]
* [HTTP/2] [1] [:path: /status.php]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [accept: */*]
> GET /status.php HTTP/2
> Host: nextcloud.server.de
> User-Agent: curl/8.4.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 200 
< server: openresty
< date: Wed, 13 Dec 2023 13:08:15 GMT
< content-type: application/json
< vary: Accept-Encoding
< set-cookie: oc_sessionPassphrase=passphrase; path=/; secure; HttpOnly; SameSite=Lax
< content-security-policy: default-src 'self'; script-src 'self' 'nonce-somejibberish'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
< set-cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
< set-cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
< set-cookie: cookie; path=/; secure; HttpOnly; SameSite=Lax
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< cache-control: no-store, no-cache, must-revalidate
< pragma: no-cache
< access-control-allow-origin: *
< referrer-policy: no-referrer
< x-content-type-options: nosniff
< x-download-options: noopen
< x-frame-options: SAMEORIGIN
< x-permitted-cross-domain-policies: none
< x-robots-tag: noindex, nofollow
< x-xss-protection: 1; mode=block
< x-served-by: nextcloud.server.de
< 
* Connection #0 to host nextcloud.server.de left intact
{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"27.1.1.0","versionstring":"27.1.1","edition":"","productname":"Nextcloud","extendedSupport":false}

So it seems as if my homeserver can resolve the DNS to the respective IP address, but then runs into an error.
Container/homeserver curls office.server.de, resolves the DNS name to the appropriate IP adress, links to the ip adress of my vps which should forward this request to the homeserver/container. And then back. But somewhere in this line is the culprit as far as I understand.

tough stuff… I have no idea how to spot the issue easily. maybe checking tcpdump of the systems one by one gives you an idea e.g. if the traffic leaves you network and comes back. luckily you can easily test with curl so you only need to analyze short network traces.

I made a drawing to better understand the architecture - let me know if this is not right.

according to you all the way from client to both services work.
but the two connections from Nextcloud and Collabora are broken. As we know DNS is right the problem must be routing or firewall. You can check the routing into the internet if you do curl www.google.com or any other external resource - if this works you know routing and firewall from your local system to the internet works. if internet access works the most promising failure spot is the VPS - here the request coming from internal #wireguard tunnel/interface must leave towards the internet and the come back and flow all the way back to the systems… this might be an issue where the logic could fail in many places - the system might fail connecting to itself or route the traffic from wireguard → internet → internet → wireguard.

PS: I have long lived plans to check if docker internal dnsalias works to shortcut the traffic one the reverse proxy. once I have time to test I will update. This is definitely the most effective and performant solution for such setups.

1 Like

finally I found time and motivation to test Docker network alias feature to avoid network traffic through the internet for communication between Nextcloud and Collabora.

Following instructions describe how to avoid the internet loop and route the traffic straight between Collabora ↔ Reverse Proxy ↔ Nextcloud which should improve your overall experience by removing all the delays from VPN tunnel and additional processing on the VPS :metal:

Having a docker network proxy where all 3 containers are connected to (it is used to publish applications) I added following directive to the compose of reverse proxy container:

    networks:
      proxy:
        aliases:
          - collabora.mydomain.tld
          - cloud.mydomain.tld

which resulted in curl -v https://collabora.mydomain.tld and curl -v https://cloud.mydomain.tld showing the IP address of the reverse proxy… but document edit failed :frowning:

logs on collabora-online

wsd-00001-00045 2023-12-26 20:40:39.740787 +0100 [ docbroker_003 ] ERR  loading document exception: Access denied, 403. WOPI::CheckFileInfo failed on: https://cloud.mydomain.tld//index.php/apps/richdocuments/wopi/files/6106_oc52dthqts8g?access_token=k7zUSGSwky22tcbLigVybQAZcw7vfGX3&access_token_ttl=0&permission=edit| wsd/DocumentBroker.cpp:2631

and cloud

fd00:feed:beef:1::2 - - [26/Dec/2023:19:40:39 +0000] "GET //index.php/apps/richdocuments/wopi/files/6106_oc52dthqts8g?access_token=k7zUSGSwky22tcbLigVybQAZcw7vfGX3&access_token_ttl=0&permission=edit HTTP/1.1" 403 2139 "-" "COOLWSD HTTP Agent 23.05.5.4"

showed the issue fast: CODE was blocked by “allow list for WOPI requests” on NC side - which was not aware of IPv6 addresses I enabled IPv6

Docker IPv6 enabled /etc/docker/daemon.json

(majority of docker installations will run using IPv4-only - which is default - and only require the 172.16.0.0/12 network)

{
    "userland-proxy": false,
    "ipv6": true,
    "fixed-cidr-v6": "fd00:beef:beef::/48",
    "experimental": true,
    "ip6tables": true
}

adding the respective config

image

made it work like a charm :fireworks:


Update: link a detailed write-up from CODE perspective:

wopi_allowlist

4 Likes

Dear @wwe

thank you for this great idea also as an inspiration for my issues with WOPI access lists with Collabora in another thread.

Trying to add the alias as you stated to in my case at the end of the compose file / Portainer stack file of Nginx proxy manager leads to the following error

failed to deploy a stack: validating /data/compose/38/docker-compose.yml: networks.nc-stage Additional property aliases is not allowed

It may be a result of the wrong place for the alias insert. Can you please supply a few more lines of the compose file, where to add the alias?

Thank You

Pascal

The error definitely looks like malformed yaml file. the aliases array must reside below the network node of the reverse proxy service (in my case network is named “proxy”) - take a look at the Docker docs I provided for more details.

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.