mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-05-08 05:10:14 +03:00
matrix-tuwunel: add Tuwunel homeserver role (#5200)
Tuwunel is a Matrix homeserver maintained by the matrix-construct organisation. See https://matrix-construct.github.io/tuwunel/. The rendered TOML emits only keys exposed as Ansible variables; the rest fall back to tuwunel's upstream defaults. Anything not surfaced can be set via the TUWUNEL_* env extension or by overriding the template path. Popular features Tuwunel adds variables for: - OAuth2/OIDC identity providers (a list of `[[global.identity_provider]]` blocks; brand-aware defaults for Google, GitHub, Keycloak, MAS, etc) - LDAP and JWT authentication - Media storage providers (native local and S3 with multipart upload) - RocksDB tuning (compression, direct_io, parallelism, online backups) - Native TLS dual-protocol mode - Blurhashing, Sentry crash reporting Auto-wired from existing playbook globals: well-known client URL, TURN/coturn, MatrixRTC LiveKit URL, federation. The `tuwunel-migrate-from-conduwuit` tag performs a binary-swap migration. Migration from any other Conduit derivative is unsupported and would corrupt the database. Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -53,6 +53,7 @@ The homeserver is the backbone of your Matrix system. Choose one from the follow
|
||||
| [Synapse](https://github.com/element-hq/synapse) | ✅ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network | [Link](docs/configuring-playbook-synapse.md) |
|
||||
| [Conduit](https://conduit.rs) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Conduit is a lightweight open-source server implementation of the Matrix Specification with a focus on easy setup and low system requirements | [Link](docs/configuring-playbook-conduit.md) |
|
||||
| [continuwuity](https://continuwuity.org) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. | [Link](docs/configuring-playbook-continuwuity.md) |
|
||||
| [Tuwunel](https://matrix-construct.github.io/tuwunel/) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit. | [Link](docs/configuring-playbook-tuwunel.md) |
|
||||
| [Dendrite](https://github.com/element-hq/dendrite) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse. | [Link](docs/configuring-playbook-dendrite.md) |
|
||||
|
||||
### Clients
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Jason Volk
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
# Configuring Tuwunel (optional)
|
||||
|
||||
The playbook can install and configure the [Tuwunel](https://matrix-construct.github.io/tuwunel/) Matrix homeserver for you.
|
||||
|
||||
Tuwunel is a featureful homeserver written entirely in Rust, intended as a scalable, low-cost, enterprise-ready alternative to Synapse that fully implements the [Matrix specification](https://spec.matrix.org/latest/) for all but the most niche uses. It is the official successor to [conduwuit](configuring-playbook-conduwuit.md), is now sponsored by the government of Switzerland 🇨🇭 (where it is currently deployed for citizens), and is used by a number of organisations with a vested interest in its continued development. See the project's [documentation](https://matrix-construct.github.io/tuwunel/) for further background.
|
||||
|
||||
By default, the playbook installs [Synapse](https://github.com/element-hq/synapse) as it's the only full-featured Matrix server at the moment. If that's okay, you can skip this document.
|
||||
|
||||
> [!WARNING]
|
||||
> - **You can't switch an existing Matrix server's implementation** (e.g. Synapse → Tuwunel). Proceed below only if you're OK with starting over, or you're dealing with a server on a new domain name which hasn't participated in the Matrix federation yet. The one exception is migrating from conduwuit; see [Migrating from conduwuit](#migrating-from-conduwuit).
|
||||
> - **Homeserver implementations other than Synapse may not be fully functional** with every part of this playbook. Make yourself familiar with the trade-offs before proceeding.
|
||||
|
||||
## Adjusting the playbook configuration
|
||||
|
||||
To use Tuwunel, set the following on `inventory/host_vars/matrix.example.com/vars.yml`:
|
||||
|
||||
```yaml
|
||||
matrix_homeserver_implementation: tuwunel
|
||||
|
||||
# Open the registration endpoint long enough to create your first user.
|
||||
# After signing up, set this back to false.
|
||||
matrix_tuwunel_config_allow_registration: true
|
||||
|
||||
# A registration token to protect the endpoint from abuse.
|
||||
# Generate one with `pwgen -s 64 1` or similar.
|
||||
matrix_tuwunel_config_registration_token: ''
|
||||
```
|
||||
|
||||
The first user account that registers becomes a server admin and is automatically invited to the admin room. See [Creating the first user account](#creating-the-first-user-account) below for the bootstrap procedure.
|
||||
|
||||
## Wiring done for you
|
||||
|
||||
When `matrix_homeserver_implementation: tuwunel` is set, the playbook automatically integrates Tuwunel with the rest of your stack:
|
||||
|
||||
- **Federation.** Toggled by `matrix_homeserver_federation_enabled`. The federation virtual host (port 8448 in the default setup) is wired up via Traefik labels.
|
||||
- **Well-known.** `matrix_tuwunel_config_well_known_client` is set to your public homeserver URL whenever SSL is enabled. Matrix clients use this for delegated-domain server discovery; identity-provider entries below can also omit their `callback_url`, since Tuwunel derives `<well-known>/_matrix/client/unstable/login/sso/callback/<client_id>` automatically.
|
||||
- **Element Call / MatrixRTC.** When the [LiveKit JWT service](configuring-playbook-matrix-rtc.md) is enabled, Tuwunel publishes its public URL through `.well-known/matrix/client` per [MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143).
|
||||
- **Legacy calls (TURN).** When [Coturn](configuring-playbook-turn.md) is enabled, its URIs and shared secret (or username/password, depending on `coturn_authentication_method`) are wired automatically.
|
||||
|
||||
## Extending the configuration
|
||||
|
||||
Tuwunel exposes a large configuration surface. The role surfaces commonly used options as Ansible variables under `matrix_tuwunel_config_*`. See [`roles/custom/matrix-tuwunel/defaults/main.yml`](../roles/custom/matrix-tuwunel/defaults/main.yml) for the complete list, and [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) for the rendered configuration.
|
||||
|
||||
For options that aren't surfaced as a dedicated variable, [environment variables](https://matrix-construct.github.io/tuwunel/configuration.html#environment-variables) are the recommended override mechanism. They take priority over the rendered TOML, are scoped to the running container, and require no template patching:
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_environment_variables_extension: |
|
||||
TUWUNEL_REQUEST_TIMEOUT=60
|
||||
TUWUNEL_DNS_CACHE_SIZE=131072
|
||||
```
|
||||
|
||||
Keys nested under a TOML section use `__` (double underscore) to descend, e.g. `TUWUNEL_WELL_KNOWN__SERVER`. User-named sections become path segments too: `TUWUNEL_STORAGE_PROVIDER__ARCHIVE__S3__URL` overrides the `url` field of the `archive` storage provider in the example below.
|
||||
|
||||
If you need wholesale control of the configuration file, copy [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) into your inventory and point `matrix_tuwunel_template_tuwunel_config` at your copy.
|
||||
|
||||
The container image published as `:latest` is built with `io_uring`, `jemalloc`, LDAP, blurhashing, URL preview, sentry telemetry, and zstd compression all enabled, so most opt-in features are simply a configuration toggle away.
|
||||
|
||||
### Identity providers (OAuth2 / OIDC)
|
||||
|
||||
Configure one or more `[[global.identity_provider]]` entries via a list. Each entry maps directly to Tuwunel's [identity-provider fields](https://matrix-construct.github.io/tuwunel/authentication/providers.html); only the fields you set are emitted. GitHub, GitLab, and Google have built-in `issuer_url` defaults so a `client_id` plus `client_secret` is enough; for any other `brand` (Apple, Facebook, Keycloak, MAS, Twitter, etc.) you must supply `issuer_url` explicitly:
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_identity_providers:
|
||||
- brand: keycloak
|
||||
client_id: matrix
|
||||
client_secret: '<provider secret>'
|
||||
issuer_url: https://sso.example.com/realms/matrix
|
||||
callback_url: https://matrix.example.com/_matrix/client/unstable/login/sso/callback/matrix
|
||||
trusted: true
|
||||
- brand: github
|
||||
client_id: '<github oauth app id>'
|
||||
client_secret: '<github oauth app secret>'
|
||||
```
|
||||
|
||||
Self-hosted providers must supply both `client_id` and `issuer_url`. Set `trusted: true` only on providers you operate yourself; trusting a public provider (GitHub, Google, etc.) is an account-takeover risk.
|
||||
|
||||
### LDAP
|
||||
|
||||
Tuwunel can authenticate `m.login.password` requests against an LDAP directory and, in search-then-bind mode, keep admin status in sync with directory membership. The shipped image already includes the `ldap` build feature.
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_ldap_enabled: true
|
||||
matrix_tuwunel_config_ldap_uri: ldaps://ldap.example.com:636
|
||||
matrix_tuwunel_config_ldap_base_dn: ou=users,dc=example,dc=org
|
||||
matrix_tuwunel_config_ldap_bind_dn: cn=ldap-reader,dc=example,dc=org
|
||||
matrix_tuwunel_config_ldap_bind_password_file: /etc/tuwunel/ldap.pw
|
||||
matrix_tuwunel_config_ldap_filter: '(&(objectClass=person)(memberOf=cn=matrix,ou=groups,dc=example,dc=org))'
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> `bind_password_file` is read **inside the container**. The role bind-mounts `/matrix/tuwunel/config` to `/etc/tuwunel` (read-only) and `/matrix/tuwunel/data` to `/var/lib/tuwunel`. To make the file available at the path above, drop it on the host at `/matrix/tuwunel/config/ldap.pw` (owned by `matrix:matrix`) before running the playbook; the role does not template secret files for you.
|
||||
|
||||
For direct-bind, anonymous-search, and admin-sync details, see [LDAP authentication](https://matrix-construct.github.io/tuwunel/authentication/ldap.html).
|
||||
|
||||
### JWT login
|
||||
|
||||
Tuwunel can accept signed JSON Web Tokens both as a login flow and as a User-Interactive Authentication step:
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_jwt_enabled: true
|
||||
matrix_tuwunel_config_jwt_key: '<shared secret>'
|
||||
matrix_tuwunel_config_jwt_format: HMAC # one of HMAC, B64HMAC, ECDSA, EDDSA
|
||||
matrix_tuwunel_config_jwt_algorithm: HS256
|
||||
matrix_tuwunel_config_jwt_audience: ['matrix']
|
||||
matrix_tuwunel_config_jwt_issuer: ['https://issuer.example.com']
|
||||
```
|
||||
|
||||
The defaults match Synapse's `experimental_features.jwt_config` semantics, so a key + algorithm port should authenticate the same set of tokens. See [Enterprise JWT](https://matrix-construct.github.io/tuwunel/authentication/jwt.html) for the full reference, including the asymmetric (ECDSA / EdDSA) formats and the operator-controlled UIAA override flow.
|
||||
|
||||
### Media storage providers
|
||||
|
||||
Each entry becomes a `[global.storage_provider.<id>.<kind>]` block. `kind` is `local` or `s3`; the remaining keys map directly to the fields documented in [Storage providers](https://matrix-construct.github.io/tuwunel/media/storage.html):
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_storage_providers:
|
||||
- id: primary
|
||||
kind: local
|
||||
base_path: /var/lib/tuwunel/media
|
||||
|
||||
- id: archive
|
||||
kind: s3
|
||||
url: s3://my-bucket/media
|
||||
region: us-east-1
|
||||
key: AKIA...
|
||||
secret: '<aws secret>'
|
||||
multipart_threshold: 100 MiB
|
||||
```
|
||||
|
||||
The S3 backend ships with native multipart upload, so no goofys/rclone sidecar is required. MinIO, Cloudflare R2, and DigitalOcean Spaces all work; set `endpoint` and `use_vhost_request: false` as appropriate.
|
||||
|
||||
> [!NOTE]
|
||||
> Local provider paths must live under `/var/lib/tuwunel` (the container's data mount, persisted on the host at `/matrix/tuwunel/data`), or you must mount the target directory into the container yourself via `matrix_tuwunel_container_extra_arguments`. The container otherwise runs read-only.
|
||||
|
||||
### RocksDB and cache tuning
|
||||
|
||||
Tuwunel embeds RocksDB. The defaults (`rocksdb_compression_algo: zstd`) suit most deployments. For high-throughput servers you may want to enable direct I/O, raise parallelism, and bump the cache modifier:
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_rocksdb_direct_io: true
|
||||
matrix_tuwunel_config_rocksdb_parallelism_threads: 8
|
||||
matrix_tuwunel_config_cache_capacity_modifier: 2.0
|
||||
matrix_tuwunel_config_database_backup_path: /var/lib/tuwunel/backups
|
||||
```
|
||||
|
||||
If you run on ZFS, the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html#zfs) lists the dataset properties (`recordsize`, `primarycache`, `compression`, `atime`, `logbias`) and config flags (`rocksdb_direct_io`, `rocksdb_allow_fallocate`) you need to adjust to avoid severe write amplification.
|
||||
|
||||
To enable Sentry crash reporting, set `matrix_tuwunel_config_sentry_enabled: true`.
|
||||
|
||||
### Federation gating
|
||||
|
||||
Tuwunel accepts regular-expression patterns at every level of remote-server filtering:
|
||||
|
||||
```yaml
|
||||
matrix_tuwunel_config_forbidden_remote_server_names:
|
||||
- 'bad\.example\.com$'
|
||||
matrix_tuwunel_config_forbidden_remote_room_directory_server_names:
|
||||
- 'spam\.example\.com$'
|
||||
matrix_tuwunel_config_prevent_media_downloads_from:
|
||||
- 'heavy\.example\.com$'
|
||||
```
|
||||
|
||||
Tuwunel additionally implements [MSC4284 policy servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) for room-level federation gating; that lives in room state and needs no playbook configuration.
|
||||
|
||||
### Default room version
|
||||
|
||||
The role sets `default_room_version: '12'`, so newly created rooms default to Matrix [room version 12](https://github.com/matrix-org/matrix-spec-proposals/pull/4289) ("Hydra"). Override `matrix_tuwunel_config_default_room_version` if you need an earlier version for client compatibility.
|
||||
|
||||
## Creating the first user account
|
||||
|
||||
Unlike Synapse and Dendrite, Tuwunel does not register users from the command line or via the playbook. On first startup it logs a one-time-use registration token to its journal:
|
||||
|
||||
```sh
|
||||
# Adjust the duration if necessary or remove the --since argument.
|
||||
journalctl -u matrix-tuwunel.service --since="10 minutes ago"
|
||||
```
|
||||
|
||||
Use the token to create your first account from any client that supports token-gated registration (e.g. [Element Web](configuring-playbook-client-element-web.md)). The account is auto-promoted to admin and invited to the admin room together with the `@conduit:<server_name>` server bot. The bot keeps the legacy `conduit` localpart due to the project's lineage from Conduit.
|
||||
|
||||
## Configuring bridges and appservices
|
||||
|
||||
The playbook does not auto-register appservices for Tuwunel. After your bridge has produced its `registration.yaml` (e.g. `/matrix/mautrix-signal/bridge/registration.yaml`), register it manually by sending the contents to the admin room, prefixed with `!admin appservices register` and wrapped in a fenced code block:
|
||||
|
||||
!admin appservices register
|
||||
```
|
||||
id: signal
|
||||
url: http://matrix-mautrix-signal:29328
|
||||
as_token: <token>
|
||||
hs_token: <token>
|
||||
sender_localpart: _bot_signalbot
|
||||
rate_limited: false
|
||||
namespaces:
|
||||
users:
|
||||
- exclusive: true
|
||||
regex: '^@signal_.+:example\.org$'
|
||||
- exclusive: true
|
||||
regex: '^@signalbot:example\.org$'
|
||||
aliases:
|
||||
- exclusive: true
|
||||
regex: '^#signal_.+:example\.org$'
|
||||
```
|
||||
|
||||
Registrations stored this way are persisted in the database and survive restarts. Re-running the command with the same `id` replaces the existing entry. See [Application services](https://matrix-construct.github.io/tuwunel/appservices.html) for the full reference and admin commands.
|
||||
|
||||
## Migrating from conduwuit
|
||||
|
||||
Tuwunel is a "binary swap" for conduwuit; it reads conduwuit's RocksDB layout directly, so migration is a data move, not an export/import.
|
||||
|
||||
1. Set `matrix_homeserver_implementation: tuwunel` on `vars.yml` and remove any `matrix_conduwuit_*` overrides.
|
||||
2. Run a full installation so that the new service is created and the old one removed (e.g. `just setup-all`).
|
||||
3. Run `just run-tags tuwunel-migrate-from-conduwuit`.
|
||||
|
||||
The migration stops `matrix-conduwuit.service`, copies `/matrix/conduwuit` into `/matrix/tuwunel`, renames the config file, and starts `matrix-tuwunel.service`. The freshly generated tuwunel data directory is preserved alongside as `/matrix/tuwunel_old` until you remove it manually.
|
||||
|
||||
> [!CAUTION]
|
||||
> Migrating from any other Conduit derivative (Conduit itself, Continuwuity, or any other fork) is **not supported** and will corrupt your database. All Conduit forks share the same linear database version with no awareness of each other; switching between them produces unrecoverable damage. See the [upstream migration table](https://matrix-construct.github.io/tuwunel/#migrating-to-tuwunel).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
As with all other services, the logs are available via [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html):
|
||||
|
||||
```sh
|
||||
journalctl -fu matrix-tuwunel
|
||||
```
|
||||
|
||||
Logging verbosity is controlled by `matrix_tuwunel_config_log` in [`tracing-subscriber` env-filter syntax](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html). The default (`info,state_res=warn`) is reasonable for production; for debugging, try `debug` or scope it tighter, e.g. `info,tuwunel_service::sending=debug`.
|
||||
|
||||
For RocksDB-level issues, online backups, and offline backup procedures, see the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html). For protocol-compliance state across MSCs, the spec, and Complement, the project's [compliance dashboard](https://matrix-construct.github.io/tuwunel/development/compliance.html) is the authoritative tracker.
|
||||
@@ -53,6 +53,8 @@ For a more custom setup, see the [Other configuration options](#other-configurat
|
||||
|
||||
- [Configuring continuwuity](configuring-playbook-continuwuity.md), if you've switched to the [continuwuity](https://continuwuity.org) homeserver implementation
|
||||
|
||||
- [Configuring Tuwunel](configuring-playbook-tuwunel.md), if you've switched to the [Tuwunel](https://matrix-construct.github.io/tuwunel/) homeserver implementation
|
||||
|
||||
- [Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation
|
||||
|
||||
- Server components:
|
||||
|
||||
@@ -28,6 +28,7 @@ We try to stick to official images (provided by their respective projects) as mu
|
||||
| [Synapse](configuring-playbook-synapse.md) | [element-hq/synapse](https://ghcr.io/element-hq/synapse) | ✅ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network |
|
||||
| [Conduit](configuring-playbook-conduit.md) | [matrixconduit/matrix-conduit](https://hub.docker.com/r/matrixconduit/matrix-conduit) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Conduit is a lightweight open-source server implementation of the Matrix Specification with a focus on easy setup and low system requirements |
|
||||
| [continuwuity](configuring-playbook-continuwuity.md) | [continuwuation/continuwuity](https://forgejo.ellis.link/continuwuation/continuwuity) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. continuwuity is a continuation of conduwuit. |
|
||||
| [Tuwunel](configuring-playbook-tuwunel.md) | [matrix-construct/tuwunel](https://ghcr.io/matrix-construct/tuwunel) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit. |
|
||||
| [Dendrite](configuring-playbook-dendrite.md) | [matrixdotorg/dendrite-monolith](https://hub.docker.com/r/matrixdotorg/dendrite-monolith/) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse. |
|
||||
|
||||
## Clients
|
||||
|
||||
@@ -26,7 +26,7 @@ The up-to-date list can be accessed on [traefik's documentation](https://doc.tra
|
||||
|
||||
**Note**: the changes below instruct you how to do this for a basic Synapse installation. You will need to adapt the variable name and the content of the labels:
|
||||
|
||||
- if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md) or [Dendrite](./configuring-playbook-dendrite.md))
|
||||
- if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md), [Tuwunel](./configuring-playbook-tuwunel.md) or [Dendrite](./configuring-playbook-dendrite.md))
|
||||
- if you're using [Synapse with workers enabled](./configuring-playbook-synapse.md#load-balancing-with-workers) (`matrix_synapse_workers_enabled: true`). In that case, it's actually the `matrix-synapse-reverse-proxy-companion` service which has Traefik labels attached
|
||||
|
||||
Also, all instructions below are from an older version of the playbook and may not work anymore.
|
||||
|
||||
@@ -631,6 +631,7 @@ devture_systemd_service_manager_services_list_auto: |
|
||||
'restart_necessary': (
|
||||
(matrix_conduit_restart_necessary | bool) if matrix_homeserver_implementation == 'conduit'
|
||||
else (matrix_continuwuity_restart_necessary | bool) if matrix_homeserver_implementation == 'continuwuity'
|
||||
else (matrix_tuwunel_restart_necessary | bool) if matrix_homeserver_implementation == 'tuwunel'
|
||||
else (matrix_dendrite_restart_necessary | bool) if matrix_homeserver_implementation == 'dendrite'
|
||||
else true
|
||||
),
|
||||
@@ -1008,6 +1009,7 @@ matrix_homeserver_container_client_api_endpoint: |-
|
||||
'dendrite': ('matrix-dendrite:' + matrix_dendrite_http_bind_port | default('8008') | string),
|
||||
'conduit': ('matrix-conduit:' + matrix_conduit_port_number | default('8008') | string),
|
||||
'continuwuity': ('matrix-continuwuity:' + matrix_continuwuity_config_port_number | default('8008') | string),
|
||||
'tuwunel': ('matrix-tuwunel:' + matrix_tuwunel_config_port_number | default('8008') | string),
|
||||
}[matrix_homeserver_implementation]
|
||||
}}
|
||||
|
||||
@@ -1018,6 +1020,7 @@ matrix_homeserver_container_federation_api_endpoint: |-
|
||||
'dendrite': ('matrix-dendrite:' + matrix_dendrite_http_bind_port | default('8008') | string),
|
||||
'conduit': ('matrix-conduit:' + matrix_conduit_port_number | default('8008') | string),
|
||||
'continuwuity': ('matrix-continuwuity:' + matrix_continuwuity_config_port_number | default('8008') | string),
|
||||
'tuwunel': ('matrix-tuwunel:' + matrix_tuwunel_config_port_number | default('8008') | string),
|
||||
}[matrix_homeserver_implementation]
|
||||
}}
|
||||
|
||||
@@ -5558,6 +5561,7 @@ grafana_default_home_dashboard_path: |-
|
||||
'dendrite': ('/etc/grafana/dashboards/node-exporter-full.json' if prometheus_node_exporter_enabled else ''),
|
||||
'conduit': ('/etc/grafana/dashboards/node-exporter-full.json' if prometheus_node_exporter_enabled else ''),
|
||||
'continuwuity': ('/etc/grafana/dashboards/node-exporter-full.json' if prometheus_node_exporter_enabled else ''),
|
||||
'tuwunel': ('/etc/grafana/dashboards/node-exporter-full.json' if prometheus_node_exporter_enabled else ''),
|
||||
}[matrix_homeserver_implementation]
|
||||
}}
|
||||
|
||||
@@ -5618,6 +5622,7 @@ matrix_registration_shared_secret: |-
|
||||
'dendrite': matrix_dendrite_client_api_registration_shared_secret | default (''),
|
||||
'conduit': '',
|
||||
'continuwuity': '',
|
||||
'tuwunel': '',
|
||||
}[matrix_homeserver_implementation]
|
||||
}}
|
||||
|
||||
@@ -5843,6 +5848,67 @@ matrix_continuwuity_systemd_wanted_services_list_auto: |
|
||||
######################################################################
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# matrix-tuwunel
|
||||
#
|
||||
######################################################################
|
||||
|
||||
matrix_tuwunel_enabled: "{{ matrix_homeserver_implementation == 'tuwunel' }}"
|
||||
|
||||
matrix_tuwunel_hostname: "{{ matrix_server_fqn_matrix }}"
|
||||
|
||||
matrix_tuwunel_config_allow_federation: "{{ matrix_homeserver_federation_enabled }}"
|
||||
|
||||
matrix_tuwunel_config_well_known_client: "{{ matrix_homeserver_url if matrix_playbook_ssl_enabled else '' }}"
|
||||
|
||||
matrix_tuwunel_container_image_registry_prefix_upstream: "{{ matrix_container_global_registry_prefix_override if matrix_container_global_registry_prefix_override else matrix_tuwunel_container_image_registry_prefix_upstream_default }}"
|
||||
|
||||
matrix_tuwunel_container_network: "{{ matrix_homeserver_container_network }}"
|
||||
|
||||
matrix_tuwunel_container_additional_networks_auto: |
|
||||
{{
|
||||
(
|
||||
([matrix_playbook_reverse_proxyable_services_additional_network] if matrix_tuwunel_container_labels_traefik_enabled and matrix_playbook_reverse_proxyable_services_additional_network else [])
|
||||
) | unique
|
||||
}}
|
||||
|
||||
matrix_tuwunel_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and not matrix_synapse_workers_enabled }}"
|
||||
matrix_tuwunel_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}"
|
||||
matrix_tuwunel_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}"
|
||||
matrix_tuwunel_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}"
|
||||
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_enabled: "{{ matrix_tuwunel_container_labels_public_client_root_redirection_url != '' }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_url: "{{ (('https://' if matrix_playbook_ssl_enabled else 'http://') + matrix_server_fqn_element) if matrix_client_element_enabled else '' }}"
|
||||
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_hostname: "{{ matrix_server_fqn_matrix_federation }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints: "{{ matrix_federation_traefik_entrypoint_name }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_tls: "{{ matrix_federation_traefik_entrypoint_tls }}"
|
||||
|
||||
matrix_tuwunel_container_labels_internal_client_api_enabled: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled }}"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_name }}"
|
||||
|
||||
matrix_tuwunel_config_well_known_livekit_url: "{{ matrix_livekit_jwt_service_public_url if matrix_livekit_jwt_service_enabled else '' }}"
|
||||
|
||||
matrix_tuwunel_config_turn_uris: "{{ coturn_turn_uris if coturn_enabled else [] }}"
|
||||
matrix_tuwunel_config_turn_secret: "{{ coturn_turn_static_auth_secret if (coturn_enabled and coturn_authentication_method == 'auth-secret') else '' }}"
|
||||
matrix_tuwunel_config_turn_username: "{{ coturn_lt_cred_mech_username if (coturn_enabled and coturn_authentication_method == 'lt-cred-mech') else '' }}"
|
||||
matrix_tuwunel_config_turn_password: "{{ coturn_lt_cred_mech_password if (coturn_enabled and coturn_authentication_method == 'lt-cred-mech') else '' }}"
|
||||
|
||||
matrix_tuwunel_self_check_validate_certificates: "{{ matrix_playbook_ssl_enabled }}"
|
||||
|
||||
matrix_tuwunel_systemd_wanted_services_list_auto: |
|
||||
{{
|
||||
([coturn_identifier ~ '.service'] if coturn_enabled else [])
|
||||
}}
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# /matrix-tuwunel
|
||||
#
|
||||
######################################################################
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# matrix-user-creator
|
||||
|
||||
@@ -84,7 +84,7 @@ matrix_monitoring_container_network: matrix-monitoring
|
||||
matrix_homeserver_enabled: true
|
||||
|
||||
# This will contain the homeserver implementation that is in use.
|
||||
# Valid values: synapse, dendrite, conduit, continuwuity
|
||||
# Valid values: synapse, dendrite, conduit, continuwuity, tuwunel
|
||||
#
|
||||
# By default, we use Synapse, because it's the only full-featured Matrix server at the moment.
|
||||
#
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- name: Fail if invalid homeserver implementation
|
||||
ansible.builtin.fail:
|
||||
msg: "You need to set a valid homeserver implementation in `matrix_homeserver_implementation`"
|
||||
when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity']"
|
||||
when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity', 'tuwunel']"
|
||||
|
||||
- name: (Deprecation) Catch and report renamed settings
|
||||
ansible.builtin.fail:
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
# Tuwunel is a Matrix homeserver, the official successor to conduwuit.
|
||||
# Project source code URL: https://github.com/matrix-construct/tuwunel
|
||||
# See: https://matrix-construct.github.io/tuwunel/
|
||||
|
||||
matrix_tuwunel_enabled: true
|
||||
|
||||
matrix_tuwunel_hostname: ''
|
||||
|
||||
# renovate: datasource=docker depName=ghcr.io/matrix-construct/tuwunel
|
||||
matrix_tuwunel_version: latest
|
||||
|
||||
matrix_tuwunel_container_image: "{{ matrix_tuwunel_container_image_registry_prefix }}matrix-construct/tuwunel:{{ matrix_tuwunel_container_image_tag }}"
|
||||
matrix_tuwunel_container_image_tag: "{{ matrix_tuwunel_version }}"
|
||||
matrix_tuwunel_container_image_registry_prefix: "{{ matrix_tuwunel_container_image_registry_prefix_upstream }}"
|
||||
matrix_tuwunel_container_image_registry_prefix_upstream: "{{ matrix_tuwunel_container_image_registry_prefix_upstream_default }}"
|
||||
matrix_tuwunel_container_image_registry_prefix_upstream_default: ghcr.io/
|
||||
|
||||
matrix_tuwunel_base_path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
matrix_tuwunel_config_path: "{{ matrix_tuwunel_base_path }}/config"
|
||||
matrix_tuwunel_data_path: "{{ matrix_tuwunel_base_path }}/data"
|
||||
|
||||
matrix_tuwunel_config_port_number: 6167
|
||||
|
||||
matrix_tuwunel_tmp_directory_size_mb: 500
|
||||
|
||||
# List of systemd services that matrix-tuwunel.service depends on
|
||||
matrix_tuwunel_systemd_required_services_list: "{{ matrix_tuwunel_systemd_required_services_list_default + matrix_tuwunel_systemd_required_services_list_auto + matrix_tuwunel_systemd_required_services_list_custom }}"
|
||||
matrix_tuwunel_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}"
|
||||
matrix_tuwunel_systemd_required_services_list_auto: []
|
||||
matrix_tuwunel_systemd_required_services_list_custom: []
|
||||
|
||||
# List of systemd services that matrix-tuwunel.service wants
|
||||
matrix_tuwunel_systemd_wanted_services_list: "{{ matrix_tuwunel_systemd_wanted_services_list_default + matrix_tuwunel_systemd_wanted_services_list_auto + matrix_tuwunel_systemd_wanted_services_list_custom }}"
|
||||
matrix_tuwunel_systemd_wanted_services_list_default: []
|
||||
matrix_tuwunel_systemd_wanted_services_list_auto: []
|
||||
matrix_tuwunel_systemd_wanted_services_list_custom: []
|
||||
|
||||
# Controls how long to sleep for after starting the matrix-tuwunel container,
|
||||
# so that subsequent services that depend on it can start after the homeserver
|
||||
# is fully up.
|
||||
#
|
||||
# Set to 0 to remove the delay.
|
||||
matrix_tuwunel_systemd_service_post_start_delay_seconds: 3
|
||||
|
||||
# The base container network. It will be auto-created by this role if it doesn't exist already.
|
||||
matrix_tuwunel_container_network: ""
|
||||
|
||||
# A list of additional container networks that the container would be connected to.
|
||||
# The role does not create these networks, so make sure they already exist.
|
||||
# Use this to expose this container to another reverse proxy, which runs in a different container network.
|
||||
matrix_tuwunel_container_additional_networks: "{{ matrix_tuwunel_container_additional_networks_auto + matrix_tuwunel_container_additional_networks_custom }}"
|
||||
matrix_tuwunel_container_additional_networks_auto: []
|
||||
matrix_tuwunel_container_additional_networks_custom: []
|
||||
|
||||
# matrix_tuwunel_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container.
|
||||
# See `../templates/labels.j2` for details.
|
||||
#
|
||||
# To inject your own other container labels, see `matrix_tuwunel_container_labels_additional_labels`.
|
||||
matrix_tuwunel_container_labels_traefik_enabled: true
|
||||
matrix_tuwunel_container_labels_traefik_docker_network: "{{ matrix_tuwunel_container_network }}"
|
||||
matrix_tuwunel_container_labels_traefik_entrypoints: web-secure
|
||||
matrix_tuwunel_container_labels_traefik_tls_certResolver: default # noqa var-naming
|
||||
|
||||
# Controls whether labels will be added for handling the root (/) path on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_client_root_enabled: true
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_root_traefik_hostname }}`) && Path(`/`)"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints != 'web' }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_enabled: false
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_url: ""
|
||||
|
||||
# Controls whether labels will be added that expose the Client-Server API on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_client_api_enabled: true
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix: /_matrix
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints != 'web' }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
|
||||
# Controls whether labels will be added that expose the Client-Server API on the internal Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_internal_client_api_enabled: false
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_rule: "PathPrefix(`{{ matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_priority: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }}"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints: ""
|
||||
|
||||
# Controls whether labels will be added that expose the Server-Server (Federation) API on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_federation_api_enabled: "{{ matrix_tuwunel_config_allow_federation }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix: /_matrix
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints: ''
|
||||
# TLS is force-enabled because the spec (https://spec.matrix.org/latest/server-server-api/#tls) requires the federation API use HTTPS.
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_tls: true
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
|
||||
# Additional Docker container labels (multiline string) appended verbatim to the label file.
|
||||
# See `../templates/labels.j2`.
|
||||
matrix_tuwunel_container_labels_additional_labels: ''
|
||||
|
||||
# Extra arguments for the Docker container
|
||||
matrix_tuwunel_container_extra_arguments: []
|
||||
|
||||
# Specifies which template files to use when configuring tuwunel.
|
||||
# To override the rendered config wholesale, copy the template into your inventory and point this at it:
|
||||
# matrix_tuwunel_template_tuwunel_config: "{{ playbook_dir }}/inventory/host_vars/matrix.example.com/tuwunel.toml.j2"
|
||||
matrix_tuwunel_template_tuwunel_config: "{{ role_path }}/templates/tuwunel.toml.j2"
|
||||
|
||||
# The pretty server name used as a suffix on user/room IDs. Cannot be changed after first start without a database wipe.
|
||||
matrix_tuwunel_config_server_name: "{{ matrix_domain }}"
|
||||
|
||||
# Max size for uploads, in bytes
|
||||
matrix_tuwunel_config_max_request_size: 20000000
|
||||
|
||||
# Enables open registration. If false, no users can register on this server.
|
||||
matrix_tuwunel_config_allow_registration: false
|
||||
|
||||
# When registration is enabled, set a strong token to protect the endpoint from abuse.
|
||||
# Generate one with e.g. `pwgen -s 64 1`. If left empty AND `allow_registration` is true,
|
||||
# you must explicitly opt in via the open-registration acknowledgement variable below.
|
||||
matrix_tuwunel_config_registration_token: ''
|
||||
|
||||
# Acknowledgement required to allow registration with no token.
|
||||
# Maps to tuwunel's `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`.
|
||||
matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse: false
|
||||
|
||||
# Suffix appended to new-user displaynames upon registration. Empty disables it.
|
||||
# Upstream defaults to a flag glyph; we keep MDAD homeserver behavior consistent and leave this empty.
|
||||
matrix_tuwunel_config_new_user_displayname_suffix: ""
|
||||
|
||||
# Emergency password to grant access to the admin user when locked out. Empty disables.
|
||||
matrix_tuwunel_config_emergency_password: ''
|
||||
|
||||
# Trusted notary servers used for key verification.
|
||||
matrix_tuwunel_config_trusted_servers:
|
||||
- "matrix.org"
|
||||
|
||||
# Logging directives in `tracing-subscriber` env-filter syntax.
|
||||
matrix_tuwunel_config_log: "info,state_res=warn"
|
||||
|
||||
# TURN integration
|
||||
matrix_tuwunel_config_turn_uris: []
|
||||
matrix_tuwunel_config_turn_secret: ''
|
||||
matrix_tuwunel_config_turn_username: ''
|
||||
matrix_tuwunel_config_turn_password: ''
|
||||
|
||||
# Self-check toggles
|
||||
matrix_tuwunel_self_check_validate_certificates: true
|
||||
|
||||
# Encryption / room creation policy
|
||||
matrix_tuwunel_config_allow_encryption: true
|
||||
matrix_tuwunel_config_allow_room_creation: true
|
||||
|
||||
# Default room version newly created rooms will use.
|
||||
matrix_tuwunel_config_default_room_version: '12'
|
||||
|
||||
# Rooms newly registered users will be auto-joined to.
|
||||
# Must be rooms this server has joined at least once and that are public.
|
||||
matrix_tuwunel_config_auto_join_rooms: []
|
||||
|
||||
# (De)federation toggles
|
||||
matrix_tuwunel_config_allow_federation: true
|
||||
matrix_tuwunel_config_allowed_remote_server_names: []
|
||||
matrix_tuwunel_config_forbidden_remote_server_names: []
|
||||
matrix_tuwunel_config_forbidden_remote_room_directory_server_names: []
|
||||
matrix_tuwunel_config_prevent_media_downloads_from: []
|
||||
|
||||
# Outgoing presence is heavy on CPU and network and almost no clients use it. Off by default.
|
||||
matrix_tuwunel_config_allow_outgoing_presence: false
|
||||
|
||||
# URL preview gating
|
||||
matrix_tuwunel_config_url_preview_domain_contains_allowlist: []
|
||||
matrix_tuwunel_config_url_preview_domain_explicit_allowlist: []
|
||||
matrix_tuwunel_config_url_preview_check_root_domain: false
|
||||
|
||||
# Well-known overrides
|
||||
# Maps to `[global.well_known] client = "..."` and `server = "host:port"`.
|
||||
matrix_tuwunel_config_well_known_client: ''
|
||||
matrix_tuwunel_config_well_known_server: ''
|
||||
matrix_tuwunel_config_well_known_support_page: ''
|
||||
matrix_tuwunel_config_well_known_support_email: ''
|
||||
matrix_tuwunel_config_well_known_support_mxid: ''
|
||||
|
||||
# MatrixRTC foci served via /_matrix/client/v1/rtc/transports (MSC4143)
|
||||
matrix_tuwunel_config_well_known_livekit_url: ''
|
||||
|
||||
# RocksDB tuning. Empty values let tuwunel auto-pick.
|
||||
matrix_tuwunel_config_rocksdb_compression_algo: 'zstd' # one of: zstd, lz4, bz2, none
|
||||
matrix_tuwunel_config_rocksdb_compression_level: ''
|
||||
matrix_tuwunel_config_rocksdb_bottommost_compression_level: ''
|
||||
matrix_tuwunel_config_rocksdb_direct_io: false
|
||||
matrix_tuwunel_config_rocksdb_parallelism_threads: 0
|
||||
matrix_tuwunel_config_rocksdb_max_log_file_size: ''
|
||||
matrix_tuwunel_config_rocksdb_log_time_to_roll: ''
|
||||
matrix_tuwunel_config_database_backup_path: ''
|
||||
matrix_tuwunel_config_database_backups_to_keep: 1
|
||||
|
||||
# Cache sizing. Empty values let tuwunel auto-pick (scaled by CPU count).
|
||||
matrix_tuwunel_config_cache_capacity_modifier: ''
|
||||
matrix_tuwunel_config_db_cache_capacity_mb: ''
|
||||
matrix_tuwunel_config_db_write_buffer_capacity_mb: ''
|
||||
|
||||
# Admin room
|
||||
matrix_tuwunel_config_create_admin_room: true
|
||||
matrix_tuwunel_config_federate_admin_room: false
|
||||
matrix_tuwunel_config_grant_admin_to_first_user: true
|
||||
|
||||
# Sentry crash/error reporting (off by default)
|
||||
matrix_tuwunel_config_sentry_enabled: false
|
||||
matrix_tuwunel_config_sentry_endpoint: ''
|
||||
matrix_tuwunel_config_sentry_send_server_name: false
|
||||
matrix_tuwunel_config_sentry_traces_sample_rate: 0.15
|
||||
|
||||
# Blurhashing for image previews
|
||||
matrix_tuwunel_config_blurhashing_enabled: true
|
||||
matrix_tuwunel_config_blurhashing_components_x: 4
|
||||
matrix_tuwunel_config_blurhashing_components_y: 3
|
||||
matrix_tuwunel_config_blurhashing_max_raw_size: 33554432
|
||||
|
||||
# Native TLS (use only when reverse-proxying is not desired)
|
||||
matrix_tuwunel_config_tls_certs: ''
|
||||
matrix_tuwunel_config_tls_key: ''
|
||||
matrix_tuwunel_config_tls_dual_protocol: false
|
||||
|
||||
# LDAP authentication ([global.ldap] in tuwunel.toml).
|
||||
# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html
|
||||
matrix_tuwunel_config_ldap_enabled: false
|
||||
matrix_tuwunel_config_ldap_uri: ''
|
||||
matrix_tuwunel_config_ldap_base_dn: ''
|
||||
matrix_tuwunel_config_ldap_bind_dn: ''
|
||||
matrix_tuwunel_config_ldap_bind_password_file: ''
|
||||
matrix_tuwunel_config_ldap_filter: '(objectClass=*)'
|
||||
matrix_tuwunel_config_ldap_uid_attribute: 'uid'
|
||||
matrix_tuwunel_config_ldap_name_attribute: 'givenName'
|
||||
matrix_tuwunel_config_ldap_admin_base_dn: ''
|
||||
matrix_tuwunel_config_ldap_admin_filter: ''
|
||||
|
||||
# JWT authentication ([global.jwt] in tuwunel.toml).
|
||||
matrix_tuwunel_config_jwt_enabled: false
|
||||
matrix_tuwunel_config_jwt_key: ''
|
||||
matrix_tuwunel_config_jwt_format: 'HMAC' # one of: HMAC, B64HMAC, ECDSA, EDDSA
|
||||
matrix_tuwunel_config_jwt_algorithm: 'HS256'
|
||||
matrix_tuwunel_config_jwt_register_user: true
|
||||
matrix_tuwunel_config_jwt_audience: []
|
||||
matrix_tuwunel_config_jwt_issuer: []
|
||||
matrix_tuwunel_config_jwt_require_exp: false
|
||||
matrix_tuwunel_config_jwt_require_nbf: false
|
||||
matrix_tuwunel_config_jwt_validate_exp: true
|
||||
matrix_tuwunel_config_jwt_validate_nbf: true
|
||||
|
||||
# OAuth2/OIDC identity providers.
|
||||
#
|
||||
# Each entry becomes a `[[global.identity_provider]]` block. Only fields you set are emitted;
|
||||
# tuwunel applies brand-aware defaults for known providers (Google, GitHub, Keycloak, MAS, etc).
|
||||
#
|
||||
# Example:
|
||||
# matrix_tuwunel_config_identity_providers:
|
||||
# - brand: keycloak
|
||||
# client_id: matrix
|
||||
# client_secret: '...'
|
||||
# issuer_url: https://sso.example.com/realms/matrix
|
||||
# callback_url: https://matrix.example.com/_matrix/client/unstable/login/sso/callback/matrix
|
||||
# trusted: true
|
||||
# - brand: github
|
||||
# client_id: '...'
|
||||
# client_secret: '...'
|
||||
#
|
||||
# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html
|
||||
matrix_tuwunel_config_identity_providers: []
|
||||
|
||||
# Media storage providers.
|
||||
#
|
||||
# Each entry maps an ID to a backend. `kind` is `local` or `s3`; remaining keys map directly
|
||||
# to fields under `[global.storage_provider.<ID>.<kind>]`.
|
||||
#
|
||||
# Examples:
|
||||
# matrix_tuwunel_config_storage_providers:
|
||||
# - id: primary
|
||||
# kind: local
|
||||
# base_path: /var/lib/tuwunel/media
|
||||
# - id: archive
|
||||
# kind: s3
|
||||
# url: s3://my-bucket/media
|
||||
# region: us-east-1
|
||||
# key: AKIA...
|
||||
# secret: '...'
|
||||
#
|
||||
# See: https://matrix-construct.github.io/tuwunel/media/storage.html
|
||||
matrix_tuwunel_config_storage_providers: []
|
||||
|
||||
# Additional environment variables to pass to the container, one per line.
|
||||
# Environment variables override the rendered config file.
|
||||
#
|
||||
# Example:
|
||||
# matrix_tuwunel_environment_variables_extension: |
|
||||
# TUWUNEL_REQUEST_TIMEOUT=60
|
||||
# TUWUNEL_DNS_CACHE_SIZE=131072
|
||||
matrix_tuwunel_environment_variables_extension: ''
|
||||
|
||||
# matrix_tuwunel_restart_necessary controls whether the service will be restarted (when true)
|
||||
# or merely started (when false) by the systemd service-manager role when conditional restart
|
||||
# is enabled. Computed during installation based on whether config / unit / image changed.
|
||||
matrix_tuwunel_restart_necessary: false
|
||||
@@ -0,0 +1,76 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Ensure tuwunel config path exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_tuwunel_config_path }}"
|
||||
state: directory
|
||||
mode: '0750'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
|
||||
- name: Ensure tuwunel data path exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_tuwunel_data_path }}"
|
||||
state: directory
|
||||
mode: '0770'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
|
||||
- name: Ensure tuwunel configuration installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ matrix_tuwunel_template_tuwunel_config }}"
|
||||
dest: "{{ matrix_tuwunel_config_path }}/tuwunel.toml"
|
||||
mode: '0644'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
register: matrix_tuwunel_config_result
|
||||
|
||||
- name: Ensure tuwunel support files installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/{{ item }}.j2"
|
||||
dest: "{{ matrix_tuwunel_base_path }}/{{ item }}"
|
||||
mode: '0640'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
with_items:
|
||||
- labels
|
||||
- env
|
||||
register: matrix_tuwunel_support_files_result
|
||||
|
||||
- name: Ensure tuwunel container network is created
|
||||
community.general.docker_network:
|
||||
enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}"
|
||||
name: "{{ matrix_tuwunel_container_network }}"
|
||||
driver: bridge
|
||||
driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}"
|
||||
|
||||
- name: Ensure tuwunel container image is pulled
|
||||
community.docker.docker_image_pull:
|
||||
name: "{{ matrix_tuwunel_container_image }}"
|
||||
pull: always
|
||||
register: matrix_tuwunel_container_image_pull_result
|
||||
retries: "{{ devture_playbook_help_container_retries_count }}"
|
||||
delay: "{{ devture_playbook_help_container_retries_delay }}"
|
||||
until: matrix_tuwunel_container_image_pull_result is not failed
|
||||
|
||||
- name: Ensure matrix-tuwunel.service installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/systemd/matrix-tuwunel.service.j2"
|
||||
dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
mode: '0644'
|
||||
register: matrix_tuwunel_systemd_service_result
|
||||
|
||||
- name: Determine whether tuwunel needs a restart
|
||||
ansible.builtin.set_fact:
|
||||
matrix_tuwunel_restart_necessary: >-
|
||||
{{
|
||||
matrix_tuwunel_config_result.changed | default(false)
|
||||
or matrix_tuwunel_support_files_result.changed | default(false)
|
||||
or matrix_tuwunel_systemd_service_result.changed | default(false)
|
||||
or matrix_tuwunel_container_image_pull_result.changed | default(false)
|
||||
}}
|
||||
@@ -0,0 +1,40 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- tags:
|
||||
- setup-all
|
||||
- setup-tuwunel
|
||||
- install-all
|
||||
- install-tuwunel
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml"
|
||||
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml"
|
||||
|
||||
- tags:
|
||||
- setup-all
|
||||
- setup-tuwunel
|
||||
block:
|
||||
- when: not matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml"
|
||||
|
||||
- tags:
|
||||
- self-check
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_client_api.yml"
|
||||
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_federation_api.yml"
|
||||
|
||||
- tags:
|
||||
- tuwunel-migrate-from-conduwuit
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/migrate_from_conduwuit.yml"
|
||||
@@ -0,0 +1,83 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
# Migrates from the conduwuit server implementation (`/matrix/conduwuit`) to tuwunel (`/matrix/tuwunel`).
|
||||
# Tuwunel is the official successor to conduwuit and reads conduwuit's RocksDB layout directly.
|
||||
# We back up the freshly generated tuwunel directory, copy conduwuit's data into it,
|
||||
# rename the config file, restore tuwunel's labels file, and start the new service.
|
||||
|
||||
- name: Check existence of conduwuit directory
|
||||
ansible.builtin.stat:
|
||||
path: "{{ matrix_base_data_path }}/conduwuit"
|
||||
register: matrix_removed_conduwuit_directory_stat
|
||||
|
||||
- name: Check existence of tuwunel directory
|
||||
ansible.builtin.stat:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
register: matrix_tuwunel_directory_stat
|
||||
|
||||
- when: >
|
||||
matrix_removed_conduwuit_directory_stat.stat.exists | bool and
|
||||
matrix_tuwunel_directory_stat.stat.exists | bool
|
||||
block:
|
||||
- name: Ensure matrix-tuwunel.service systemd service is stopped
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: stopped
|
||||
enabled: false
|
||||
daemon_reload: true
|
||||
|
||||
- name: Ensure tuwunel directory is backed up
|
||||
ansible.builtin.command:
|
||||
cmd: "mv {{ matrix_base_data_path }}/tuwunel {{ matrix_base_data_path }}/tuwunel_old"
|
||||
creates: "{{ matrix_base_data_path }}/tuwunel_old"
|
||||
removes: "{{ matrix_base_data_path }}/tuwunel"
|
||||
|
||||
- name: Ensure conduwuit directory contents are copied to tuwunel
|
||||
ansible.builtin.copy:
|
||||
src: "{{ matrix_base_data_path }}/conduwuit/"
|
||||
dest: "{{ matrix_base_data_path }}/tuwunel"
|
||||
remote_src: true
|
||||
mode: preserve
|
||||
|
||||
- name: Ensure conduwuit.toml file is renamed
|
||||
ansible.builtin.command:
|
||||
cmd: "mv {{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml {{ matrix_base_data_path }}/tuwunel/config/tuwunel.toml"
|
||||
removes: "{{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml"
|
||||
|
||||
- name: Ensure tuwunel labels are restored
|
||||
ansible.builtin.copy:
|
||||
src: "{{ matrix_base_data_path }}/tuwunel_old/labels"
|
||||
dest: "{{ matrix_base_data_path }}/tuwunel/labels"
|
||||
remote_src: true
|
||||
force: true
|
||||
mode: preserve
|
||||
|
||||
- name: Ensure directories ownership is set
|
||||
block:
|
||||
- name: Set tuwunel ownership
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
state: directory
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
recurse: true
|
||||
|
||||
- name: Set tuwunel_old ownership
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel_old"
|
||||
state: directory
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
recurse: true
|
||||
|
||||
- name: Ensure matrix-tuwunel.service systemd service is started
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
@@ -0,0 +1,28 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check Matrix Client API
|
||||
ansible.builtin.uri:
|
||||
url: "{{ matrix_tuwunel_client_api_url_endpoint_public }}"
|
||||
follow_redirects: none
|
||||
validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}"
|
||||
register: result_matrix_tuwunel_client_api
|
||||
ignore_errors: true
|
||||
check_mode: false
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
delegate_to: 127.0.0.1
|
||||
become: false
|
||||
|
||||
- name: Fail if Matrix Client API not working
|
||||
ansible.builtin.fail:
|
||||
msg: "Failed checking Matrix Client API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`). Is tuwunel running? Is port 443 open in your firewall? Full error: {{ result_matrix_tuwunel_client_api }}"
|
||||
when: "matrix_tuwunel_enabled | bool and (result_matrix_tuwunel_client_api.failed or 'json' not in result_matrix_tuwunel_client_api)"
|
||||
|
||||
- name: Report working Matrix Client API
|
||||
ansible.builtin.debug:
|
||||
msg: "The Matrix Client API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`) is working"
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
@@ -0,0 +1,33 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check Matrix Federation API
|
||||
ansible.builtin.uri:
|
||||
url: "{{ matrix_tuwunel_federation_api_url_endpoint_public }}"
|
||||
follow_redirects: none
|
||||
validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}"
|
||||
register: result_matrix_tuwunel_federation_api
|
||||
ignore_errors: true
|
||||
check_mode: false
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
delegate_to: 127.0.0.1
|
||||
become: false
|
||||
|
||||
- name: Fail if Matrix Federation API not working
|
||||
ansible.builtin.fail:
|
||||
msg: "Failed checking Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`). Is tuwunel running? Is port {{ matrix_federation_public_port }} open in your firewall? Full error: {{ result_matrix_tuwunel_federation_api }}"
|
||||
when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool and (result_matrix_tuwunel_federation_api.failed or 'json' not in result_matrix_tuwunel_federation_api)"
|
||||
|
||||
- name: Fail if Matrix Federation API unexpectedly enabled
|
||||
ansible.builtin.fail:
|
||||
msg: "Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) despite being disabled."
|
||||
when: "matrix_tuwunel_enabled | bool and not matrix_tuwunel_config_allow_federation | bool and not result_matrix_tuwunel_federation_api.failed"
|
||||
|
||||
- name: Report working Matrix Federation API
|
||||
ansible.builtin.debug:
|
||||
msg: "The Matrix Federation API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) is working"
|
||||
when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool"
|
||||
@@ -0,0 +1,8 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml"
|
||||
@@ -0,0 +1,8 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml"
|
||||
@@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check existence of matrix-tuwunel service
|
||||
ansible.builtin.stat:
|
||||
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
register: matrix_tuwunel_service_stat
|
||||
|
||||
- when: matrix_tuwunel_service_stat.stat.exists | bool
|
||||
block:
|
||||
- name: Ensure matrix-tuwunel is stopped
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: stopped
|
||||
daemon_reload: true
|
||||
|
||||
- name: Ensure matrix-tuwunel.service doesn't exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
state: absent
|
||||
@@ -0,0 +1,44 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Fail if required tuwunel settings not defined
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
You need to define a required configuration setting (`{{ item.name }}`).
|
||||
when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0"
|
||||
with_items:
|
||||
- {'name': 'matrix_tuwunel_hostname', when: true}
|
||||
- {'name': 'matrix_tuwunel_container_network', when: true}
|
||||
- {'name': 'matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints', when: "{{ matrix_tuwunel_container_labels_internal_client_api_enabled }}"}
|
||||
|
||||
- name: Fail if registration is enabled without a token or explicit acknowledgement
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
`matrix_tuwunel_config_allow_registration` is true, but neither
|
||||
`matrix_tuwunel_config_registration_token` nor
|
||||
`matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`
|
||||
is set. Set a registration token (recommended) or explicitly opt in to open registration.
|
||||
when: >-
|
||||
matrix_tuwunel_config_allow_registration | bool
|
||||
and (matrix_tuwunel_config_registration_token | length == 0)
|
||||
and not (matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool)
|
||||
|
||||
- name: Fail if a storage provider is missing required fields
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Storage provider `{{ item.id | default('?') }}` is missing required fields.
|
||||
Each entry must define both `id` and `kind` (one of: local, s3).
|
||||
when: "(item.id | default('') | length == 0) or (item.kind | default('') not in ['local', 's3'])"
|
||||
with_items: "{{ matrix_tuwunel_config_storage_providers }}"
|
||||
|
||||
- name: Fail if an identity provider is missing required fields
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Identity provider entry is missing both `client_id` and `brand`.
|
||||
At minimum one of these is required for tuwunel to identify the provider.
|
||||
when: "(item.client_id | default('') | length == 0) and (item.brand | default('') | length == 0)"
|
||||
with_items: "{{ matrix_tuwunel_config_identity_providers }}"
|
||||
@@ -0,0 +1 @@
|
||||
{{ matrix_tuwunel_environment_variables_extension }}
|
||||
@@ -0,0 +1,4 @@
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
@@ -0,0 +1,141 @@
|
||||
{#
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_traefik_enabled %}
|
||||
traefik.enable=true
|
||||
|
||||
{% if matrix_tuwunel_container_labels_traefik_docker_network %}
|
||||
traefik.docker.network={{ matrix_tuwunel_container_labels_traefik_docker_network }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.services.matrix-tuwunel.loadbalancer.server.port={{ matrix_tuwunel_config_port_number }}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Root path (/) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
{% set client_root_middlewares = [] %}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_redirection_enabled %}
|
||||
{% set client_root_middlewares = client_root_middlewares + ['matrix-tuwunel-client-root-redirect'] %}
|
||||
traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.regex=(.*)
|
||||
traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.replacement={{ matrix_tuwunel_container_labels_public_client_root_redirection_url }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.rule={{ matrix_tuwunel_container_labels_public_client_root_traefik_rule }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.middlewares={{ client_root_middlewares | join(',') }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.priority={{ matrix_tuwunel_container_labels_public_client_root_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.entrypoints={{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints }}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.tls={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Root path (/) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.rule={{ matrix_tuwunel_container_labels_public_client_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.priority={{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.entrypoints={{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.tls={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls | to_json }}
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_internal_client_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Internal Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.rule={{ matrix_tuwunel_container_labels_internal_client_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_internal_client_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.priority={{ matrix_tuwunel_container_labels_internal_client_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.entrypoints={{ matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints }}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Internal Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Federation-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.rule={{ matrix_tuwunel_container_labels_public_federation_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.priority={{ matrix_tuwunel_container_labels_public_federation_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.entrypoints={{ matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.tls={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls | to_json }}
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Federation-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{{ matrix_tuwunel_container_labels_additional_labels }}
|
||||
@@ -0,0 +1,55 @@
|
||||
#jinja2: lstrip_blocks: True
|
||||
[Unit]
|
||||
Description=Tuwunel Matrix homeserver
|
||||
{% for service in matrix_tuwunel_systemd_required_services_list %}
|
||||
Requires={{ service }}
|
||||
After={{ service }}
|
||||
{% endfor %}
|
||||
{% for service in matrix_tuwunel_systemd_wanted_services_list %}
|
||||
Wants={{ service }}
|
||||
{% endfor %}
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}"
|
||||
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true'
|
||||
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true'
|
||||
|
||||
ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \
|
||||
--rm \
|
||||
--name=matrix-tuwunel \
|
||||
--log-driver=none \
|
||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||
--cap-drop=ALL \
|
||||
--read-only \
|
||||
--tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_tuwunel_tmp_directory_size_mb }}m \
|
||||
--network={{ matrix_tuwunel_container_network }} \
|
||||
--env-file={{ matrix_tuwunel_base_path }}/env \
|
||||
--env TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml \
|
||||
--label-file={{ matrix_tuwunel_base_path }}/labels \
|
||||
--mount type=bind,src={{ matrix_tuwunel_data_path }},dst=/var/lib/tuwunel \
|
||||
--mount type=bind,src={{ matrix_tuwunel_config_path }},dst=/etc/tuwunel,ro \
|
||||
{% for arg in matrix_tuwunel_container_extra_arguments %}
|
||||
{{ arg }} \
|
||||
{% endfor %}
|
||||
{{ matrix_tuwunel_container_image }}
|
||||
|
||||
{% for network in matrix_tuwunel_container_additional_networks %}
|
||||
ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-tuwunel
|
||||
{% endfor %}
|
||||
|
||||
ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-tuwunel
|
||||
|
||||
{% if matrix_tuwunel_systemd_service_post_start_delay_seconds != 0 %}
|
||||
ExecStartPost=-{{ matrix_host_command_sleep }} {{ matrix_tuwunel_systemd_service_post_start_delay_seconds }}
|
||||
{% endif %}
|
||||
|
||||
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true'
|
||||
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true'
|
||||
ExecReload={{ devture_systemd_docker_base_host_command_docker }} exec matrix-tuwunel /bin/sh -c 'kill -HUP 1'
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
SyslogIdentifier=matrix-tuwunel
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,4 @@
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
@@ -0,0 +1,238 @@
|
||||
{#
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
### Tuwunel configuration rendered by matrix-docker-ansible-deploy.
|
||||
###
|
||||
### This file only emits options exposed as Ansible variables. All other knobs
|
||||
### keep tuwunel's upstream defaults. To override anything not surfaced here,
|
||||
### use `matrix_tuwunel_environment_variables_extension` (env vars override TOML)
|
||||
### or replace the template via `matrix_tuwunel_template_tuwunel_config`.
|
||||
###
|
||||
### Reference: https://matrix-construct.github.io/tuwunel/configuration.html
|
||||
|
||||
[global]
|
||||
server_name = {{ matrix_tuwunel_config_server_name | to_json }}
|
||||
address = "0.0.0.0"
|
||||
port = {{ matrix_tuwunel_config_port_number }}
|
||||
database_path = "/var/lib/tuwunel"
|
||||
|
||||
max_request_size = {{ matrix_tuwunel_config_max_request_size }}
|
||||
|
||||
new_user_displayname_suffix = {{ matrix_tuwunel_config_new_user_displayname_suffix | to_json }}
|
||||
|
||||
allow_registration = {{ matrix_tuwunel_config_allow_registration | to_json }}
|
||||
{% if matrix_tuwunel_config_registration_token | length > 0 %}
|
||||
registration_token = {{ matrix_tuwunel_config_registration_token | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool %}
|
||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_emergency_password | length > 0 %}
|
||||
emergency_password = {{ matrix_tuwunel_config_emergency_password | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_encryption = {{ matrix_tuwunel_config_allow_encryption | to_json }}
|
||||
allow_room_creation = {{ matrix_tuwunel_config_allow_room_creation | to_json }}
|
||||
default_room_version = {{ matrix_tuwunel_config_default_room_version | to_json }}
|
||||
{% if matrix_tuwunel_config_auto_join_rooms | length > 0 %}
|
||||
auto_join_rooms = {{ matrix_tuwunel_config_auto_join_rooms | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_federation = {{ matrix_tuwunel_config_allow_federation | to_json }}
|
||||
trusted_servers = {{ matrix_tuwunel_config_trusted_servers | to_json }}
|
||||
{% if matrix_tuwunel_config_allowed_remote_server_names | length > 0 %}
|
||||
allowed_remote_server_names_experimental = {{ matrix_tuwunel_config_allowed_remote_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_forbidden_remote_server_names | length > 0 %}
|
||||
forbidden_remote_server_names = {{ matrix_tuwunel_config_forbidden_remote_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_forbidden_remote_room_directory_server_names | length > 0 %}
|
||||
forbidden_remote_room_directory_server_names = {{ matrix_tuwunel_config_forbidden_remote_room_directory_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_prevent_media_downloads_from | length > 0 %}
|
||||
prevent_media_downloads_from = {{ matrix_tuwunel_config_prevent_media_downloads_from | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_outgoing_presence = {{ matrix_tuwunel_config_allow_outgoing_presence | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_config_url_preview_domain_contains_allowlist | length > 0 %}
|
||||
url_preview_domain_contains_allowlist = {{ matrix_tuwunel_config_url_preview_domain_contains_allowlist | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_url_preview_domain_explicit_allowlist | length > 0 %}
|
||||
url_preview_domain_explicit_allowlist = {{ matrix_tuwunel_config_url_preview_domain_explicit_allowlist | to_json }}
|
||||
{% endif %}
|
||||
url_preview_check_root_domain = {{ matrix_tuwunel_config_url_preview_check_root_domain | to_json }}
|
||||
|
||||
create_admin_room = {{ matrix_tuwunel_config_create_admin_room | to_json }}
|
||||
federate_admin_room = {{ matrix_tuwunel_config_federate_admin_room | to_json }}
|
||||
grant_admin_to_first_user = {{ matrix_tuwunel_config_grant_admin_to_first_user | to_json }}
|
||||
|
||||
log = {{ matrix_tuwunel_config_log | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_config_turn_uris | length > 0 %}
|
||||
turn_uris = {{ matrix_tuwunel_config_turn_uris | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_secret | length > 0 %}
|
||||
turn_secret = {{ matrix_tuwunel_config_turn_secret | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_username | length > 0 %}
|
||||
turn_username = {{ matrix_tuwunel_config_turn_username | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_password | length > 0 %}
|
||||
turn_password = {{ matrix_tuwunel_config_turn_password | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_rocksdb_compression_algo | length > 0 %}
|
||||
rocksdb_compression_algo = {{ matrix_tuwunel_config_rocksdb_compression_algo | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_compression_level | string | length > 0 %}
|
||||
rocksdb_compression_level = {{ matrix_tuwunel_config_rocksdb_compression_level }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_bottommost_compression_level | string | length > 0 %}
|
||||
rocksdb_bottommost_compression_level = {{ matrix_tuwunel_config_rocksdb_bottommost_compression_level }}
|
||||
{% endif %}
|
||||
rocksdb_direct_io = {{ matrix_tuwunel_config_rocksdb_direct_io | to_json }}
|
||||
{% if matrix_tuwunel_config_rocksdb_parallelism_threads | int > 0 %}
|
||||
rocksdb_parallelism_threads = {{ matrix_tuwunel_config_rocksdb_parallelism_threads }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_max_log_file_size | string | length > 0 %}
|
||||
rocksdb_max_log_file_size = {{ matrix_tuwunel_config_rocksdb_max_log_file_size }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_log_time_to_roll | string | length > 0 %}
|
||||
rocksdb_log_time_to_roll = {{ matrix_tuwunel_config_rocksdb_log_time_to_roll }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_database_backup_path | length > 0 %}
|
||||
database_backup_path = {{ matrix_tuwunel_config_database_backup_path | to_json }}
|
||||
database_backups_to_keep = {{ matrix_tuwunel_config_database_backups_to_keep }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_cache_capacity_modifier | string | length > 0 %}
|
||||
cache_capacity_modifier = {{ matrix_tuwunel_config_cache_capacity_modifier }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_db_cache_capacity_mb | string | length > 0 %}
|
||||
db_cache_capacity_mb = {{ matrix_tuwunel_config_db_cache_capacity_mb }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_db_write_buffer_capacity_mb | string | length > 0 %}
|
||||
db_write_buffer_capacity_mb = {{ matrix_tuwunel_config_db_write_buffer_capacity_mb }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_sentry_enabled | bool %}
|
||||
sentry = true
|
||||
{% if matrix_tuwunel_config_sentry_endpoint | length > 0 %}
|
||||
sentry_endpoint = {{ matrix_tuwunel_config_sentry_endpoint | to_json }}
|
||||
{% endif %}
|
||||
sentry_send_server_name = {{ matrix_tuwunel_config_sentry_send_server_name | to_json }}
|
||||
sentry_traces_sample_rate = {{ matrix_tuwunel_config_sentry_traces_sample_rate }}
|
||||
{% endif %}
|
||||
|
||||
{% if (matrix_tuwunel_config_tls_certs | length > 0) and (matrix_tuwunel_config_tls_key | length > 0) %}
|
||||
|
||||
[global.tls]
|
||||
certs = {{ matrix_tuwunel_config_tls_certs | to_json }}
|
||||
key = {{ matrix_tuwunel_config_tls_key | to_json }}
|
||||
dual_protocol = {{ matrix_tuwunel_config_tls_dual_protocol | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% set well_known_keys = [
|
||||
matrix_tuwunel_config_well_known_client,
|
||||
matrix_tuwunel_config_well_known_server,
|
||||
matrix_tuwunel_config_well_known_support_page,
|
||||
matrix_tuwunel_config_well_known_support_email,
|
||||
matrix_tuwunel_config_well_known_support_mxid,
|
||||
matrix_tuwunel_config_well_known_livekit_url,
|
||||
] %}
|
||||
{% if well_known_keys | select | list | length > 0 %}
|
||||
|
||||
[global.well_known]
|
||||
{% if matrix_tuwunel_config_well_known_client | length > 0 %}
|
||||
client = {{ matrix_tuwunel_config_well_known_client | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_server | length > 0 %}
|
||||
server = {{ matrix_tuwunel_config_well_known_server | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_page | length > 0 %}
|
||||
support_page = {{ matrix_tuwunel_config_well_known_support_page | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_email | length > 0 %}
|
||||
support_email = {{ matrix_tuwunel_config_well_known_support_email | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_mxid | length > 0 %}
|
||||
support_mxid = {{ matrix_tuwunel_config_well_known_support_mxid | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_livekit_url | length > 0 %}
|
||||
livekit_url = {{ matrix_tuwunel_config_well_known_livekit_url | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_blurhashing_enabled | bool %}
|
||||
|
||||
[global.blurhashing]
|
||||
components_x = {{ matrix_tuwunel_config_blurhashing_components_x }}
|
||||
components_y = {{ matrix_tuwunel_config_blurhashing_components_y }}
|
||||
blurhash_max_raw_size = {{ matrix_tuwunel_config_blurhashing_max_raw_size }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_ldap_enabled | bool %}
|
||||
|
||||
[global.ldap]
|
||||
enable = true
|
||||
uri = {{ matrix_tuwunel_config_ldap_uri | to_json }}
|
||||
base_dn = {{ matrix_tuwunel_config_ldap_base_dn | to_json }}
|
||||
{% if matrix_tuwunel_config_ldap_bind_dn | length > 0 %}
|
||||
bind_dn = {{ matrix_tuwunel_config_ldap_bind_dn | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_ldap_bind_password_file | length > 0 %}
|
||||
bind_password_file = {{ matrix_tuwunel_config_ldap_bind_password_file | to_json }}
|
||||
{% endif %}
|
||||
filter = {{ matrix_tuwunel_config_ldap_filter | to_json }}
|
||||
uid_attribute = {{ matrix_tuwunel_config_ldap_uid_attribute | to_json }}
|
||||
name_attribute = {{ matrix_tuwunel_config_ldap_name_attribute | to_json }}
|
||||
{% if matrix_tuwunel_config_ldap_admin_base_dn | length > 0 %}
|
||||
admin_base_dn = {{ matrix_tuwunel_config_ldap_admin_base_dn | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_ldap_admin_filter | length > 0 %}
|
||||
admin_filter = {{ matrix_tuwunel_config_ldap_admin_filter | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_jwt_enabled | bool %}
|
||||
|
||||
[global.jwt]
|
||||
enable = true
|
||||
{% if matrix_tuwunel_config_jwt_key | length > 0 %}
|
||||
key = {{ matrix_tuwunel_config_jwt_key | to_json }}
|
||||
{% endif %}
|
||||
format = {{ matrix_tuwunel_config_jwt_format | to_json }}
|
||||
algorithm = {{ matrix_tuwunel_config_jwt_algorithm | to_json }}
|
||||
register_user = {{ matrix_tuwunel_config_jwt_register_user | to_json }}
|
||||
{% if matrix_tuwunel_config_jwt_audience | length > 0 %}
|
||||
audience = {{ matrix_tuwunel_config_jwt_audience | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_jwt_issuer | length > 0 %}
|
||||
issuer = {{ matrix_tuwunel_config_jwt_issuer | to_json }}
|
||||
{% endif %}
|
||||
require_exp = {{ matrix_tuwunel_config_jwt_require_exp | to_json }}
|
||||
require_nbf = {{ matrix_tuwunel_config_jwt_require_nbf | to_json }}
|
||||
validate_exp = {{ matrix_tuwunel_config_jwt_validate_exp | to_json }}
|
||||
validate_nbf = {{ matrix_tuwunel_config_jwt_validate_nbf | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% for idp in matrix_tuwunel_config_identity_providers %}
|
||||
|
||||
[[global.identity_provider]]
|
||||
{% for key, value in idp.items() %}
|
||||
{{ key }} = {{ value | to_json }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for sp in matrix_tuwunel_config_storage_providers %}
|
||||
|
||||
[global.storage_provider.{{ sp.id }}.{{ sp.kind }}]
|
||||
{% for key, value in sp.items() if key not in ['id', 'kind'] %}
|
||||
{{ key }} = {{ value | to_json }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,9 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
matrix_tuwunel_client_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}/_matrix/client/versions"
|
||||
matrix_tuwunel_federation_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}:{{ matrix_federation_public_port }}/_matrix/federation/v1/version"
|
||||
Reference in New Issue
Block a user