Tuwunel for Docker
Matrixプロトコルに準拠したサーバTumunelをDockerコンテナで運用するためのティップス。
Matrix
Matrix:分散型ネットワークで通信するためのオープンプロトコル。異なるサーバ間でリアルタイムにメッセージなどの送受信を可能にします(エンドツーエンド暗号化対応)。
Matrix対応サーバ
Matrix対応クライアント
Tumunel GitHub
Matrixプロトコルに準拠したサーバアプリケーション。ソースコードはRustで記述。
Official successor to conduwuit
設定ファイル(サンプル)
### 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]
このファイルは切り詰められています。 オリジナルを表示
Tuwunel Dockerコンテナ
リバースプロキシ:Caddyコンテナ
TLS認証を自動化するために採用。
Caddy as a reverse proxy for Docker
Caddy
Turnサーバ:Coturnの設定
turnserver.conf
# Coturn TURN SERVER configuration file
#
# Boolean values note: where a boolean value is supposed to be used,
# you can use '0', 'off', 'no', 'false', or 'f' as 'false',
# and you can use '1', 'on', 'yes', 'true', or 't' as 'true'
# If the value is missing, then it means 'true' by default.
#
# Listener interface device (optional, Linux only).
# NOT RECOMMENDED.
#
#listening-device=eth0
# TURN listener port for UDP and TCP (Default: 3478).
# Note: actually, TLS & DTLS sessions can connect to the
# "plain" TCP & UDP port(s), too - if allowed by configuration.
#
#listening-port=3478
# TURN listener port for TLS (Default: 5349).
このファイルは切り詰められています。 オリジナルを表示
Element : Matrixクライアント
Elementから提供されている以下のオープンソースMatrixクライアントで、音声・ビデオ通話、メッセージを送受信。
element x android
Android Matrix messenger application using the Matrix Rust Sdk and Jetpack Compose
element x ios
Next generation Matrix client for iOS built with SwiftUI on top of matrix-rust-sdk.
element web
ウェブアプリ
A glossy Matrix collaboration client for the web.
element-call
上記アプリの音声・ビデオ通話機能は、以下のelement-callが担っています。
Group calls powered by Matrix
Self-Hosting Element Call
# Self-Hosting Element Call
> [!NOTE]
> For In-App calling (Element X, Element Web, Element Desktop) use-case only
> section [Prerequisites](#Prerequisites) is required.
## Prerequisites
> [!IMPORTANT]
> This section covers the requirements for deploying a **Matrix site**
> compatible with MatrixRTC, the foundation of Element Call. These requirements
> apply to both Standalone as well as Widget mode operation of Element Call.
### A Matrix Homeserver
The following [MSCs](https://github.com/matrix-org/matrix-spec-proposals) are
required for Element Call to work properly:
- **[MSC3266](https://github.com/deepbluev7/matrix-doc/blob/room-summaries/proposals/3266-room-summary.md):
Room Summary API**: In Standalone mode Element Call is able to join rooms
このファイルは切り詰められています。 オリジナルを表示
参考
システム構成
構成ファイル
docker-compose.yaml
services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
container_name: caddy
ports:
- 80:80
- 443:443
environment:
- CADDY_INGRESS_NETWORKS=caddy
- CADDY_DOCKER_CADDYFILE_PATH=/config/caddy/Caddyfile
networks:
- caddy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
- ./Caddyfile:/config/caddy/Caddyfile
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
homeserver:
image: jevolk/tuwunel:latest
container_name: tuwunel
restart: unless-stopped
volumes:
- ./db:/var/lib/tuwunel
- ./tuwunel.toml:/etc/tuwunel.toml
environment:
TUWUNEL_CONFIG: '/etc/tuwunel.toml'
networks:
- caddy
matrix-rtc-jwt:
image: ghcr.io/element-hq/lk-jwt-service:latest
container_name: jwt
environment:
- LIVEKIT_JWT_BIND=:8081
- LIVEKIT_URL=wss://matrix-rtc.example.com
- LIVEKIT_KEY=${MRTCKEY}
- LIVEKIT_SECRET=${MRTCSECRET}
- LIVEKIT_FULL_ACCESS_HOMESERVERS=matrix.example.com
restart: unless-stopped
networks:
- caddy
matrix-rtc-livekit:
image: livekit/livekit-server:latest
container_name: livekit
command: --config /etc/livekit.yaml
restart: unless-stopped
volumes:
- ./livekit.yaml:/etc/livekit.yaml:ro
network_mode: "host"
# Certbot just only for Coturn TLS
certbot:
image: certbot/dns-cloudflare
container_name: certbot
restart: unless-stopped
volumes:
- ./certbot/certs:/etc/letsencrypt
- ./certbot/cloudflare.ini:/etc/letsencrypt/cloudflare.ini:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./certbot/deploy-hook.sh:/etc/letsencrypt/renewal-hooks/deploy/restart-coturn.sh:ro
entrypoint: /bin/sh -c
command: >
"certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
--dns-cloudflare-propagation-seconds 30
-d turn.example.com
--email [email protected]
--agree-tos
--non-interactive
&& trap exit TERM;
while :; do
sleep 12h &
wait $${!};
certbot renew --quiet;
done"
coturn:
image: docker.io/coturn/coturn
container_name: coturn
restart: unless-stopped
network_mode: host
user: root
volumes:
- ./turnserver.conf:/etc/coturn/turnserver.conf
- ./certbot/certs:/etc/letsencrypt:ro
networks:
caddy:
external: true
注)
- LIVEKIT_KEY=${MRTCKEY} —> “$ pwgen -s 20 1” で生成した文字列を.envに記載
- LIVEKIT_SECRET=${MRTCSECRET} ”$ pwgen -s 64 1”で生成した文字列を.envに記載
Caddyfile
matrix.example.com {
handle /.well-known/matrix/server {
header Content-Type "application/json"
respond `{"m.server":"matrix.example.com:443"}`
}
handle /.well-known/matrix/client {
header Access-Control-Allow-Origin "*"
header Content-Type "application/json"
respond `{"m.homeserver":{"base_url":"https://matrix.example.com"},"org.matrix.msc3575.proxy":{"url":"https://matrix.example.com"},"m.identity_server":{"base_url":"https://vector.im"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://matrix-rtc.example.com"}]}`
}
reverse_proxy homeserver:6167
}
matrix-rtc.example.com {
@jwt_service {
path /sfu/get* /healthz* /get_token*
}
handle @jwt_service {
reverse_proxy matrix-rtc-jwt:8081
}
handle {
reverse_proxy host.docker.internal:7880 {
header_up Connection "upgrade"
header_up Upgrade {http.request.header.Upgrade}
}
}
}
Caddyfile構文チェック
$ docker compose exec caddy caddy validate --config /config/caddy/Caddyfile
証明書確認
$ ls -la ./data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/
tuwunel.toml
[global]
server_name = "matrix.example.com"
database_path = "/var/lib/tuwunel"
address = ["0.0.0.0", "::"]
port = 6167
max_request_size = 20000000
allow_registration = true
registration_token = "xxxxxxxxxxxxxxxxxxxxx"
allow_federation = true
trusted_servers = ["matrix.org"]
turn_uris = ["turns:turn.example.com:5349?transport=tcp", "turns:turn.example.com:5349?transport=udp"]
turn_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
[global.well_known]
client = "https://matrix.example.com"
server = "matrix.example.com:443"
livekit_url = "https://matrix-rtc.example.com"
注)registration_tokenはhomeserverのドメイン:matrix.example.comでユーザ登録する際に必要。Caddyで.well-known/matrix/clientに"https://matrix-rtc.example.com "を指定していれば[global.well_known]の項目は不要(全てコメントアウト)
クローズドサーバの場合、allow_federation=false
livekit.yaml
port: 7880
bind_addresses:
- "::"
rtc:
tcp_port: 7881
port_range_start: 50301
port_range_end: 50400
use_external_ip: true
enable_loopback_candidate: false
turn_servers:
- host: turn.example.com
port: 5349
protocol: tls
secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
keys:
xxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
注)keys:には .env の MRTCKET: MRTCSECRET を記述。
turnserver.conf
listening-port=3478
tls-listening-port=5349
listening-ip=::
realm=turn.example.com
use-auth-secret
static-auth-secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
log-file=stdout
no-tcp-relay
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
no-multicast-peers
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
allowed-peer-ip=2404:7a87:9140:1000:5054:ff:fe8e:4360
user-quota=12 # 4 streams per video call, so 12 streams = 3 simultaneous relayed calls per user.
total-quota=1200
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
external-ip=EXTERNAL_IPV6
min-port=50201
max-port=50300
公開ポート
7880:7881/tcp ALLOW Anywhere
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
3478 (v6) ALLOW Anywhere (v6)
5349/tcp (v6) ALLOW Anywhere (v6)
7880:7881/tcp (v6) ALLOW Anywhere (v6)
50201:50400/udp (v6) ALLOW Anywhere (v6)
LiveKit が :: でバインドする際、OSの設定によって動作が変わります。このためIPv4の7880:7881もポート開放必要。
原因
/proc/sys/net/ipv6/bindv6only の値を確認
$ cat /proc/sys/net/ipv6/bindv6only
0 → IPv6ソケットがIPv4も兼用(dual-stack)→ *:7880 と表示される
1 → IPv6専用 → :::7880 と表示される
Admin Roomでの操作
Matrixサーバ:Tuwunelで、ユーザの登録・作成などの各種操作はAdmin Roomで行います。
Admin RoomはデフォルトでTuwunel初回起動時に作成されます。
name: matrix.example.com Admin Room
以下の設定により(デフォルト)、最初に登録したユーザーが自動でAdmin Roomに入ります。
tuwunel.toml
grant_admin_to_first_user = true
create_admin_room = true
このAdmin Roomでユーザ作成など各種操作をするには、メッセージ欄に
”!admin + コマンド"
と入力します。
例)ヘルプ:コマンド一覧
!admin help
> Usage: !admin <COMMAND>
Commands:
appservices - Commands for managing appservices
users - Commands for managing local users
rooms - Commands for managing rooms
federation - Commands for managing federation
server - Commands for managing the server
media - Commands for managing media
debug - Commands for debugging things
query - Low-level queries for database getters and iterators
token - Commands for managing registration tokens
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Element-Web
Elementのウェブアプリを自前で用意する場合、以下のサービスをdocker-compose.ymlに追加。
docker-compose.yaml
element-web:
# https://hub.docker.com/r/vectorim/element-web
image: vectorim/element-web:latest
container_name: element-web
volumes:
- ./element-config.json:/app/config.json:ro
networks:
- caddy
設定ファイル
element-config.json
{
"default_server_name": "example.com",
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.example.com"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api"
],
"show_labs_settings": true,
"room_directory": {
"servers": ["matrix.example.com", "matrix.org"]
},
"enable_presence_by_hs_url": {
"https://matrix.example.com": true
},
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
"setting_defaults": {
"RustCrypto.staged_rollout_percent": 60
},
"features": {
"feature_video_rooms": true,
"feature_group_calls": true,
"feature_element_call_video_rooms": true
},
"element_call": {
"url": "https://call.element.io",
"use_exclusively": false
}
}
Caddyプロキシには以下を追加。
Caddyfile
chat.example.com {
handle /.well-known/matrix/client {
header Content-Type application/json
header Access-Control-Allow-Origin *
respond `{
"m.homeserver": {
"base_url": "https://matrix.example.com"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
}` 200
}
reverse_proxy element-web:80
}
アプリで直接ユーザ登録を行うには、registration_tokenが必要。
補足説明
フェデレーション:
federationという設定項目がありますが、これは他のMatrixサーバと連携するための設定です。クローズドサーバの場合、allow_federation = false として下さい。
tuwunel.toml
# 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 = false
# 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 = false
Element-Webのスレッド
チャット画面の内部にスレッドという吹出しアイコンがありますが、これは特定のチャットメッセージを枝分かれさせるためのものです。
ユーザアドレス
ユーザアドレスの表記ルール(@ユーザ名:サーバドメイン)
@user001 :matrix.example.com
Tumunel Dockerイメージについて
Tuwunelはdistrolessイメージで、これはGoogleが開発するアプリケーションの実行に必要な最小限の依存関係(ランタイム)のみを含んだコンテナイメージ。コンテナ内でシェルコマンドは使用できません。
🥑 Language focused docker images, minus the operating system.
APIエンドポイント
サーバとクライアントのエンドポイントは以下を参照して下さい。
Matrix homeservers use the Federation APIs (also known as server-server APIs)
to communicate with each other. Homeservers use these APIs to push messages in
real-time, retrieve historic messages, and query profile or presence
information about users...
The client-server API allows clients to send messages, control rooms and
synchronise conversation history. It is designed to support both lightweight
clients which store no state and lazy-load data from the server as required,
as well as heavyweight...
クライアント:Elementの特徴(Matrix準拠)
暗号化
ダブルラチェットプロトコルによる暗号化。
クロスサイン認証:ユーザーを認証すると、その信頼はそのユーザーが持つ全デバイスに自動的に引き継がれます。デバイスごとに個別に認証する手間が省けます。
フェデレーション
他のネットワークとの連携。メールサーバのように他のドメインに所属するユーザアドレス同士のコミュニケーションが可能。
Federation enables multiple networks to work together. Element offers closed, ecosystem and open federation. Element enables even the most complex of organisations to balance security, ecosystem connectivity and usability.
データ所有権
データは登録したドメインのサーバのみが所有・管理できるが、データそのものは暗号化されているためユーザ以外では解読不可能。
Data sovereignty means keeping ownership and control of your data, so it remains subject to your governance structure. Element delivers data sovereignty whether it's deployed on-premise, self-hosted in a private cloud or through our fully managed...
分散型ネットワーク
分散型サーバで完全に独立した運営が可能。