aboutsummaryrefslogtreecommitdiffstats
path: root/whiterabbit.sh
diff options
context:
space:
mode:
Diffstat (limited to 'whiterabbit.sh')
-rwxr-xr-xwhiterabbit.sh367
1 files changed, 205 insertions, 162 deletions
diff --git a/whiterabbit.sh b/whiterabbit.sh
index e68351f..e6e3b58 100755
--- a/whiterabbit.sh
+++ b/whiterabbit.sh
@@ -1,104 +1,185 @@
1#!/usr/bin/sh 1#!/bin/sh
2set -euo pipefail 2set -eu
3 3
4echo "=== Matrix Dendrite + Coturn auto-setup (Docker + standalone Coturn) ===" 4BASE_DIR="/opt/matrix"
5 5
6# ---- User Input ---- 6usage() {
7read -rp "Matrix domain (eg. matrix.example.com): " MATRIX_DOMAIN 7 cat <<'EOF'
8read -rp "TURN domain(eg. turn.example.com): " TURN_DOMAIN 8whiterabbit: auto-configure Matrix homeservers (Dendrite or Synapse)
9read -rp "Let's Encrypt certificate email: " EMAIL 9with a global Coturn instance and Nginx + Let's Encrypt proxy.
10read -rp "Postgres secret: " DB_PASS 10
11read -rp "registration_shared_secret: " REG_SECRET 11Main actions:
12read -rp "TURN shared secret: " TURN_SECRET 12 turn Install or configure the global Coturn server
13read -rp "TURN IP (eg. 127.0.0.1): " TURN_SERVER_IP 13 dendrite Add a new Matrix server (Dendrite)
14read -rp "MATRIX server IP (eg. 127.0.0.1): " MATRIX_SERVER_IP 14 synapse Add a new Matrix server (Synapse)
15read -rp "Listening device (eg. eth0): " TURN_LISTENING_DEVICE 15 list Show all configured Matrix servers
16 16 remove Remove a Matrix server by domain
17INSTALL_DIR="/opt/matrix/$MATRIX_DOMAIN" 17
18mkdir -p "$INSTALL_DIR/config" 18Notes:
19cd "$INSTALL_DIR" 19 • Coturn should be installed only once using 'turn'.
20 20 • All Matrix servers share the same Coturn (TURN domain/secret).
21cat <<EOF > .env 21 • TLS certificates are issued automatically using Let's Encrypt.
22# PostgreSQL 22 • Requirements: docker, docker-compose, nginx, certbot, coturn.
23
24EOF
25 exit 1
26}
27
28list_servers() {
29 echo "=== Installed servers ==="
30 ls -1 "$BASE_DIR" 2>/dev/null || echo "No servers installed"
31}
32
33install_turn() {
34 echo "=== Installing global Coturn ==="
35 printf "TURN domain (eg. turn.example.com): "
36 read -r TURN_DOMAIN
37 printf "TURN IP (eg. 127.0.0.1): "
38 read -r TURN_SERVER_IP
39 printf "Listening device (eg. eth0): "
40 read -r TURN_LISTENING_DEVICE
41 printf "TURN shared secret: "
42 read -r TURN_SECRET
43
44 mkdir -p /etc/turn
45 cat <<EOF > /etc/turn/turnserver.conf
46listening-device=$TURN_LISTENING_DEVICE
47listening-port=3478
48tls-listening-port=5349
49listening-ip=$TURN_SERVER_IP
50min-port=49152
51max-port=65535
52use-auth-secret
53static-auth-secret=$TURN_SECRET
54realm=$TURN_DOMAIN
55syslog
56no-rfc5780
57no-stun-backward-compatibility
58response-origin-only-with-rfc5780
59EOF
60
61 echo "$TURN_DOMAIN" > /etc/turn/domain
62 echo "$TURN_SECRET" > /etc/turn/secret
63
64 systemctl enable --now coturn || true
65 echo "[OK] Global Coturn configured ($TURN_DOMAIN)"
66}
67
68common_prompts() {
69 printf "Matrix domain (eg. matrix.example.com): "
70 read -r MATRIX_DOMAIN
71 printf "Let's Encrypt certificate email: "
72 read -r EMAIL
73 printf "Postgres secret: "
74 read -r DB_PASS
75 printf "registration_shared_secret: "
76 read -r REG_SECRET
77 printf "MATRIX server IP (eg. 127.0.0.1): "
78 read -r MATRIX_SERVER_IP
79
80 TURN_DOMAIN=$(cat /etc/turn/domain)
81 TURN_SECRET=$(cat /etc/turn/secret)
82}
83
84configure_nginx() {
85 DOMAIN="$1"
86 SERVICE_PORT="$2"
87
88 cat <<EOF > "/etc/nginx/sites-available/$DOMAIN"
89server {
90 listen 80;
91 server_name $DOMAIN;
92
93 location /.well-known/matrix/server {
94 default_type application/json;
95 return 200 '{ "m.server": "$DOMAIN:443" }';
96 }
97
98 location /.well-known/matrix/client {
99 default_type application/json;
100 return 200 '{
101 "m.homeserver": { "base_url": "https://$DOMAIN" },
102 "m.identity_server": { "base_url": "https://vector.im" }
103 }';
104 }
105
106 location / {
107 proxy_pass http://127.0.0.1:$SERVICE_PORT;
108 proxy_set_header Host \$host;
109 proxy_set_header X-Forwarded-For \$remote_addr;
110 }
111}
112EOF
113
114 ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN"
115 nginx -t && systemctl reload nginx
116
117 certbot --nginx --non-interactive --agree-tos -m "$EMAIL" -d "$DOMAIN"
118
119 echo "[OK] Nginx and SSL certificate configured for $DOMAIN"
120}
121
122install_dendrite() {
123 echo "=== Installing Matrix Dendrite ==="
124 common_prompts
125
126 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN"
127 mkdir -p "$INSTALL_DIR/config"
128 cd "$INSTALL_DIR" || exit 1
129
130 cat <<EOF > .env
23POSTGRES_HOSTNAME=postgres 131POSTGRES_HOSTNAME=postgres
24POSTGRES_VERSION=15-alpine 132POSTGRES_VERSION=15-alpine
25POSTGRES_USER=dendrite 133POSTGRES_USER=dendrite
26POSTGRES_PASSWORD=$DB_PASS 134POSTGRES_PASSWORD=$DB_PASS
27POSTGRES_DB=dendrite 135POSTGRES_DB=dendrite
28 136
29# Monolith
30MONOLITH_HOSTNAME=monolith 137MONOLITH_HOSTNAME=monolith
31MONOLITH_IMAGE=matrixdotorg/dendrite-monolith:latest 138MONOLITH_IMAGE=matrixdotorg/dendrite-monolith:latest
32MONOLITH_PORT_HTTP=8008 139MONOLITH_PORT_HTTP=8008
33MONOLITH_PORT_HTTPS=8448 140MONOLITH_PORT_HTTPS=8448
34EOF 141EOF
35 142
36cat <<'EOF' > compose.yml 143 cat <<'EOF' > compose.yml
37services: 144services:
38 postgres: 145 postgres:
39 hostname: ${POSTGRES_HOSTNAME:-postgres}
40 image: postgres:${POSTGRES_VERSION:-15-alpine} 146 image: postgres:${POSTGRES_VERSION:-15-alpine}
41 restart: always 147 restart: always
42 volumes: 148 volumes:
43 - ./dendrite_postgres_data:/var/lib/postgresql/data 149 - ./dendrite_postgres_data:/var/lib/postgresql/data
44 environment: 150 environment:
45 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-itsasecret} 151 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
46 POSTGRES_USER: ${POSTGRES_USER:-dendrite} 152 POSTGRES_USER: ${POSTGRES_USER}
47 POSTGRES_DB: ${POSTGRES_DB:-dendrite} 153 POSTGRES_DB: ${POSTGRES_DB}
48 healthcheck: 154 networks: [ internal ]
49 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-dendrite}"]
50 interval: 5s
51 timeout: 5s
52 retries: 5
53 networks:
54 - internal
55 monolith: 155 monolith:
56 hostname: ${MONOLITH_HOSTNAME:-monolith} 156 image: ${MONOLITH_IMAGE}
57 image: ${MONOLITH_IMAGE:-matrixdotorg/dendrite-monolith:latest}
58 ports: 157 ports:
59 - ${MONOLITH_PORT_HTTP:-8008}:8008 158 - ${MONOLITH_PORT_HTTP}:8008
60 - ${MONOLITH_PORT_HTTPS:-8448}:8448 159 - ${MONOLITH_PORT_HTTPS}:8448
61 volumes: 160 volumes:
62 - ./config:/etc/dendrite 161 - ./config:/etc/dendrite
63 - ./dendrite_media:/var/dendrite/media 162 - ./dendrite_media:/var/dendrite/media
64 - ./dendrite_jetstream:/var/dendrite/jetstream 163 depends_on: [ postgres ]
65 - ./dendrite_search_index:/var/dendrite/searchindex 164 networks: [ internal ]
66 - ./:/mnt
67 depends_on:
68 postgres:
69 condition: service_healthy
70 networks:
71 - internal
72 restart: unless-stopped 165 restart: unless-stopped
73networks: 166networks:
74 internal: 167 internal:
75 attachable: true 168 attachable: true
76volumes:
77 dendrite_postgres_data:
78 dendrite_media:
79 dendrite_jetstream:
80 dendrite_search_index:
81EOF 169EOF
82 170
83cat <<EOF > config/dendrite.yaml 171 cat <<EOF > config/dendrite.yaml
84version: 2 172version: 2
85global: 173global:
86 server_name: $MATRIX_DOMAIN 174 server_name: $MATRIX_DOMAIN
87 private_key: /mnt/matrix_key.pem 175 private_key: /mnt/matrix_key.pem
88 old_private_keys:
89 key_validity_period: 168h0m0s
90 database: 176 database:
91 connection_string: postgresql://dendrite:$DB_PASS@postgres/dendrite?sslmode=disable 177 connection_string: postgresql://dendrite:$DB_PASS@postgres/dendrite?sslmode=disable
92 max_open_conns: 90
93 max_idle_conns: 5
94 conn_max_lifetime: -1
95
96 well_known_server_name: "$MATRIX_DOMAIN:443" 178 well_known_server_name: "$MATRIX_DOMAIN:443"
97 well_known_client_name: "https://$MATRIX_DOMAIN" 179 well_known_client_name: "https://$MATRIX_DOMAIN"
98 180
99client_api: 181client_api:
100 registration_disabled: true 182 registration_disabled: true
101 guests_disabled: true
102 registration_shared_secret: "$REG_SECRET" 183 registration_shared_secret: "$REG_SECRET"
103 184
104 turn: 185 turn:
@@ -107,118 +188,80 @@ client_api:
107 - turn:$TURN_DOMAIN?transport=udp 188 - turn:$TURN_DOMAIN?transport=udp
108 - turn:$TURN_DOMAIN?transport=tcp 189 - turn:$TURN_DOMAIN?transport=tcp
109 turn_shared_secret: "$TURN_SECRET" 190 turn_shared_secret: "$TURN_SECRET"
110
111federation_api:
112 send_max_retries: 16
113 disable_tls_validation: false
114
115media_api:
116 base_path: ./media_store
117 max_file_size_bytes: 10485760
118 dynamic_thumbnails: false
119 thumbnail_sizes:
120 - width: 96
121 height: 96
122 method: crop
123 - width: 640
124 height: 480
125 method: scale
126
127user_api:
128 bcrypt_cost: 10
129 auto_join_rooms:
130 - "#main:$MATRIX_DOMAIN"
131
132logging:
133 - type: std
134 level: info
135EOF 191EOF
136 192
137cat <<EOF > /etc/turnserver.conf 193 docker compose up -d
138listening-device=$TURN_LISTENING_DEVICE
139listening-port=3478
140tls-listening-port=5349
141listening-ip=$TURN_SERVER_IP
142min-port=49152
143max-port=65535
144use-auth-secret
145static-auth-secret=$TURN_SECRET
146syslog
147no-rfc5780
148no-stun-backward-compatibility
149response-origin-only-with-rfc5780
150EOF
151 194
152echo "[INFO] Generating server keys..." 195 configure_nginx "$MATRIX_DOMAIN" "8008"
153docker 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
154 196
155echo "[INFO] Booting up containers(HTTP-only test)..." 197 echo "[OK] Dendrite server ($MATRIX_DOMAIN) is running."
156docker compose up -d 198}
157 199
158echo "[INFO] Waiting for dendrite monolith to answer..." 200install_synapse() {
159for i in {1..30}; do 201 echo "=== Installing Matrix Synapse ==="
160 if curl -fs "http://$MATRIX_SERVER_IP:8008/_matrix/client/versions" >/dev/null 2>&1; then 202 common_prompts
161 echo "[OK] Monolith działa na http://$MATRIX_SERVER_IP:8008"
162 break
163 fi
164 echo " ...retry $i"
165 sleep 5
166done
167 203
168echo "[INFO] Setting up NGINX RevPrx files" 204 INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN"
169cat <<EOF > /etc/nginx/sites-available/$MATRIX_DOMAIN 205 mkdir -p "$INSTALL_DIR"
170server { 206 cd "$INSTALL_DIR" || exit 1
171 listen 80;
172 listen [::]:80;
173 server_name $MATRIX_DOMAIN;
174 location /.well-known/matrix/client {
175 return 301 https://$host$request_uri;
176 }
177 location /.well-known/matrix/server {
178 return 301 https://$host$request_uri;
179 }
180 location / {
181 return 301 https://$host$request_uri;
182 }
183}
184 207
185server { 208 cat <<EOF > docker-compose.yml
186 listen 443 ssl http2; 209version: '3.4'
187 listen [::]:443 ssl http2; 210services:
188 server_name $MATRIX_DOMAIN; 211 db:
212 image: postgres:15-alpine
213 environment:
214 POSTGRES_USER: synapse
215 POSTGRES_PASSWORD: $DB_PASS
216 POSTGRES_DB: synapse
217 volumes:
218 - ./db:/var/lib/postgresql/data
189 219
190 ssl_certificate /etc/letsencrypt/live/$MATRIX_DOMAIN/fullchain.pem; 220 synapse:
191 ssl_certificate_key /etc/letsencrypt/live/$MATRIX_DOMAIN/privkey.pem; 221 image: matrixdotorg/synapse:latest
192 include /etc/letsencrypt/options-ssl-nginx.conf; 222 depends_on: [ db ]
193 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; 223 environment:
224 SYNAPSE_SERVER_NAME: $MATRIX_DOMAIN
225 SYNAPSE_REPORT_STATS: "yes"
226 POSTGRES_PASSWORD: $DB_PASS
227 ports:
228 - 8008:8008
229 - 8448:8448
230 volumes:
231 - ./data:/data
232EOF
194 233
195 location / { 234 docker compose up -d
196 proxy_pass http://127.0.0.1:8008;
197 proxy_http_version 1.1;
198 proxy_set_header Host $host;
199 proxy_set_header X-Real-IP $remote_addr;
200 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
201 proxy_set_header X-Forwarded-Proto $scheme;
202 proxy_set_header Upgrade $http_upgrade;
203 proxy_set_header Connection "upgrade";
204 }
205 235
206 location /.well-known/matrix/client { 236 cat <<EOF > data/homeserver-extra.yaml
207 default_type application/json; 237turn_uris: [ "turn:$TURN_DOMAIN?transport=udp", "turn:$TURN_DOMAIN?transport=tcp" ]
208 add_header Access-Control-Allow-Origin *; 238turn_shared_secret: "$TURN_SECRET"
209 return 200 '{"m.homeserver": {"base_url": "https://$MATRIX_DOMAIN"}}'; 239turn_user_lifetime: "5m"
210 } 240EOF
211 241
212 location /.well-known/matrix/server { 242 configure_nginx "$MATRIX_DOMAIN" "8008"
213 default_type application/json; 243
214 add_header Access-Control-Allow-Origin *; 244 echo "[OK] Synapse server ($MATRIX_DOMAIN) is running."
215 return 200 '{"m.server": "$MATRIX_DOMAIN:443"}';
216 }
217} 245}
218EOF
219 246
220ln -s /etc/nginx/sites-available/$MATRIX_DOMAIN 247remove_server() {
221echo "============================================" 248 DOMAIN="$1"
222echo " Matrix server setup finished!" 249 [ -z "$DOMAIN" ] && usage
223echo " HomeServer: https://$MATRIX_DOMAIN:8448" 250 SERVER_DIR="$BASE_DIR/$DOMAIN"
224echo " TURN: $TURN_DOMAIN (3478/5349)" 251 rm -rf "$SERVER_DIR"
252 rm -f "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN"
253 nginx -t && systemctl reload nginx
254 echo "[OK] Server $DOMAIN removed."
255}
256
257# --- CLI router ---
258CMD="${1:-}"
259
260case "$CMD" in
261 turn) install_turn ;;
262 dendrite) install_dendrite ;;
263 synapse) install_synapse ;;
264 list) list_servers ;;
265 remove) remove_server "${2:-}" ;;
266 *) usage ;;
267esac