diff --git a/README.md b/README.md index d6139a5a..54dd31ac 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ This is just a summary for the impatient. See the full [documentation](https://matrix-construct.github.io/tuwunel/). > [!TIP] -> Avoid using a sub-domain for your `server_name`. You can always delegate later with a [`.well-known`](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md) +> Avoid using a sub-domain for your `server_name`. You can always delegate later with a [`.well-known`](https://matrix-construct.github.io/tuwunel/deploying/root-domain-delegation.html) > file, but you can never change your `server_name`. **2.** Setup TLS certificates. Most users enjoy the [Caddy](https://caddyserver.com/) reverse-proxy diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 1093e03c..c859ce1c 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -8,6 +8,7 @@ - [Reverse Proxy - Caddy](deploying/reverse-proxy-caddy.md) - [Reverse Proxy - Nginx](deploying/reverse-proxy-nginx.md) - [Reverse Proxy - Traefik](deploying/reverse-proxy-traefik.md) + - [Example: root domain delegation](deploying/root-domain-delegation.md) - [NixOS](deploying/nixos.md) - [Docker](deploying/docker.md) - [Kubernetes](deploying/kubernetes.md) @@ -15,6 +16,7 @@ - [Debian](deploying/debian.md) - [Red Hat](deploying/redhat.md) - [FreeBSD](deploying/freebsd.md) + - [Podman systemd](deploying/podman-systemd.md) - [TURN](turn.md) - [Matrix RTC (Element Call)](matrix_rtc.md) - [Appservices](appservices.md) diff --git a/docs/configuration.md b/docs/configuration.md index 4e82f5ca..894650d4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -35,7 +35,7 @@ string. This does not apply to options that take booleans or numbers: - `-O max_request_size=99999999` works ✅ - `-O server_name=example.com` does not work ❌ - `--option log=\"debug\"` works ✅ -- `--option server_name='"example.com'"` works ✅ +- `--option server_name='"example.com"'` works ✅ ## Relevance of configuration settings diff --git a/docs/deploying/generic.md b/docs/deploying/generic.md index c724b9fc..d2c56ce1 100644 --- a/docs/deploying/generic.md +++ b/docs/deploying/generic.md @@ -73,7 +73,7 @@ Matrix's default federation port is port 8448, and clients must be using port 44 If you would like to use only port 443, or a different port, you will need to setup delegation. Tuwunel has config options for doing delegation, or you can configure your reverse proxy to manually serve the necessary JSON files to do delegation -(see the `[global.well_known]` config section). +(see the `[global.well_known]` config section and the [delegation example](root-domain-delegation.md)). If Tuwunel runs behind a router or in a container and has a different public IP address than the host system these public ports need to be forwarded directly @@ -158,7 +158,7 @@ Regardless of which reverse proxy you choose, you will need to: - `/_tuwunel/` - ad-hoc Tuwunel routes such as `/local_user_count` and `/server_version` 2. **Optionally reverse proxy (recommended):** - - `/.well-known/matrix/client` and `/.well-known/matrix/server` if using Tuwunel to perform delegation (see the `[global.well_known]` config section) + - `/.well-known/matrix/client` and `/.well-known/matrix/server` if using Tuwunel to perform delegation (see the `[global.well_known]` config section and the [delegation example](root-domain-delegation.md)) - `/.well-known/matrix/support` if using Tuwunel to send the homeserver admin contact and support page (formerly known as MSC1929) - `/` if you would like to see `hewwo from tuwunel woof!` at the root diff --git a/docs/deploying/reverse-proxy-nginx.md b/docs/deploying/reverse-proxy-nginx.md index 53008e2b..83be9958 100644 --- a/docs/deploying/reverse-proxy-nginx.md +++ b/docs/deploying/reverse-proxy-nginx.md @@ -24,6 +24,10 @@ sudo pacman -S nginx Create a new configuration file at `/etc/nginx/sites-available/tuwunel` (or `/etc/nginx/conf.d/tuwunel.conf` on some distributions): ```nginx +upstream tuwunel { + 127.0.0.1:8008; # IP and port where tuwunel is listening +} + # Client-Server API over HTTPS (port 443) server { listen 443 ssl http2; @@ -34,9 +38,9 @@ server { # Increase this to match the max_request_size in your tuwunel.toml client_max_body_size 100M; - # Forward requests to Tuwunel (listening on 127.0.0.1:8008) + # Forward requests to Tuwunel location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; # Preserve host and scheme - critical for proper Matrix operation proxy_set_header Host $host; @@ -62,7 +66,7 @@ server { # Forward to the same local port as client-server API location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; @@ -103,7 +107,7 @@ However, if you experience federation retries or dropped long-poll connections, ```nginx location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; diff --git a/docs/deploying/root-domain-delegation.md b/docs/deploying/root-domain-delegation.md new file mode 100644 index 00000000..b2f60104 --- /dev/null +++ b/docs/deploying/root-domain-delegation.md @@ -0,0 +1,141 @@ +# Example: using the root domain as the homeserver name + +[<= Back to Generic Deployment Guide](generic.md#quick-overview) + +It is possible to host tuwunel on a subdomain such as `matrix.example.com` but delegate from `example.com` as the server name. This means that usernames will be `@user:example.com` rather than `@user:matrix.example.com`. + +Federating servers and clients accessing tuwunel at `example.com` will attempt to discover the subdomain by accessing the `example.com/.well-known/matrix/client` and `example.com/.well-known/matrix/server` endpoints. These need to be set up to point back to `matrix.example.com`. + +> [!NOTE] +> In all of the following examples, replace `matrix.example.com` with the subdomain where tuwunel is hosted, `` with the external port for federation, and `example.com` with the domain you want to use as the public-facing homeserver. + +## Configuration + +Make sure the following are set in your [configuration file](<../configuration/examples.md#:~:text=### Tuwunel Configuration>) or via [environment variables](../configuration.md#environment-variables): + +1. [Server name](<../configuration/examples.md#:~:text=# The server_name,#server_name>): set `TUWUNEL_SERVER_NAME=example.com` or in the configuration file: + ```toml,hidelines=~ + [global] + ~ + ~# The server_name is the pretty name of this server. It is used as a + ~# suffix for user and room IDs/aliases. + ~# + ~# See the docs for reverse proxying and delegation: + ~# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy + ~# + ~# Also see the `[global.well_known]` config section at the very bottom. + ~# + ~# Examples of delegation: + ~# - https://matrix.org/.well-known/matrix/server + ~# - https://matrix.org/.well-known/matrix/client + ~# + ~# YOU NEED TO EDIT THIS. THIS CANNOT BE CHANGED AFTER WITHOUT A DATABASE + ~# WIPE. + ~# + ~# example: "girlboss.ceo" + ~# + server_name = example.com + ``` +2. [Client-server URL](../configuration/examples.md#:~:text=#[global.well_known],#client): set `TUWUNEL_WELL_KNOWN__CLIENT=https://matrix.example.com` or in the configuration file: + ```toml,hidelines=~ + [global.well_known] + ~ + ~# The server URL that the client well-known file will serve. This should + ~# not contain a port, and should just be a valid HTTPS URL. + ~# + ~# example: "https://matrix.example.com" + ~# + client = https://matrix.example.com + ``` +3. [Server-server federation domain and port](<../configuration/examples.md#:~:text=# The server base domain,#server>): where `` is the external port for federation (default 8448, but often 443 when reverse proxying), set `TUWUNEL_WELL_KNOWN__SERVER=matrix.example.com:` or in the configuration file: + ```toml,hidelines=~ + [global.well_known] + ~ + ~# The server URL that the client well-known file will serve. This should + ~# not contain a port, and should just be a valid HTTPS URL. + ~# + ~# example: "https://matrix.example.com" + ~# + ~client = https://matrix.example.com + ~ + ~# The server base domain of the URL with a specific port that the server + ~# well-known file will serve. This should contain a port at the end, and + ~# should not be a URL. + ~# + ~# example: "matrix.example.com:443" + ~# + server = matrix.example.com: # e.g. matrix.example.com:443 + ``` + +## Serving `.well-known` endpoints + +With the above configuration, tuwunel will generate and serve the appropriate `/.well-known/matrix` entries for delegation, so these can be served by reverse proxying `/.well-known/matrix` on `example.com` to tuwunel. Alternatively, if `example.com` is not behind a reverse proxy, static JSON files can be served directly. + +### Option 1: Static JSON files + +At a minimum, the following JSON files should be created: + +1. At `example.com/.well-known/matrix/client`: + ```json + { + "m.homeserver": { + "base_url": "https://matrix.example.com/" + } + } + ``` +2. At `example.com/.well-known/matrix/server` (substituting `` as above): + ```json + { + "m.server": "matrix.example.com:" // e.g. "matrix.example.com:443" + } + ``` + +### Option 2: Reverse proxy + +These are example configurations if `example.com` is reverse-proxied behing Nginx or Caddy. + +> [!NOTE] +> Replace `tuwunel` with the URL where tuwunel is listening; this may look like `127.0.0.1:8008`, `matrix.example.com`, or `tuwunel` if you declared an `upstream tuwunel` block. + +> [!IMPORTANT] +> These configurations need to be applied to the reverse proxy for `example.com`, **not** `matrix.example.com`. + +#### Caddy + + + +```caddy +example.com { + reverse_proxy /.well-known/matrix/* https://matrix.example.com { + header_up Host {upstream_hostport} + } +} +``` + +#### Nginx + +```nginx,hidelines=~ +server { + ~listen 443 ssl http2; + ~listen [::]:443 ssl http2; + server_name example.com; + + location /.well-known/matrix { + proxy_pass http://tuwunel/.well-known/matrix; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_ssl_server_name on; + } + ~ + ~# The remainder of your nginx configuration for example.com including SSL termination, other locations, etc. +} +``` + +## Testing + +Navigate to `example.com/.well-known/matrix/client` and `example.com/.well-known/matrix/server`. These should display results similar to the [JSON snippets above](#option-1-static-json-files). + +Entering `example.com` in the [Matrix federation tester](https://federationtester.matrix.org/) should also work. + +## Additional resources + +For a more complete guide, see the Matrix setup with Ansible and Docker [documentation on setting up `.well-known`](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md).