Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
- [Introduction](introduction.md)
- [Configuration](configuration.md)
- [Examples](configuration/examples.md)
- [OpenID Connect](configuration/openid-connect.md)
- [Deploying](deploying.md)
- [Generic](deploying/generic.md)
- [Reverse Proxy - Caddy](deploying/reverse-proxy-caddy.md)
- [Reverse Proxy - Nginx](deploying/reverse-proxy-nginx.md)
- [Reverse Proxy - Traefik](deploying/reverse-proxy-traefik.md)
- [NixOS](deploying/nixos.md)
- [Docker](deploying/docker.md)
- [Containers](deploying/containers.md)
- [Docker](deploying/docker.md)
- [Podman](deploying/podman-systemd.md)
- [Kubernetes](deploying/kubernetes.md)
- [Arch Linux](deploying/arch-linux.md)
- [Debian](deploying/debian.md)
Expand Down
40 changes: 40 additions & 0 deletions docs/configuration/openid-connect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# OpenID Connect / OIDC

## Keycloak

Keycloak is a self-hostable OpenID Connect provider.

> Ensure your matrix .well-known values are being served correctly before beginning. Such as with [matrixtest](../troubleshooting.md#matrixrtc-testing-tools)

### Keycloak configuration

1. Create client on your keycloak server:
- Ensure `Client Authentication` is toggled `on`
- Root Url = `https://<your.matrix.example.com>`
- Valid Redirect Urls = `https://<your.matrix.tld.example.com>/_matrix/client/unstable/login/sso/callback/<client_id>`
- Web Origins = `https://<your.matrix.example.com>`
2. Navigate to the Client Credentials tab, note the value of `client secret`
3. Note the `realm` you are creating the client in.

### Tuwunel configuration

Add the following identity provider section to you tuwunel.toml config file. Replace the `< placeholders>` with the values noted in your keycloak `client`.

#### tuwunel.toml
```toml

[[global.identity_provider]]
brand = 'keycloak'
client_id = '<client_id_in_keycloak>'
client_secret = '<client_secret_from_credentials_tab_in_keycloak>'
issuer_url = 'https://<your.keycloak.example.com>/realms/<realm_name>'
```
#### Environment variables
Example Environment variables that can be added to a `docker-compose.yaml` or podman `tuwunel.env` if preferred:

```env
TUWUNEL_IDENTITY_PROVIDER__0__BRAND="keycloak"
TUWUNEL_IDENTITY_PROVIDER__0__CLIENT_ID="<client_id>"
TUWUNEL_IDENTITY_PROVIDER__0__CLIENT_SECRET="<secret>"
TUWUNEL_IDENTITY_PROVIDER__0__ISSUER_URL="https://<your.keycloak.example.com>/realm/<realm_name>"
```
3 changes: 3 additions & 0 deletions docs/deploying/containers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Containers
Tuwunel can be deployed in containers such as [Docker](docker.md) or [Podman](podman-systemd.md).

76 changes: 70 additions & 6 deletions docs/deploying/podman-systemd.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,80 @@
# tuwunel in Podman systemd
# Podman, Quadlets, and systemd

Copy [tuwunel.container](tuwunel.container) to ~/.config/containers/systemd/tuwunel.container.
Reload daemon:
For a rootless setup, we can use quadlets and systemd to manage the container lifecycle.

> If this is the first container managed with quadlets for your user, ensure that linger is enabled so your containers are not killed after logging out.
>
> `sudo loginctl enable-linger <username>`

## Installation
1. Copy quadlet files to `~/.config/containers/systemd/tuwunel`

### tuwunel.container

<details>
<summary>tuwunel container quadlet</summary>

```
{{#include ../../quadlet/tuwunel.container}}
```

</details>

### tuwunel-db.volume

<details>
<summary>tuwunel database volume quadlet</summary>

```
{{#include ../../quadlet/tuwunel-db.volume}}
```

</details>

### tuwunel.env

<details>
<summary>tuwunel environment variable quadlet</summary>

```env
{{#include ../../quadlet/tuwunel.env}}
```

</details>




```
mkdir -p ~/.config/containers/systemd/tuwunel
```

2.
- Modify tuwunel.env to desired values.
- Modify [tuwenel.toml](generic.md#creating-the-tuwunel-configuration-file) to desired values. This can be saved in your user home directory if desired.

3. Reload daemon to generate our systemd unit files:
```
systemctl --user daemon-reload
```
Start the service:
4. Start tuwunel:
```
systemctl --user start tuwunel
```

## Logging
To check the logs, run:
```
journalctl -eu tuwunel.container --user
systemctl --user status tuwunel
```
or

```
podman logs tuwunel-homeserver
```
#### Troubleshooting systemd unit file generation

Look for errors in the output:


`/usr/lib/systemd/system-generators/podman-system-generator --user --dryrun`

4 changes: 4 additions & 0 deletions docs/deploying/redhat.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
{{#include ../../rpm/README.md}}

## Podman / Quadlets

Podman and Quadlets are well supported on Redhat-based distributions. See [Podman and systemd](podman-systemd.md) for examples.
23 changes: 23 additions & 0 deletions docs/deploying/reverse-proxy-caddy.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ After starting Caddy, verify it's working by checking:
curl https://your.server.name/_tuwunel/server_version
curl https://your.server.name:8448/_tuwunel/server_version
```
## Caddy and .well-known

Caddy can serve `.well-known/matrix/client` and `.well-known/matrix/server` instead of `tuwunel`. This can be done by using the `respond` directive in your caddyfile.

Useful if you want to delegate a domain such as `example.com` -> `matrix.example.com`.

> [!info] Note the use of \` (backtic) in the respond directive to escape JSON that contains \" (double quotes).

```caddyfile
your.server.name, your.server.name:8848 {

@matrix path /.well-known/matrix/*
#Recommended CORS headers (https://spec.matrix.org/v1.17/client-server-api/#well-known-uris)
header @matrix {
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization
}
respond /.well-known/matrix/client `{"m.homeserver": {"base_url":"https://<your.server.name>"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://<your.matrix-rtc-jwt.server>"}]} `
respond /.well-known/matrix/server `{"m.server": "<your.server.name>:443"}`
}
```


---

Expand Down
16 changes: 8 additions & 8 deletions docs/maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ running compaction is not recommended, or compaction via a timer, due to
creating unnecessary I/O amplification. RocksDB is built with io_uring support
via liburing for improved read performance.

RocksDB troubleshooting can be found [in the RocksDB section of troubleshooting](troubleshooting.md).
RocksDB troubleshooting can be found [in the RocksDB section of troubleshooting](troubleshooting.md#rocksdb--database-issues).

### Compression

Expand Down Expand Up @@ -77,15 +77,14 @@ would like to store nearly none at all, see the `rocksdb_max_log_files`
config option.

## Backups
### Online
Currently only RocksDB supports online backups.

Currently only RocksDB supports online backups. If you'd like to backup your
database online without any downtime, see the `!admin server` command for the
backup commands and the `database_backup_path` config options in the example
config. Please note that the format of the database backup is not the exact
same. This is unfortunately a bad design choice by Facebook as we are using the
database backup engine API from RocksDB, however the data is still there and can
still be joined together.
If you'd like to backup your database online without any downtime, see the `!admin server` command for the backup commands and the `database_backup_path` config options in the example config.

Please note that the format of the database backup is not the exact same. This is unfortunately a bad design choice by Facebook as we are using the database backup engine API from RocksDB, however the data is still there and can still be joined together.

#### Restoring online backup
To restore a backup from an online RocksDB backup:

- shutdown Tuwunel
Expand All @@ -101,6 +100,7 @@ if you have multiple) to your new directory
old one with the new one you crafted
- start up Tuwunel again and it should open as normal

### Offline
If you'd like to do an offline backup, shutdown Tuwunel and copy your
`database_path` directory elsewhere. This can be restored with no modifications
needed.
Expand Down
29 changes: 29 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,32 @@ and is not easy for non-developers to understand.

[unbound-tuning]: https://unbound.docs.nlnetlabs.nl/en/latest/topics/core/performance.html
[unbound-arch]: https://wiki.archlinux.org/title/Unbound

#### MatrixRTC testing tools
[testmatrix](https://pypi.org/project/testmatrix/) is a command line tool for testing various aspects of a matrix server and guiding debugging.

```
$ ./test_matrix.py -u <my-user> -t <token that can be extracted from element-web: all settings: help and about: advanced> example.com
Testing server example.com
Federation url: https://matrix.example.com:443
✔ Server well-known exists
✔ Client well-known has proper CORS header
Client url: https://matrix.example.com
Adding livekit service URL: https://matrixrtc.example.com/livekit/jwt
✔ Server version: Tuwunel (1.5.0)
✔ Federation API endpoints seem to work fine
✔ Client API endpoints seem to work fine
Server oauth metadata endpoint failed (spec 1.15)
QR code login is disabled (MSC 4108)
Public room directory is disabled
✔ MatrixRTC SFU configured
Adding livekit service URL: https://matrixrtc.example.com/livekit/jwt
✔ JWTauth healthz responds
✔ jwt /get_token without auth returns 405, good.
✔ /get_token succeeded. Use the below information to test your livekit SFU on https://livekit.io/connection-test
[...]
𐄂 MatrixRTC configured but delayed events turned off (MSC4140). BAD!
✔ Room summaries (MSC3266) support in matrix compat v1.15
✔ Room summaries stable support works
𐄂 Direct open registration might not be forbidden (returned 401)!
```
2 changes: 2 additions & 0 deletions quadlet/tuwunel-db.volume
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Volume]
VolumeName=tuwunel-db
21 changes: 21 additions & 0 deletions quadlet/tuwunel.container
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# tuwenel.container

[Unit]
Description=Tuwunel Matrix Homeserver

[Container]
ContainerName=tuwunel-homeserver
Image=ghcr.io/matrix-construct/tuwunel:latest
PublishPort=8008:8008
Volume=tuwunel-db:/var/lib/tuwunel/

#Example location in ~/tuwunel/confing/
Volume=%h/tuwunel/config/tuwunel.toml:/etc/tuwunel.toml
EnvironmentFile=tuwunel.env

[Service]
# Uncomment when your system is properly configured, restart=always can mask start up errors.
#Restart=always

[Install]
WantedBy=default.target
15 changes: 15 additions & 0 deletions quadlet/tuwunel.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
TUWUNEL_SERVER_NAME="your.server.tld"
TUWUNEL_PORT=8008
TUWUNEL_MAX_REQUEST_SIZE=20000000
TUWUNEL_ALLOW_REGISTRATION=true
TUWUNEL_REGISTRATION_TOKEN=<replace with a passphrase or random string>
TUWUNEL_ALLOW_FEDERATION=true
TUWUNEL_TRUSTED_SERVERS=["matrix.org"]
TUWUNEL_LOG=info

#Listen on this host for IPv4 and v6
TUWUNEL_ADDRESS=["0.0.0.0", "::"]

#Tell Tuwunel to use the user config file
TUWUNEL_CONFIG=/etc/tuwunel.toml