diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a34ac713..98283d233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +# 2026-02-21 + +## (BC Break) coturn is no longer auto-enabled by default + +By default, the [coturn](./docs/configuring-playbook-turn.md) TURN server component is no longer enabled for every deployment. + +This reduces resources and attach surface for deployments which: + +- either don't need calls at all +- or use the modern [Matrix RTC](docs/configuring-playbook-matrix-rtc.md)/[Element Call](docs/configuring-playbook-element-call.md) stack. + +Coturn is still auto-enabled when [Jitsi](./docs/configuring-playbook-jitsi.md) is enabled (`jitsi_enabled: true`), because Jitsi still depends on TURN for legacy Matrix integration. + +Additionally, Coturn (when enabled) now defaults to using automatic IP detection of your server's external IP address, instead of assuming your Ansible inventory (`ansible_host`) points to a public address and using it for configuring `coturn_turn_external_ip_address`. + +To restore the old behavior (needed for legacy call setups), add the following configuration to your `vars.yml`: + +```yml +coturn_enabled: true + +# If you'd like explicit control over the external IP address (like before), keep this too. +coturn_turn_external_ip_address: "{{ ansible_host }}" +``` + +## LiveKit TURN TLS is now automatically fronted by playbook-managed Traefik + +For deployments that use the playbook-managed Traefik reverse-proxy, LiveKit TURN over TCP is now SSL-terminated at Traefik and passed as plain TCP to LiveKit (`turn.external_tls = true`) by default. + +To disable this behavior, set `livekit_server_config_turn_external_tls: false` and the playbook will revert to the old behavior - using traefik-certs-dumper to extract SSL certificates out of Traefik and pass them to LiveKit for explicit SSL termination there. + +If you are using `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), this change does **not** switch behavior automatically. That mode remains using certificate files in the container (Traefik certificates dumper flow) unless you explicitly set the TURN-Traefik mode variables to opt in. + # 2026-02-17 ## (BC Break) prometheus-nginxlog-exporter role has been relocated and variable names need adjustments diff --git a/README.md b/README.md index 7fb937636..7beadd224 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Services that run on the server to make the various parts of your installation w | Name | Default? | Description | Documentation | | ---- | -------- | ----------- | ------------- | | [PostgreSQL](https://www.postgresql.org/)| ✅ | Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible. | [Link](docs/configuring-playbook-external-postgres.md) | -| [coturn](https://github.com/coturn/coturn) | ✅ | STUN/TURN server for WebRTC audio/video calls | [Link](docs/configuring-playbook-turn.md) | +| [coturn](https://github.com/coturn/coturn) | ❌ | STUN/TURN server for WebRTC audio/video calls | [Link](docs/configuring-playbook-turn.md) | | [Traefik](https://doc.traefik.io/traefik/) | ✅ | Web server, listening on ports 80, 443 and 8448 - standing in front of all the other services. [Using your own webserver](docs/configuring-playbook-own-webserver.md) is also possible. | [Link](docs/configuring-playbook-traefik.md) | | [Let's Encrypt](https://letsencrypt.org/) | ✅ | Free SSL certificate, which secures the connection to all components | [Link](docs/configuring-playbook-ssl-certificates.md) | | [Exim](https://www.exim.org/) | ✅ | Mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) | [Link](docs/configuring-playbook-email.md) | diff --git a/docs/configuring-playbook-jitsi.md b/docs/configuring-playbook-jitsi.md index 6c035dee4..ea9d7cd02 100644 --- a/docs/configuring-playbook-jitsi.md +++ b/docs/configuring-playbook-jitsi.md @@ -18,6 +18,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later The playbook can install and configure the [Jitsi](https://jitsi.org/) video-conferencing platform for you. +Because Jitsi still requires a TURN server, enabling Jitsi +automatically enables coturn (`coturn_enabled: true`) unless you explicitly disable it. + Jitsi is an open source video-conferencing platform. It can not only be integrated with Element clients ([Element Web](configuring-playbook-client-element-web.md)/Desktop, Android and iOS) as a widget, but also be used as standalone web app. 💡 If you're into experimental technology, you may also be interested in trying out [Element Call](configuring-playbook-element-call.md) - a native Matrix video conferencing application. diff --git a/docs/configuring-playbook-livekit-server.md b/docs/configuring-playbook-livekit-server.md index 3579feb56..574e93f28 100644 --- a/docs/configuring-playbook-livekit-server.md +++ b/docs/configuring-playbook-livekit-server.md @@ -31,8 +31,39 @@ To ensure LiveKit Server functions correctly, the following firewall rules and p 💡 The suggestions above are inspired by the upstream [Ports and Firewall](https://docs.livekit.io/home/self-hosting/ports-firewall/) documentation based on how LiveKit is configured in the playbook. If you've using custom configuration for the LiveKit Server role, you may need to adjust the firewall rules accordingly. +## TURN TLS handling + +When `matrix_playbook_reverse_proxy_type` is `playbook-managed-traefik` (which is the default for this playbook), TURN over TCP is terminated by Traefik and forwarded to LiveKit with `turn.external_tls = true`. In this playbook default, this mode is enabled automatically when SSL is enabled and TURN is enabled. + +- The playbook installs a dedicated Traefik TCP entrypoint for TURN (`matrix-livekit-turn`) by default and binds it to `tcp/5350`. +- `livekit_server_config_turn_external_tls` is automatically enabled for this setup. +- Because Traefik handles TLS, LiveKit no longer needs certificate-file paths for TURN in this mode. + +To opt out and keep TURN TLS termination in LiveKit itself, set: + +```yml +livekit_server_config_turn_external_tls: false +``` + +In this playbook, certificate paths are managed automatically via `group_vars/matrix_servers` when certificate dumping is enabled. + +If your setup uses `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), behavior is unchanged by default and still relies on certificates being available inside the container as before. + +Deployments using `other-traefik-container` can opt into the same Traefik-terminated mode there, by setting: + +```yml +livekit_server_config_turn_external_tls: true +livekit_server_container_labels_turn_traefik_enabled: true +livekit_server_container_labels_turn_traefik_entrypoints: "" +``` + +and configuring their own Traefik TCP entrypoint dedicated to LiveKit TURN traffic. + ## Limitations -For some reason, LiveKit Server's TURN ports (`3479/udp` and `5350/tcp`) are not reachable over IPv6 regardless of whether you've [enabled IPv6](./configuring-ipv6.md) for your server. +LiveKit Server's TURN listener behavior depends on where TLS is terminated: + +- Direct LiveKit TURN listeners (`livekit_server_config_turn_external_tls: false`) still use IPv4-only sockets for `3479/udp` and `5350/tcp`, so IPv6 connectivity to these endpoints is not possible. +- With [TURN TLS handling](#turn-tls-handling) (`livekit_server_config_turn_external_tls: true`), the playbook's dedicated `matrix-livekit-turn` TCP entrypoint can still listen on both IPv4 and IPv6. Traefik then forwards TURN/TCP to LiveKit. -It seems like LiveKit Server intentionally only listens on `udp4` and `tcp4` as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92). +It appears that LiveKit Server intentionally only listens on `udp4` and `tcp4` in direct mode, as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92). diff --git a/docs/configuring-playbook-synapse.md b/docs/configuring-playbook-synapse.md index dbb6ef0d6..846694f0b 100644 --- a/docs/configuring-playbook-synapse.md +++ b/docs/configuring-playbook-synapse.md @@ -80,6 +80,29 @@ A separate Ansible role (`matrix-synapse-reverse-proxy-companion`) and component In case any problems occur, make sure to have a look at the [list of synapse issues about workers](https://github.com/element-hq/synapse/issues?q=workers+in%3Atitle) and your `journalctl --unit 'matrix-*'`. +### Limit joining heavy rooms on constrained hosts + +If your server is underpowered, joining heavy rooms can cause Synapse to consume a lot of resources and be unavailable for long (while it catches up). + +To avoid this, Synapse can be configured to reject joins for remote rooms that are too complex before users enter them. + +Complexity is computed as `current_state_events / 500` (Synapse state event count for current room state). When the resulting value is higher than `matrix_synapse_limit_remote_rooms_complexity` and `matrix_synapse_limit_remote_rooms_enabled` is `true`, Synapse blocks joining the room. + +We recommend using this as a guardrail on low-resource servers: + +```yaml +matrix_synapse_limit_remote_rooms_enabled: true + +# Tweak as necessary +matrix_synapse_limit_remote_rooms_complexity: 1.0 + +# Uncomment and tweak if necessary +# matrix_synapse_limit_remote_rooms_complexity_error: "Your homeserver is unable to join rooms this large or complex. Please speak to your server administrator, or upgrade your instance to join this room." + +# If you'd like your admins to be exempt from this limit, uncomment the line below +# matrix_synapse_limit_remote_rooms_admins_can_join: true +``` + ### Synapse + OpenID Connect for Single-Sign-On 💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment. diff --git a/docs/configuring-playbook-turn.md b/docs/configuring-playbook-turn.md index 42fc80787..d9d0c3be0 100644 --- a/docs/configuring-playbook-turn.md +++ b/docs/configuring-playbook-turn.md @@ -13,34 +13,48 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Configuring a TURN server (optional, advanced) -By default, this playbook installs and configures the [coturn](https://github.com/coturn/coturn) as a TURN server, through which clients can make audio/video calls even from [NAT](https://en.wikipedia.org/wiki/Network_address_translation)-ed networks. It also configures the Synapse chat server by default, so that it points to the coturn TURN server installed by the playbook. If that's okay, you can skip this document. +By default, the [coturn](https://github.com/coturn/coturn) TURN server component is enabled automatically only when [Jitsi](configuring-playbook-jitsi.md) is enabled. If you're not using Jitsi, coturn is not enabled by default. -If you'd like to stop the playbook installing the server, see the section [below](#disabling-coturn) to check the configuration for disabling it. +If you explicitly need coturn while not using Jitsi, enable it with: + +```yaml +coturn_enabled: true +``` + +and configure its IP-related settings in the section below. + +If you'd like coturn to stay disabled even when Jitsi is enabled, or if you prefer to use an external TURN provider, see [disabling coturn](#disabling-coturn) section below. + +When Coturn is not enabled, homeservers (like Synapse) would not point to TURN servers and *legacy* audio/video call functionality may fail. If you're using [Matrix RTC](configuring-playbook-rtc.md) (for [Element Call](configuring-playbook-element-call.md)), you likely don't have a need to enable coturn. + +## Adjusting firewall rules + +To ensure Coturn functions correctly, the following firewall rules and port forwarding settings are required when coturn is enabled: + +- `3478/tcp`: STUN/TURN over TCP +- `3478/udp`: STUN/TURN over UDP +- `5349/tcp`: TURN over TCP +- `5349/udp`: TURN over UDP +- `49152-49172/udp`: TURN/UDP relay range + +💡 Docker configures the server's internal firewall for you. In most cases, you don't need to do anything special on the host itself. ## Adjusting the playbook configuration ### Define public IP manually (optional) -In the `hosts` file we explicitly ask for your server's external IP address when defining `ansible_host`, because the same value is used for configuring coturn. - -If you'd rather use a local IP for `ansible_host`, add the following configuration to your `vars.yml` file. Make sure to replace `YOUR_PUBLIC_IP` with the pubic IP used by the server. +If you enable coturn (either via Jitsi or manually), we recommend that you configure the public IP addresses of your server in the `vars.yml` file: ```yaml -coturn_turn_external_ip_address: "YOUR_PUBLIC_IP" +# You can define multiple IP addresses if your server has multiple external IP addresses +coturn_turn_external_ip_addresses: ["YOUR_PUBLIC_IP"] ``` -If you'd like to rely on external IP address auto-detection (not recommended unless you need it), set an empty value to the variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable. +If you'd like to rely on external IP address auto-detection (not recommended unless you need it), avoid configuring this variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable. >[!NOTE] > You can self-host the echoip service by using the [Mother-of-All-Self-Hosting (MASH)](https://github.com/mother-of-all-self-hosting/mash-playbook) Ansible playbook. See [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/echoip.md) for the instruction to install it with the playbook. If you are wondering how to use it for your Matrix server, refer to [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/setting-up-services-on-mdad-server.md) for the overview. -If your server has multiple external IP addresses, the coturn role offers a different variable for specifying them: - -```yaml -# Note: coturn_turn_external_ip_addresses is different than coturn_turn_external_ip_address -coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7'] -``` - ### Change the authentication mechanism (optional) The playbook uses the [`auth-secret` authentication method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L186-L199) by default, but you may switch to the [`lt-cred-mech` method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L178) which [some report](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191) to be working better. @@ -119,14 +133,14 @@ Take a look at: ## Disabling coturn -If, for some reason, you'd like for the playbook to not install coturn (or to uninstall it if it was previously installed), add the following configuration to your `vars.yml` file: +Coturn is only enabled by default when [Jitsi](configuring-playbook-jitsi.md) is enabled. In most instances, you don't need to explicitly disable it. + +To force the playbook to not install Coturn (even when Jitsi is enabled), add the following configuration to your `vars.yml` file: ```yaml coturn_enabled: false ``` -In that case, Synapse would not point to any coturn servers and audio/video call functionality may fail. - ## Installing After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: diff --git a/docs/faq.md b/docs/faq.md index 662a7e55d..309edfb8b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -305,18 +305,23 @@ See [Serving the base domain](configuring-playbook-base-domain-serving.md). ### How do I optimize this setup for a low-power server? +For a low-power server, it's best to use an alternative homeserver implementation (other than [Synapse](configuring-playbook-synapse.md)). + You can disable some not-so-important services to save on memory. ```yaml # Disabling this will prevent email-notifications and other such things from working. exim_relay_enabled: false +``` -# You can also disable this to save more RAM, -# at the expense of audio/video calls being unreliable. -coturn_enabled: false +If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform. -# This makes Synapse not keep track of who is online/offline. -# + +#### Synapse-specific optimizations + +If you're using [Synapse](configuring-playbook-synapse.md), you can also consider the following optimizations: + +```yaml # Keeping track of this and announcing such online-status in federated rooms with # hundreds of servers inside is insanely heavy (https://github.com/matrix-org/synapse/issues/3971). # @@ -324,18 +329,14 @@ coturn_enabled: false matrix_synapse_presence_enabled: false ``` -You can also consider implementing a restriction on room complexity, in order to prevent users from joining very heavy rooms: +You can also consider [implementing a restriction on room complexity](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts), in order to prevent users from joining very heavy rooms: ```yaml -matrix_synapse_configuration_extension_yaml: | - limit_remote_rooms: - enabled: true - complexity: 1.0 # this limits joining complex (~large) rooms, can be - # increased, but larger values can require more RAM +# See: docs/configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts +matrix_synapse_limit_remote_rooms_enabled: true +matrix_synapse_limit_remote_rooms_complexity: 1.0 ``` -If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform. - ### I already have Docker on my server. Can you stop installing Docker via the playbook? Yes, we can stop installing Docker ourselves. Just use this in your `vars.yml` file: diff --git a/docs/installing.md b/docs/installing.md index 7b6dc33ef..9bbfd5873 100644 --- a/docs/installing.md +++ b/docs/installing.md @@ -146,6 +146,7 @@ After completing the installation, you can: - or learn how to [maintain your server](faq.md#maintenance) - or join some Matrix rooms: * via the *Explore rooms* feature in Element Web or some other clients, or by discovering them using this [matrix-static list](https://view.matrix.org). **Note**: joining large rooms may overload small servers. + For tuning guidance on constrained hosts, see [Limit joining heavy rooms on constrained hosts](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts). * or come say Hi in our support room — [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting. - or help make this playbook better by contributing (code, documentation, or [coffee/beer](https://liberapay.com/s.pantaleev/donate)) diff --git a/docs/maintenance-synapse.md b/docs/maintenance-synapse.md index 15b6eb62b..7b7791227 100644 --- a/docs/maintenance-synapse.md +++ b/docs/maintenance-synapse.md @@ -83,6 +83,8 @@ You should then be able to browse the adminer database administration GUI at htt Synapse's presence feature which tracks which users are online and which are offline can use a lot of processing power. You can disable presence by adding `matrix_synapse_presence_enabled: false` to your `vars.yml` file. +On smaller servers, consider limiting joins to very complex rooms with [the room complexity guard](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts). + If you have enough compute resources (CPU & RAM), you can make Synapse better use of them by [enabling load-balancing with workers](configuring-playbook-synapse.md#load-balancing-with-workers). [Tuning your PostgreSQL database](maintenance-postgres.md#tuning-postgresql) could also improve Synapse performance. The playbook tunes the integrated Postgres database automatically, but based on your needs you may wish to adjust tuning variables manually. If you're using an [external Postgres database](configuring-playbook-external-postgres.md), you will also need to tune Postgres manually. diff --git a/docs/prerequisites.md b/docs/prerequisites.md index 5ed76ad2c..b9c5f441f 100644 --- a/docs/prerequisites.md +++ b/docs/prerequisites.md @@ -57,12 +57,7 @@ We will be using `example.com` as the domain in the following instruction. Pleas - `80/tcp`: HTTP webserver - `443/tcp` and `443/udp`: HTTPS webserver - - `3478/tcp`: STUN/TURN over TCP (used by [coturn](./configuring-playbook-turn.md)) - - `3478/udp`: STUN/TURN over UDP (used by [coturn](./configuring-playbook-turn.md)) - - `5349/tcp`: TURN over TCP (used by [coturn](./configuring-playbook-turn.md)) - - `5349/udp`: TURN over UDP (used by [coturn](./configuring-playbook-turn.md)) - `8448/tcp` and `8448/udp`: Matrix Federation API HTTPS webserver. Some components like [Matrix User Verification Service](configuring-playbook-user-verification-service.md#open-matrix-federation-port) require this port to be opened **even with federation disabled**. - - the range `49152-49172/udp`: TURN over UDP - potentially some other ports, depending on the additional (non-default) services that you enable in the **configuring the playbook** step (later on). Consult each service's documentation page in `docs/` for that. --------------------------------------------- diff --git a/examples/hosts b/examples/hosts index 7099f1fa4..4204b60d8 100644 --- a/examples/hosts +++ b/examples/hosts @@ -1,6 +1,3 @@ -# We explicitly ask for your server's external IP address, because the same value is used for configuring coturn. -# If you'd rather use a local IP here, make sure to set up `coturn_turn_external_ip_address`. -# # To connect using a non-root user (and elevate to root with sudo later), # replace `ansible_ssh_user=root` with something like this: `ansible_ssh_user=username ansible_become=true ansible_become_user=root`. # If sudo requires a password, either add `ansible_become_password=PASSWORD_HERE` to the host line @@ -18,4 +15,4 @@ # to the host line below. [matrix_servers] -matrix.example.com ansible_host= ansible_ssh_user=root +matrix.example.com ansible_host= ansible_ssh_user=root diff --git a/examples/vars.yml b/examples/vars.yml index 727346aa1..655e75c24 100644 --- a/examples/vars.yml +++ b/examples/vars.yml @@ -53,18 +53,10 @@ devture_systemd_docker_base_ipv6_enabled: true # The value used here must be shorter than 100 characters. postgres_connection_password: '' -# By default, we configure coturn's external IP address using the value specified for `ansible_host` in your `inventory/hosts` file. -# If this value is an external IP address, you can skip this section. -# -# If `ansible_host` is not the server's external IP address, you have 2 choices: -# 1. Uncomment the line below, to allow IP address auto-detection to happen (more on this below) -# 2. Uncomment and adjust the line below to specify an IP address manually -# -# By default, auto-detection will be attempted using the `https://ifconfig.co/json` API. -# Default values for this are specified in `coturn_turn_external_ip_address_auto_detection_*` variables in the coturn role -# (see `roles/galaxy/coturn/defaults/main.yml`). -# -# If your server has multiple IP addresses, you may define them in another variable which allows a list of addresses. -# Example: `coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7']` +# You can limit heavy room joins on constrained hosts. +# See: +# docs/configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts # -# coturn_turn_external_ip_address: '' +# matrix_synapse_limit_remote_rooms_enabled: true +# matrix_synapse_limit_remote_rooms_complexity: 1.0 +# matrix_synapse_limit_remote_rooms_admins_can_join: false diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 805bfb819..c69422fb2 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -246,15 +246,14 @@ matrix_addons_homeserver_systemd_services_list: | # - so that addon services (starting later) can communicte with the homeserver via Traefik's internal entrypoint # (see `matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled`) # - core services (the homeserver) get a level of ~1000 -# - services that the homeserver depends on (database, Redis, ntfy, coturn, etc.) get a lower level — between 500 and 1000 -# - coturn gets a higher priority level (= starts later) if `devture_systemd_service_manager_service_restart_mode == 'one-by-one'` to intentionally delay it, because: -# - starting services one by one means that the service manager role waits for each service to fully start before proceeding to the next one +# - services that the homeserver depends on (database, Redis, ntfy, etc.) get a lower level — between 500 and 1000 +# - coturn gets a higher priority level (= starts later) in all cases, to intentionally delay it in relation to the homeserver, because: +# - when starting services one by one, the service manager waits for each service to fully start before proceeding to the next one # - if coturn has a lower priority than the homeserver, it would be started before it -# - since coturn is started before the homeserver, there's no container label telling Traefik to get a `matrix.example.com` certificate +# - if coturn is started before the homeserver, there'd be no container label (usually on the homeserver) telling Traefik to get a `matrix.example.com` certificate # - thus, coturn would spin and wait for a certificate until it fails. We'd get a playbook failure due to it, but service manager will proceed to start all other services anyway. # - only later, when the homeserver actually starts, would that certificate be fetched and dumped -# - this is not a problem with `all-at-once` (default) or `priority-batched` (services start concurrently), -# or with `clean-stop-start` (everything stops first, then starts in priority order — coturn at 900 is fine) +# - this is a problem for `one-by-one`, `clean-stop-start` (which behaves like one-by-one initially) and possibly other modes, except `all-at-once` # - reverse-proxying services get level 3000 # - Matrix utility services (bridges, bots) get a level of 2000/2200, so that: # - they can start before the reverse-proxy @@ -607,14 +606,14 @@ devture_systemd_service_manager_services_list_auto: | + ([{ 'name': ('matrix-' + matrix_homeserver_implementation + '.service'), - 'priority': 1000, + 'priority': matrix_homeserver_systemd_service_manager_priority, 'restart_necessary': true, 'groups': ['matrix', 'homeservers', matrix_homeserver_implementation], }] if matrix_homeserver_enabled else []) + ([{ 'name': 'matrix-corporal.service', - 'priority': 1500, + 'priority': (matrix_homeserver_systemd_service_manager_priority + 500), 'restart_necessary': (matrix_corporal_restart_necessary | bool), 'groups': ['matrix', 'corporal'], }] if matrix_corporal_enabled else []) @@ -635,7 +634,7 @@ devture_systemd_service_manager_services_list_auto: | + ([{ 'name': (coturn_identifier + '.service'), - 'priority': (1500 if devture_systemd_service_manager_service_restart_mode == 'one-by-one' else 900), + 'priority': (matrix_homeserver_systemd_service_manager_priority + 500), 'restart_necessary': (coturn_restart_necessary | bool), 'groups': ['matrix', 'coturn'], }] if coturn_enabled else []) @@ -3498,7 +3497,9 @@ matrix_rageshake_container_labels_traefik_tls_certResolver: "{{ traefik_certReso # ###################################################################### -coturn_enabled: true +# Coturn is enabled by default only when Jitsi is enabled because Jitsi still +# depends on legacy TURN integration for compatibility. +coturn_enabled: "{{ jitsi_enabled | bool }}" coturn_identifier: matrix-coturn @@ -3514,11 +3515,6 @@ coturn_container_image_registry_prefix_upstream: "{{ matrix_container_global_reg coturn_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" -# We make the assumption that `ansible_host` points to an external IP address, which may not always be the case. -# Users are free to set `coturn_turn_external_ip_address` to an empty string -# to allow auto-detection (via an echoip service) to happen at runtime. -coturn_turn_external_ip_address: "{{ ansible_host }}" - # By default, we use the official public instance. coturn_turn_external_ip_address_auto_detection_echoip_service_url: https://ifconfig.co/json @@ -5945,6 +5941,8 @@ traefik_additional_entrypoints_auto: | ([matrix_playbook_public_matrix_federation_api_traefik_entrypoint_definition] if matrix_playbook_public_matrix_federation_api_traefik_entrypoint_enabled else []) + ([matrix_playbook_internal_matrix_client_api_traefik_entrypoint_definition] if matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled else []) + + + ([matrix_playbook_livekit_turn_traefik_entrypoint_definition] if matrix_playbook_livekit_turn_traefik_entrypoint_enabled else []) }} traefik_config_providers_docker_endpoint: "{{ container_socket_proxy_endpoint if container_socket_proxy_enabled else 'unix:///var/run/docker.sock' }}" @@ -6104,6 +6102,11 @@ livekit_server_container_image_registry_prefix_upstream: "{{ matrix_container_gl livekit_server_container_network: "{{ matrix_addons_container_network }}" livekit_server_container_additional_networks_auto: "{{ [matrix_playbook_reverse_proxyable_services_additional_network] if (livekit_server_container_labels_traefik_enabled and matrix_playbook_reverse_proxyable_services_additional_network) else [] }}" +# We expose LiveKit TURN/TLS via Traefik on a dedicated TCP entrypoint. +matrix_playbook_livekit_turn_traefik_entrypoint_enabled: "{{ matrix_playbook_reverse_proxy_type == 'playbook-managed-traefik' and livekit_server_config_turn_enabled and livekit_server_config_turn_external_tls and livekit_server_container_labels_traefik_enabled }}" +matrix_playbook_livekit_turn_traefik_entrypoint_port: "{{ livekit_server_config_turn_tls_port }}" +matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port: "{{ (matrix_playbook_service_host_bind_interface_prefix ~ (matrix_playbook_livekit_turn_traefik_entrypoint_port | string)) if matrix_playbook_service_host_bind_interface_prefix else (matrix_playbook_livekit_turn_traefik_entrypoint_port | string) }}" + livekit_server_container_additional_volumes_auto: | {{ ( @@ -6118,7 +6121,7 @@ livekit_server_container_additional_volumes_auto: | 'dst': livekit_server_config_turn_key_file, 'options': 'ro', }, - ] if (matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and (livekit_server_config_turn_cert_file and livekit_server_config_turn_key_file)) else [] + ] if (matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and not (livekit_server_config_turn_external_tls | bool) and (livekit_server_config_turn_cert_file and livekit_server_config_turn_key_file)) else [] ) }} @@ -6126,6 +6129,9 @@ livekit_server_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_pro livekit_server_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}" livekit_server_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}" livekit_server_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}" +livekit_server_container_labels_turn_traefik_enabled: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_enabled }}" +livekit_server_container_labels_turn_traefik_entrypoints: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_name }}" +livekit_server_container_labels_turn_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}" livekit_server_container_labels_public_metrics_middleware_basic_auth_enabled: "{{ matrix_metrics_exposure_http_basic_auth_enabled }}" livekit_server_container_labels_public_metrics_middleware_basic_auth_users: "{{ matrix_metrics_exposure_http_basic_auth_users }}" @@ -6164,15 +6170,19 @@ livekit_server_config_turn_tls_port: 5350 # Note that TURN is not enabled by default. See `livekit_server_config_turn_enabled`. livekit_server_config_turn_udp_port: 3479 -# LiveKit's TURN implementation requires SSL certificates. -# We only enable it if we can provide them automatically via Traefik + Traefik Certs Dumper. -livekit_server_config_turn_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled }}" +# In this mode, Traefik terminates TURN/TLS and forwards plaintext TCP to LiveKit's `turn.tls_port`. +# We only enable it automatically when Traefik is managed by this playbook. +livekit_server_config_turn_external_tls: "{{ matrix_playbook_reverse_proxy_type == 'playbook-managed-traefik' and matrix_playbook_ssl_enabled }}" +# TURN stays enabled for either mode: +# - external TLS termination by playbook-managed Traefik +# - in-container TLS using certificates from Traefik Certs Dumper +livekit_server_config_turn_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and (livekit_server_config_turn_external_tls or traefik_certs_dumper_enabled) }}" livekit_server_config_turn_cert_file: |- {{ { - 'playbook-managed-traefik': ('/certificate.crt' if traefik_certs_dumper_enabled else ''), - 'other-traefik-container': ('/certificate.crt' if traefik_certs_dumper_enabled else ''), + 'playbook-managed-traefik': ('/certificate.crt' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), + 'other-traefik-container': ('/certificate.crt' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), 'none': '', }[matrix_playbook_reverse_proxy_type] }} @@ -6180,15 +6190,15 @@ livekit_server_config_turn_cert_file: |- livekit_server_config_turn_key_file: |- {{ { - 'playbook-managed-traefik': ('/privatekey.key' if traefik_certs_dumper_enabled else ''), - 'other-traefik-container': ('/privatekey.key' if traefik_certs_dumper_enabled else ''), + 'playbook-managed-traefik': ('/privatekey.key' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), + 'other-traefik-container': ('/privatekey.key' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), 'none': '', }[matrix_playbook_reverse_proxy_type] }} livekit_server_systemd_required_services_list_auto: | {{ - ([traefik_certs_dumper_identifier + '-wait-for-domain@' + livekit_server_config_turn_domain + '.service'] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled else []) + ([traefik_certs_dumper_identifier + '-wait-for-domain@' + livekit_server_config_turn_domain + '.service'] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and not (livekit_server_config_turn_external_tls | bool) else []) }} ######################################################################## diff --git a/requirements.yml b/requirements.yml index cdd6ae7f7..fea795011 100644 --- a/requirements.yml +++ b/requirements.yml @@ -7,7 +7,7 @@ version: v1.4.3-2.1.1-1 name: backup_borg - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-cinny.git - version: v4.10.3-0 + version: v4.10.5-0 name: cinny - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-container-socket-proxy.git version: v0.4.2-3 @@ -42,7 +42,7 @@ version: v10741-0 name: jitsi - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-livekit-server.git - version: v1.9.11-1 + version: v1.9.11-2 name: livekit_server - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-ntfy.git version: v2.17.0-1 @@ -84,7 +84,7 @@ version: v1.1.0-1 name: timesync - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik.git - version: v3.6.8-4 + version: v3.6.9-0 name: traefik - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik-certs-dumper.git version: v2.10.0-5 diff --git a/roles/custom/matrix-base/defaults/main.yml b/roles/custom/matrix-base/defaults/main.yml index 49b3c89f3..15ea0ebe6 100644 --- a/roles/custom/matrix-base/defaults/main.yml +++ b/roles/custom/matrix-base/defaults/main.yml @@ -92,6 +92,10 @@ matrix_homeserver_enabled: true # Note that the homeserver implementation of a server will not be able to be changed without data loss. matrix_homeserver_implementation: synapse +# The priority that the homeserver starts with (lower = starts earlier). +# Related to the systemd_service_manager role and `devture_systemd_service_manager_services_list*` variables. +matrix_homeserver_systemd_service_manager_priority: 1000 + # This contains a secret, which is used for generating various other secrets later on. matrix_homeserver_generic_secret_key: '' @@ -393,6 +397,22 @@ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_definition: host_bind_port: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_host_bind_port }}" config: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_config }}" +# Controls whether to enable an additional Traefik entrypoint for LiveKit TURN/TLS (TCP) traffic. +matrix_playbook_livekit_turn_traefik_entrypoint_enabled: false +matrix_playbook_livekit_turn_traefik_entrypoint_name: matrix-livekit-turn +matrix_playbook_livekit_turn_traefik_entrypoint_port: 5350 +matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_port }}" +matrix_playbook_livekit_turn_traefik_entrypoint_config: "{{ (matrix_playbook_livekit_turn_traefik_entrypoint_config_default | combine(matrix_playbook_livekit_turn_traefik_entrypoint_config_auto)) | combine(matrix_playbook_livekit_turn_traefik_entrypoint_config_custom, recursive=True) }}" +matrix_playbook_livekit_turn_traefik_entrypoint_config_default: {} +matrix_playbook_livekit_turn_traefik_entrypoint_config_auto: {} +matrix_playbook_livekit_turn_traefik_entrypoint_config_custom: {} + +matrix_playbook_livekit_turn_traefik_entrypoint_definition: + name: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_name }}" + port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_port }}" + host_bind_port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port }}" + config: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_config }}" + # Variables to Control which parts of our roles run. run_postgres_import: true run_postgres_upgrade: true diff --git a/roles/custom/matrix-static-files/defaults/main.yml b/roles/custom/matrix-static-files/defaults/main.yml index f33b07c92..37c42a315 100644 --- a/roles/custom/matrix-static-files/defaults/main.yml +++ b/roles/custom/matrix-static-files/defaults/main.yml @@ -121,6 +121,10 @@ matrix_static_files_environment_variable_server_log_remote_address: false # See: https://static-web-server.net/configuration/environment-variables/ matrix_static_files_environment_variable_server_config_file: /config/config.toml +# Controls the SERVER_IGNORE_HIDDEN_FILES environment variable. +# See: https://static-web-server.net/configuration/environment-variables/ +matrix_static_files_environment_variable_server_ignore_hidden_files: false + # Additional environment variables. matrix_static_files_environment_variables_additional_variables: '' diff --git a/roles/custom/matrix-static-files/templates/env.j2 b/roles/custom/matrix-static-files/templates/env.j2 index 0dd9b6f10..b095e0deb 100644 --- a/roles/custom/matrix-static-files/templates/env.j2 +++ b/roles/custom/matrix-static-files/templates/env.j2 @@ -10,5 +10,6 @@ SERVER_LOG_LEVEL={{ matrix_static_files_environment_variable_server_log_level }} SERVER_LOG_REMOTE_ADDRESS={{ 'true' if matrix_static_files_environment_variable_server_log_remote_address else 'false' }} SERVER_CONFIG_FILE={{ matrix_static_files_environment_variable_server_config_file }} +SERVER_IGNORE_HIDDEN_FILES={{ matrix_static_files_environment_variable_server_ignore_hidden_files | to_json }} {{ matrix_static_files_environment_variables_additional_variables }} diff --git a/roles/custom/matrix-synapse/defaults/main.yml b/roles/custom/matrix-synapse/defaults/main.yml index 9fdfe6f6d..e4df1cb47 100644 --- a/roles/custom/matrix-synapse/defaults/main.yml +++ b/roles/custom/matrix-synapse/defaults/main.yml @@ -570,6 +570,21 @@ matrix_synapse_report_stats_endpoint: "https://matrix.org/report-usage-stats/pus # disabling this will decrease server load significantly. matrix_synapse_presence_enabled: true +# Controls whether remote room complexity checks are enabled when joining rooms. +# When enabled, Synapse checks a room's complexity before joining a remote room. +# Complexity is measured as `current_state_events / 500` and can prevent +# users from joining very large/active rooms on constrained servers. +matrix_synapse_limit_remote_rooms_enabled: false + +# Maximum complexity allowed before join is blocked. +matrix_synapse_limit_remote_rooms_complexity: 1.0 + +# Error message returned when a user attempts to join a too-complex room. +matrix_synapse_limit_remote_rooms_complexity_error: "Your homeserver is unable to join rooms this large or complex. Please speak to your server administrator, or upgrade your instance to join this room." + +# Allow server admins to join rooms even when they exceed the complexity limit. +matrix_synapse_limit_remote_rooms_admins_can_join: false + # Controls whether accessing the server's public rooms directory can be done without authentication. # For private servers, you most likely wish to require authentication, # unless you know what list of rooms you're publishing to the world and explicitly want to do it. diff --git a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 index 558dc1729..65c32dac4 100644 --- a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -452,30 +452,11 @@ admin_contact: {{ matrix_synapse_admin_contact | to_json }} #server_context: context # Resource-constrained homeserver settings -# -# When this is enabled, the room "complexity" will be checked before a user -# joins a new remote room. If it is above the complexity limit, the server will -# disallow joining, or will instantly leave. -# -# Room complexity is an arbitrary measure based on factors such as the number of -# users in the room. -# limit_remote_rooms: - # Uncomment to enable room complexity checking. - # - #enabled: true - - # the limit above which rooms cannot be joined. The default is 1.0. - # - #complexity: 0.5 - - # override the error which is returned when the room is too complex. - # - #complexity_error: "This room is too complex." - - # allow server admins to join complex rooms. Default is false. - # - #admins_can_join: true + enabled: {{ matrix_synapse_limit_remote_rooms_enabled | to_json }} + complexity: {{ matrix_synapse_limit_remote_rooms_complexity | to_json }} + complexity_error: {{ matrix_synapse_limit_remote_rooms_complexity_error | to_json }} + admins_can_join: {{ matrix_synapse_limit_remote_rooms_admins_can_join | to_json }} # Whether to require a user to be in the room to add an alias to it. # Defaults to 'true'.