Multiple domains for one host?

  • Used Zammad version: 6.5.0
  • Used Zammad installation type: package
  • Operating system: Ubuntu 24.04

Expected behavior:

  • I configured nginx for multiple domains and obtained corresponding SSL certificate
  • Also configure OIDC authentication:
    • OIDC (Keycloak) IdP client supports different redirect URLs corresponding to configured domains
  • I can reach the Zammad installation via pre-configured domains
  • I can login whatever pre-configured domain I access

Actual behavior:

  • Unfortunately authentication fails on all domains except one with “openid_connect: csrf_detected”
  • The only one which works corresponds to settings.fqdn

Probably because of “fixed” callback URL in Zammad as #settings.fqdn/auth/openid_connect/callback

There was a number of topics open on how to configure multiple domains in Zammad, e.g.:

  • What is the status on that?
  • Can be FQDN taken from the nginx $host somehow?
  • Is there any “work-around” or any good solution to have OIDC authentication for multiple domains?

It has been said several times:
Zammad does not support more than one FQDN. While it may work at some parts, it is not supported in any way. You should not do it, decide for one FQDN.

You can try do this with a reverse proxy (like NGINX or Apache).

Zammad itself only allows one ZAMMAD_WEBSOCKET_ORIGIN, which breaks multi-domain WebSocket support out of the box.
But you can handle both domains at the proxy layer, including HTTP and HTTPS redirection.

Here’s an NGINX example that does everything:

# Redirect all HTTP to HTTPS
server {
    listen 80;
    server_name zammad.example.com support.example.org;
    return 301 https://$host$request_uri;
}

# HTTPS for zammad.example.com
server {
    listen 443 ssl;
    server_name zammad.example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /ws {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header Origin "https://zammad.example.com";
    }
}

# HTTPS for support.example.org
server {
    listen 443 ssl;
    server_name support.example.org;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /ws {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header Origin "https://zammad.example.com";
    }
}

How does this work?
• All HTTP traffic redirects to HTTPS.
• Both domains serve HTTPS and proxy to the same Zammad backend.
• For WebSockets, the Origin header is rewritten to the single allowed domain (https://zammad.example.com).

Issues:
• This weakens origin security. It allows multiple public domains to bypass the Origin check.
• It’s a trade-off between multi-domain support and strict security.

I’m not sure if this would work at all. Either way, the only way it could work is with a reverse proxy in front of Zammad.

Your Browser (F12) might complain about CROSS-ORIGIN issues. Good luck fixing that - although possible, this would be a different nut to crack.

1 Like

Thank you for your suggestion! It got me one more step further, but now I am getting:
“openid_connect: ActionController::InvalidAuthenticityToken”

Anything in the “openid_connect” I can manually configure?

Your error comes from CSRF protection failing during OIDC login. Zammad strictly enforces that all login, redirect, and cookies match the single fqdn you configured.

If users hit the app at Domain B, but OIDC redirects to Domain A, the CSRF token check will fail.

There is no separate openid_connect setting in Zammad to “allow” multiple domains for login. You need to enforce a single canonical domain for all access.

Solution (a different NGINX reverse proxy config):

Force all alternate domains to redirect to your canonical FQDN (e.g. zammad.example.com).

# Redirect all HTTP to HTTPS
server {
  listen 80;
  server_name zammad.example.com support.example.org;
  return 301 https://zammad.example.com$request_uri;
}

# Force support.example.org HTTPS to main domain
server {
  listen 443 ssl;
  server_name support.example.org;
  ssl_certificate      /path/fullchain.pem;
  ssl_certificate_key  /path/privkey.pem;

  return 301 https://zammad.example.com$request_uri;
}

# Serve Zammad on the canonical domain
server {
  listen 443 ssl;
  server_name zammad.example.com;
  ssl_certificate      /path/fullchain.pem;
  ssl_certificate_key  /path/privkey.pem;

  location / {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  location /ws {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header Origin "https://zammad.example.com";
  }
}

Result:

  • All access is redirected to one domain.
  • CSRF tokens and OIDC login will work reliably.
  • Users can still enter via any domain, but will always land on the FQDN you configured in Zammad.

I don’t know if that’s really what you want, because with this setup users will always see your main FQDN (for example, they’ll be redirected from Domain B to Domain A and see Domain A in the browser).

But honestly, that’s the only way to make OIDC and CSRF protection work correctly in a single Zammad instance. Zammad simply doesn’t support multiple domains for login natively.

If you really need users to stay on different domains without redirect, you’d have to run and maintain separate Zammad instances, each with its own FQDN and config, as @MrGeneration already pointed out.