synapse icon indicating copy to clipboard operation
synapse copied to clipboard

Multi-domain support

Open williamkray opened this issue 3 years ago • 11 comments

Description: As a mail server can be configured to be the MTA for multiple email domains, so should Synapse be able to support being the homeserver for multiple domains.

I currently run two synapse servers on two separate domains in docker containers, but on the same host (using separate docker container stacks). This leads to excessive configuration regarding additional networking, database storage with duplicate datasets, and federation across two synapse servers sitting directly next to each other. Ideally, synapse should be aware that the server handles homeserver duties for multiple domains, and skip excessive federation or data storage for things that would otherwise be federated across the network.

Additionally, it would be nice to have the ability (like in mail servers) to have "alias" functionality for vanity user accounts or domains (e.g. a publicly published matrix ID of @mycoolusername:myworkdomain.net would actually just send messages to and from the @user:personaldomain.com matrix ID).

williamkray avatar Dec 05 '20 19:12 williamkray

This will be inherently supported when portable identities (initially MSC1228 and now its successor MSC2787) is implemented. Portable identities will allow users to show up to any old homeserver with their MXID and UPK, and that homeserver will then send messages on their behalf.

In this world where MXIDs will map to user keys, I imagine aliases will be much easier to implement.

anoadragon453 avatar Dec 07 '20 10:12 anoadragon453

It's good to know this is in progress. Another use case that require this multi-domain feature, a slightly different than the Alias approach. Not sure if the "portable identities" can achieve this as well:

Say i am hosting a matrix instance for myself, using myName.com, and I have one (or few) MXID for my own uses, work or personal. It works great so right now I want to bring my friend onboard. It's definitely possible to ask them to register through matrix.org or other homeservers, but I would like to offer them opportunity to use my homeserver. However it looks weird if I give them @their_name:myname.com ID (use my server's domain). So I would like to add an additional domain name (eg. whatNet.com) so I can assign different domain to my friend on one single instances. I believe XMPP can do it, one instances that hosts multiple domains.

Of course, i can run two different instances, for two different domain, but then it back to William's issue,

"excessive configuration regarding additional networking, database storage with duplicate datasets, and federation across two synapse servers sitting directly next to each other."

Zenuncl avatar Feb 08 '21 19:02 Zenuncl

@SharkIng I believe your use-case is the intended use-case for this feature, aliases were just an additional bonus.

Portable identities do not actually completely solve this issue inherently (AFAIK) as it is currently written, because it sounds like creating an MXID would still require operating a homeserver on that domain. But I added a suggestion that would enable this behavior at https://github.com/matrix-org/matrix-doc/pull/2787#discussion_r563031023

jonaharagon avatar Feb 09 '21 15:02 jonaharagon

Is this the best issue to follow for this?

This would be awesome to have. I'm in the same boat running things in docker with the exception that I want to run two, but would love to do it with a minimum of fuss.

Thank you for all of your hard work on this!

chernesk avatar May 04 '21 19:05 chernesk

I've been using Synapse for several years now via docker and I wanted to add my two cents. Recently, I too found myself wanting to expand usage into completely different projects. This feature is a must to be able to do so. Otherwise as others have stated, the added complexity of maintaining multiple instances (even with tools like Ansible and the like) make this a no go currently.

Also, big thanks to all the folks who work on this project. I moved away from Whatsapp (Facebook) a few years ago and enjoy the fact that I own my data, not some corporate entity. Cheers!

june07 avatar Dec 06 '21 17:12 june07

Adding some keywords: multi-tenant multi-tenancy

clokep avatar Dec 20 '21 15:12 clokep

How is it going? Is the multi-tenant support there? My use case is that I want synapse to use different databases inside a same DB-server.

dulguun0225 avatar May 02 '22 08:05 dulguun0225

I've been using Synapse for several years now via docker and I wanted to add my two cents. Recently, I too found myself wanting to expand usage into completely different projects. This feature is a must to be able to do so. Otherwise as others have stated, the added complexity of maintaining multiple instances (even with tools like Ansible and the like) make this a no go currently.

I'm in the same boat - we run several projects, and their public rooms (at least) should be in their respective domains. I cannot just choose one and let other projects borrow its name. I could come up with yet another domain independent of all of them just to run Matrix, but that sounds stupid, and also is not great for PR... An alternative by running several instances requires significantly more resources and also increases maintenance costs.

marmarek avatar May 04 '22 12:05 marmarek

@marmarek if all you want is room aliases on a domain you can use https://github.com/tulir/mauliasproxy

aaronraimist avatar May 04 '22 17:05 aaronraimist

Please implement this feature! I am currently forced to run two homeserver instances on the same metal just for the sake of separating business chat ([email protected]) from family chat ([email protected]). It would be really great if I could simply host both MXIDs ([email protected] and [email protected]) on the same technical instance as it halfs the metal and effort needed! Thanks! 👍

mkarg avatar Jun 12 '22 12:06 mkarg

thumbs up on this one

devvythelopper avatar Aug 10 '22 18:08 devvythelopper

Adding keywords: vhost virtual host hosts

Mikaela avatar Nov 24 '22 14:11 Mikaela

Are there any updates on this? I’d also like to share one install for more than one domain…

gymnae avatar May 01 '23 21:05 gymnae

As seemingly portable identities aren't happening anytime soon, could we please just solve it using a workaround as trivial as possible?

  • https://indieweb.org/architecture_astronomy

We would badly need to enable by default people to register to free shared Synapse instances with their own domain or subdomain. It's way better spam protection than requiring an email address and as a bonus, could also provide for a transition path for the user if the HS dies. Even if all account data is otherwise lost, the user could get to keep their established name.

bkil avatar May 09 '23 12:05 bkil

I hacked together a solution for me with using caddy v2 as reverse proxy. My scenario:

  1. Nextcloud works as an auth provider for matrix/synapse
  2. My Nextcloud install is reachable by domain1.tld, domain2.tld and domain3.tld
  3. My matrix install is reachable by domain4.tld
  4. All are running in rootless docker containers on the same host
  5. Caddy rewrites headers (namely adapting Location and Set-cookies) from nextcloud to matrix and the vice-versa, so that they don't see the domain change and are always happy thinking there is no CORS happening. Which it is.

As a result, I can log in to element.web from within an iframe (!) inside nextcloud, no matter which domain I'm using for nextcloud, without changing homeserver.yaml. I'm also using just one auth client ID for all domains.

This is the relevant code block for reverse proxying matrix & synapse:

matrix.domain1.tld, matrix.domain2.tld {
        encode zstd
        respond /.well-known/matrix/server `{"m.server": "{host}:443"}`
        respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"{host}"}}`

        header {
                Access-Control-Allow-Origin "{header.origin}"
                /.well-known/matrix/* Content-Type application/json
        }

        map {query.redirectUrl} {redirurl} {
                ~^https?://(?:[a-z0-9.-]+\.)?([a-z0-9-]+\.[a-z]{2,})(?:$|/.*)$ "https://matrix.${1}/_synapse/client/pick_idp?idp=oidc-nextlcoud1&redirectUrl=https%3A/cloud.${1}/apps/riotchat/riot/%23/login"
        }

        reverse_proxy /_matrix/* matrix-synapse-1:8008 {
                header_down Access-Control-Expose-Headers "set-cookie, Synapse-Trace-Id"
                header_down Content-Security-Policy "^frame-ancestors 'none';$" "frame-ancestors 'self' {host} https://domain1.tld https://domain2.tld https://cloud.domain2.tld http://cloud.domain1.tld; frame-src 'self' https://cloud.domain2.tld https://cloud.domain1.tld;"
                header_down -Access-Control-Allow-Origin
                header_down Set-Cookie "(^|;\s*)(oidc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain={host}; "
                header_down Set-Cookie "(^|;\s*)(oc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain=.{labels.1}.{labels.0}; "
                header_up Set-Cookie "(^|;\s*)(oidc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain=.{labels.1}.{labels.0};         "
                header_up Set-Cookie "(^|;\s*)(oc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain=.{labels.1}.{labels.0}; "
         }
        reverse_proxy /_synapse/client/* matrix-synapse-1:8008 {
                header_down Access-Control-Expose-Headers "set-cookie, Synapse-Trace-Id"
                header_down Content-Security-Policy "^frame-ancestors 'none';$" "frame-ancestors 'self' {host} https://domain2.tld https://domain1.tld https://cloud.domain2.tld http://cloud.domain1.tld; frame-src 'self' https://cloud.domain2.tld https://cloud.domain1.tld;"
                header_down -Access-Control-Allow-Origin
                header_down Set-Cookie "(^|;\s*)(oidc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain={labels.1}.{labels.0}; "
                header_down Set-Cookie "(^|;\s*)(oc[^=]*=)([^;]*)($|;\s*)" "$2$3; domain={labels.1}.{labels.0}; "
                header_down Location "(?i)\b(?:\.[a-z0-9]+)*\.[a-z]{2,}\b" ".{labels.1}.{labels.0}"
        }
        redir /_matrix/client/r0/login/sso/* {redirurl}
}

This approach may be adaptable to keep synapse and its singular public_baseurl but make it reachable by many domains. The MXID server part would still be same for all, based on the servername.

Note: Playing with the cookie domains and CSP is not a great thing to do, but I hoped I did not create an open window for malpractice

gymnae avatar May 09 '23 15:05 gymnae