aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wh.189
-rwxr-xr-xwh.sh441
2 files changed, 295 insertions, 235 deletions
diff --git a/wh.1 b/wh.1
index 8a6230f..53ffeb6 100644
--- a/wh.1
+++ b/wh.1
@@ -1,67 +1,74 @@
1.\" Manpage for whiterabbit 1.\" Manpage for whiterabbit
2.TH WHITERABBIT 1 "2025-09-25" "1.0.0" "whiterabbit manual" 2.TH WHITERABBIT 1 "2025-10-02" "1.1.0" "whiterabbit manual"
3.SH NAME 3.SH NAME
4whiterabbit \- auto-configure Matrix homeservers (Dendrite or Synapse) 4whiterabbit \- auto-configure Matrix homeservers (Dendrite, Synapse, or Tuwunel)
5.SH SYNOPSIS 5.SH SYNOPSIS
6.B whiterabbit 6.B whiterabbit
7[\fIturn\fR|\fIdendrite\fR|\fIsynapse\fR|\fIlist\fR|\fIremove <domain>\fR| 7[\fIturn <domain> <ip> <device> <secret>\fR|
8\fI-t\fR|\fI-d\fR|\fI-s\fR|\fI-l\fR|\fI-r <domain>\fR] 8 \fIdendrite <domain> <email> <server_ip>\fR|
9 \fIsynapse <domain> <email> <server_ip>\fR|
10 \fItuwunel <domain> <email> <server_ip>\fR|
11 \fIlist\fR|
12 \fIremove <domain>...\fR]
9.SH DESCRIPTION 13.SH DESCRIPTION
10whiterabbit sets up Matrix homeservers with a global Coturn server and Nginx/Let's Encrypt support. 14whiterabbit sets up Matrix homeservers (Dendrite, Synapse, or Tuwunel) with a global Coturn server and Nginx/Let's Encrypt proxying.
11 15
12Main commands and their short flag equivalents: 16Main subcommands:
13.TP 17.TP
14.B turn, -t 18.B turn <domain> <ip> <device> <secret>
15Install or configure the global Coturn server. 19Install or configure the global Coturn server.
16.TP 20.TP
17.B dendrite, -d 21.B dendrite <domain> <email> <server_ip>
18Add a new Matrix Dendrite server. 22Add a new Matrix Dendrite server with automatic TLS and Nginx reverse proxy.
19.TP 23.TP
20.B synapse, -s 24.B synapse <domain> <email> <server_ip>
21Add a new Matrix Synapse server. 25Add a new Matrix Synapse server with automatic TLS and Nginx reverse proxy.
22.TP 26.TP
23.B list, -l 27.B tuwunel <domain> <email> <server_ip>
24List all configured Matrix servers. 28Add a Tuwunel homeserver with automatic TLS and Nginx reverse proxy.
25.TP 29.TP
26.B remove <domain>, -r <domain> 30.B list
27Remove a Matrix server by domain. 31List all configured Matrix servers and their container status.
32.TP
33.B remove <domain> [domain2 ...]
34Remove one or more Matrix servers by domain name.
28 35
29.SH EXAMPLES 36.SH EXAMPLES
30.TP 37.TP
31whiterabbit turn 38whiterabbit turn turn.example.com 192.168.1.10 eth0 myturnsecret
32Set up the global Coturn server. 39Set up the global Coturn server bound to eth0 on IP 192.168.1.10.
33.TP
34whiterabbit -t
35Same as above using flag.
36.TP
37whiterabbit dendrite
38Add a Dendrite server with TLS and Nginx.
39.TP 40.TP
40whiterabbit -d 41whiterabbit dendrite matrix.example.com admin@example.com 192.168.1.20
41Same as above using flag. 42Add a Dendrite server.
42.TP 43.TP
43whiterabbit synapse 44whiterabbit synapse matrix.example.com admin@example.com 192.168.1.21
44Add a Synapse server with TLS and Nginx. 45Add a Synapse server.
45.TP 46.TP
46whiterabbit -s 47whiterabbit tuwunel tuw.example.com admin@example.com 192.168.1.22
47Same as above using flag. 48Add a Tuwunel server.
48.TP 49.TP
49whiterabbit list 50whiterabbit list
50Show all servers. 51Show all installed servers and their status.
51.TP
52whiterabbit -l
53Same as above using flag.
54.TP
55whiterabbit remove matrix.example.com
56Remove a server.
57.TP 52.TP
58whiterabbit -r matrix.example.com 53whiterabbit remove matrix.example.com another.example.org
59Same as above using flag. 54Remove one or more servers.
60 55
61.SH NOTES 56.SH NOTES
62All Matrix servers share the same Coturn instance. 57All Matrix homeservers share the same Coturn instance.
63TLS certificates are issued automatically via Let's Encrypt. 58TLS certificates are issued automatically via Let's Encrypt.
64Requires docker, docker-compose, nginx, certbot, and coturn. 59Requires docker, docker-compose, nginx, certbot, and coturn.
65 60
66.SH AUTHOR 61.SH COMMAND DISPATCH
67Filip Wandzio <contact@philw.dev> 62The script internally dispatches commands as follows:
63.nf
64CMD="${1:-}"
65case "$CMD" in
66 turn) shift; install_turn "$@" ;;
67 dendrite) shift; install_dendrite "$@" ;;
68 # synapse) shift; install_synapse "$@" ;;
69 tuwunel) shift; install_tuwunel "$@" ;;
70 list) list_servers ;;
71 remove) shift; remove_server "$@" ;;
72 *) usage ;;
73esac
74.fi
diff --git a/wh.sh b/wh.sh
index db1c12d..35de2b6 100755
--- a/wh.sh
+++ b/wh.sh
@@ -1,5 +1,11 @@
1#!/bin/sh 1#!/bin/sh
2set -eu 2set -eu
3ESCALATE=$(command -v sudo || command -v doas) || {
4 echo "[ERROR] Neither sudo nor doas found. Cannot run as root." >&2
5 exit 1
6}
7
8[ "$(id -u)" -eq 0 ] || exec $ESCALATE "$0" "$@"
3 9
4BASE_DIR="/opt/matrix" 10BASE_DIR="/opt/matrix"
5 11
@@ -10,15 +16,15 @@ DOCKER_COMPOSE=$(command -v docker-compose || command -v docker compose) || {
10 16
11usage() { 17usage() {
12 cat <<'EOF' 18 cat <<'EOF'
13whiterabbit: auto-configure Matrix homeservers (Dendrite or Synapse) 19whiterabbit: auto-configure [matrix] Homeservers
14with a global Coturn instance and Nginx + Let's Encrypt proxy. 20with a global Coturn instance and Nginx + Let's Encrypt proxy.
15 21
16Main actions: 22Usage:
17 turn Install or configure the global Coturn server 23 wh turn <domain> <ip> <device> <secret>
18 dendrite Add a new Matrix server (Dendrite) 24 wh dendrite <matrix_domain> <email> <server_ip>
19 synapse Add a new Matrix server (Synapse) 25 wh tuwunel <domain> <email> <server_ip>
20 list Show all configured Matrix servers 26 wh list
21 remove Remove a Matrix server by domain 27 wh remove <domain1> [domain2 ...]
22EOF 28EOF
23 exit 1 29 exit 1
24} 30}
@@ -38,36 +44,35 @@ list_servers() {
38 [ -d "$dir" ] || continue 44 [ -d "$dir" ] || continue
39 name=$(basename "$dir") 45 name=$(basename "$dir")
40 46
41 status=$(docker ps --filter "name=^${name}$" --format "{{.Status}}") 47 container_info=$(docker ps --format "{{.Names}} {{.Status}} {{.Ports}}" | grep "^${name}") || container_info=""
42 ports=$(docker ps --filter "name=^${name}$" --format "{{.Ports}}" | sed 's/, /\n /g')
43 48
44 [ -n "$status" ] && { 49 [ -n "$container_info" ] && {
45 echo "- $name [RUNNING] on:" 50 echo "- $name [RUNNING] on:"
46 echo " $ports" 51 echo "$container_info" | while read line; do
52 cname=$(echo "$line" | awk '{print $1}')
53 cstatus=$(echo "$line" | awk '{print $2}')
54 cports=$(echo "$line" | awk '{$1=$2=""; print $0}' | sed 's/^ //')
55 echo " $cname : $cstatus, ports: $cports"
56 done
47 } || echo "- $name [STOPPED]" 57 } || echo "- $name [STOPPED]"
48 done 58 done
49} 59}
50 60
51install_turn() { 61install_turn() {
52 echo "=== Installing global Coturn ===" 62 TURN_DOMAIN="$1"
53 printf "TURN domain (eg. turn.example.com): " 63 TURN_SERVER_IP="$2"
54 read -r TURN_DOMAIN 64 TURN_LISTENING_DEVICE="$3"
55 require_nonempty TURN_DOMAIN "$TURN_DOMAIN" 65 TURN_SECRET="$4"
56 66
57 printf "TURN IP (eg. 127.0.0.1): " 67 require_nonempty TURN_DOMAIN "$TURN_DOMAIN"
58 read -r TURN_SERVER_IP
59 require_nonempty TURN_SERVER_IP "$TURN_SERVER_IP" 68 require_nonempty TURN_SERVER_IP "$TURN_SERVER_IP"
60
61 printf "Listening device (eg. eth0): "
62 read -r TURN_LISTENING_DEVICE
63 require_nonempty TURN_LISTENING_DEVICE "$TURN_LISTENING_DEVICE" 69 require_nonempty TURN_LISTENING_DEVICE "$TURN_LISTENING_DEVICE"
64
65 printf "TURN shared secret: "
66 read -r TURN_SECRET
67 require_nonempty TURN_SECRET "$TURN_SECRET" 70 require_nonempty TURN_SECRET "$TURN_SECRET"
68 71
72 echo "=== Installing global Coturn ($TURN_DOMAIN) ==="
73
69 mkdir -p /etc/turn 74 mkdir -p /etc/turn
70 cat <<EOF > /etc/turn/turnserver.conf 75 cat <<EOF > /etc/turnserver.conf
71listening-device=$TURN_LISTENING_DEVICE 76listening-device=$TURN_LISTENING_DEVICE
72listening-port=3478 77listening-port=3478
73tls-listening-port=5349 78tls-listening-port=5349
@@ -95,20 +100,20 @@ EOF
95} 100}
96 101
97common_prompts() { 102common_prompts() {
98 printf "Matrix domain (eg. matrix.example.com): " 103 MATRIX_DOMAIN="$1"
99 read -r MATRIX_DOMAIN 104 EMAIL="$2"
100 require_nonempty MATRIX_DOMAIN "$MATRIX_DOMAIN" 105 MATRIX_SERVER_IP="$3"
101 106
102 printf "Let's Encrypt certificate email: " 107 require_nonempty MATRIX_DOMAIN "$MATRIX_DOMAIN"
103 read -r EMAIL
104 require_nonempty EMAIL "$EMAIL" 108 require_nonempty EMAIL "$EMAIL"
109 require_nonempty MATRIX_SERVER_IP "$MATRIX_SERVER_IP"
110
105 DB_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 32) 111 DB_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 32)
106 REG_SECRET=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 64) 112 REG_SECRET=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 64)
107 printf "MATRIX server IP (eg. 127.0.0.1): " 113
108 read -r MATRIX_SERVER_IP
109 require_nonempty MATRIX_SERVER_IP "$MATRIX_SERVER_IP"
110 TURN_DOMAIN=$(cat /etc/turn/domain) 114 TURN_DOMAIN=$(cat /etc/turn/domain)
111 TURN_SECRET=$(cat /etc/turn/secret) 115 TURN_SECRET=$(cat /etc/turn/secret)
116
112 HASH=$(printf "%s" "$MATRIX_DOMAIN" | cksum | cut -d ' ' -f1) 117 HASH=$(printf "%s" "$MATRIX_DOMAIN" | cksum | cut -d ' ' -f1)
113 PORT_BASE=$(( (HASH % 1000) + 8000 )) 118 PORT_BASE=$(( (HASH % 1000) + 8000 ))
114 PORT_HTTP=$PORT_BASE 119 PORT_HTTP=$PORT_BASE
@@ -151,24 +156,67 @@ EOF
151 ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN" 156 ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN"
152 nginx -t || { echo "[ERROR] Invalid nginx config"; exit 1; } 157 nginx -t || { echo "[ERROR] Invalid nginx config"; exit 1; }
153 158
154
155 case $(command -v systemctl >/dev/null && echo y || echo n) in 159 case $(command -v systemctl >/dev/null && echo y || echo n) in
156 y) systemctl reload nginx ;; 160 y) systemctl reload nginx ;;
157 n) nginx -s reload ;; 161 n) nginx -s reload ;;
158 esac 162 esac
159 163
160 case $(command -v certbot >/dev/null && echo y || echo n) in 164 case $(command -v certbot >/dev/null && echo y || echo n) in
161 y) certbot --nginx --non-interactive --agree-tos -m "$EMAIL" -d "$DOMAIN" || { 165 y) certbot --nginx --non-interactive --agree-tos -m "$EMAIL" -d "$DOMAIN" || {
162 echo "[WARN] Certbot failed for $DOMAIN" 166 echo "[WARN] Certbot failed for $DOMAIN"
163 } ;; 167 } ;;
164 n) echo "[WARN] Certbot not installed, skipping TLS setup" ;; 168 n) echo "[WARN] Certbot not installed, skipping TLS setup" ;;
165 esac 169 esac
166} 170}
167 171
172install_tuwunel() {
173 echo "=== Installing Tuwunel ==="
174 common_prompts "$@"
175
176 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN"
177 mkdir -p "$INSTALL_DIR/config"
178 cd "$INSTALL_DIR" || exit 1
168 179
180 cat <<EOF > .env
181TUWUNEL_SERVER_NAME=$MATRIX_DOMAIN
182TUWUNEL_DATABASE_PATH=/var/lib/tuwunel
183TUWUNEL_PORT=6167
184TUWUNEL_MAX_REQUEST_SIZE=20000000
185TUWUNEL_ALLOW_REGISTRATION=false
186TUWUNEL_REGISTRATION_TOKEN=$REG_SECRET
187TUWUNEL_ALLOW_ENCRYPTION=true
188TUWUNEL_ALLOW_FEDERATION=true
189TUWUNEL_TRUSTED_SERVERS='["matrix.org", "matrix.philw.dev"]'
190
191TUWUNEL_ADDRESS=0.0.0.0
192TUWUNEL_TURN_SECRET="$TURN_SECRET"
193TUWUNEL_TURN_URIS=["turn:$TURN_DOMAIN?transport=udp", "turn:$TURN_DOMAIN?transport=tcp"]
194TUWUNEL_NEW_USER_DISPLAYNAME_SUFFIX=""
195EOF
196
197cat <<EOF > compose.yml
198services:
199 homeserver:
200 image: jevolk/tuwunel:latest
201 container_name: tuw.philw.dev-tuwunel
202 restart: unless-stopped
203 ports:
204 - "$PORT_HTTP:6167"
205 volumes:
206 - db:/var/lib/tuwunel
207 env_file:
208 - .env
209volumes:
210 db:
211EOF
212
213 $DOCKER_COMPOSE up -d
214 configure_nginx "$MATRIX_DOMAIN" "$PORT_HTTP"
215 echo "[OK] Tuwunel server ($MATRIX_DOMAIN) is running."
216}
169install_dendrite() { 217install_dendrite() {
170 echo "=== Installing Matrix Dendrite ===" 218 echo "=== Installing Dendrite ==="
171 common_prompts 219 common_prompts "$@"
172 220
173 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN" 221 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN"
174 mkdir -p "$INSTALL_DIR/config" 222 mkdir -p "$INSTALL_DIR/config"
@@ -309,192 +357,197 @@ dns_cache:
309EOF 357EOF
310 358
311 echo "[INFO] Generating Dendrite keys..." 359 echo "[INFO] Generating Dendrite keys..."
312 360 docker run --rm --entrypoint="" -v "$(pwd)":/mnt matrixdotorg/dendrite-monolith:latest \
313 docker run --rm --entrypoint="" -v $(pwd):/mnt matrixdotorg/dendrite-monolith:latest /usr/bin/generate-keys -private-key /mnt/matrix_key.pem -tls-cert /mnt/server.crt -tls-key /mnt/server.key 361 /usr/bin/generate-keys -private-key /mnt/matrix_key.pem -tls-cert /mnt/server.crt -tls-key /mnt/server.key
314 echo "[OK] Keys generated in $PWD" 362 echo "[OK] Keys generated in $PWD"
315 363
316 $DOCKER_COMPOSE up -d 364 $DOCKER_COMPOSE up -d
317 configure_nginx "$MATRIX_DOMAIN" "$PORT_HTTP" 365 configure_nginx "$MATRIX_DOMAIN" "$PORT_HTTP"
318 echo "[OK] Dendrite server ($MATRIX_DOMAIN) is running." 366 echo "[OK] Dendrite server ($MATRIX_DOMAIN) is running."
319} 367}
320 368
321install_synapse() { 369# @TODO STILL BROKEN
322 echo "=== Installing Matrix Synapse ===" 370# install_synapse() {
323 common_prompts 371# echo "=== Installing Synapse ==="
324 372# MATRIX_DOMAIN="$1"
325 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN" 373# EMAIL="$2"
326 mkdir -p "$INSTALL_DIR" 374# MATRIX_SERVER_IP="$3"
327 cd "$INSTALL_DIR" || exit 1 375#
328 mkdir -p data db 376# require_nonempty MATRIX_DOMAIN "$MATRIX_DOMAIN"
329 chown -R 991:991 data/ 377# require_nonempty EMAIL "$EMAIL"
330 chown -R 999:999 db/ 378# require_nonempty MATRIX_SERVER_IP "$MATRIX_SERVER_IP"
331 DB_USER="synapse" 379#
332 DB_NAME="synapse" 380# INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN"
333 DB_PASS=$(openssl rand -hex 16) 381# mkdir -p "$INSTALL_DIR"
334 REG_SECRET=$(openssl rand -hex 32) 382# cd "$INSTALL_DIR" || exit 1
335 383# mkdir -p data db
336 : "${PORT_HTTP:=8008}" 384#
337 : "${PORT_HTTPS:=8448}" 385# DB_USER="synapse"
338 386# DB_NAME="synapse"
339 cat <<EOF > .env 387# DB_PASS=$(openssl rand -hex 16)
340# Matrix Synapse environment 388# REG_SECRET=$(openssl rand -hex 32)
341MATRIX_DOMAIN=$MATRIX_DOMAIN 389# if command -v docker-compose >/dev/null 2>&1; then
342PORT_HTTP=$PORT_HTTP 390# DOCKER_COMPOSE_CMD="docker-compose"
343PORT_HTTPS=$PORT_HTTPS 391# elif command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
344 392# DOCKER_COMPOSE_CMD="docker compose"
345DB_USER=$DB_USER 393# else
346DB_NAME=$DB_NAME 394# echo "[ERROR] Neither docker-compose nor docker compose available" >&2
347DB_PASS=$DB_PASS 395# exit 1
348 396# fi
349REG_SECRET=$REG_SECRET 397#
350TURN_DOMAIN=$TURN_DOMAIN 398# PORT_HTTP=${PORT_HTTP:-8008}
351TURN_SECRET=$TURN_SECRET 399# PORT_HTTPS=${PORT_HTTPS:-8448}
352EOF 400# TURN_DOMAIN=$(cat /etc/turn/domain 2>/dev/null || true)
353 401# TURN_SECRET=$(cat /etc/turn/secret 2>/dev/null || true)
354 402# cat > .env <<EOF
355cat <<EOF > compose.yml 403# MATRIX_DOMAIN=${MATRIX_DOMAIN}
356services: 404# PORT_HTTP=${PORT_HTTP}
357 db: 405# PORT_HTTPS=${PORT_HTTPS}
358 image: postgres:15-alpine 406#
359 restart: always 407# DB_USER=${DB_USER}
360 environment: 408# DB_NAME=${DB_NAME}
361 POSTGRES_USER: ${DB_USER} 409# DB_PASS=${DB_PASS}
362 POSTGRES_PASSWORD: ${DB_PASS} 410#
363 POSTGRES_DB: ${DB_NAME} 411# REG_SECRET=${REG_SECRET}
364 LANG: C 412# TURN_DOMAIN=${TURN_DOMAIN}
365 LC_ALL: C 413# TURN_SECRET=${TURN_SECRET}
366 command: postgres -c lc_collate=C -c lc_ctype=C 414# EOF
367 volumes: 415# cat > compose.yml <<EOF
368 - ./db:/var/lib/postgresql/data 416# services:
369 networks: 417# db:
370 - synapse-net 418# image: postgres:15-alpine
371 419# container_name: ${MATRIX_DOMAIN}-db
372 synapse: 420# restart: always
373 image: matrixdotorg/synapse:latest 421# environment:
374 restart: always 422# POSTGRES_USER: ${DB_USER}
375 depends_on: 423# POSTGRES_PASSWORD: ${DB_PASS}
376 - db 424# POSTGRES_DB: ${DB_NAME}
377 environment: 425# LANG: C
378 SYNAPSE_SERVER_NAME: ${MATRIX_DOMAIN} 426# LC_COLLATE: C
379 SYNAPSE_REPORT_STATS: "yes" 427# LC_CTYPE: C
380 ports: 428# volumes:
381 - "${PORT_HTTP}:8008" 429# - ./db:/var/lib/postgresql/data
382 - "${PORT_HTTPS}:8448" 430# healthcheck:
383 volumes: 431# test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
384 - ./data:/data 432# interval: 5s
385 networks: 433# timeout: 5s
386 - synapse-net 434# retries: 5
387 435#
388networks: 436# synapse:
389 synapse-net: 437# image: matrixdotorg/synapse:latest
390 driver: bridge 438# container_name: ${MATRIX_DOMAIN}-synapse
391EOF 439# restart: always
392 440# depends_on:
393$DOCKER_COMPOSE --env-file .env up -d 441# db:
394docker run -it --rm -v ./data:/data -e SYNAPSE_SERVER_NAME=$MATRIX_DOMAIN -e SYNAPSE_REPORT_STATS=no matrixdotorg/synapse:latest generate 442# condition: service_healthy
395 443# environment:
396echo "[INFO] Generating homeserver.yaml for Postgres + TURN..." 444# SYNAPSE_SERVER_NAME: ${MATRIX_DOMAIN}
397cat <<EOF > data/homeserver.yaml 445# SYNAPSE_REPORT_STATS: "no"
398server_name: $MATRIX_DOMAIN 446# POSTGRES_DB: ${DB_NAME}
399pid_file: /data/homeserver.pid 447# POSTGRES_USER: ${DB_USER}
400 448# POSTGRES_PASSWORD: ${DB_PASS}
401listeners: 449# POSTGRES_HOST: db
402 - port: $PORT_HTTP 450# volumes:
403 tls: false 451# - ./data:/data
404 type: http 452# ports:
405 x_forwarded: true 453# - "${PORT_HTTP}:8008"
406 resources: 454# - "${PORT_HTTPS}:8448"
407 - names: [client, federation] 455# EOF
408 compress: false 456# docker run --rm -v "$(pwd)/data:/data" \
409 457# -e SYNAPSE_SERVER_NAME="${MATRIX_DOMAIN}" \
410database: 458# -e SYNAPSE_REPORT_STATS="no" \
411 name: psycopg2 459# matrixdotorg/synapse:latest generate
412 args: 460# cat > data/homeserver.yaml <<EOF
413 user: $DB_USER 461# server_name: "${MATRIX_DOMAIN}"
414 password: $DB_PASS 462# pid_file: /data/homeserver.pid
415 host: db 463#
416 database: $DB_NAME 464# listeners:
417 cp_min: 5 465# - port: ${PORT_HTTP}
418 cp_max: 10 466# tls: false
419 467# type: http
420enable_registration: false 468# x_forwarded: true
421registration_shared_secret: "$REG_SECRET" 469# resources:
422 470# - names: [client, federation]
423turn_uris: 471# compress: false
424 - turn:$TURN_DOMAIN?transport=udp 472#
425 - turn:$TURN_DOMAIN?transport=tcp 473# database:
426turn_shared_secret: "$TURN_SECRET" 474# name: psycopg2
427turn_user_lifetime: "5m" 475# args:
428 476# user: "${DB_USER}"
429log_config: "/data/$MATRIX_DOMAIN.log.config" 477# password: "${DB_PASS}"
430media_store_path: /data/media_store 478# host: db
431report_stats: false 479# database: "${DB_NAME}"
432 480# cp_min: 5
433macaroon_secret_key: $REG_SECRET 481# cp_max: 10
434form_secret: $REG_SECRET 482#
435signing_key_path: "/data/$MATRIX_DOMAIN.signing.key" 483# enable_registration: false
436 484# registration_shared_secret: "${REG_SECRET}"
437trusted_key_servers: 485#
438 - server_name: "matrix.org" 486# turn_uris:
439suppress_key_server_warning: true 487# - turn:${TURN_DOMAIN}?transport=udp
440EOF 488# - turn:${TURN_DOMAIN}?transport=tcp
441 489# turn_shared_secret: "${TURN_SECRET}"
442 echo "[INFO] Restarting Synapse with full config..." 490# turn_user_lifetime: "5m"
443 $DOCKER_COMPOSE --env-file .env restart synapse 491#
444 $DOCKER_COMPOSE --env-file .env restart synapse 492# log_config: "/data/${MATRIX_DOMAIN}.log.config"
445 493# media_store_path: /data/media_store
446 configure_nginx "$MATRIX_DOMAIN" "$PORT_HTTP" 494# report_stats: false
447 echo "[OK] Synapse server ($MATRIX_DOMAIN) is running with Postgres." 495#
448} 496# macaroon_secret_key: "${REG_SECRET}"
449 497# form_secret: "${REG_SECRET}"
498# signing_key_path: "/data/${MATRIX_DOMAIN}.signing.key"
499#
500# trusted_key_servers:
501# - server_name: "matrix.org"
502# suppress_key_server_warning: true
503# EOF
504#
505# if [ "$DOCKER_COMPOSE_CMD" = "docker compose" ]; then
506# eval "$DOCKER_COMPOSE_CMD --env-file .env up -d"
507# else
508# $DOCKER_COMPOSE_CMD --env-file .env up -d
509# fi
510#
511# sleep 3
512# if [ "$DOCKER_COMPOSE_CMD" = "docker compose" ]; then
513# eval "$DOCKER_COMPOSE_CMD --env-file .env restart synapse"
514# else
515# $DOCKER_COMPOSE_CMD --env-file .env restart synapse
516# fi
517#
518# configure_nginx "$MATRIX_DOMAIN" "$PORT_HTTP"
519# echo "[OK] Synapse server ($MATRIX_DOMAIN) is running with Postgres."
520# }
450 521
451remove_server() { 522remove_server() {
452 [ "$#" -eq 0 ] && echo "Usage: remove_server <domain1> [domain2 ...]" && return 1 523 [ "$#" -eq 0 ] && echo "Usage: remove_server <domain1> [domain2 ...]" && return 1
453
454 for DOMAIN in "$@"; do 524 for DOMAIN in "$@"; do
455 SERVER_DIR="$BASE_DIR/$DOMAIN" 525 SERVER_DIR="$BASE_DIR/$DOMAIN"
456
457 case "$DOMAIN" in 526 case "$DOMAIN" in
458 ""|"/"|".") 527 ""|"/"|".")
459 echo "[ERROR] Refusing to delete dangerous path ($DOMAIN)" 528 echo "[ERROR] Refusing to delete dangerous path ($DOMAIN)"
460 continue 529 continue
461 ;; 530 ;;
462 esac 531 esac
463
464 [ -d "$SERVER_DIR" ] && \ 532 [ -d "$SERVER_DIR" ] && \
465 echo "[INFO] Stopping and removing server: $DOMAIN" && \ 533 echo "[INFO] Stopping and removing server: $DOMAIN" && \
466 (cd "$SERVER_DIR" && $DOCKER_COMPOSE down -v) || \ 534 (cd "$SERVER_DIR" && $DOCKER_COMPOSE down -v) || \
467 echo "[WARN] Failed to stop container for $DOMAIN" 535 echo "[WARN] Failed to stop container for $DOMAIN"
468
469 rm -rf "$SERVER_DIR" 536 rm -rf "$SERVER_DIR"
470 rm -f "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN" 537 rm -f "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN"
471 done 538 done
472
473 nginx -t && (systemctl reload nginx 2>/dev/null || nginx -s reload) 539 nginx -t && (systemctl reload nginx 2>/dev/null || nginx -s reload)
474 echo "[OK] Done removing servers: $*" 540 echo "[OK] Done removing servers: $*"
475} 541}
476 542
477CMD="${1:-}" 543CMD="${1:-}"
478
479case "$CMD" in 544case "$CMD" in
480 -t) install_turn ;; 545 turn) shift; install_turn "$@" ;;
481 -d) install_dendrite ;; 546 dendrite) shift; install_dendrite "$@" ;;
482 -s) install_synapse ;; 547 # synapse) shift; install_synapse "$@" ;;
483 -l) list_servers ;; 548 tuwunel) shift; install_tuwunel "$@" ;;
484 -r)
485 [ -z "$2" ] && { echo "Usage: $0 -r <domain1> [domain2 ...]"; exit 1; }
486 shift
487 remove_server "$@"
488 ;;
489 turn) install_turn ;;
490 dendrite) install_dendrite ;;
491 synapse) install_synapse ;;
492 list) list_servers ;; 549 list) list_servers ;;
493 remove) 550 remove) shift; remove_server "$@" ;;
494 [ -z "$2" ] && { echo "Usage: $0 remove <domain1> [domain2 ...]"; exit 1; }
495 shift
496 remove_server "$@"
497 ;;
498 *) usage ;; 551 *) usage ;;
499esac 552esac
500 553