From 39a531cf874161aa6fc8fc3d26b41d1242e8cf9f Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 21 Feb 2026 17:11:09 +0100 Subject: [PATCH] set up tuwunel matrix server --- plays/emma.yml | 15 + .../files/site.Caddyfile | 4 +- .../files/tuwunel.Caddyfile | 3 + .../files/tuwunel.data.backup.sh | 12 + roles/any.software.tuwunel/handlers/main.yml | 6 + roles/any.software.tuwunel/meta/main.yml | 3 + roles/any.software.tuwunel/tasks/main.yml | 75 + .../templates/tuwunel.service.j2 | 68 + .../templates/tuwunel.toml.j2 | 2437 +++++++++++++++++ 9 files changed, 2622 insertions(+), 1 deletion(-) create mode 100644 roles/any.software.tuwunel/files/tuwunel.Caddyfile create mode 100644 roles/any.software.tuwunel/files/tuwunel.data.backup.sh create mode 100644 roles/any.software.tuwunel/handlers/main.yml create mode 100644 roles/any.software.tuwunel/meta/main.yml create mode 100644 roles/any.software.tuwunel/tasks/main.yml create mode 100644 roles/any.software.tuwunel/templates/tuwunel.service.j2 create mode 100644 roles/any.software.tuwunel/templates/tuwunel.toml.j2 diff --git a/plays/emma.yml b/plays/emma.yml index dd7fb3a..a089367 100644 --- a/plays/emma.yml +++ b/plays/emma.yml @@ -253,3 +253,18 @@ name: 'jef' - path: '/mnt/data1/photos/lambroek' name: 'lambroek' + +- name: Set up Tuwunel + hosts: emma + tags: tuwunel + become: true + roles: + - role: any.common.btrfs-subvolumes + vars: + subvolumes: + - filesystem_uuid: "{{ btrfs_nvme.uuid }}" + filesystem_path: "{{ btrfs_nvme.path }}" + name: "/@rootfs/data/matrix-tuwunel/data" + - role: any.software.tuwunel + vars: + tuwunel_data_dir: '/data/matrix-tuwunel/data' diff --git a/roles/any.software.site-podman/files/site.Caddyfile b/roles/any.software.site-podman/files/site.Caddyfile index 1c69c6e..698789c 100644 --- a/roles/any.software.site-podman/files/site.Caddyfile +++ b/roles/any.software.site-podman/files/site.Caddyfile @@ -1,3 +1,5 @@ rustybever.be www.rustybever.be { - reverse_proxy 127.0.0.1:8021 + reverse_proxy 127.0.0.1:8021 { + header_down Access-Control-Allow-Origin * + } } diff --git a/roles/any.software.tuwunel/files/tuwunel.Caddyfile b/roles/any.software.tuwunel/files/tuwunel.Caddyfile new file mode 100644 index 0000000..14a14ba --- /dev/null +++ b/roles/any.software.tuwunel/files/tuwunel.Caddyfile @@ -0,0 +1,3 @@ +matrix.rustybever.be, matrix.rustybever.be:8448 { + reverse_proxy localhost:8025 +} diff --git a/roles/any.software.tuwunel/files/tuwunel.data.backup.sh b/roles/any.software.tuwunel/files/tuwunel.data.backup.sh new file mode 100644 index 0000000..dc63b24 --- /dev/null +++ b/roles/any.software.tuwunel/files/tuwunel.data.backup.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +data_dir='/mnt/data1/otter/data' +snapshot_dir="${data_dir}.snapshot" + +# Read-only snapshot for atomic backup +btrfs subvolume snapshot -r "$data_dir" "$snapshot_dir" || exit $? + +/usr/local/bin/restic backup "$snapshot_dir" + +# Always remove snapshot subvolume, even if restic fails +btrfs subvolume delete "$snapshot_dir" diff --git a/roles/any.software.tuwunel/handlers/main.yml b/roles/any.software.tuwunel/handlers/main.yml new file mode 100644 index 0000000..e88c7d6 --- /dev/null +++ b/roles/any.software.tuwunel/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: 'restart tuwunel' + ansible.builtin.service: + name: 'tuwunel' + state: 'restarted' + daemon_reload: true diff --git a/roles/any.software.tuwunel/meta/main.yml b/roles/any.software.tuwunel/meta/main.yml new file mode 100644 index 0000000..d620a12 --- /dev/null +++ b/roles/any.software.tuwunel/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: any.tools.caddy diff --git a/roles/any.software.tuwunel/tasks/main.yml b/roles/any.software.tuwunel/tasks/main.yml new file mode 100644 index 0000000..f50f112 --- /dev/null +++ b/roles/any.software.tuwunel/tasks/main.yml @@ -0,0 +1,75 @@ +--- +- name: Ensure tuwunel is installed + ansible.builtin.apt: + deb: 'https://github.com/matrix-construct/tuwunel/releases/download/v1.5.0/v1.5.0-release-all-x86_64-v3-linux-gnu-tuwunel.deb' + +- name: Ensure system group exists + ansible.builtin.group: + name: 'tuwunel' + gid: 205 + system: true + state: present + +- name: Ensure system user exists + ansible.builtin.user: + name: 'tuwunel' + group: 'tuwunel' + uid: 205 + system: true + create_home: false + +- name: Ensure permissions are correct + ansible.builtin.file: + path: "{{ tuwunel_data_dir }}" + state: directory + mode: '0755' + owner: '205' + group: '205' + +- name: Ensure configuration directory is present + ansible.builtin.file: + path: '/etc/tuwunel' + state: directory + mode: '0755' + +- name: Ensure config file is present + ansible.builtin.template: + src: 'tuwunel.toml.j2' + dest: '/etc/tuwunel/tuwunel.toml' + mode: '0644' + owner: 'root' + group: 'root' + notify: 'restart tuwunel' + +- name: Ensure Caddyfile is present + ansible.builtin.copy: + src: 'tuwunel.Caddyfile' + dest: '/etc/caddy/tuwunel.Caddyfile' + owner: root + group: root + mode: '0644' + notify: reload caddy + +# - name: Ensure backup scripts are present +# ansible.builtin.copy: +# src: "tuwunel.{{ item }}.backup.sh" +# dest: "/etc/backups/tuwunel.{{ item }}.backup.sh" +# owner: 'root' +# group: 'root' +# mode: '0644' +# loop: +# - 'data' + +- name: Ensure service file is present + ansible.builtin.template: + src: 'tuwunel.service.j2' + dest: '/lib/systemd/system/tuwunel.service' + owner: 'root' + group: 'root' + mode: '0644' + notify: 'restart tuwunel' + +- name: Ensure tuwunel service is enabled + ansible.builtin.service: + name: 'tuwunel' + enabled: true diff --git a/roles/any.software.tuwunel/templates/tuwunel.service.j2 b/roles/any.software.tuwunel/templates/tuwunel.service.j2 new file mode 100644 index 0000000..c343e47 --- /dev/null +++ b/roles/any.software.tuwunel/templates/tuwunel.service.j2 @@ -0,0 +1,68 @@ +# https://matrix-construct.github.io/tuwunel/configuration/examples.html#debian-systemd-unit-file +[Unit] +Description=Tuwunel Matrix homeserver +Wants=network-online.target +After=network-online.target +Documentation=https://tuwunel.chat/ + +[Service] +User=tuwunel +Group=tuwunel +Type=notify + +Environment="TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml" + +ExecStart=/usr/sbin/tuwunel + +ReadWritePaths={{ tuwunel_data_dir }} /etc/tuwunel + +AmbientCapabilities= +CapabilityBoundingSet= + +ManagedOOMPreference=avoid + +DevicePolicy=closed +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +#ProcSubset=pid +ProtectClock=yes +ProtectControlGroups=yes +ProtectHome=yes +ProtectHostname=yes +ProtectKernelLogs=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectProc=invisible +ProtectSystem=strict +PrivateDevices=yes +PrivateMounts=yes +PrivateTmp=yes +PrivateUsers=yes +PrivateIPC=yes +RemoveIPC=yes +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service @resources +SystemCallFilter=~@clock @debug @module @mount @reboot @swap @cpu-emulation @obsolete @timer @chown @setuid @privileged @keyring @ipc +SystemCallErrorNumber=EPERM +#StateDirectory=tuwunel + +RuntimeDirectory=tuwunel +RuntimeDirectoryMode=0750 + +Restart=on-failure +RestartSec=5 + +TimeoutStopSec=2m +TimeoutStartSec=2m + +StartLimitInterval=1m +StartLimitBurst=5 + +[Install] +WantedBy=multi-user.target +Alias=matrix-tuwunel.service diff --git a/roles/any.software.tuwunel/templates/tuwunel.toml.j2 b/roles/any.software.tuwunel/templates/tuwunel.toml.j2 new file mode 100644 index 0000000..9b8ea0a --- /dev/null +++ b/roles/any.software.tuwunel/templates/tuwunel.toml.j2 @@ -0,0 +1,2437 @@ +# vim: set ft=toml +### Tuwunel Configuration +### +### THIS FILE IS GENERATED. CHANGES/CONTRIBUTIONS IN THE REPO WILL BE +### OVERWRITTEN! +### +### You should rename this file before configuring your server. Changes to +### documentation and defaults can be contributed in source code at +### src/core/config/mod.rs. This file is generated when building. +### +### Any values pre-populated are the default values for said config option. +### +### At the minimum, you MUST edit all the config options to your environment +### that say "YOU NEED TO EDIT THIS". +### +### For more information, see: +### https://tuwunel.chat/configuration.html + + +[global] + +# The server_name is the pretty name of this server. It is used as a +# suffix for user and room IDs/aliases. +# +# See the docs for reverse proxying and delegation: +# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy +# +# Also see the `[global.well_known]` config section at the very bottom. +# +# Examples of delegation: +# - https://matrix.org/.well-known/matrix/server +# - https://matrix.org/.well-known/matrix/client +# +# YOU NEED TO EDIT THIS. THIS CANNOT BE CHANGED AFTER WITHOUT A DATABASE +# WIPE. +# +# example: "girlboss.ceo" +# +server_name = "rustybever.be" + +# This is the only directory where tuwunel will save its data, including +# media. Note: this was previously "/var/lib/matrix-conduit". +# +database_path = "{{ tuwunel_data_dir }}" + +# Text which will be added to the end of the user's displayname upon +# registration with a space before the text. In Conduit, this was the +# lightning bolt emoji. +# +# To disable, set this to "" (an empty string). +# +new_user_displayname_suffix = "" + +# The default address (IPv4 or IPv6) tuwunel will listen on. +# +# If you are using Docker or a container NAT networking setup, this must +# be "0.0.0.0". +# +# To listen on multiple addresses, specify a vector e.g. ["127.0.0.1", +# "::1"] +# +#address = ["127.0.0.1", "::1"] + +# The port(s) tuwunel will listen on. +# +# For reverse proxying, see: +# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy +# +# If you are using Docker, don't change this, you'll need to map an +# external port to this. +# +# To listen on multiple ports, specify a vector e.g. [8080, 8448] +# +port = 8025 + +# The UNIX socket tuwunel will listen on. +# +# Remember to make sure that your reverse proxy has access to this socket +# file, either by adding your reverse proxy to the 'tuwunel' group or +# granting world R/W permissions with `unix_socket_perms` (666 minimum). +# +# example: "/run/tuwunel/tuwunel.sock" +# +#unix_socket_path = + +# The default permissions (in octal) to create the UNIX socket with. +# +#unix_socket_perms = 660 + +# Error on startup if any config option specified is unknown to Tuwunel. +# +# This is false by default to allow easier deprecation or removal of +# config options in the future without breaking existing deployments. The +# default behaviour is to simply warn on startup. +# +#error_on_unknown_config_opts = false + +# tuwunel supports online database backups using RocksDB's Backup engine +# API. To use this, set a database backup path that tuwunel can write +# to. +# +# For more information, see: +# https://tuwunel.chat/maintenance.html#backups +# +# example: "/opt/tuwunel-db-backups" +# +#database_backup_path = + +# The amount of online RocksDB database backups to keep/retain, if using +# "database_backup_path", before deleting the oldest one. +# +#database_backups_to_keep = 1 + +# Set this to any float value to multiply tuwunel's in-memory LRU caches +# with such as "auth_chain_cache_capacity". +# +# May be useful if you have significant memory to spare to increase +# performance. +# +# If you have low memory, reducing this may be viable. +# +# By default, the individual caches such as "auth_chain_cache_capacity" +# are scaled by your CPU core count. +# +#cache_capacity_modifier = 1.0 + +# Set this to any float value in megabytes for tuwunel to tell the +# database engine that this much memory is available for database read +# caches. +# +# May be useful if you have significant memory to spare to increase +# performance. +# +# Similar to the individual LRU caches, this is scaled up with your CPU +# core count. +# +# This defaults to 128.0 + (64.0 * CPU core count). +# +#db_cache_capacity_mb = varies by system + +# Set this to any float value in megabytes for tuwunel to tell the +# database engine that this much memory is available for database write +# caches. +# +# May be useful if you have significant memory to spare to increase +# performance. +# +# Similar to the individual LRU caches, this is scaled up with your CPU +# core count. +# +# This defaults to 48.0 + (4.0 * CPU core count). +# +#db_write_buffer_capacity_mb = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#pdu_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#auth_chain_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#shorteventid_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#eventidshort_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#eventid_pdu_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#shortstatekey_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#statekeyshort_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#servernameevent_data_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#stateinfo_cache_capacity = varies by system + +# This item is undocumented. Please contribute documentation for it. +# +#roomid_spacehierarchy_cache_capacity = varies by system + +# Minimum timeout a client can request for long-polling sync. Requests +# will be clamped up to this value if smaller. +# +#client_sync_timeout_min = 5000 + +# Default timeout for long-polling sync if a client does not request +# another in their query-string. +# +#client_sync_timeout_default = 30000 + +# Maximum timeout a client can request for long-polling sync. Requests +# will be clamped down to this value if larger. +# +#client_sync_timeout_max = 90000 + +# Maximum entries stored in DNS memory-cache. The size of an entry may +# vary so please take care if raising this value excessively. Only +# decrease this when using an external DNS cache. Please note that +# systemd-resolved does *not* count as an external cache, even when +# configured to do so. +# +#dns_cache_entries = 32768 + +# Minimum time-to-live in seconds for entries in the DNS cache. The +# default may appear high to most administrators; this is by design as the +# exotic loads of federating to many other servers require a higher TTL +# than many domains have set. Even when using an external DNS cache the +# problem is shifted to that cache which is ignorant of its role for +# this application and can adhere to many low TTL's increasing its load. +# +#dns_min_ttl = 10800 + +# Minimum time-to-live in seconds for NXDOMAIN entries in the DNS cache. +# This value is critical for the server to federate efficiently. +# NXDOMAIN's are assumed to not be returning to the federation and +# aggressively cached rather than constantly rechecked. +# +# Defaults to 3 days as these are *very rarely* false negatives. +# +#dns_min_ttl_nxdomain = 259200 + +# Number of DNS nameserver retries after a timeout or error. +# +#dns_attempts = 10 + +# The number of seconds to wait for a reply to a DNS query. Please note +# that recursive queries can take up to several seconds for some domains, +# so this value should not be too low, especially on slower hardware or +# resolvers. +# +#dns_timeout = 10 + +# Fallback to TCP on DNS errors. Set this to false if unsupported by +# nameserver. +# +#dns_tcp_fallback = true + +# Enable to query all nameservers until the domain is found. Referred to +# as "trust_negative_responses" in hickory_resolver. This can avoid +# useless DNS queries if the first nameserver responds with NXDOMAIN or +# an empty NOERROR response. +# +#query_all_nameservers = true + +# Enable using *only* TCP for querying your specified nameservers instead +# of UDP. +# +# If you are running tuwunel in a container environment, this config +# option may need to be enabled. For more details, see: +# https://tuwunel.chat/troubleshooting.html#potential-dns-issues-when-using-docker +# +#query_over_tcp_only = false + +# DNS A/AAAA record lookup strategy +# +# Takes a number of one of the following options: +# 1 - Ipv4Only (Only query for A records, no AAAA/IPv6) +# +# 2 - Ipv6Only (Only query for AAAA records, no A/IPv4) +# +# 3 - Ipv4AndIpv6 (Query for A and AAAA records in parallel, uses whatever +# returns a successful response first) +# +# 4 - Ipv6thenIpv4 (Query for AAAA record, if that fails then query the A +# record) +# +# 5 - Ipv4thenIpv6 (Query for A record, if that fails then query the AAAA +# record) +# +# If you don't have IPv6 networking, then for better DNS performance it +# may be suitable to set this to Ipv4Only (1) as you will never ever use +# the AAAA record contents even if the AAAA record is successful instead +# of the A record. +# +#ip_lookup_strategy = 5 + +# List of domain patterns resolved via the alternative path without any +# persistent cache, very small memory cache, and no enforced TTL. This +# is intended for internal network and application services which require +# these specific properties. This path does not support federation or +# general purposes. +# +# example: ["*\.dns\.podman$"] +# +#dns_passthru_domains = [] + +# Whether to resolve appservices via the alternative path; setting this is +# superior to providing domains in `dns_passthru_domains` if all +# appservices intend to be matched anyway. The overhead of matching regex +# and maintaining the list of domains can be avoided. +# +#dns_passthru_appservices = false + +# Enable or disable case randomization for DNS queries. This is a security +# mitigation where answer spoofing is prevented by having to exactly match +# the question. Occasional errors seen in logs which may have lead you +# here tend to be from overloading DNS. Nevertheless for servers which +# are truly incapable this can be set to false. +# +# This currently defaults to false due to user reports regarding some +# popular DNS caches which may or may not be patched soon. It may again +# default to true in an upcoming release. +# +#dns_case_randomization = false + +# Max request size for file uploads in bytes. +# +#max_request_size = 24 MiB + +# This item is undocumented. Please contribute documentation for it. +# +#max_fetch_prev_events = 192 + +# Default/base connection timeout (seconds). This is used only by URL +# previews and update/news endpoint checks. +# +#request_conn_timeout = 10 + +# Default/base request timeout (seconds). The time waiting to receive more +# data from another server. This is used only by URL previews, +# update/news, and misc endpoint checks. +# +#request_timeout = 35 + +# Default/base request total timeout (seconds). The time limit for a whole +# request. This is set very high to not cancel healthy requests while +# serving as a backstop. This is used only by URL previews and update/news +# endpoint checks. +# +#request_total_timeout = 320 + +# Default/base idle connection pool timeout (seconds). This is used only +# by URL previews and update/news endpoint checks. +# +#request_idle_timeout = 5 + +# Default/base max idle connections per host. This is used only by URL +# previews and update/news endpoint checks. Defaults to 1 as generally the +# same open connection can be re-used. +# +#request_idle_per_host = 1 + +# Federation well-known resolution connection timeout (seconds). +# +#well_known_conn_timeout = 6 + +# Federation HTTP well-known resolution request timeout (seconds). +# +#well_known_timeout = 10 + +# Federation client request timeout (seconds). You most definitely want +# this to be high to account for extremely large room joins, slow +# homeservers, your own resources etc. +# +#federation_timeout = 300 + +# Federation client idle connection pool timeout (seconds). +# +#federation_idle_timeout = 25 + +# Federation client max idle connections per host. Defaults to 1 as +# generally the same open connection can be re-used. +# +#federation_idle_per_host = 1 + +# Federation sender request timeout (seconds). The time it takes for the +# remote server to process sent transactions can take a while. +# +#sender_timeout = 180 + +# Federation sender idle connection pool timeout (seconds). +# +#sender_idle_timeout = 180 + +# Federation sender transaction retry backoff limit (seconds). +# +#sender_retry_backoff_limit = 86400 + +# Appservice URL request connection timeout. Defaults to 35 seconds as +# generally appservices are hosted within the same network. +# +#appservice_timeout = 35 + +# Appservice URL idle connection pool timeout (seconds). +# +#appservice_idle_timeout = 300 + +# Notification gateway pusher idle connection pool timeout. +# +#pusher_idle_timeout = 15 + +# Maximum time to receive a request from a client (seconds). +# +#client_receive_timeout = 75 + +# Maximum time to process a request received from a client (seconds). +# +#client_request_timeout = 240 + +# Maximum time to transmit a response to a client (seconds) +# +#client_response_timeout = 120 + +# Grace period for clean shutdown of client requests (seconds). +# +#client_shutdown_timeout = 10 + +# Grace period for clean shutdown of federation requests (seconds). +# +#sender_shutdown_timeout = 5 + +# Enables registration. If set to false, no users can register on this +# server. +# +# If set to true without a token configured, users can register with no +# form of 2nd-step only if you set the following option to true: +# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` +# +# If you would like registration only via token reg, please configure +# `registration_token` or `registration_token_file`. +# +allow_registration = true + +# Enabling this setting opens registration to anyone without restrictions. +# This makes your server vulnerable to abuse +# +#yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = false + +# A static registration token that new users will have to provide when +# creating an account. If unset and `allow_registration` is true, +# you must set +# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` +# to true to allow open registration without any conditions. +# +# YOU NEED TO EDIT THIS OR USE registration_token_file. +# +# example: "o&^uCtes4HPf0Vu@F20jQeeWE7" +# +registration_token = "{{ tuwunel_registration_token }}" + +# Path to a file on the system that gets read for additional registration +# tokens. Multiple tokens can be added if you separate them with +# whitespace +# +# tuwunel must be able to access the file, and it must not be empty +# +# example: "/etc/tuwunel/.reg_token" +# +#registration_token_file = + +# Controls whether encrypted rooms and events are allowed. +# +#allow_encryption = true + +# Controls whether locally-created rooms should be end-to-end encrypted by +# default. This option is equivalent to the one found in Synapse. +# +# Options: +# - "all": All created rooms are encrypted. +# - "invite": Any room created with `private_chat` or +# `trusted_private_chat` presets. +# - Other values default to no effect. +# +#encryption_enabled_by_default_for_room_type = false + +# Controls whether federation is allowed or not. It is not recommended to +# disable this after installation due to potential federation breakage but +# this is technically not a permanent setting. +# +#allow_federation = true + +# Sets the default `m.federate` property for newly created rooms when the +# client does not request one. If `allow_federation` is set to false at +# the same this value is set to false it then always overrides the client +# requested `m.federate` value to false. +# +# Rooms are fixed to the setting at the time of their creation and can +# never be changed; changing this value only affects new rooms. +# +#federate_created_rooms = true + +# Allows federation requests to be made to itself +# +# This isn't intended and is very likely a bug if federation requests are +# being sent to yourself. This currently mainly exists for development +# purposes. +# +#federation_loopback = false + +# Always calls /forget on behalf of the user if leaving a room. This is a +# part of MSC4267 "Automatically forgetting rooms on leave" +# +#forget_forced_upon_leave = false + +# Set this to true to require authentication on the normally +# unauthenticated profile retrieval endpoints (GET) +# "/_matrix/client/v3/profile/{userId}". +# +# This can prevent profile scraping. +# +#require_auth_for_profile_requests = false + +# Set this to true to allow your server's public room directory to be +# federated. Set this to false to protect against /publicRooms spiders, +# but will forbid external users from viewing your server's public room +# directory. If federation is disabled entirely (`allow_federation`), this +# is inherently false. +# +#allow_public_room_directory_over_federation = false + +# Set this to true to allow your server's public room directory to be +# queried without client authentication (access token) through the Client +# APIs. Set this to false to protect against /publicRooms spiders. +# +#allow_public_room_directory_without_auth = false + +# Allows room directory searches to match on partial room_id's when the +# search term starts with '!'. +# +#allow_public_room_search_by_id = true + +# Set this to false to limit results of rooms when searching by ID to +# those that would be found by an alias or other query; specifically +# those listed in the public rooms directory. By default this is set to +# true allowing any joinable room to match. This satisfies the Principle +# of Least Expectation when pasting a room_id into a search box with +# intent to join; many rooms simply opt-out of public listings. Therefor +# to prevent this feature from abuse, knowledge of several characters of +# the room_id is required before any results are returned. +# +#allow_unlisted_room_search_by_id = true + +# Show all local users in user directory. With this set to false, only +# users in public rooms or those that share a room with the user making +# the search will be shown. +# +#show_all_local_users_in_user_directory = false + +# Allow guests/unauthenticated users to access TURN credentials. +# +# This is the equivalent of Synapse's `turn_allow_guests` config option. +# This allows any unauthenticated user to call the endpoint +# `/_matrix/client/v3/voip/turnServer`. +# +# It is unlikely you need to enable this as all major clients support +# authentication for this endpoint and prevents misuse of your TURN server +# from potential bots. +# +#turn_allow_guests = false + +# Set this to true to lock down your server's public room directory and +# only allow admins to publish rooms to the room directory. Unpublishing +# is still allowed by all users with this enabled. +# +#lockdown_public_room_directory = false + +# Set this to true to allow federating device display names / allow +# external users to see your device display name. If federation is +# disabled entirely (`allow_federation`), this is inherently false. For +# privacy reasons, this is best left disabled. +# +#allow_device_name_federation = false + +# Config option to allow or disallow incoming federation requests that +# obtain the profiles of our local users from +# `/_matrix/federation/v1/query/profile` +# +# Increases privacy of your local user's such as display names, but some +# remote users may get a false "this user does not exist" error when they +# try to invite you to a DM or room. Also can protect against profile +# spiders. +# +# This is inherently false if `allow_federation` is disabled +# +#allow_inbound_profile_lookup_federation_requests = true + +# Allow standard users to create rooms. Appservices and admins are always +# allowed to create rooms +# +#allow_room_creation = true + +# Set to false to disable users from joining or creating room versions +# that aren't officially supported by tuwunel. Unstable room versions may +# have flawed specifications or our implementation may be non-conforming. +# Correct operation may not be guaranteed, but incorrect operation may be +# tolerable and unnoticed. +# +# tuwunel officially supports room versions 6+. tuwunel has slightly +# experimental (though works fine in practice) support for versions 3 - 5. +# +#allow_unstable_room_versions = true + +# Set to true to enable experimental room versions. +# +# Unlike unstable room versions these versions are either under +# development, protype spec-changes, or somehow present a serious risk to +# the server's operation or database corruption. This is for developer use +# only. +# +#allow_experimental_room_versions = false + +# Default room version tuwunel will create rooms with. +# +# The default is prescribed by the spec, but may be selected by developer +# recommendation. To prevent stale documentation we no longer list it +# here. It is only advised to override this if you know what you are +# doing, and by doing so, updates with new versions are precluded. +# +#default_room_version = + +# This item is undocumented. Please contribute documentation for it. +# +#allow_jaeger = false + +# This item is undocumented. Please contribute documentation for it. +# +#jaeger_filter = "info" + +# If the 'perf_measurements' compile-time feature is enabled, enables +# collecting folded stack trace profile of tracing spans using +# tracing_flame. The resulting profile can be visualized with inferno[1], +# speedscope[2], or a number of other tools. +# +# [1]: https://github.com/jonhoo/inferno +# [2]: www.speedscope.app +# +#tracing_flame = false + +# This item is undocumented. Please contribute documentation for it. +# +#tracing_flame_filter = "info" + +# This item is undocumented. Please contribute documentation for it. +# +#tracing_flame_output_path = "./tracing.folded" + +# Examples: +# +# - No proxy (default): +# +# proxy = "none" +# +# - For global proxy, create the section at the bottom of this file: +# +# [global.proxy] +# global = { url = "socks5h://localhost:9050" } +# +# - To proxy some domains: +# +# [global.proxy] +# [[global.proxy.by_domain]] +# url = "socks5h://localhost:9050" +# include = ["*.onion", "matrix.myspecial.onion"] +# exclude = ["*.myspecial.onion"] +# +# Include vs. Exclude: +# +# - If include is an empty list, it is assumed to be `["*"]`. +# +# - If a domain matches both the exclude and include list, the proxy will +# only be used if it was included because of a more specific rule than +# it was excluded. In the above example, the proxy would be used for +# `ordinary.onion`, `matrix.myspecial.onion`, but not +# `hello.myspecial.onion`. +# +#proxy = "none" + +# Servers listed here will be used to gather public keys of other servers +# (notary trusted key servers). +# +# Currently, tuwunel doesn't support inbound batched key requests, so +# this list should only contain other Synapse servers. +# +# example: ["matrix.org", "tchncs.de"] +# +#trusted_servers = ["matrix.org"] + +# Whether to query the servers listed in trusted_servers first or query +# the origin server first. For best security, querying the origin server +# first is advised to minimize the exposure to a compromised trusted +# server. For maximum federation/join performance this can be set to true, +# however other options exist to query trusted servers first under +# specific high-load circumstances and should be evaluated before setting +# this to true. +# +#query_trusted_key_servers_first = false + +# Whether to query the servers listed in trusted_servers first +# specifically on room joins. This option limits the exposure to a +# compromised trusted server to room joins only. The join operation +# requires gathering keys from many origin servers which can cause +# significant delays. Therefor this defaults to true to mitigate +# unexpected delays out-of-the-box. The security-paranoid or those willing +# to tolerate delays are advised to set this to false. Note that setting +# query_trusted_key_servers_first to true causes this option to be +# ignored. +# +#query_trusted_key_servers_first_on_join = true + +# Only query trusted servers for keys and never the origin server. This is +# intended for clusters or custom deployments using their trusted_servers +# as forwarding-agents to cache and deduplicate requests. Notary servers +# do not act as forwarding-agents by default, therefor do not enable this +# unless you know exactly what you are doing. +# +#only_query_trusted_key_servers = false + +# Maximum number of keys to request in each trusted server batch query. +# +#trusted_server_batch_size = 192 + +# Maximum number of request batches in flight simultaneously when querying +# a trusted server. +# +#trusted_server_batch_concurrency = 2 + +# Max log level for tuwunel. Allows debug, info, warn, or error. +# +# See also: +# https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives +# +# **Caveat**: +# For release builds, the tracing crate is configured to only implement +# levels higher than error to avoid unnecessary overhead in the compiled +# binary from trace macros. For debug builds, this restriction is not +# applied. +# +#log = "info" + +# Output logs with ANSI colours. +# +#log_colors = true + +# Sets the log format to compact mode. +# +#log_compact = false + +# Configures the span events which will be outputted with the log. +# +#log_span_events = "none" + +# Configures whether TUWUNEL_LOG EnvFilter matches values using regular +# expressions. See the tracing_subscriber documentation on Directives. +# +#log_filter_regex = true + +# Toggles the display of ThreadId in tracing log output. +# +#log_thread_ids = false + +# Redirects logging to standard error (stderr). The default is false for +# stdout. For those using our systemd features the redirection to stderr +# occurs as necessary and setting this option should not be required. We +# offer this option for all other users who desire such redirection. +# +#log_to_stderr = false + +# Setting to false disables the logging/tracing system at a lower level. +# In contrast to configuring an empty `log` string where the system is +# still operating but muted, when this option is false the system was not +# initialized and is not operating. Changing this option has no effect +# after startup. This option is intended for developers and expert use +# only: configuring an empty log string is preferred over using this. +# +#log_enable = true + +# Setting to false disables the logging/tracing system at a lower level +# similar to `log_enable`. In this case the system is configured normally, +# but not registered as the global handler in the final steps. This option +# is for developers and expert use only. +# +#log_global_default = true + +# OpenID token expiration/TTL in seconds. +# +# These are the OpenID tokens that are primarily used for Matrix account +# integrations (e.g. Vector Integrations in Element), *not* OIDC/OpenID +# Connect/etc. +# +#openid_token_ttl = 3600 + +# Allow an existing session to mint a login token for another client. +# This requires interactive authentication, but has security ramifications +# as a malicious client could use the mechanism to spawn more than one +# session. Enabled by default. +# +#login_via_existing_session = true + +# Whether to enable the login token route to accept login tokens at all. +# Login tokens may be generated by the server for authorization flows such +# as SSO; disabling tokens may break such features. +# +# This option is distinct from `login_via_existing_session` and does not +# carry the same security implications; the intent is to leave this +# enabled while disabling the former to prevent clients from commanding +# login token creation but without preventing the server from doing so. +# +#login_via_token = true + +# Login token expiration/TTL in milliseconds. +# +# These are short-lived tokens for the m.login.token endpoint. +# This is used to allow existing sessions to create new sessions. +# see login_via_existing_session. +# +#login_token_ttl = 120000 + +# Access token TTL in seconds. +# +# For clients that support refresh-tokens, the access-token provided on +# login will be invalidated after this amount of time and the client will +# be soft-logged-out until refreshing it. +# +#access_token_ttl = 604800 + +# Static TURN username to provide the client if not using a shared secret +# ("turn_secret"), It is recommended to use a shared secret over static +# credentials. +# +#turn_username = false + +# Static TURN password to provide the client if not using a shared secret +# ("turn_secret"). It is recommended to use a shared secret over static +# credentials. +# +#turn_password = false + +# Vector list of TURN URIs/servers to use. +# +# Replace "example.turn.uri" with your TURN domain, such as the coturn +# "realm" config option. If using TURN over TLS, replace the URI prefix +# "turn:" with "turns:". +# +# example: ["turn:example.turn.uri?transport=udp", +# "turn:example.turn.uri?transport=tcp"] +# +#turn_uris = [] + +# TURN secret to use for generating the HMAC-SHA1 hash apart of username +# and password generation. +# +# This is more secure, but if needed you can use traditional static +# username/password credentials. +# +#turn_secret = false + +# TURN secret to use that's read from the file path specified. +# +# This takes priority over "turn_secret" first, and falls back to +# "turn_secret" if invalid or failed to open. +# +# example: "/etc/tuwunel/.turn_secret" +# +#turn_secret_file = + +# TURN TTL, in seconds. +# +#turn_ttl = 86400 + +# List/vector of room IDs or room aliases that tuwunel will make newly +# registered users join. The rooms specified must be rooms that you have +# joined at least once on the server, and must be public. +# +# example: ["#tuwunel:tuwunel.chat", +# "!eoIzvAvVwY23LPDay8:tuwunel.chat"] +# +#auto_join_rooms = [] + +# Config option to automatically deactivate the account of any user who +# attempts to join a: +# - banned room +# - forbidden room alias +# - room alias or ID with a forbidden server name +# +# This may be useful if all your banned lists consist of toxic rooms or +# servers that no good faith user would ever attempt to join, and +# to automatically remediate the problem without any admin user +# intervention. +# +# This will also make the user leave all rooms. Federation (e.g. remote +# room invites) are ignored here. +# +# Defaults to false as rooms can be banned for non-moderation-related +# reasons and this performs a full user deactivation. +# +#auto_deactivate_banned_room_attempts = false + +# RocksDB log level. This is not the same as tuwunel's log level. This +# is the log level for the RocksDB engine/library which show up in your +# database folder/path as `LOG` files. tuwunel will log RocksDB errors +# as normal through tracing or panics if severe for safety. +# +#rocksdb_log_level = "error" + +# This item is undocumented. Please contribute documentation for it. +# +#rocksdb_log_stderr = false + +# Max RocksDB `LOG` file size before rotating in bytes. Defaults to 4MB in +# bytes. +# +#rocksdb_max_log_file_size = 4194304 + +# Time in seconds before RocksDB will forcibly rotate logs. +# +#rocksdb_log_time_to_roll = 0 + +# Set this to true to use RocksDB config options that are tailored to HDDs +# (slower device storage). +# +# It is worth noting that by default, tuwunel will use RocksDB with +# Direct IO enabled. *Generally* speaking this improves performance as it +# bypasses buffered I/O (system page cache). However there is a potential +# chance that Direct IO may cause issues with database operations if your +# setup is uncommon. This has been observed with FUSE filesystems, and +# possibly ZFS filesystem. RocksDB generally deals/corrects these issues +# but it cannot account for all setups. If you experience any weird +# RocksDB issues, try enabling this option as it turns off Direct IO and +# feel free to report in the tuwunel Matrix room if this option fixes +# your DB issues. +# +# For more information, see: +# https://github.com/facebook/rocksdb/wiki/Direct-IO +# +#rocksdb_optimize_for_spinning_disks = false + +# Enables direct-io to increase database performance via unbuffered I/O. +# +# For more details about direct I/O and RockDB, see: +# https://github.com/facebook/rocksdb/wiki/Direct-IO +# +# Set this option to false if the database resides on a filesystem which +# does not support direct-io like FUSE, or any form of complex filesystem +# setup such as possibly ZFS. +# +#rocksdb_direct_io = true + +# Amount of threads that RocksDB will use for parallelism on database +# operations such as cleanup, sync, flush, compaction, etc. Set to 0 to +# use all your logical threads. Defaults to your CPU logical thread count. +# +#rocksdb_parallelism_threads = varies by system + +# Maximum number of LOG files RocksDB will keep. This must *not* be set to +# 0. It must be at least 1. Defaults to 3 as these are not very useful +# unless troubleshooting/debugging a RocksDB bug. +# +#rocksdb_max_log_files = 3 + +# Type of RocksDB database compression to use. +# +# Available options are "zstd", "bz2", "lz4", or "none". +# +# It is best to use ZSTD as an overall good balance between +# speed/performance, storage, IO amplification, and CPU usage. For more +# performance but less compression (more storage used) and less CPU usage, +# use LZ4. +# +# For more details, see: +# https://github.com/facebook/rocksdb/wiki/Compression +# +# "none" will disable compression. +# +#rocksdb_compression_algo = "zstd" + +# Level of compression the specified compression algorithm for RocksDB to +# use. +# +# Default is 32767, which is internally read by RocksDB as the default +# magic number and translated to the library's default compression level +# as they all differ. See their `kDefaultCompressionLevel`. +# +# Note when using the default value we may override it with a setting +# tailored specifically tuwunel. +# +#rocksdb_compression_level = 32767 + +# Level of compression the specified compression algorithm for the +# bottommost level/data for RocksDB to use. Default is 32767, which is +# internally read by RocksDB as the default magic number and translated to +# the library's default compression level as they all differ. See their +# `kDefaultCompressionLevel`. +# +# Since this is the bottommost level (generally old and least used data), +# it may be desirable to have a very high compression level here as it's +# less likely for this data to be used. Research your chosen compression +# algorithm. +# +# Note when using the default value we may override it with a setting +# tailored specifically tuwunel. +# +#rocksdb_bottommost_compression_level = 32767 + +# Whether to enable RocksDB's "bottommost_compression". +# +# At the expense of more CPU usage, this will further compress the +# database to reduce more storage. It is recommended to use ZSTD +# compression with this for best compression results. This may be useful +# if you're trying to reduce storage usage from the database. +# +# See https://github.com/facebook/rocksdb/wiki/Compression for more details. +# +#rocksdb_bottommost_compression = true + +# Database recovery mode (for RocksDB WAL corruption). +# +# Use this option when the server reports corruption and refuses to start. +# Set mode 2 (PointInTime) to cleanly recover from this corruption. The +# server will continue from the last good state, several seconds or +# minutes prior to the crash. Clients may have to run "clear-cache & +# reload" to account for the rollback. Upon success, you may reset the +# mode back to default and restart again. Please note in some cases the +# corruption error may not be cleared for at least 30 minutes of operation +# in PointInTime mode. +# +# As a very last ditch effort, if PointInTime does not fix or resolve +# anything, you can try mode 3 (SkipAnyCorruptedRecord) but this will +# leave the server in a potentially inconsistent state. +# +# The default mode 1 (TolerateCorruptedTailRecords) will automatically +# drop the last entry in the database if corrupted during shutdown, but +# nothing more. It is extraordinarily unlikely this will desynchronize +# clients. To disable any form of silent rollback set mode 0 +# (AbsoluteConsistency). +# +# The options are: +# 0 = AbsoluteConsistency +# 1 = TolerateCorruptedTailRecords (default) +# 2 = PointInTime (use me if trying to recover) +# 3 = SkipAnyCorruptedRecord (you now voided your tuwunel warranty) +# +# For more information on these modes, see: +# https://github.com/facebook/rocksdb/wiki/WAL-Recovery-Modes +# +# For more details on recovering a corrupt database, see: +# https://tuwunel.chat/troubleshooting.html#database-corruption +# +#rocksdb_recovery_mode = 1 + +# Enables or disables paranoid SST file checks. This can improve RocksDB +# database consistency at a potential performance impact due to further +# safety checks ran. +# +# For more information, see: +# https://github.com/facebook/rocksdb/wiki/Online-Verification#columnfamilyoptionsparanoid_file_checks +# +#rocksdb_paranoid_file_checks = false + +# Enables or disables checksum verification in rocksdb at runtime. +# Checksums are usually hardware accelerated with low overhead; they are +# enabled in rocksdb by default. Older or slower platforms may see gains +# from disabling. +# +#rocksdb_checksums = true + +# Enables the "atomic flush" mode in rocksdb. This option is not intended +# for users. It may be removed or ignored in future versions. Atomic flush +# may be enabled by the paranoid to possibly improve database integrity at +# the cost of performance. +# +#rocksdb_atomic_flush = false + +# Database repair mode (for RocksDB SST corruption). +# +# Use this option when the server reports corruption while running or +# panics. If the server refuses to start use the recovery mode options +# first. Corruption errors containing the acronym 'SST' which occur after +# startup will likely require this option. +# +# - Backing up your database directory is recommended prior to running the +# repair. +# +# - Disabling repair mode and restarting the server is recommended after +# running the repair. +# +# See https://tuwunel.chat/troubleshooting.html#database-corruption for more details on recovering a corrupt database. +# +#rocksdb_repair = false + +# This item is undocumented. Please contribute documentation for it. +# +#rocksdb_read_only = false + +# This item is undocumented. Please contribute documentation for it. +# +#rocksdb_secondary = false + +# Enables idle CPU priority for compaction thread. This is not enabled by +# default to prevent compaction from falling too far behind on busy +# systems. +# +#rocksdb_compaction_prio_idle = false + +# Enables idle IO priority for compaction thread. This prevents any +# unexpected lag in the server's operation and is usually a good idea. +# Enabled by default. +# +#rocksdb_compaction_ioprio_idle = true + +# Enables RocksDB compaction. You should never ever have to set this +# option to false. If you for some reason find yourself needing to use +# this option as part of troubleshooting or a bug, please reach out to us +# in the tuwunel Matrix room with information and details. +# +# Disabling compaction will lead to a significantly bloated and +# explosively large database, gradually poor performance, unnecessarily +# excessive disk read/writes, and slower shutdowns and startups. +# +#rocksdb_compaction = true + +# Level of statistics collection. Some admin commands to display database +# statistics may require this option to be set. Database performance may +# be impacted by higher settings. +# +# Option is a number ranging from 0 to 6: +# 0 = No statistics. +# 1 = No statistics in release mode (default). +# 2 to 3 = Statistics with no performance impact. +# 3 to 5 = Statistics with possible performance impact. +# 6 = All statistics. +# +#rocksdb_stats_level = 1 + +# Ignores the list of dropped columns set by developers. +# +# This should be set to true when knowingly moving between versions in +# ways which are not recommended or otherwise forbidden, or for +# diagnostic and development purposes; requiring preservation across such +# movements. +# +# The developer's list of dropped columns is meant to safely reduce space +# by erasing data no longer in use. If this is set to true that storage +# will not be reclaimed as intended. +# +#rocksdb_never_drop_columns = false + +# Configures RocksDB to not preallocate WAL logs. +# +# Normally, RocksDB allocates certain types of files by calling +# fallocate, writing the file contents, then truncating the logs to the +# proper size. This causes pathological disk space usage on btrfs due +# how it interacts with its Copy-on-Write implementation. +# +# It is recommended to set this to false if you run the server on btrfs, +# and not touch it otherwise. +# +#rocksdb_allow_fallocate = true + +# This is a password that can be configured that will let you login to the +# server bot account (currently `@conduit`) for emergency troubleshooting +# purposes such as recovering/recreating your admin room, or inviting +# yourself back. +# +# See https://tuwunel.chat/troubleshooting.html#lost-access-to-admin-room +# for other ways to get back into your admin room. +# +# Once this password is unset, all sessions will be logged out for +# security purposes. +# +# example: "F670$2CP@Hw8mG7RY1$%!#Ic7YA" +# +#emergency_password = + +# This item is undocumented. Please contribute documentation for it. +# +#notification_push_path = "/_matrix/push/v1/notify" + +# For compatibility and special purpose use only. Setting this option to +# true will not filter messages sent to pushers based on rules or actions. +# Everything will be sent to the pusher. This option is offered for +# several reasons, but should not be necessary: +# - Bypass to workaround bugs or outdated server-side ruleset support. +# - Allow clients to evaluate pushrules themselves (due to the above). +# - Hosting or companies which have custom pushers and internal needs. +# +# Note that setting this option to true will not affect the record of +# notifications found in the notifications pane. +# +#push_everything = false + +# Setting to false disables the heroes calculation made by sliding and +# legacy client sync. The heroes calculation is mandated by the Matrix +# specification and your client may not operate properly unless this +# option is set to true. +# +# This option is intended for custom software deployments seeking purely +# to minimize unused resources; the overall savings are otherwise +# negligible. +# +#calculate_heroes = true + +# Allow local (your server only) presence updates/requests. +# +# Note that presence on tuwunel is very fast unlike Synapse's. If using +# outgoing presence, this MUST be enabled. +# +#allow_local_presence = true + +# Allow incoming federated presence updates/requests. +# +# This option receives presence updates from other servers, but does not +# send any unless `allow_outgoing_presence` is true. Note that presence on +# tuwunel is very fast unlike Synapse's. +# +#allow_incoming_presence = true + +# Allow outgoing presence updates/requests. +# +# This option sends presence updates to other servers, but does not +# receive any unless `allow_incoming_presence` is true. Note that presence +# on tuwunel is very fast unlike Synapse's. If using outgoing presence, +# you MUST enable `allow_local_presence` as well. +# +#allow_outgoing_presence = true + +# How many seconds without presence updates before you become idle. +# Defaults to 5 minutes. +# +#presence_idle_timeout_s = 300 + +# How many seconds without presence updates before you become offline. +# Defaults to 30 minutes. +# +#presence_offline_timeout_s = 1800 + +# Enable the presence idle timer for remote users. +# +# Disabling is offered as an optimization for servers participating in +# many large rooms or when resources are limited. Disabling it may cause +# incorrect presence states (i.e. stuck online) to be seen for some remote +# users. +# +#presence_timeout_remote_users = true + +# Suppresses push notifications for users marked as active. (Experimental) +# +# When enabled, users with `Online` presence and recent activity +# (based on presence state and sync activity) won’t receive push +# notifications, reducing duplicate alerts while they're active +# on another client. +# +# Disabled by default to preserve legacy behavior. +# +#suppress_push_when_active = false + +# Allow receiving incoming read receipts from remote servers. +# +#allow_incoming_read_receipts = true + +# Allow sending read receipts to remote servers. +# +#allow_outgoing_read_receipts = true + +# Allow outgoing typing updates to federation. +# +#allow_outgoing_typing = true + +# Allow incoming typing updates from federation. +# +#allow_incoming_typing = true + +# Maximum time federation user can indicate typing. +# +#typing_federation_timeout_s = 30 + +# Minimum time local client can indicate typing. This does not override a +# client's request to stop typing. It only enforces a minimum value in +# case of no stop request. +# +#typing_client_timeout_min_s = 15 + +# Maximum time local client can indicate typing. +# +#typing_client_timeout_max_s = 45 + +# Set this to true for tuwunel to compress HTTP response bodies using +# zstd. This option does nothing if tuwunel was not built with +# `zstd_compression` feature. Please be aware that enabling HTTP +# compression may weaken TLS. Most users should not need to enable this. +# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH +# before deciding to enable this. +# +#zstd_compression = false + +# Set this to true for tuwunel to compress HTTP response bodies using +# gzip. This option does nothing if tuwunel was not built with +# `gzip_compression` feature. Please be aware that enabling HTTP +# compression may weaken TLS. Most users should not need to enable this. +# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH before +# deciding to enable this. +# +# If you are in a large amount of rooms, you may find that enabling this +# is necessary to reduce the significantly large response bodies. +# +#gzip_compression = false + +# Set this to true for tuwunel to compress HTTP response bodies using +# brotli. This option does nothing if tuwunel was not built with +# `brotli_compression` feature. Please be aware that enabling HTTP +# compression may weaken TLS. Most users should not need to enable this. +# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH +# before deciding to enable this. +# +#brotli_compression = false + +# Set to true to allow user type "guest" registrations. Some clients like +# Element attempt to register guest users automatically. +# +#allow_guest_registration = false + +# Set to true to log guest registrations in the admin room. Note that +# these may be noisy or unnecessary if you're a public homeserver. +# +#log_guest_registrations = false + +# Set to true to allow guest registrations/users to auto join any rooms +# specified in `auto_join_rooms`. +# +#allow_guests_auto_join_rooms = false + +# Enable the legacy unauthenticated Matrix media repository endpoints. +# These endpoints consist of: +# - /_matrix/media/*/config +# - /_matrix/media/*/upload +# - /_matrix/media/*/preview_url +# - /_matrix/media/*/download/* +# - /_matrix/media/*/thumbnail/* +# +# The authenticated equivalent endpoints are always enabled. +# +# Defaults to false. +# +#allow_legacy_media = false + +# Fallback to requesting legacy unauthenticated media from remote servers. +# Unauthenticated media was removed in ~2024Q3; enabling this adds +# considerable federation requests which are unlikely to succeed. +# +#request_legacy_media = false + +# This item is undocumented. Please contribute documentation for it. +# +#freeze_legacy_media = true + +# Check consistency of the media directory at startup: +# 1. When `media_compat_file_link` is enabled, this check will upgrade +# media when switching back and forth between Conduit and tuwunel. Both +# options must be enabled to handle this. +# 2. When media is deleted from the directory, this check will also delete +# its database entry. +# +# If none of these checks apply to your use cases, and your media +# directory is significantly large setting this to false may reduce +# startup time. +# +#media_startup_check = true + +# Enable backward-compatibility with Conduit's media directory by creating +# symlinks of media. +# +# This option is only necessary if you plan on using Conduit again. +# Otherwise setting this to false reduces filesystem clutter and overhead +# for managing these symlinks in the directory. This is now disabled by +# default. You may still return to upstream Conduit but you have to run +# tuwunel at least once with this set to true and allow the +# media_startup_check to take place before shutting down to return to +# Conduit. +# +#media_compat_file_link = false + +# Prune missing media from the database as part of the media startup +# checks. +# +# This means if you delete files from the media directory the +# corresponding entries will be removed from the database. This is +# disabled by default because if the media directory is accidentally moved +# or inaccessible, the metadata entries in the database will be lost with +# sadness. +# +#prune_missing_media = false + +# Vector list of regex patterns of server names that tuwunel will refuse +# to download remote media from. +# +# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] +# +#prevent_media_downloads_from = [] + +# List of forbidden server names via regex patterns that we will block +# incoming AND outgoing federation with, and block client room joins / +# remote user invites. +# +# This check is applied on the room ID, room alias, sender server name, +# sender user's server name, inbound federation X-Matrix origin, and +# outbound federation handler. +# +# Basically "global" ACLs. +# +# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] +# +#forbidden_remote_server_names = [] + +# List of forbidden server names via regex patterns that we will block all +# outgoing federated room directory requests for. Useful for preventing +# our users from wandering into bad servers or spaces. +# +# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"] +# +#forbidden_remote_room_directory_server_names = [] + +# Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you +# do not want tuwunel to send outbound requests to. Defaults to +# RFC1918, unroutable, loopback, multicast, and testnet addresses for +# security. +# +# Please be aware that this is *not* a guarantee. You should be using a +# firewall with zones as doing this on the application layer may have +# bypasses. +# +# Currently this does not account for proxies in use like Synapse does. +# +# To disable, set this to be an empty vector (`[]`). +# +# Defaults to: +# ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", +# "192.168.0.0/16", "100.64.0.0/10", "192.0.0.0/24", "169.254.0.0/16", +# "192.88.99.0/24", "198.18.0.0/15", "192.0.2.0/24", "198.51.100.0/24", +# "203.0.113.0/24", "224.0.0.0/4", "::1/128", "fe80::/10", "fc00::/7", +# "2001:db8::/32", "ff00::/8", "fec0::/10"] +# +#ip_range_denylist = + +# Optional IP address or network interface-name to bind as the source of +# URL preview requests. If not set, it will not bind to a specific +# address or interface. +# +# Interface names only supported on Linux, Android, and Fuchsia platforms; +# all other platforms can specify the IP address. To list the interfaces +# on your system, use the command `ip link show`. +# +# example: `"eth0"` or `"1.2.3.4"` +# +#url_preview_bound_interface = + +# Vector list of domains allowed to send requests to for URL previews. +# +# This is a *contains* match, not an explicit match. Putting "google.com" +# will match "https://google.com" and +# "http://mymaliciousdomainexamplegoogle.com" Setting this to "*" will +# allow all URL previews. Please note that this opens up significant +# attack surface to your server, you are expected to be aware of the risks +# by doing so. +# +#url_preview_domain_contains_allowlist = [] + +# Vector list of explicit domains allowed to send requests to for URL +# previews. +# +# This is an *explicit* match, not a contains match. Putting "google.com" +# will match "https://google.com", "http://google.com", but not +# "https://mymaliciousdomainexamplegoogle.com". Setting this to "*" will +# allow all URL previews. Please note that this opens up significant +# attack surface to your server, you are expected to be aware of the risks +# by doing so. +# +#url_preview_domain_explicit_allowlist = [] + +# Vector list of explicit domains not allowed to send requests to for URL +# previews. +# +# This is an *explicit* match, not a contains match. Putting "google.com" +# will match "https://google.com", "http://google.com", but not +# "https://mymaliciousdomainexamplegoogle.com". The denylist is checked +# first before allowlist. Setting this to "*" will not do anything. +# +#url_preview_domain_explicit_denylist = [] + +# Vector list of URLs allowed to send requests to for URL previews. +# +# Note that this is a *contains* match, not an explicit match. Putting +# "google.com" will match "https://google.com/", +# "https://google.com/url?q=https://mymaliciousdomainexample.com", and +# "https://mymaliciousdomainexample.com/hi/google.com" Setting this to "*" +# will allow all URL previews. Please note that this opens up significant +# attack surface to your server, you are expected to be aware of the risks +# by doing so. +# +#url_preview_url_contains_allowlist = [] + +# Maximum amount of bytes allowed in a URL preview body size when +# spidering. Defaults to 256KB in bytes. +# +#url_preview_max_spider_size = 256000 + +# Option to decide whether you would like to run the domain allowlist +# checks (contains and explicit) on the root domain or not. Does not apply +# to URL contains allowlist. Defaults to false. +# +# Example usecase: If this is enabled and you have "wikipedia.org" allowed +# in the explicit and/or contains domain allowlist, it will allow all +# subdomains under "wikipedia.org" such as "en.m.wikipedia.org" as the +# root domain is checked and matched. Useful if the domain contains +# allowlist is still too broad for you but you still want to allow all the +# subdomains under a root domain. +# +#url_preview_check_root_domain = false + +# List of forbidden room aliases and room IDs as strings of regex +# patterns. +# +# Regex can be used or explicit contains matches can be done by just +# specifying the words (see example). +# +# This is checked upon room alias creation, custom room ID creation if +# used, and startup as warnings if any room aliases in your database have +# a forbidden room alias/ID. +# +# example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"] +# +#forbidden_alias_names = [] + +# List of forbidden username patterns/strings. +# +# Regex can be used or explicit contains matches can be done by just +# specifying the words (see example). +# +# This is checked upon username availability check, registration, and +# startup as warnings if any local users in your database have a forbidden +# username. +# +# example: ["administrator", "b[a4]dusernam[3e]", "badphrase"] +# +#forbidden_usernames = [] + +# List of server names to deprioritize joining through. +# +# If a client requests a join through one of these servers, +# they will be tried last. +# +# Useful for preventing failed joins due to timeouts +# from a certain homeserver. +# +#deprioritize_joins_through_servers = ["matrix\.org"] + +# Maximum make_join requests to attempt within each join attempt. Each +# attempt tries a different server, as each server is only tried once; +# though retries can occur when the join request as a whole is retried. +# +#max_make_join_attempts_per_join_attempt = 48 + +# Maximum join attempts to conduct per client join request. Each join +# attempt consists of one or more make_join requests limited above, and a +# single send_join request. This value allows for additional servers to +# act as the join-server prior to reporting the last error back to the +# client, which can be frustrating for users. Therefor the default value +# is greater than one, but less than excessively exceeding the client's +# request timeout, though that may not be avoidable in some cases. +# +#max_join_attempts_per_join_request = 3 + +# Retry failed and incomplete messages to remote servers immediately upon +# startup. This is called bursting. If this is disabled, said messages may +# not be delivered until more messages are queued for that server. Do not +# change this option unless server resources are extremely limited or the +# scale of the server's deployment is huge. Do not disable this unless you +# know what you are doing. +# +#startup_netburst = true + +# Messages are dropped and not reattempted. The `startup_netburst` option +# must be enabled for this value to have any effect. Do not change this +# value unless you know what you are doing. Set this value to -1 to +# reattempt every message without trimming the queues; this may consume +# significant disk. Set this value to 0 to drop all messages without any +# attempt at redelivery. +# +#startup_netburst_keep = 50 + +# Block non-admin local users from sending room invites (local and +# remote), and block non-admin users from receiving remote room invites. +# +# Admins are always allowed to send and receive all room invites. +# +#block_non_admin_invites = false + +# Allow admins to enter commands in rooms other than "#admins" (admin +# room) by prefixing your message with "\!admin" or "\\!admin" followed up +# a normal tuwunel admin command. The reply will be publicly visible to +# the room, originating from the sender. +# +# example: \\!admin debug ping puppygock.gay +# +#admin_escape_commands = true + +# Automatically activate the tuwunel admin room console / CLI on +# startup. This option can also be enabled with `--console` tuwunel +# argument. +# +#admin_console_automatic = false + +# List of admin commands to execute on startup. +# +# This option can also be configured with the `--execute` tuwunel +# argument and can take standard shell commands and environment variables +# +# For example: `./tuwunel --execute "server admin-notice tuwunel has +# started up at $(date)"` +# +# example: admin_execute = ["debug ping puppygock.gay", "debug echo hi"]` +# +#admin_execute = [] + +# Ignore errors in startup commands. +# +# If false, tuwunel will error and fail to start if an admin execute +# command (`--execute` / `admin_execute`) fails. +# +#admin_execute_errors_ignore = false + +# List of admin commands to execute on SIGUSR2. +# +# Similar to admin_execute, but these commands are executed when the +# server receives SIGUSR2 on supporting platforms. +# +#admin_signal_execute = [] + +# Controls the max log level for admin command log captures (logs +# generated from running admin commands). Defaults to "info" on release +# builds, else "debug" on debug builds. +# +#admin_log_capture = "info" + +# The default room tag to apply on the admin room. +# +# On some clients like Element, the room tag "m.server_notice" is a +# special pinned room at the very bottom of your room list. The tuwunel +# admin room can be pinned here so you always have an easy-to-access +# shortcut dedicated to your admin room. +# +#admin_room_tag = "m.server_notice" + +# Whether to grant the first user to register admin privileges by joining +# them to the admin room. Note that technically the next user to register +# when the admin room is empty (or only contains the server-user) is +# granted, and only when the admin room is enabled. +# +#grant_admin_to_first_user = true + +# Whether the admin room is created on first startup. Users should not set +# this to false. Developers can set this to false during integration tests +# to reduce activity and output. +# +#create_admin_room = true + +# Whether to enable federation on the admin room. This cannot be changed +# after the admin room is created. +# +#federate_admin_room = true + +# Sentry.io crash/panic reporting, performance monitoring/metrics, etc. +# This is NOT enabled by default. tuwunel's default Sentry reporting +# endpoint domain is `o4509498990067712.ingest.us.sentry.io`. +# +#sentry = false + +# Sentry reporting URL, if a custom one is desired. +# +#sentry_endpoint = "" + +# Report your tuwunel server_name in Sentry.io crash reports and +# metrics. +# +#sentry_send_server_name = false + +# Performance monitoring/tracing sample rate for Sentry.io. +# +# Note that too high values may impact performance, and can be disabled by +# setting it to 0.0 (0%) This value is read as a percentage to Sentry, +# represented as a decimal. Defaults to 15% of traces (0.15) +# +#sentry_traces_sample_rate = 0.15 + +# Whether to attach a stacktrace to Sentry reports. +# +#sentry_attach_stacktrace = false + +# Send panics to Sentry. This is true by default, but Sentry has to be +# enabled. The global `sentry` config option must be enabled to send any +# data. +# +#sentry_send_panic = true + +# Send errors to sentry. This is true by default, but sentry has to be +# enabled. This option is only effective in release-mode; forced to false +# in debug-mode. +# +#sentry_send_error = true + +# Controls the tracing log level for Sentry to send things like +# breadcrumbs and transactions +# +#sentry_filter = "info" + +# Enable the tokio-console. This option is only relevant to developers. +# +# For more information, see: +# https://tuwunel.chat/development.html#debugging-with-tokio-console +# +#tokio_console = false + +# Arbitrary argument vector for integration testing. Functionality in the +# server is altered or informed for the requirements of integration tests. +# - "smoke" performs a shutdown after startup admin commands rather than +# hanging on client handling. +# +#test = [] + +# Controls whether admin room notices like account registrations, password +# changes, account deactivations, room directory publications, etc will be +# sent to the admin room. Update notices and normal admin command +# responses will still be sent. +# +#admin_room_notices = true + +# Save original events before applying redaction to them. +# +# They can be retrieved with `admin debug get-retained-pdu` or MSC2815. +# +#save_unredacted_events = true + +# Redaction retention period in seconds. +# +# By default the unredacted events are stored for 60 days. +# +#redaction_retention_seconds = 5184000 + +# Allows users with `redact` power level to request unredacted events with +# MSC2815. +# +# Server admins can request unredacted events regardless of the value of +# this option. +# +#allow_room_admins_to_request_unredacted_events = true + +# Prevents local users from sending redactions. +# +# This check does not apply to server admins. +# +#disable_local_redactions = false + +# Enable database pool affinity support. On supporting systems, block +# device queue topologies are detected and the request pool is optimized +# for the hardware; db_pool_workers is determined automatically. +# +#db_pool_affinity = true + +# Sets the number of worker threads in the frontend-pool of the database. +# This number should reflect the I/O capabilities of the system, +# such as the queue-depth or the number of simultaneous requests in +# flight. Defaults to 32 times the number of CPU cores. +# +# Note: This value is only used if db_pool_affinity is disabled or not +# detected on the system, otherwise it is determined automatically. +# +#db_pool_workers = 32 + +# When db_pool_affinity is enabled and detected, the size of any worker +# group will not exceed the determined value. This is necessary when +# thread-pooling approach does not scale to the full capabilities of +# high-end hardware; using detected values without limitation could +# degrade performance. +# +# The value is multiplied by the number of cores which share a device +# queue, since group workers can be scheduled on any of those cores. +# +#db_pool_workers_limit = 64 + +# Limits the total number of workers across all worker groups. When the +# sum of all groups exceeds this value the worker counts are reduced until +# this constraint is satisfied. +# +# By default this value is only effective on larger systems (e.g. 16+ +# cores) where it will tamper the overall thread-count. The thread-pool +# model will never achieve hardware capacity but this value can be raised +# on huge systems if the scheduling overhead is determined to not +# bottleneck and the worker groups are divided too small. +# +#db_pool_max_workers = 2048 + +# Determines the size of the queues feeding the database's frontend-pool. +# The size of the queue is determined by multiplying this value with the +# number of pool workers. When this queue is full, tokio tasks conducting +# requests will yield until space is available; this is good for +# flow-control by avoiding buffer-bloat, but can inhibit throughput if +# too low. +# +#db_pool_queue_mult = 4 + +# Sets the initial value for the concurrency of streams. This value simply +# allows overriding the default in the code. The default is 32, which is +# the same as the default in the code. Note this value is itself +# overridden by the computed stream_width_scale, unless that is disabled; +# this value can serve as a fixed-width instead. +# +#stream_width_default = 32 + +# Scales the stream width starting from a base value detected for the +# specific system. The base value is the database pool worker count +# determined from the hardware queue size (e.g. 32 for SSD or 64 or 128+ +# for NVMe). This float allows scaling the width up or down by multiplying +# it (e.g. 1.5, 2.0, etc). The maximum result can be the size of the pool +# queue (see: db_pool_queue_mult) as any larger value will stall the tokio +# task. The value can also be scaled down (e.g. 0.5) to improve +# responsiveness for many users at the cost of throughput for each. +# +# Setting this value to 0.0 causes the stream width to be fixed at the +# value of stream_width_default. The default scale is 1.0 to match the +# capabilities detected for the system. +# +#stream_width_scale = 1.0 + +# Sets the initial amplification factor. This controls batch sizes of +# requests made by each pool worker, multiplying the throughput of each +# stream. This value is somewhat abstract from specific hardware +# characteristics and can be significantly larger than any thread count or +# queue size. This is because each database query may require several +# index lookups, thus many database queries in a batch may make progress +# independently while also sharing index and data blocks which may or may +# not be cached. It is worthwhile to submit huge batches to reduce +# complexity. The maximum value is 32768, though sufficient hardware is +# still advised for that. +# +#stream_amplification = 1024 + +# Number of sender task workers; determines sender parallelism. Default is +# '0' which means the value is determined internally, likely matching the +# number of tokio worker-threads or number of cores, etc. Override by +# setting a non-zero value. +# +#sender_workers = 0 + +# Enables listener sockets; can be set to false to disable listening. This +# option is intended for developer/diagnostic purposes only. +# +#listening = true + +# Enables configuration reload when the server receives SIGUSR1 on +# supporting platforms. +# +#config_reload_signal = true + +# Sets the `Access-Control-Allow-Origin` header included by this server in +# all responses. A list of multiple values can be specified. The default +# is an empty list. The actual header defaults to `*` upon an empty list. +# +# There is no reason to configure this without specific intent. Incorrect +# values may degrade or disrupt clients. +# +#access_control_allow_origin = [] + +# Backport state-reset security fixes to all room versions. +# +# This option applies the State Resolution 2.1 mitigation developed during +# project Hydra for room version 12 to all prior State Resolution 2.0 room +# versions (all room versions supported by this server). These mitigations +# increase resilience to state-resets without any new definition of +# correctness; therefor it is safe to set this to true for existing rooms. +# +# Furthermore, state-reset attacks are not consistent as they result in +# rooms without any single consensus, therefor it is unnecessary to set +# this to false to match other servers which set this to false or simply +# lack support; even if replicating the post-reset state suffered by other +# servers is somehow desired. +# +# This option exists for developer and debug use, and as a failsafe in +# lieu of hardcoding it. +# +#hydra_backports = true + +# Delete rooms when the last user from this server leaves. This feature is +# experimental and for the purpose of least-surprise is not enabled by +# default but can be enabled for deployments interested in conserving +# space. It may eventually default to true in a future release. +# +# Note that not all pathways which can remove the last local user +# currently invoke this operation, so in some cases you may find the room +# still exists. +# +#delete_rooms_after_leave = false + +# Limits the number of One Time Keys per device (not per-algorithm). The +# reference implementation maintains 50 OTK's at any given time, therefor +# our default is at least five times that. There is no known reason for an +# administrator to adjust this value; it is provided here rather than +# hardcoding it. +# +#one_time_key_limit = 256 + +# (EXPERIMENTAL) Setting this option to true replaces the list of identity +# providers displayed on a client's login page with a single button "Sign +# in with single sign-on" linking to the URL +# `/_matrix/client/v3/login/sso/redirect`. All configured providers are +# attempted for authorization. All authorizations associate with the same +# Matrix user. NOTE: All authorizations must succeed, as there is no +# reliable way to skip a provider. +# +# This option is disabled by default, allowing the client to list +# configured providers and permitting privacy-conscious users to authorize +# only their choice. +# +# Note that fluffychat always displays a single button anyway. You do not +# need to enable this to use fluffychat; instead we offer a +# default-provider option, see `default` in the provider config section. +# +#single_sso = false + +# Setting this option to true replaces the list of identity providers on +# the client's login screen with a single button "Sign in with single +# sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The +# deployment is expected to intercept this URL with their reverse-proxy to +# provide a custom webpage listing providers; each entry linking or +# redirecting back to one of the configured identity providers at +# /_matrix/client/v3/login/sso/redirect/`. +# +# This option defaults to false, allowing the client to generate the list +# of providers or hide all SSO-related options when none configured. +# +#sso_custom_providers_page = false + +# Under development; do not enable. +# +#sso_aware_preferred = false + + + +#[global.tls] + +# Path to a valid TLS certificate file. +# +# example: "/path/to/my/certificate.crt" +# +#certs = + +# Path to a valid TLS certificate private key. +# +# example: "/path/to/my/certificate.key" +# +#key = + +# Whether to listen and allow for HTTP and HTTPS connections (insecure!) +# +#dual_protocol = false + + + +#[global.well_known] + +# The server URL that the client well-known file will serve. This should +# not contain a port, and should just be a valid HTTPS URL. +# +# example: "https://matrix.example.com" +# +#client = + +# The server base domain of the URL with a specific port that the server +# well-known file will serve. This should contain a port at the end, and +# should not be a URL. +# +# example: "matrix.example.com:443" +# +#server = + +# The URL of the support web page. This and the below generate the content +# of `/.well-known/matrix/support`. +# +# example: "https://example.com/support" +# +#support_page = + +# The name of the support role. +# +# example: "m.role.admin" +# +#support_role = + +# The email address for the above support role. +# +# example: "admin@example.com" +# +#support_email = + +# The Matrix User ID for the above support role. +# +# example "@admin:example.com" +# +#support_mxid = + +# Element Call / MatrixRTC configuration (MSC4143). +# Configures the LiveKit SFU server for voice/video calls. +# +# Requires a LiveKit server with JWT authentication. +# The `livekit_service_url` should point to your LiveKit JWT endpoint. +# +# Note: You must also set `client` above to your homeserver URL. +# +# Example: +# ```toml +# [global.well_known] +# client = "https://matrix.yourdomain.com" +# +# [[global.well_known.rtc_transports]] +# type = "livekit" +# livekit_service_url = "https://livekit.yourdomain.com" +# ``` +# +#rtc_transports = [] + + + +#[global.blurhashing] + +# blurhashing x component, 4 is recommended by https://blurha.sh/ +# +#components_x = 4 + +# blurhashing y component, 3 is recommended by https://blurha.sh/ +# +#components_y = 3 + +# Max raw size that the server will blurhash, this is the size of the +# image after converting it to raw data, it should be higher than the +# upload limit but not too high. The higher it is the higher the +# potential load will be for clients requesting blurhashes. The default +# is 33.55MB. Setting it to 0 disables blurhashing. +# +#blurhash_max_raw_size = 33554432 + + + +#[global.ldap] + +# Whether to enable LDAP login. +# +# example: "true" +# +#enable = false + +# URI of the LDAP server. +# +# example: "ldap://ldap.example.com:389" +# +#uri = + +# Root of the searches. +# +# example: "ou=users,dc=example,dc=org" +# +#base_dn = + +# Bind DN if anonymous search is not enabled. +# +# You can use the variable `{username}` that will be replaced by the +# entered username. In such case, the password used to bind will be the +# one provided for the login and not the one given by +# `bind_password_file`. Beware: automatically granting admin rights will +# not work if you use this direct bind instead of a LDAP search. +# +# example: "cn=ldap-reader,dc=example,dc=org" or +# "cn={username},ou=users,dc=example,dc=org" +# +#bind_dn = "" + +# Path to a file on the system that contains the password for the +# `bind_dn`. +# +# The server must be able to access the file, and it must not be empty. +# +#bind_password_file = "" + +# Search filter to limit user searches. +# +# You can use the variable `{username}` that will be replaced by the +# entered username for more complex filters. +# +# example: "(&(objectClass=person)(memberOf=matrix))" +# +#filter = "(objectClass=*)" + +# Attribute to use to uniquely identify the user. +# +# example: "uid" or "cn" +# +#uid_attribute = "uid" + +# Attribute containing the mail of the user. +# +# example: "mail" +# +#mail_attribute = "mail" + +# Attribute containing the distinguished name of the user. +# +# example: "givenName" or "sn" +# +#name_attribute = "givenName" + +# Root of the searches for admin users. +# +# Defaults to `base_dn` if empty. +# +# example: "ou=admins,dc=example,dc=org" +# +#admin_base_dn = + +# The LDAP search filter to find administrative users for tuwunel. +# +# If left blank, administrative state must be configured manually for each +# user. +# +# You can use the variable `{username}` that will be replaced by the +# entered username for more complex filters. +# +# example: "(objectClass=tuwunelAdmin)" or "(uid={username})" +# +#admin_filter = + + + +#[global.jwt] + +# Enable JWT logins +# +#enable = false + +# Validation key, also called 'secret' in Synapse config. The type of key +# can be configured in 'format', but defaults to the common HMAC which +# is a plaintext shared-secret, so you should keep this value private. +# +#key = + +# Format of the 'key'. Only HMAC, ECDSA, and B64HMAC are supported +# Binary keys cannot be pasted into this config, so B64HMAC is an +# alternative to HMAC for properly random secret strings. +# - HMAC is a plaintext shared-secret private-key. +# - B64HMAC is a base64-encoded version of HMAC. +# - ECDSA is a PEM-encoded public-key. +# - EDDSA is a PEM-encoded Ed25519 public-key. +# +#format = "HMAC" + +# Automatically create new user from a valid claim, otherwise access is +# denied for an unknown even with an authentic token. +# +#register_user = true + +# JWT algorithm +# +#algorithm = "HS256" + +# Optional audience claim list. The token must claim one or more values +# from this list when set. +# +#audience = [] + +# Optional issuer claim list. The token must claim one or more values +# from this list when set. +# +#issuer = [] + +# Require expiration claim in the token. This defaults to false for +# synapse migration compatibility. +# +#require_exp = false + +# Require not-before claim in the token. This defaults to false for +# synapse migration compatibility. +# +#require_nbf = false + +# Validate expiration time of the token when present. Whether or not it is +# required depends on require_exp, but when present this ensures the token +# is not used after a time. +# +#validate_exp = true + +# Validate not-before time of the token when present. Whether or not it is +# required depends on require_nbf, but when present this ensures the token +# is not used before a time. +# +#validate_nbf = true + +# Bypass validation for diagnostic/debug use only. +# +#validate_signature = true + + + +#[[global.identity_provider]] + +# The brand-name of the service (e.g. Apple, Facebook, GitHub, GitLab, +# Google) or the software (e.g. keycloak, MAS) providing the identity. +# When a brand is recognized we apply certain defaults to this config +# for your convenience. For certain brands we apply essential internal +# workarounds specific to that provider; it is important to configure this +# field properly when a provider needs to be recognized (like GitHub for +# example). +# +# Several configured providers can share the same brand name. It is not +# case-sensitive. As a convenience for common simple deployments we can +# identify this provider by brand in addition to the unique `client_id` if +# and only if there is a single provider for the brand; see notes for +# `client_id`. +# +#brand = + +# The ID of your OAuth application which the provider generates upon +# registration. This ID then uniquely identifies this configuration +# instance itself, becoming the identity provider's ID and must be unique +# and remain unchanged. +# +# As a convenience we also identify this config by `brand` if and only if +# there is a single provider configured for a `brand`. Note carefully that +# multiple providers configured with the same `brand` is not an error and +# this provider will simply not be found when querying by `brand`. +# +#client_id = + +# Secret key the provider generated for you along with the `client_id` +# above. Unlike the `client_id`, the `client_secret` can be changed here +# whenever the provider regenerates one for you. +# +#client_secret = + +# Secret key to use that's read from the file path specified. +# +# This takes priority over "client_secret" first, and falls back to +# "client_secret" if invalid or failed to open. +# +# example: "/etc/tuwunel/.client_secret" +# +#client_secret_file = + +# Issuer URL the provider publishes for you. We have pre-supplied default +# values for some of the canonical public providers, making this field +# optional based on the `brand` set above. Otherwise it is required to +# find self-hosted providers. It must be identical to what is configured +# and expected by the provider and must never change because we associate +# identities to it. If the `/.well-known/openid-configuration` is not +# found behind this URL see `base_path` below as a workaround. +# +#issuer_url = + +# The callback URL configured when registering the OAuth application with +# the provider. Tuwunel's callback URL must be strictly formatted exactly +# as instructed. The URL host must point directly at the matrix server and +# use the following path: +# `/_matrix/client/unstable/login/sso/callback/` where +# `` is the same one configured for this provider above. +# +#callback_url = + +# When more than one identity_provider has been configured and +# `single_sso` is false and `sso_custom_providers_page` is false this will +# determine the behavior of the `/_matrix/client/v3/login/sso/redirect` +# endpoint (note the url lacks a trailing `client_id`). +# +# When only one identity_provider is configured it will be interpreted +# as the default and this does not need to be set. Otherwise a default +# *must* be selected for some clients (e.g. fluffychat) to work properly +# when the above conditions require it. To operate out-of-the-box we +# default to one configured provider if none are explicitly default; a +# warning will be logged on startup for this condition. +# +# (EXPERIMENTAL) Multiple providers can be set to default. All providers +# configured with this option set to `true` will associate with the same +# Matrix account when a client flows through +# `/_matrix/client/v3/login/sso/redirect`. +# +# When a user authorizes any provider configured default, the flow will +# include all other providers configured default as well for association. +# NOTE: authorization must succeed for ALL default providers. +# +#default = false + +# Optional display-name for this provider instance seen on the login page +# by users. It defaults to `brand`. When configuring multiple providers +# using the same `brand` this can be set to distinguish them. +# +#name = + +# Optional icon for the provider. The canonical providers have a default +# icon based on the `brand` supplied above when this is not supplied. Note +# that it uses an MXC url which is curious in the auth-media era and may +# not be reliable. +# +#icon = + +# Optional list of scopes to authorize. An empty array does not impose any +# restrictions from here, effectively defaulting to all scopes you +# configured for the OAuth application at the provider. This setting +# allows for restricting to a subset of those scopes for this instance. +# Note the user can further restrict scopes during their authorization. +# +#scope = [] + +# Optional list of userinfo claims which shape and restrict the way we +# compute a Matrix UserId for new registrations. Reviewing Tuwunel's +# documentation will be necessary for a complete description in detail. An +# empty array imposes no restriction here, avoiding generated fallbacks as +# much as possible. For simplicity we reserve a claim called "unique" +# which can be listed alone to ensure *only* generated ID's are used for +# registrations. +# +#userid_claims = [] + +# Optional extra path components after the issuer_url leading to the +# location of the `.well-known` directory used for discovery. If the path +# starts with a slash it will be treated as absolute, meaning overwriting +# any path in the issuer_url. The path needs to end with a slash. This +# will be empty for specification-compliant providers. We have supplied +# any known values based on `brand` (e.g. `login/oauth/` for GitHub). +# +#base_path = + +# Overrides the `.well-known` location where the provider's openid +# configuration is found. It is very unlikely you will need to set this; +# available for developers or special purposes only. +# +#discovery_url = + +# Overrides the authorize URL requested during the grant phase. This is +# generally discovered or derived automatically, but may be required as a +# workaround for any non-standard or undiscoverable provider. +# +#authorization_url = + +# Overrides the access token URL; the same caveats apply as with the other +# URL overrides. +# +#token_url = + +# Overrides the revocation URL; the same caveats apply as with the other +# URL overrides. +# +#revocation_url = + +# Overrides the introspection URL; the same caveats apply as with the +# other URL overrides. +# +#introspection_url = + +# Overrides the userinfo URL; the same caveats apply as with the other URL +# overrides. +# +#userinfo_url = + +# Whether to perform discovery and adjust this provider's configuration +# accordingly. This defaults to true. When true, it is an error when +# discovery fails and authorizations will not be attempted to the +# provider. +# +#discovery = true + +# The duration in seconds before a grant authorization session expires. +# +#grant_session_duration = 300 + + + +#[global.appservice.] + +# The URL for the application service. +# +# Optionally set to `null` if no traffic is required. +# +#url = + +# A unique token for application services to use to authenticate requests +# to Homeservers. +# +#as_token = + +# A unique token for Homeservers to use to authenticate requests to +# application services. +# +#hs_token = + +# The localpart of the user associated with the application service. +# +#sender_localpart = + +# Whether requests from masqueraded users are rate-limited. +# +# The sender is excluded. +# +#rate_limited = false + +# The external protocols which the application service provides (e.g. +# IRC). +# +#protocols = [] + +# Whether the application service wants to receive ephemeral data. +# +#receive_ephemeral = false + +# Whether the application service wants to do device management, as part +# of MSC4190. +# +#device_management = false + + + +#[[global.appservice..]] + +# Whether this application service has exclusive access to events within +# this namespace. +# +#exclusive = false + +# A regular expression defining which values this namespace includes. +# +#regex =