Redirection loop in a 2 server setup.

I have a VPS with mydomain.com pointed to it with traefik, netbird, and keycloak running in podman containers.

The VPS and a second server at home are connected to the VPN using Netbird’s cli client applications. Netbird allows forwarding of ports 80 and 443 from the VPS to the home server.

Traefik is handling all TLS and is configured to forward all requests to home.mydomain.com and *.home.mydomain.com to the home server’s Netbird IP.

On the home server, nginx proxy manager is handling all requests to home.mydomain.com and *.home.mydomain.com and routing them to the appropriate containerised services. I already have 2 services served from the home server this way, including bookstack successfully integrated with keycloak.

I’ve been trying to serve oCIS at files.home.mydomain.com unsuccessfully for about close to a month now. In the web browser’s network monitor I get status 308 and 20 requests in total before it fails.

If I change the nginx proxy manager entry for files.home.mydomain.com from http://ocis:9200 to another container like https://filestash:8334, that service becomes accessible without issue.

oCIS compose file

services:
ocis:
image: owncloud/ocis:latest
container_name: ocis
hostname: ocis
networks:
- frontend
entrypoint:
- /bin/sh
# run ocis init to initialize a configuration file with random secrets
# it will fail on subsequent runs, because the config file already exists
# therefore we ignore the error and then start the ocis server
command: [“-c”, “ocis init || true; ocis server”]
environment:
# Keycloak IDP specific configuration
PROXY_AUTOPROVISION_ACCOUNTS: “true”
PROXY_ROLE_ASSIGNMENT_DRIVER: “oidc”
OCIS_OIDC_ISSUER: https://auth.mydomain.com/realms/home
PROXY_OIDC_REWRITE_WELLKNOWN: “true”
WEB_OIDC_CLIENT_ID: ocis-client
# general config
OCIS_URL: https://files.home.mydomain.com
OCIS_LOG_LEVEL: “info”
OCIS_LOG_COLOR: “false”
PROXY_TLS: “false” # do not use SSL between Traefik and oCIS
PROXY_USER_OIDC_CLAIM: “preferred_username”
PROXY_USER_CS3_CLAIM: “username”
# INSECURE: needed if oCIS / Traefik is using self generated certificates
OCIS_INSECURE: “true”
OCIS_ADMIN_USER_ID: “”
OCIS_EXCLUDE_RUN_SERVICES: “idp”
GRAPH_ASSIGN_DEFAULT_USER_ROLE: “false”
GRAPH_USERNAME_MATCH: “none”
# password policies
OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST: “banned-password-list.txt”
PROXY_CSP_CONFIG_FILE_LOCATION: /etc/ocis/csp.yaml
KEYCLOAK_DOMAIN: auth.mydomain.com
# CORS
OCIS_CORS_ALLOW_ORIGINS: “"
OCIS_CORS_ALLOW_METHODS: “GET,POST,PUT,PATCH,DELETE,OPTIONS”
OCIS_CORS_ALLOW_HEADERS: "

volumes:
- ./config/banned-password-list.txt:/etc/ocis/banned-password-list.txt
- ./config/csp.yaml:/etc/ocis/csp.yaml
- ocis-config:/etc/ocis
- ocis-data:/var/lib/ocis
restart: always

volumes:
ocis-config:
external: true
ocis-data:
external: true

networks:
frontend:
external: true

Relevant part from traefik compose.yml on the VPS
  traefik.http.routers.home.entrypoints: websecure
  traefik.http.routers.home.rule: Host(`home.mydomain.com`) || HostRegexp(`^.+\.home\.mydomain\.com`)
  traefik.http.routers.home.tls: true
  traefik.http.routers.home.tls.certresolver: cloudflare
  traefik.http.routers.home.tls.domains[0].main: "home.mydomain.com"
  traefik.http.routers.home.tls.domains[0].sans: "*.home.mydomain.com"
  traefik.http.routers.home.priority: 999
  traefik.http.routers.home.service: home@file
Web browser network monitor

GET
scheme https
host files.home.mydomain.com
filename /
Address redacted
Status 308
Version HTTP/2
Transferred269 B (0 B size)
Referrer Policystrict-origin-when-cross-origin
Request PriorityHighest
DNS Resolution System

Response Headers
HTTP/2 308
content-type: text/html; charset=utf-8
date: Mon, 30 Dec 2024 09:42:57 GMT
location: https://files.gfc.badhippo.xyz/
server: openresty
x-request-id: ocis/bb1EOBEFde-000082
x-served-by: files.home.mydomain.com
content-length: 67
X-Firefox-Spdy: h2

Request Headers
GET / HTTP/2
Host: files.home.mydmain.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i
TE: trailers

curl -i output

HTTP/2 308
content-type: text/html; charset=utf-8
date: Mon, 30 Dec 2024 16:43:47 GMT
location: https://files.home.mydomain.com/
server: openresty
x-request-id: ocis/bb1EOBEFde-000086
x-served-by: files.home.mydomain.com

curl -v output
  • CONNECT phase completed

  • CONNECT tunnel established, response 200

  • ALPN: curl offers h2,http/1.1

  • TLSv1.3 (OUT), TLS handshake, Client hello (1):

  • CAfile: /etc/pki/tls/certs/ca-bundle.crt

  • CApath: none

  • 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_128_GCM_SHA256 / x25519 / id-ecPublicKey

  • ALPN: server accepted h2

  • Server certificate:

  • subject: CN=home.mydomain.com

  • start date: Dec 17 15:30:25 2024 GMT

  • expire date: Mar 17 15:30:24 2025 GMT

  • subjectAltName: host “files.home.mydomain.com” matched cert’s “*.home.mydomain.com”

  • issuer: C=US; O=Let’s Encrypt; CN=E5

  • SSL certificate verify ok.

  • Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384

  • Certificate level 1: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using sha256WithRSAEncryption

  • Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption

  • TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):

  • using HTTP/2

  • [HTTP/2] [1] OPENED stream for https://files.home.mydomain.com/

  • [HTTP/2] [1] [:method: GET]

  • [HTTP/2] [1] [:scheme: https]

  • [HTTP/2] [1] [:authority: files.home.mydomain.com]

  • [HTTP/2] [1] [:path: /]

  • [HTTP/2] [1] [user-agent: curl/8.9.1]

  • [HTTP/2] [1] [accept: /]
    GET / HTTP/2
    Host: files.home.mydomain.com
    User-Agent: curl/8.9.1
    Accept: /

  • Request completely sent off
    < HTTP/2 308
    < content-type: text/html; charset=utf-8
    < date: Mon, 30 Dec 2024 16:39:20 GMT
    < location: https://files.home.mydomain.com/
    < server: openresty
    < x-request-id: ocis/bb1EOBEFde-000083
    < x-served-by: files.home.mydomain.com
    < content-length: 67
    Permanent Redirect.

I’ve been over the documentation and a forum posts over and over without any success. The only thing I have not successfully tried yet is adding headers to traefik. That’s because it’s my first time using it and I still haven’t wrapped my head around how I should actually do that and every one of my attempts resulted in a non-working config. I don’t even know if that would solve anything.