Compare commits

..

7 Commits

Author SHA1 Message Date
3wc
e9f84f8fd8 Pin docker image tag 2021-04-03 14:38:46 +02:00
3wc
ef719bcee4 Update for COTURN 2020-10-29 19:45:42 +02:00
3wc
309122240a SERVICE -> APP 2020-10-29 19:42:05 +02:00
3wc
fd3c7a606a Rejig .envrc.sample
[ci skip]
2020-10-06 01:52:00 +02:00
3wc
ad6a1c87dd Simplify set-up using custom abra command 2020-09-11 18:14:16 +02:00
3wc
cfbd809761 Working(?) TURN server 2020-09-11 18:14:02 +02:00
3wc
2d78fff08f Add initial coturn server 2020-09-11 00:10:21 +02:00
32 changed files with 115 additions and 2762 deletions

View File

@ -1,49 +0,0 @@
---
kind: pipeline
name: deploy to swarm-test.autonomic.zone
steps:
- name: deployment
image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest
settings:
host: swarm-test.autonomic.zone
stack: matrix-synapse
generate_secrets: true
purge: true
deploy_key:
from_secret: drone_ssh_swarm_test
networks:
- proxy
environment:
DOMAIN: matrix-synapse.swarm-test.autonomic.zone
STACK_NAME: matrix-synapse
LETS_ENCRYPT_ENV: production
DISCORD_BRIDGE_YAML_VERSION: v1
ENTRYPOINT_CONF_VERSION: v1
HOMESERVER_YAML_VERSION: v17
LOG_CONFIG_VERSION: v1
SHARED_SECRET_AUTH_VERSION: v1
SIGNAL_BRIDGE_YAML_VERSION: v1
TELEGRAM_BRIDGE_YAML_VERSION: v1
SECRET_DB_PASSWORD_VERSION: v1
SECRET_FORM_SECRET_VERSION: v1
SECRET_MACAROON_SECRET_KEY_VERSION: v1
SECRET_REGISTRATION_SHARED_SECRET_VERSION: v1
trigger:
branch:
- main
---
kind: pipeline
name: generate recipe catalogue
steps:
- name: release a new version
image: plugins/downstream
settings:
server: https://build.coopcloud.tech
token:
from_secret: drone_abra-bot_token
fork: true
repositories:
- coop-cloud/auto-recipes-catalogue-json
trigger:
event: tag

View File

@ -1,153 +0,0 @@
TYPE=matrix-synapse
DOMAIN=matrix-synapse.example.com
#TIMEOUT=300
#ENABLE_AUTO_UPDATE=true
LETS_ENCRYPT_ENV=production
COMPOSE_FILE="compose.yml"
# POST_DEPLOY_CMDS="db set_admin"
## Admin details
SYNAPSE_ADMIN_EMAIL=admin@example.com
## Secrets
SECRET_DB_PASSWORD_VERSION=v1
SECRET_FORM_SECRET_VERSION=v1
SECRET_MACAROON_VERSION=v1
SECRET_REGISTRATION_VERSION=v1
## Federation
#DISABLE_FEDERATION=1
# Set "true" to enable federation endpoint on $DOMAIN/.well-known/matrix/server
SERVE_SERVER_WELLKNOWN=false
## Registration
ENABLE_REGISTRATION=false
PASSWORD_LOGIN_ENABLED=true
## Room auto-join
#AUTO_JOIN_ROOM_ENABLED=1
#AUTO_JOIN_ROOM="#example:example.com"
## Logging
# for the homserver
SQL_LOG_LEVEL=WARN
ROOT_LOG_LEVEL=WARN
## Privacy
ENABLE_3PID_LOOKUP=true
USER_IPS_MAX_AGE=1d
ENCRYPTED_BY_DEFAULT=all
#ENABLE_ALLOWLIST=1
#FEDERATION_ALLOWLIST="[]"
# Set these to keyservers you trust - usually the same as your federation allowlist
#TRUSTED_KEYSERVERS="trusted_key_servers:\n - server_name: 'example.com'\n - server_name: 'example2.com'"
## Retention
ALLOWED_LIFETIME_MAX=4w
REDACTION_RETENTION_PERIOD=7d
RETENTION_MAX_LIFETIME=4w
#MEDIA_RETENTION_LOCAL_LIFETIME=30d
#MEDIA_RETENTION_REMOTE_LIFETIME=14d
## Keycloak SSO
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml"
#KEYCLOAK_ENABLED=1
#KEYCLOAK_ID=keycloak
#KEYCLOAK_NAME=
#KEYCLOAK_URL=
#KEYCLOAK_CLIENT_ID=
#KEYCLOAK_CLIENT_DOMAIN=
#KEYCLOAK_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1
## TURN
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml"
#KEYCLOAK3_ENABLED=1
#KEYCLOAK3_ID=keycloak3
#KEYCLOAK3_NAME=
#KEYCLOAK3_URL=
#KEYCLOAK3_CLIENT_ID=
#KEYCLOAK3_CLIENT_DOMAIN=
#KEYCLOAK3_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml"
#TURN_ENABLED=1
#TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]"
#TURN_ALLOW_GUESTS=true
#SECRET_TURN_SHARED_SECRET_VERSION=v1
## SMTP
#COMPOSE_FILE="$COMPOSE_FILE:compose.smtp.yml"
#SMTP_ENABLED=1
#SMTP_APP_NAME=
#SMTP_FROM=
#SMTP_HOST=
#SMTP_PORT=
#SMTP_USER=
#SECRET_SMTP_PASSWORD_VERSION=v1
## App services
#APP_SERVICES_ENABLED=1
#APP_SERVICE_CONFIGS="[\"...\"]"
## Telegram bridge
#COMPOSE_FILE="$COMPOSE_FILE:compose.telegram.yml"
#APP_SERVICE_BOT_USERNAME=telegrambot
#APP_SERVICE_DISPLAY_NAME="Telegram bridge bot"
#APP_SERVICE_ID=
#HOMESERVER_DOMAIN=
#HOMESERVER_URL=
#VERIFY_SSL=false
#ENABLE_ENCRYPTION=true
#TELEGRAM_APP_ID=
#TELEGRAM_BRIDGE_PERMISSIONS="{ \"*\": \"relaybot\" }"
#TELEGRAM_SYNC_CHANNEL_MEMBERS=true
#SECRET_TELEGRAM_DB_PASSWORD_VERSION=v1
#SECRET_TELEGRAM_API_HASH_VERSION=v1
#SECRET_TELEGRAM_BOT_TOKEN_VERSION=v1
#SECRET_TELEGRAM_AS_TOKEN_VERSION=v1
#SECRET_TELEGRAM_HS_TOKEN_VERSION=v1
## Discord bridge
#COMPOSE_FILE="$COMPOSE_FILE:compose.discord.yml"
#DISCORD_CLIENT_ID=
#DISCORD_BRIDGE_ADMIN=
#SECRET_DISCORD_BOT_TOKEN_VERSION=v1
#SECRET_DISCORD_DB_PASSWORD_VERSION=v1
## Signal bridge
#COMPOSE_FILE="$COMPOSE_FILE:compose.signal.yml"
#SIGNAL_ENABLE_ENCRYPTION=true
#SIGNAL_BRIDGE_PERMISSIONS="{ \"*\": \"relay\" }"
#SECRET_SIGNAL_AS_TOKEN_VERSION=v1
#SECRET_SIGNAL_DB_PASSWORD_VERSION=v1
#SECRET_SIGNAL_HS_TOKEN_VERSION=v1
## Shared auth
#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml"
#SHARED_SECRET_AUTH_ENABLED=1
#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128

11
.envrc.sample Normal file
View File

@ -0,0 +1,11 @@
export STACK_NAME=matrix
export APP=matrix
export DOMAIN=matrix.example.com
export LETS_ENCRYPT_ENV=production
export ENTRYPOINT_CONF_VERSION=v1
## TURN server
#export TURNSERVER_CONF_VERSION=v1
#export COTURN_SHARED_SECRET_VERSION=v1

3
.gitignore vendored
View File

@ -1,2 +1 @@
.envrc
synapse
/.envrc

128
README.md
View File

@ -1,115 +1,19 @@
# Matrix (Synapse)
# Matrix Synapse
<!-- metadata -->
Matrix Synapse, based on the [official `matrixdotorg/synapse`
image][synapse-docker].
* **Category**: Apps
* **Status**: 0, work-in-progress
* **Image**: [`matrixdotorg/synapse`](https://hub.docker.com/r/matrixdotorg/synapse), 4, upstream
* **Healthcheck**: Yes
* **Backups**: No
* **Email**: Yes
* **Tests**: No
* **SSO**: Yes
1. Set up Docker Swarm and [`abra`][abra]
2. Deploy [`compose-stacks/traefik`][compose-traefik]
2. `cp .envrc.sample .envrc`
3. Edit `.envrc` - be sure to change `$DOMAIN` to something that resolves to
your Docker swarm box
4. `direnv allow` (or `. .envrc`)
4. `abra secret_generate coturn_shared_secret`
5. `abra deploy`
6. `abra service_run synapse` to open a shell
7. `abra register_new_matrix_user`
<!-- endmetadata -->
## Basic usage
1. Set up Docker Swarm and [`abra`](https://docs.coopcloud.tech/abra/)
2. Deploy [`coop-cloud/traefik`](https://git.coopcloud.tech/coop-cloud/traefik)
3. `abra app new matrix-synapse --secrets` (optionally with `--pass` if you'd like to save secrets in `pass`)
4. `abra app config YOURAPPDOMAIN` - be sure to change `$DOMAIN` to something that resolves to your Docker swarm box
5. `abra app deploy YOURAPPDOMAIN`
6. Create an initial user: `abra app run YOURAPPDOMAIN app register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008`
## Tips & Tricks
### Set Admin User
`abra app cmd YOURAPPDOMAIN db set_admin <adminuser>`
### Disabling federation
- Use `DISABLE_FEDERATION=1` to turn off federation listeners
- Don't use [`compose.matrix.yml`](https://git.coopcloud.tech/coop-cloud/traefik/src/branch/master/compose.matrix.yml) in your traefik config to keep the federation ports closed
### Enabling federation
See [`#27`](https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/27) for more. Depending on your setup, using `SERVE_SERVER_WELLKNOWN=true` might work to start federating. Make sure you don't leave `DISABLE_FEDERATION=1` set!
### Getting client discovery on a custom domain
You'll need to deploy something like [this](https://git.autonomic.zone/ruangrupa/well-known-uris). This could be implemented in this recipe but we haven't merged it in yet. Change sets are welcome.
### Telegram bridging
> WIP docs
Setting it up is a bit of a chicken/egg & chasing cats moment.
You need to get your bot setup on the telegram side first and have these values:
```
api_id: ...
api_hash: ...
telegram_bot_token: ...
```
Here is a rough guide:
```
abra app secret insert <domain> telegram_api_hash v1 <secret>
abra app secret insert <domain> telegram_bot_token v1 <secret>
abra app secret generate -a <domain>
abra app deploy <domain>
abra app run matrix.fva.wtf telegram_bridge cat /data/registration.yaml
abra app undeploy <domain>
abra app secret rm <domain> telegram_as_token
abra app secret insert <domain> telegram_as_token v1 <secret>
abra app secret rm <domain> telegram_as_token
abra app secret insert <domain> telegram_hs_token v1 <secret>
abra app deploy <domain>
```
Some helpful documentation:
- [`docs.mau.fi`](https://docs.mau.fi/bridges/python/setup/docker.html?bridge=telegram)
- [`example-config.yaml`](https://mau.dev/mautrix/telegram/-/blob/master/mautrix_telegram/example-config.yaml)
### Discord bridging
> WIP docs
Just as messy as the Telegram bridging above! Rough guide:
- get a local copy of [`config.yaml`](https://github.com/matrix-org/matrix-appservice-discord/blob/develop/config/config.sample.yaml)
- fill it out with the values you need, all the discord token stuff, etc.
- run `mkdir -p data && cp config.yaml data/` then `docker run --rm -v data:/data halfshot/matrix-appservice-discord:v1.0.0 sh -c "cd /data && node /build/src/discordas.js -r -u "http://discordbridge:9005" -c config.yaml"`
- this generates the app service registration configuration you need to feed to the homeserver
- run secret generation for the `discord_db_password`, insert your `discord_bot_token`
- run `abra app cp <domain> discord-registration.yaml app:/discord-data` (it has to be called `discord-registration.yaml`)
- deploy the bridge & happy hacking
Some helpful documentation:
- [`matrix-org/matrix-appservice-discord` docs](https://github.com/matrix-org/matrix-appservice-discord#bridging-a-room)
- [`t2bot.io/discord`](https://t2bot.io/discord/)
### Signal bridging
> WIP docs
OK, it's also awful to set this up. Do you see a pattern emerging :)
- fake that you have the required tokens:
- `abra app secret insert example.com signal_hs_token v1 foo`
- `abra app secret insert example.com signal_as_token v1 foo`
- generate the database password:
- `abra app secret generate example.com -a`
- deploy the thing and then check the `/data/registration.yaml`
- rm the fake `signal_hs/as_token` values and re-insert the new ones from `registration.yaml`
- re-deploy the whole thing and then it should come up, message `@signalbot:example.com` to test
[synapse-docker]: https://hub.docker.com/r/matrixdotorg/synapse
[abra]: https://git.autonomic.zone/autonomic-cooperative/abra
[compose-traefik]: https://git.autonomic.zone/compose-stacks/traefik

3
abra-commands.sh Normal file
View File

@ -0,0 +1,3 @@
sub_register_new_matrix_user() {
abra run synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
}

16
abra.sh
View File

@ -1,16 +0,0 @@
export DISCORD_BRIDGE_YAML_VERSION=v2
export ENTRYPOINT_CONF_VERSION=v1
export HOMESERVER_YAML_VERSION=v23
export LOG_CONFIG_VERSION=v2
export SHARED_SECRET_AUTH_VERSION=v1
export SIGNAL_BRIDGE_YAML_VERSION=v4
export TELEGRAM_BRIDGE_YAML_VERSION=v6
set_admin () {
admin=akadmin
if [ -n "$1" ]
then
admin=$1
fi
psql -U synapse -c "UPDATE users SET admin = 1 WHERE name = '@$admin:$DOMAIN'";
}

35
compose.coturn.yml Normal file
View File

@ -0,0 +1,35 @@
services:
app:
environment:
- TURN_SERVER=${DOMAIN}
- TURN_PORT=3478
secrets:
- coturn_shared_secret
coturn:
image: instrumentisto/coturn:latest
networks:
- swarm_host
secrets:
- coturn_shared_secret
configs:
- source: turnserver_conf
target: /etc/coturn/turnserver.conf
configs:
turnserver_conf:
name: ${STACK_NAME}_turnserver_conf_${TURNSERVER_CONF_VERSION}
file: turnserver.conf.tmpl
template_driver: golang
secrets:
coturn_shared_secret:
external: true
name: ${STACK_NAME}_coturn_shared_secret_${COTURN_SHARED_SECRET_VERSION}
networks:
# use host-mode networking until Docker can handle mass port-forwards:
# https://github.com/moby/moby/issues/11185
swarm_host:
external:
name: 'host'

View File

@ -1,66 +0,0 @@
---
version: "3.8"
services:
app:
environment:
- APP_SERVICES_ENABLED
- APP_SERVICE_CONFIGS
volumes:
- discord-data:/discord-data
discordbridge:
image: halfshot/matrix-appservice-discord:v1.0.0
depends_on:
- discorddb
configs:
- source: discord_bridge_yaml
target: /data/config.yaml
environment:
- DISCORD_CLIENT_ID
- DISCORD_BRIDGE_ADMIN
- HOMESERVER_DOMAIN
- HOMESERVER_URL
secrets:
- discord_bot_token
- discord_db_password
volumes:
- discord-data:/data
networks:
- internal
discorddb:
image: postgres:13-alpine
secrets:
- discord_db_password
environment:
- LC_COLLATE=C
- LC_CTYPE=C
- POSTGRES_DB=discordbridge
- POSTGRES_INITDB_ARGS="-E \"UTF8\""
- POSTGRES_PASSWORD_FILE=/run/secrets/discord_db_password
- POSTGRES_USER=discordbridge
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER" ]
volumes:
- discord-postgres:/var/lib/postgresql/data
configs:
discord_bridge_yaml:
name: ${STACK_NAME}_discord_bridge_yaml_${DISCORD_BRIDGE_YAML_VERSION}
file: discord_bridge.yaml.tmpl
template_driver: golang
volumes:
discord-data:
discord-postgres:
secrets:
discord_db_password:
external: true
name: ${STACK_NAME}_discord_db_password_${SECRET_DISCORD_DB_PASSWORD_VERSION}
discord_bot_token:
external: true
name: ${STACK_NAME}_discord_bot_token_${SECRET_DISCORD_BOT_TOKEN_VERSION}

View File

@ -1,24 +0,0 @@
---
version: "3.8"
services:
app:
secrets:
- db_password
- form_secret
- keycloak_client_secret
- macaroon_secret_key
- registration_shared_secret
environment:
- KEYCLOAK_CLIENT_DOMAIN
- KEYCLOAK_CLIENT_ID
- KEYCLOAK_ENABLED
- KEYCLOAK_NAME
- KEYCLOAK_ID
- KEYCLOAK_URL
- KEYCLOAK_ALLOW_EXISTING_USERS
secrets:
keycloak_client_secret:
external: true
name: ${STACK_NAME}_keycloak_client_secret_${SECRET_KEYCLOAK_CLIENT_SECRET_VERSION}

View File

@ -1,19 +0,0 @@
---
version: "3.8"
services:
app:
secrets:
- keycloak2_client_secret
environment:
- KEYCLOAK2_ALLOW_EXISTING_USERS
- KEYCLOAK2_CLIENT_ID
- KEYCLOAK2_ENABLED
- KEYCLOAK2_ID
- KEYCLOAK2_NAME
- KEYCLOAK2_URL
secrets:
keycloak2_client_secret:
external: true
name: ${STACK_NAME}_keycloak2_client_secret_${SECRET_KEYCLOAK2_CLIENT_SECRET_VERSION}

View File

@ -1,19 +0,0 @@
---
version: "3.8"
services:
app:
secrets:
- keycloak3_client_secret
environment:
- KEYCLOAK3_ALLOW_EXISTING_USERS
- KEYCLOAK3_CLIENT_ID
- KEYCLOAK3_ENABLED
- KEYCLOAK3_ID
- KEYCLOAK3_NAME
- KEYCLOAK3_URL
secrets:
keycloak3_client_secret:
external: true
name: ${STACK_NAME}_keycloak3_client_secret_${SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION}

View File

@ -1,22 +0,0 @@
---
version: "3.8"
services:
app:
environment:
- SHARED_SECRET_AUTH_ENABLED
secrets:
- shared_secret_auth
configs:
- source: shared_secret_auth
target: /usr/local/lib/python3.11/site-packages/shared_secret_authenticator.py
configs:
shared_secret_auth:
name: ${STACK_NAME}_shared_secret_auth_${SHARED_SECRET_AUTH_VERSION}
file: shared_secret_authenticator.py
secrets:
shared_secret_auth:
external: true
name: ${STACK_NAME}_shared_secret_auth_${SECRET_SHARED_SECRET_AUTH_VERSION}

View File

@ -1,81 +0,0 @@
---
version: "3.8"
services:
app:
environment:
- APP_SERVICES_ENABLED
- APP_SERVICE_CONFIGS
volumes:
- signal-data:/signal-data
signald:
image: docker.io/signald/signald:0.23.2-non-root
networks:
- internal
volumes:
- signald-data:/signald
signalbridge:
image: dock.mau.dev/mautrix/signal:v0.4.3
depends_on:
- signaldb
configs:
- source: signal_bridge_yaml
target: /data/config.yaml
environment:
- HOMESERVER_DOMAIN
- HOMESERVER_URL
- SIGNAL_BRIDGE_PERMISSIONS
- SIGNAL_ENABLE_ENCRYPTION
- VERIFY_SSL
secrets:
- signal_as_token
- signal_db_password
- signal_hs_token
- shared_secret_auth
volumes:
- signal-data:/data
- signald-data:/signald
networks:
- internal
signaldb:
image: postgres:13-alpine
secrets:
- signal_db_password
environment:
- LC_COLLATE=C
- LC_CTYPE=C
- POSTGRES_DB=signalbridge
- POSTGRES_INITDB_ARGS="-E \"UTF8\""
- POSTGRES_PASSWORD_FILE=/run/secrets/signal_db_password
- POSTGRES_USER=signalbridge
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER" ]
volumes:
- signal-postgres:/var/lib/postgresql/data
configs:
signal_bridge_yaml:
name: ${STACK_NAME}_signal_bridge_yaml_${SIGNAL_BRIDGE_YAML_VERSION}
file: signal_bridge.yaml.tmpl
template_driver: golang
volumes:
signald-data:
signal-data:
signal-postgres:
secrets:
signal_db_password:
external: true
name: ${STACK_NAME}_signal_db_password_${SECRET_SIGNAL_DB_PASSWORD_VERSION}
signal_as_token:
external: true
name: ${STACK_NAME}_signal_as_token_${SECRET_SIGNAL_AS_TOKEN_VERSION}
signal_hs_token:
external: true
name: ${STACK_NAME}_signal_hs_token_${SECRET_SIGNAL_HS_TOKEN_VERSION}

View File

@ -1,23 +0,0 @@
---
version: "3.8"
services:
app:
secrets:
- db_password
- form_secret
- macaroon_secret_key
- registration_shared_secret
- smtp_password
environment:
- SMTP_APP_NAME
- SMTP_ENABLED
- SMTP_FROM
- SMTP_HOST
- SMTP_PORT
- SMTP_USER
secrets:
smtp_password:
external: true
name: ${STACK_NAME}_smtp_password_${SECRET_SMTP_PASSWORD_VERSION}

View File

@ -1,85 +0,0 @@
---
version: "3.8"
services:
app:
environment:
- APP_SERVICES_ENABLED
- APP_SERVICE_CONFIGS
volumes:
- telegram-data:/telegram-data
telegrambridge:
image: dock.mau.dev/mautrix/telegram:v0.14.2
depends_on:
- telegramdb
configs:
- source: telegram_bridge_yaml
target: /data/config.yaml
environment:
- APP_SERVICE_BOT_USERNAME
- APP_SERVICE_DISPLAY_NAME
- APP_SERVICE_ID
- ENABLE_ENCRYPTION
- HOMESERVER_DOMAIN
- HOMESERVER_URL
- TELEGRAM_APP_ID
- TELEGRAM_BRIDGE_PERMISSIONS
- TELEGRAM_SYNC_CHANNEL_MEMBERS
- VERIFY_SSL
secrets:
- telegram_api_hash
- telegram_as_token
- telegram_bot_token
- telegram_db_password
- telegram_hs_token
- shared_secret_auth
volumes:
- telegram-data:/data
networks:
- internal
telegramdb:
image: postgres:13-alpine
secrets:
- telegram_db_password
environment:
- LC_COLLATE=C
- LC_CTYPE=C
- POSTGRES_DB=telegrambridge
- POSTGRES_INITDB_ARGS="-E \"UTF8\""
- POSTGRES_PASSWORD_FILE=/run/secrets/telegram_db_password
- POSTGRES_USER=telegrambridge
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER" ]
volumes:
- telegram-postgres:/var/lib/postgresql/data
configs:
telegram_bridge_yaml:
name: ${STACK_NAME}_telegram_bridge_yaml_${TELEGRAM_BRIDGE_YAML_VERSION}
file: telegram_bridge.yaml.tmpl
template_driver: golang
volumes:
telegram-data:
telegram-postgres:
secrets:
telegram_db_password:
external: true
name: ${STACK_NAME}_telegram_db_password_${SECRET_TELEGRAM_DB_PASSWORD_VERSION}
telegram_api_hash:
external: true
name: ${STACK_NAME}_telegram_api_hash_${SECRET_TELEGRAM_API_HASH_VERSION}
telegram_bot_token:
external: true
name: ${STACK_NAME}_telegram_bot_token_${SECRET_TELEGRAM_BOT_TOKEN_VERSION}
telegram_as_token:
external: true
name: ${STACK_NAME}_telegram_as_token_${SECRET_TELEGRAM_AS_TOKEN_VERSION}
telegram_hs_token:
external: true
name: ${STACK_NAME}_telegram_hs_token_${SECRET_TELEGRAM_HS_TOKEN_VERSION}

View File

@ -1,20 +0,0 @@
---
version: "3.8"
services:
app:
secrets:
- db_password
- form_secret
- macaroon_secret_key
- registration_shared_secret
- turn_shared_secret
environment:
- TURN_ALLOW_GUESTS
- TURN_ENABLED
- TURN_URIS
secrets:
turn_shared_secret:
external: true
name: ${STACK_NAME}_turn_shared_secret_${SECRET_TURN_SHARED_SECRET_VERSION}

View File

@ -3,135 +3,47 @@ version: "3.8"
services:
app:
image: "matrixdotorg/synapse:v1.93.0"
image: "matrixdotorg/synapse:v1.9.1"
volumes:
- "data:/data"
depends_on:
- db
secrets:
- db_password
- registration_shared_secret
- macaroon_secret_key
- form_secret
- "synapse:/data"
environment:
- ALLOWED_LIFETIME_MAX
- AUTO_JOIN_ROOM
- AUTO_JOIN_ROOM_ENABLED
- DISABLE_FEDERATION
- DOMAIN
- ENABLE_3PID_LOOKUP
- ENABLE_ALLOWLIST
- ENABLE_REGISTRATION
- ENCRYPTED_BY_DEFAULT
- FEDERATION_ALLOWLIST
- LETSENCRYPT_HOST=${DOMAIN}
- MEDIA_RETENTION_LOCAL_LIFETIME
- MEDIA_RETENTION_REMOTE_LIFETIME
- PASSWORD_LOGIN_ENABLED
- REDACTION_RETENTION_PERIOD
- RETENTION_MAX_LIFETIME
- ROOT_LOG_LEVEL
- SERVE_SERVER_WELLKNOWN
- SQL_LOG_LEVEL
- STACK_NAME
- SYNAPSE_ADMIN_EMAIL
- SYNAPSE_REPORT_STATS=no
- SYNAPSE_SERVER_NAME=${DOMAIN}
- USER_IPS_MAX_AGE
- VIRTUAL_HOST=${DOMAIN}
- VIRTUAL_PORT=8008
- LETSENCRYPT_HOST=${DOMAIN}
- SYNAPSE_SERVER_NAME=${DOMAIN}
- SYNAPSE_REPORT_STATS=no
networks:
- proxy
- internal
entrypoint: /docker-entrypoint.sh
configs:
- source: homeserver_yaml
target: /data/homeserver.yaml
- source: log_config
target: /data/log.config
- source: entrypoint_conf
target: /docker-entrypoint.sh
mode: 0555
entrypoint: /docker-entrypoint.sh
deploy:
restart_policy:
condition: on-failure
delay: "60s"
max_attempts: 3
window: 120s
labels:
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=8008"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "coop-cloud.${STACK_NAME}.version=4.0.0+v1.93.0"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8008/health"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
db:
image: postgres:13-alpine
secrets:
- db_password
environment:
- LC_COLLATE=C
- LC_CTYPE=C
- POSTGRES_DB=synapse
- POSTGRES_INITDB_ARGS="-E \"UTF8\""
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
- POSTGRES_USER=synapse
- DOMAIN
networks:
- internal
healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
volumes:
- postgres:/var/lib/postgresql/data
deploy:
labels:
backupbot.backup: "true"
backupbot.backup.pre-hook: "mkdir -p /tmp/backup/ && PGPASSWORD=$$(cat $${POSTGRES_PASSWORD_FILE}) pg_dump -U $${POSTGRES_USER} $${POSTGRES_DB} > /tmp/backup/backup.sql"
backupbot.backup.post-hook: "rm -rf /tmp/backup"
backupbot.backup.path: "/tmp/backup/"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true"
- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}"
volumes:
data:
postgres:
synapse:
networks:
proxy:
external: true
internal:
configs:
entrypoint_conf:
name: ${STACK_NAME}_entrypoint_${ENTRYPOINT_CONF_VERSION}
file: entrypoint.sh.tmpl
template_driver: golang
homeserver_yaml:
name: ${STACK_NAME}_homeserver_yaml_${HOMESERVER_YAML_VERSION}
file: homeserver.yaml.tmpl
template_driver: golang
log_config:
name: ${STACK_NAME}_log_config_${LOG_CONFIG_VERSION}
file: log.config.tmpl
template_driver: golang
secrets:
db_password:
external: true
name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION}
registration_shared_secret:
external: true
name: ${STACK_NAME}_registration_${SECRET_REGISTRATION_VERSION}
macaroon_secret_key:
external: true
name: ${STACK_NAME}_macaroon_${SECRET_MACAROON_VERSION}
form_secret:
external: true
name: ${STACK_NAME}_form_secret_${SECRET_FORM_SECRET_VERSION}

View File

@ -1,123 +0,0 @@
bridge:
# Domain part of the bridge, e.g. matrix.org
domain: "{{ env "HOMESERVER_DOMAIN" }}"
# This should be your publicly-facing URL because Discord may use it to
# fetch media from the media store.
homeserverUrl: "{{ env "HOMESERVER_URL" }}"
# The TCP port on which the appservice runs on.
port: 9005
# Interval at which to process users in the 'presence queue'. If you have
# 5 users, one user will be processed every 500 milliseconds according to the
# value below. This has a minimum value of 250.
# WARNING: This has a high chance of spamming the homeserver with presence
# updates since it will send one each time somebody changes state or is online.
presenceInterval: 500
# Disable setting presence for 'ghost users' which means Discord users on Matrix
# will not be shown as away or online.
disablePresence: false
# Disable sending typing notifications when somebody on Discord types.
disableTypingNotifications: false
# Disable deleting messages on Discord if a message is redacted on Matrix.
disableDeletionForwarding: false
# Disable portal bridging, where Matrix users can search for unbridged Discord
# rooms on their Matrix server.
disablePortalBridging: false
# Enable users to bridge rooms using !discord commands. See
# https://t2bot.io/discord for instructions.
enableSelfServiceBridging: true
# Disable sending of read receipts for Matrix events which have been
# successfully bridged to Discord.
disableReadReceipts: false
# Disable Join Leave echos from matrix
disableJoinLeaveNotifications: false
# Disable Invite echos from matrix
disableInviteNotifications: false
# Auto-determine the language of code blocks (this can be CPU-intensive)
determineCodeLanguage: false
# MXID of an admin user that will be PMd if the bridge experiences problems. Optional
adminMxid: '{{ env "DISCORD_BRIDGE_ADMIN" }}'
# The message to send to the bridge admin if the Discord token is not valid
invalidTokenMessage: 'Your Discord bot token seems to be invalid, and the bridge cannot function. Please update it in your bridge settings and restart the bridge'
# Authentication configuration for the discord bot.
auth:
# This MUST be a string (wrapped in quotes)
clientID: "{{ env "DISCORD_CLIENT_ID" }}"
botToken: "{{ secret "discord_bot_token" }}"
# You must enable "Privileged Gateway Intents" in your bot settings on discord.com (e.g. https://discord.com/developers/applications/12345/bot)
# for this to work
usePrivilegedIntents: false
logging:
# What level should the logger output to the console at.
console: "error" #silly, verbose, info, http, warn, error, silent
lineDateFormat: "MMM-D HH:mm:ss.SSS" # This is in moment.js format
files:
- file: "debug.log"
disable:
- "PresenceHandler" # Will not capture presence logging
- file: "warn.log" # Will capture warnings
level: "warn"
- file: "botlogs.log" # Will capture logs from DiscordBot
level: "info"
enable:
- "DiscordBot"
database:
# You may either use SQLite or Postgresql for the bridge database, which contains
# important mappings for events and user puppeting configurations.
# Use the filename option for SQLite, or connString for Postgresql.
# If you are migrating, see https://github.com/Half-Shot/matrix-appservice-discord/blob/master/docs/howto.md#migrate-to-postgres-from-sqlite
# WARNING: You will almost certainly be fine with sqlite unless your bridge
# is in heavy demand and you suffer from IO slowness.
connString: "postgres://discordbridge:{{ secret "discord_db_password" }}@discorddb/discordbridge"
room:
# Set the default visibility of alias rooms, defaults to "public".
# One of: "public", "private"
defaultVisibility: "public"
channel:
# Pattern of the name given to bridged rooms.
# Can use :guild for the guild name and :name for the channel name.
namePattern: "[Discord] :guild :name"
# Changes made to rooms when a channel is deleted.
deleteOptions:
# Prefix the room name with a string.
#namePrefix: "[Deleted]"
# Prefix the room topic with a string.
#topicPrefix: "This room has been deleted"
# Disable people from talking in the room by raising the event PL to 50
disableMessaging: false
# Remove the discord alias from the room.
unsetRoomAlias: true
# Remove the room from the directory.
unlistFromDirectory: true
# Set the room to be unavailable for joining without an invite.
setInviteOnly: true
# Make all the discord users leave the room.
ghostsLeave: true
limits:
# Delay in milliseconds between discord users joining a room.
roomGhostJoinDelay: 6000
# Lock timeout in milliseconds before sending messages to discord to avoid
# echos. Default is rather high as the lock will most likely time out
# before anyways.
# echos = (Copies of a sent message may arrive from discord before we've
# fininished handling it, causing us to echo it back to the room)
discordSendDelay: 1500
# Set a maximum of rooms to be bridged.
# roomCount: 20
ghosts:
# Pattern for the ghosts nick, available is :nick, :username, :tag and :id
nickPattern: ":nick"
# Pattern for the ghosts username, available is :username, :tag and :id
usernamePattern: ":username#:tag"
# Prometheus-compatible metrics endpoint
metrics:
enable: false
port: 9001
host: "127.0.0.1"

View File

@ -1,11 +1,18 @@
#!/bin/bash
# https://github.com/matrix-org/synapse/tree/develop/docker#running-synapse
# default user permissions for the synapse user
chown 991:991 /data
if [[ ! -f /data/{{ env "DOMAIN" }}.signing.key ]]; then
if [[ ! -f /data/homeserver.yaml ]]; then
/start.py generate
apt update && apt install -y wget
wget https://github.com/mikefarah/yq/releases/download/3.3.2/yq_linux_amd64 && \
chmod +x yq_linux_amd64 && \
mv yq_linux_amd64 /bin/yq
# turn (https://github.com/matrix-org/synapse/blob/master/docs/turn-howto.md#synapse-setup)
yq w -i /data/homeserver.yaml turn_uris "[]"
yq w -i /data/homeserver.yaml turn_uris\[0\] "turn:${TURN_SERVER}:${TURN_PORT}?transport=udp"
yq w -i /data/homeserver.yaml turn_uris\[1\] "turn:${TURN_SERVER}:${TURN_PORT}?transport=tcp"
yq w -i /data/homeserver.yaml coturn_shared_secret "$(tr -d \"\n\" < /run/secrets/coturn_shared_secret)"
fi
/start.py

6
gen.sh Executable file
View File

@ -0,0 +1,6 @@
secret="screw\$naval5seem!herb" && \
time=$(date +%s) && \
expiry=8400 && \
username=$(( $time + $expiry )) &&\
echo username:$username && \
echo password : $(echo -n $username | openssl dgst -binary -sha1 -hmac $secret | openssl base64)

View File

@ -1,779 +0,0 @@
## Modules ##
# Server admins can expand Synapse's functionality with external modules.
#
# See https://matrix-org.github.io/synapse/latest/modules.html for more
# documentation on how to configure or create custom modules for Synapse.
#
modules:
# - module: my_super_module.MySuperClass
# config:
# do_thing: true
# - module: my_other_super_module.SomeClass
# config: {}
{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }}
- module: shared_secret_authenticator.SharedSecretAuthProvider
config:
shared_secret: {{ secret "shared_secret_auth" }}
m_login_password_support_enabled: true
{{ end }}
## Server ##
# The public-facing domain of the server
#
# The server_name name will appear at the end of usernames and room addresses
# created on this server. For example if the server_name was example.com,
# usernames on this server would be in the format @user:example.com
#
# In most cases you should avoid using a matrix specific subdomain such as
# matrix.example.com or synapse.example.com as the server_name for the same
# reasons you wouldn't use user@email.example.com as your email address.
# See https://matrix-org.github.io/synapse/latest/delegate.html
# for information on how to host Synapse on a subdomain while preserving
# a clean server_name.
#
# The server_name cannot be changed later so it is important to
# configure this correctly before you start Synapse. It should be all
# lowercase and may contain an explicit port.
# Examples: matrix.org, localhost:8080
#
server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
# The public-facing base URL that clients use to access this Homeserver (not
# including _matrix/...). This is the same URL a user might enter into the
# 'Custom Homeserver URL' field on their client. If you use Synapse with a
# reverse proxy, this should be the URL to reach Synapse via the proxy.
# Otherwise, it should be the URL to reach Synapse's client HTTP listener (see
# 'listeners' below).
#
# Defaults to 'https://<server_name>/'.
#
public_baseurl: https://{{ env "DOMAIN" }}/
# Uncomment the following to tell other servers to send federation traffic on
# port 443.
#
# By default, other servers will try to reach our server on port 8448, which can
# be inconvenient in some environments.
#
# Provided 'https://<server_name>/' on port 443 is routed to Synapse, this
# option configures Synapse to serve a file at
# 'https://<server_name>/.well-known/matrix/server'. This will tell other
# servers to send traffic to port 443 instead.
#
# See https://matrix-org.github.io/synapse/latest/delegate.html for more
# information.
#
# Defaults to 'false'.
#
serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }}
# If set to 'true', removes the need for authentication to access the server's
# public rooms directory through the client API, meaning that anyone can
# query the room directory. Defaults to 'false'.
#
allow_public_rooms_without_auth: false
# If set to 'true', allows any other homeserver to fetch the server's public
# rooms directory via federation. Defaults to 'false'.
#
allow_public_rooms_over_federation: false
listeners:
# Unsecure HTTP listener: for when matrix traffic passes through a reverse proxy
# that unwraps TLS.
#
# If you plan to use a reverse proxy, please see
# https://matrix-org.github.io/synapse/latest/reverse_proxy.html.
#
- port: 8008
tls: false
type: http
x_forwarded: true
{{ if eq (env "DISABLE_FEDERATION") "1" }}
resources:
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
- names: [client, openid]
compress: true
{{ else }}
- names: [client]
compress: true
{{ end }}
{{ else }}
resources:
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
- names: [client, openid, federation]
compress: true
{{ else }}
- names: [client, federation]
compress: true
{{ end }}
{{ end }}
## Homeserver blocking ##
# How to reach the server admin, used in ResourceLimitError
#
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}'
# Resource-constrained homeserver settings
#
# When this is enabled, the room "complexity" will be checked before a user
# joins a new remote room. If it is above the complexity limit, the server will
# disallow joining, or will instantly leave.
#
# Room complexity is an arbitrary measure based on factors such as the number of
# users in the room.
#
limit_remote_rooms:
# Uncomment to enable room complexity checking.
#
enabled: true
# the limit above which rooms cannot be joined. The default is 1.0.
#
complexity: 200.0
# The largest allowed file size for a user avatar. Defaults to no restriction.
# Note that user avatar changes will not work if this is set without
# using Synapse's media repository.
#
max_avatar_size: 10M
# How long to keep redacted events in unredacted form in the database. After
# this period redacted events get replaced with their redacted form in the DB.
#
# Defaults to `7d`. Set to `null` to disable.
#
redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
# How long to track users' last seen time and IPs in the database.
#
# Defaults to `28d`. Set to `null` to disable clearing out of old rows.
#
user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }}
# Message retention policy at the server level.
#
# Room admins and mods can define a retention period for their rooms using the
# 'm.room.retention' state event, and server admins can cap this period by setting
# the 'allowed_lifetime_min' and 'allowed_lifetime_max' config options.
#
# If this feature is enabled, Synapse will regularly look for and purge events
# which are older than the room's maximum retention period. Synapse will also
# filter events received over federation so that events that should have been
# purged are ignored and not stored again.
#
retention:
# The message retention policies feature is disabled by default. Uncomment the
# following line to enable it.
#
enabled: true
# Default retention policy. If set, Synapse will apply it to rooms that lack the
# 'm.room.retention' state event. Currently, the value of 'min_lifetime' doesn't
# matter much because Synapse doesn't take it into account yet.
#
default_policy:
min_lifetime: 1d
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
# Retention policy limits. If set, and the state of a room contains a
# 'm.room.retention' event in its state which contains a 'min_lifetime' or a
# 'max_lifetime' that's out of these bounds, Synapse will cap the room's policy
# to these limits when running purge jobs.
#
allowed_lifetime_min: 1d
allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }}
# Server admins can define the settings of the background jobs purging the
# events which lifetime has expired under the 'purge_jobs' section.
#
# If no configuration is provided, a single job will be set up to delete expired
# events in every room daily.
#
# Each job's configuration defines which range of message lifetimes the job
# takes care of. For example, if 'shortest_max_lifetime' is '2d' and
# 'longest_max_lifetime' is '3d', the job will handle purging expired events in
# rooms whose state defines a 'max_lifetime' that's both higher than 2 days, and
# lower than or equal to 3 days. Both the minimum and the maximum value of a
# range are optional, e.g. a job with no 'shortest_max_lifetime' and a
# 'longest_max_lifetime' of '3d' will handle every room with a retention policy
# which 'max_lifetime' is lower than or equal to three days.
#
# The rationale for this per-job configuration is that some rooms might have a
# retention policy with a low 'max_lifetime', where history needs to be purged
# of outdated messages on a more frequent basis than for the rest of the rooms
# (e.g. every 12h), but not want that purge to be performed by a job that's
# iterating over every room it knows, which could be heavy on the server.
#
# If any purge job is configured, it is strongly recommended to have at least
# a single job with neither 'shortest_max_lifetime' nor 'longest_max_lifetime'
# set, or one job without 'shortest_max_lifetime' and one job without
# 'longest_max_lifetime' set. Otherwise some rooms might be ignored, even if
# 'allowed_lifetime_min' and 'allowed_lifetime_max' are set, because capping a
# room's policy to these values is done after the policies are retrieved from
# Synapse's database (which is done using the range specified in a purge job's
# configuration).
#
purge_jobs:
- longest_max_lifetime: 3d
interval: 12h
- shortest_max_lifetime: 3d
interval: 1d
## Federation ##
# Restrict federation to the following whitelist of domains.
# N.B. we recommend also firewalling your federation listener to limit
# inbound federation traffic as early as possible, rather than relying
# purely on this application-layer restriction. If not specified, the
# default is to whitelist everything.
#
#federation_domain_whitelist:
# - lon.example.com
# - nyc.example.com
# - syd.example.com
{{ if eq (env "DISABLE_FEDERATION") "1" }}
federation_domain_whitelist: []
{{ else if eq (env "ENABLE_ALLOWLIST") "1" }}
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }}
{{ end }}
## Database ##
# The 'database' setting defines the database that synapse uses to store all of
# its data.
#
# 'name' gives the database engine to use: either 'sqlite3' (for SQLite) or
# 'psycopg2' (for PostgreSQL).
#
# 'txn_limit' gives the maximum number of transactions to run per connection
# before reconnecting. Defaults to 0, which means no limit.
#
# 'args' gives options which are passed through to the database engine,
# except for options starting 'cp_', which are used to configure the Twisted
# connection pool. For a reference to valid arguments, see:
# * for sqlite: https://docs.python.org/3/library/sqlite3.html#sqlite3.connect
# * for postgres: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS
# * for the connection pool: https://twistedmatrix.com/documents/current/api/twisted.enterprise.adbapi.ConnectionPool.html#__init__
database:
name: psycopg2
txn_limit: 10000
args:
user: synapse
password: "{{ secret "db_password" }}"
database: synapse
host: "{{ env "STACK_NAME" }}_db"
port: 5432
cp_min: 5
cp_max: 10
keepalives_idle: 10
keepalives_interval: 10
keepalives_count: 3
## Logging ##
# A yaml python logging config file as described by
# https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema
#
log_config: "/data/log.config"
## Media Store ##
# Enable the media store service in the Synapse master. Uncomment the
# following if you are using a separate media store worker.
#
#enable_media_repo: false
# Directory where uploaded images and attachments are stored.
#
media_store_path: "/data/media_store"
# The largest allowed upload size in bytes
#
# If you are using a reverse proxy you may also need to set this value in
# your reverse proxy's config. Notably Nginx has a small max body size by default.
# See https://matrix-org.github.io/synapse/latest/reverse_proxy.html.
#
max_upload_size: 50M
{{ if eq (env "TURN_ENABLED") "1" }}
## TURN ##
# The public URIs of the TURN server to give to clients
#
turn_uris: {{ env "TURN_URIS" }}
# The shared secret used to compute passwords for the TURN server
#
turn_shared_secret: "{{ secret "turn_shared_secret" }}"
# How long generated TURN credentials last
#
turn_user_lifetime: 1h
# Whether guests should be allowed to use the TURN server.
# This defaults to True, otherwise VoIP will be unreliable for guests.
# However, it does introduce a slight security risk as it allows users to
# connect to arbitrary endpoints without having first signed up for a
# valid account (e.g. by passing a CAPTCHA).
#
turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }}
{{ end }}
## Registration ##
#
# Registration can be rate-limited using the parameters in the "Ratelimiting"
# section of this file.
# Enable registration for new users.
#
enable_registration: {{ env "ENABLE_REGISTRATION" }}
# Enable 3PIDs lookup requests to identity servers from this server.
#
enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }}
# If set, allows registration of standard or admin accounts by anyone who
# has the shared secret, even if registration is otherwise disabled.
#
registration_shared_secret: {{ secret "registration_shared_secret" }}
# Users who register on this homeserver will automatically be joined
# to these rooms.
#
# By default, any room aliases included in this list will be created
# as a publicly joinable room when the first user registers for the
# homeserver. This behaviour can be customised with the settings below.
# If the room already exists, make certain it is a publicly joinable
# room. The join rule of the room must be set to 'public'.
#
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }}
auto_join_rooms:
- "{{ env "AUTO_JOIN_ROOM" }}"
{{ end }}
## Metrics ###
# Whether or not to report anonymized homeserver usage statistics.
#
report_stats: false
## API Configuration ##
# A list of application service config files to use
#
{{ if eq (env "APP_SERVICES_ENABLED") "1" }}
app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }}
{{ end }}
# a secret which is used to sign access tokens. If none is specified,
# the registration_shared_secret is used, if one is given; otherwise,
# a secret key is derived from the signing key.
#
macaroon_secret_key: "{{ secret "macaroon_secret_key" }}"
# a secret which is used to calculate HMACs for form values, to stop
# falsification of values. Must be specified for the User Consent
# forms to work.
#
form_secret: "{{ secret "form_secret" }}"
## Signing Keys ##
# Path to the signing key to sign messages with
#
signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key"
# The trusted servers to download signing keys from.
#
# When we need to fetch a signing key, each server is tried in parallel.
#
# Normally, the connection to the key server is validated via TLS certificates.
# Additional security can be provided by configuring a `verify key`, which
# will make synapse check that the response is signed by that key.
#
# This setting supercedes an older setting named `perspectives`. The old format
# is still supported for backwards-compatibility, but it is deprecated.
#
# 'trusted_key_servers' defaults to matrix.org, but using it will generate a
# warning on start-up. To suppress this warning, set
# 'suppress_key_server_warning' to true.
#
# Options for each entry in the list include:
#
# server_name: the name of the server. required.
#
# verify_keys: an optional map from key id to base64-encoded public key.
# If specified, we will check that the response is signed by at least
# one of the given keys.
#
# accept_keys_insecurely: a boolean. Normally, if `verify_keys` is unset,
# and federation_verify_certificates is not `true`, synapse will refuse
# to start, because this would allow anyone who can spoof DNS responses
# to masquerade as the trusted key server. If you know what you are doing
# and are sure that your network environment provides a secure connection
# to the key server, you can set this to `true` to override this
# behaviour.
#
# An example configuration might look like:
#
#trusted_key_servers:
# - server_name: "my_trusted_server.example.com"
# verify_keys:
# "ed25519:auto": "abcdefghijklmnopqrstuvwxyzabcdefghijklmopqr"
# - server_name: "my_other_trusted_server.example.com"
#
{{ if eq (env "ENABLE_ALLOWLIST") "1" }}
{{ env "TRUSTED_KEYSERVERS" }}
{{ else }}
trusted_key_servers:
- server_name: "matrix.org"
{{ end }}
## Single sign-on integration ##
# List of OpenID Connect (OIDC) / OAuth 2.0 identity providers, for registration
# and login.
#
# Options for each entry include:
#
# idp_id: a unique identifier for this identity provider. Used internally
# by Synapse; should be a single word such as 'github'.
#
# Note that, if this is changed, users authenticating via that provider
# will no longer be recognised as the same user!
#
# (Use "oidc" here if you are migrating from an old "oidc_config"
# configuration.)
#
# idp_name: A user-facing name for this identity provider, which is used to
# offer the user a choice of login mechanisms.
#
# idp_icon: An optional icon for this identity provider, which is presented
# by clients and Synapse's own IdP picker page. If given, must be an
# MXC URI of the format mxc://<server-name>/<media-id>. (An easy way to
# obtain such an MXC URI is to upload an image to an (unencrypted) room
# and then copy the "url" from the source of the event.)
#
# idp_brand: An optional brand for this identity provider, allowing clients
# to style the login flow according to the identity provider in question.
# See the spec for possible options here.
#
# discover: set to 'false' to disable the use of the OIDC discovery mechanism
# to discover endpoints. Defaults to true.
#
# issuer: Required. The OIDC issuer. Used to validate tokens and (if discovery
# is enabled) to discover the provider's endpoints.
#
# client_id: Required. oauth2 client id to use.
#
# client_secret: oauth2 client secret to use. May be omitted if
# client_secret_jwt_key is given, or if client_auth_method is 'none'.
#
# client_secret_jwt_key: Alternative to client_secret: details of a key used
# to create a JSON Web Token to be used as an OAuth2 client secret. If
# given, must be a dictionary with the following properties:
#
# key: a pem-encoded signing key. Must be a suitable key for the
# algorithm specified. Required unless 'key_file' is given.
#
# key_file: the path to file containing a pem-encoded signing key file.
# Required unless 'key' is given.
#
# jwt_header: a dictionary giving properties to include in the JWT
# header. Must include the key 'alg', giving the algorithm used to
# sign the JWT, such as "ES256", using the JWA identifiers in
# RFC7518.
#
# jwt_payload: an optional dictionary giving properties to include in
# the JWT payload. Normally this should include an 'iss' key.
#
# client_auth_method: auth method to use when exchanging the token. Valid
# values are 'client_secret_basic' (default), 'client_secret_post' and
# 'none'.
#
# scopes: list of scopes to request. This should normally include the "openid"
# scope. Defaults to ["openid"].
#
# authorization_endpoint: the oauth2 authorization endpoint. Required if
# provider discovery is disabled.
#
# token_endpoint: the oauth2 token endpoint. Required if provider discovery is
# disabled.
#
# userinfo_endpoint: the OIDC userinfo endpoint. Required if discovery is
# disabled and the 'openid' scope is not requested.
#
# jwks_uri: URI where to fetch the JWKS. Required if discovery is disabled and
# the 'openid' scope is used.
#
# skip_verification: set to 'true' to skip metadata verification. Use this if
# you are connecting to a provider that is not OpenID Connect compliant.
# Defaults to false. Avoid this in production.
#
# user_profile_method: Whether to fetch the user profile from the userinfo
# endpoint. Valid values are: 'auto' or 'userinfo_endpoint'.
#
# Defaults to 'auto', which fetches the userinfo endpoint if 'openid' is
# included in 'scopes'. Set to 'userinfo_endpoint' to always fetch the
# userinfo endpoint.
#
# allow_existing_users: set to 'true' to allow a user logging in via OIDC to
# match a pre-existing account instead of failing. This could be used if
# switching from password logins to OIDC. Defaults to false.
#
# user_mapping_provider: Configuration for how attributes returned from a OIDC
# provider are mapped onto a matrix user. This setting has the following
# sub-properties:
#
# module: The class name of a custom mapping module. Default is
# 'synapse.handlers.oidc.JinjaOidcMappingProvider'.
# See https://matrix-org.github.io/synapse/latest/sso_mapping_providers.html#openid-mapping-providers
# for information on implementing a custom mapping provider.
#
# config: Configuration for the mapping provider module. This section will
# be passed as a Python dictionary to the user mapping provider
# module's `parse_config` method.
#
# For the default provider, the following settings are available:
#
# subject_claim: name of the claim containing a unique identifier
# for the user. Defaults to 'sub', which OpenID Connect
# compliant providers should provide.
#
# localpart_template: Jinja2 template for the localpart of the MXID.
# If this is not set, the user will be prompted to choose their
# own username (see 'sso_auth_account_details.html' in the 'sso'
# section of this file).
#
# display_name_template: Jinja2 template for the display name to set
# on first login. If unset, no displayname will be set.
#
# email_template: Jinja2 template for the email address of the user.
# If unset, no email address will be added to the account.
#
# extra_attributes: a map of Jinja2 templates for extra attributes
# to send back to the client during login.
# Note that these are non-standard and clients will ignore them
# without modifications.
#
# When rendering, the Jinja2 templates are given a 'user' variable,
# which is set to the claims returned by the UserInfo Endpoint and/or
# in the ID Token.
#
# It is possible to configure Synapse to only allow logins if certain attributes
# match particular values in the OIDC userinfo. The requirements can be listed under
# `attribute_requirements` as shown below. All of the listed attributes must
# match for the login to be permitted. Additional attributes can be added to
# userinfo by expanding the `scopes` section of the OIDC config to retrieve
# additional information from the OIDC provider.
#
# If the OIDC claim is a list, then the attribute must match any value in the list.
# Otherwise, it must exactly match the value of the claim. Using the example
# below, the `family_name` claim MUST be "Stephensson", but the `groups`
# claim MUST contain "admin".
#
# attribute_requirements:
# - attribute: family_name
# value: "Stephensson"
# - attribute: groups
# value: "admin"
#
# See https://matrix-org.github.io/synapse/latest/openid.html
# for information on how to configure these options.
#
# For backwards compatibility, it is also possible to configure a single OIDC
# provider via an 'oidc_config' setting. This is now deprecated and admins are
# advised to migrate to the 'oidc_providers' format. (When doing that migration,
# use 'oidc' for the idp_id to ensure that existing users continue to be
# recognised.)
#
oidc_providers:
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK_ID" }}
idp_name: {{ env "KEYCLOAK_NAME" }}
issuer: "{{ env "KEYCLOAK_URL" }}"
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
client_secret: "{{ secret "keycloak_client_secret" }}"
scopes: ["openid", "profile"]
allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
user_mapping_provider:
config:
localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}"
{{ end }}
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK2_ID" }}
idp_name: {{ env "KEYCLOAK2_NAME" }}
issuer: "{{ env "KEYCLOAK2_URL" }}"
client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}"
client_secret: "{{ secret "keycloak2_client_secret" }}"
scopes: ["openid", "profile"]
allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }}
user_mapping_provider:
config:
localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}"
{{ end }}
{{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK3_ID" }}
idp_name: {{ env "KEYCLOAK3_NAME" }}
issuer: "{{ env "KEYCLOAK3_URL" }}"
client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}"
client_secret: "{{ secret "keycloak3_client_secret" }}"
scopes: ["openid", "profile"]
allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }}
user_mapping_provider:
config:
localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}"
{{ end }}
# Additional settings to use with single-sign on systems such as OpenID Connect,
# SAML2 and CAS.
#
# Server admins can configure custom templates for pages related to SSO. See
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
#
sso:
# A list of client URLs which are whitelisted so that the user does not
# have to confirm giving access to their account to the URL. Any client
# whose URL starts with an entry in the following list will not be subject
# to an additional confirmation step after the SSO login is completed.
#
# WARNING: An entry such as "https://my.client" is insecure, because it
# will also match "https://my.client.evil.site", exposing your users to
# phishing attacks from evil.site. To avoid this, include a slash after the
# hostname: "https://my.client/".
#
# The login fallback page (used by clients that don't natively support the
# required login flows) is whitelisted in addition to any URLs in this list.
#
# By default, this list contains only the login fallback page.
#
#client_whitelist:
# - https://riot.im/develop
# - https://my.custom.client/
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
client_whitelist:
- https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }}
{{ end }}
password_config:
# Uncomment to disable password login
#
enabled: {{ env "PASSWORD_LOGIN_ENABLED" }}
# Configuration for sending emails from Synapse.
#
# Server admins can configure custom templates for email content. See
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
#
email:
{{ if eq (env "SMTP_ENABLED") "1" }}
# The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.
#
smtp_host: {{ env "SMTP_HOST" }}
# The port on the mail server for outgoing SMTP. Defaults to 25.
#
smtp_port: {{ env "SMTP_PORT" }}
# Username/password for authentication to the SMTP server. By default, no
# authentication is attempted.
#
smtp_user: {{ env "SMTP_USER" }}
smtp_pass: "{{ secret "smtp_password" }}"
# Uncomment the following to require TLS transport security for SMTP.
# By default, Synapse will connect over plain text, and will then switch to
# TLS via STARTTLS *if the SMTP server supports it*. If this option is set,
# Synapse will refuse to connect unless the server supports STARTTLS.
#
require_transport_security: true
# notif_from defines the "From" address to use when sending emails.
# It must be set if email sending is enabled.
#
# The placeholder '%(app)s' will be replaced by the application name,
# which is normally 'app_name' (below), but may be overridden by the
# Matrix client application.
#
# Note that the placeholder must be written '%(app)s', including the
# trailing 's'.
#
notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}>
# app_name defines the default value for '%(app)s' in notif_from and email
# subjects. It defaults to 'Matrix'.
#
app_name: {{ env "SMTP_APP_NAME" }}
# Uncomment the following to enable sending emails for messages that the user
# has missed. Disabled by default.
#
enable_notifs: true
# Custom URL for client links within the email notifications. By default
# links will be based on "https://matrix.to".
#
# (This setting used to be called riot_base_url; the old name is still
# supported for backwards-compatibility but is now deprecated.)
#
client_base_url: https://{{ env "DOMAIN" }}
{{ end }}
## Rooms ##
# Controls whether locally-created rooms should be end-to-end encrypted by
# default.
#
# Possible options are "all", "invite", and "off". They are defined as:
#
# * "all": any locally-created room
# * "invite": any room created with the "private_chat" or "trusted_private_chat"
# room creation presets
# * "off": this option will take no effect
#
# The default value is "off".
#
# Note that this option will only affect rooms created after it is set. It
# will also not affect rooms created by other servers.
#
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }}
# User Directory configuration
#
user_directory:
# Defines whether to search all users visible to your HS when searching
# the user directory. If false, search results will only contain users
# visible in public rooms and users sharing a room with the requester.
# Defaults to false.
#
# NB. If you set this to true, and the last time the user_directory search
# indexes were (re)built was before Synapse 1.44, you'll have to
# rebuild the indexes in order to search through all known users.
# These indexes are built the first time Synapse starts; admins can
# manually trigger a rebuild via API following the instructions at
# https://matrix-org.github.io/synapse/latest/usage/administration/admin_api/background_updates.html#run
#
# Uncomment to return search results containing all known users, even if that
# user does not share a room with the requester.
#
search_all_users: true
## Media retention ##
#
# since https://github.com/matrix-org/synapse/releases/tag/v1.61.0
media_retention:
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }}
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }}

View File

@ -1,20 +0,0 @@
version: 1
formatters:
precise:
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
formatter: precise
loggers:
synapse.storage.SQL:
level: {{ env "SQL_LOG_LEVEL" }}
root:
level: {{ env "ROOT_LOG_LEVEL" }}
handlers: [console]
disable_existing_loggers: false

View File

@ -1,6 +0,0 @@
The deployment failed due to the app/db getting confused. I think this is just
due to the recipe not having good healthcheck config. After the app container
flapped a bit, everything came up nicely. d1 @ autonomic co-op.
Same thing happened to me when deploying this for another instance. Also d1 @
autonomic co-op.

View File

@ -1,9 +0,0 @@
This upgrade adds new env variables for homeserver.yml, please add them to your .env file:
```
ENCRYPTED_BY_DEFAULT=all
SERVE_SERVER_WELLKNOWN=false
#KEYCLOAK_ID=keycloak
#KEYCLOAK_ALLOW_EXISTING_USERS=false
```

View File

@ -1,9 +0,0 @@
If you're using the horrendous `compose.keycloak2.yml` (as creator of this
horrible hack, I am allowed to call it horrendous ;)), you will need to
re-check the new ~/.abra/recipes/matrix-synapse/.env.sample, there are some new
default env vars which you'll have to add in (e.g. KEYCLOAK2_ID=...).
You'll also need to add `KEYCLOAK_ID=keycloak` if using `compose.keycloak.yml`,
it isn't vendored any more.
@decentral1se

View File

@ -1,17 +0,0 @@
WARNING: There are a lot of config breaking changes in this one, watch out!
* KEYCLOAK2* env vars have gone away, they were experimental.
* TELEGRAM_BRIDGE_ADMIN* is replaced by TELEGRAM_BRIDGE_PERMISSIONS.
* SIGNAL_BRIDGE_ADMIN* is replaced by SIGNAL_BRIDGE_PERMISSIONS.
* The homeserver config has been trimmed, see coop-cloud/matrix-synapse#33 for more.
* Bridge logging is only ERROR level now to minimise leaking plaintext.
* It is possible to use SSO & federation env vars in combination now.
* Media retention is now configurable with #MEDIA_RETENTION_* env vars.
@decentral1se

View File

@ -1,8 +0,0 @@
We had to rename some secrets: https://git.coopcloud.tech/coop-cloud/matrix-synapse/issues/35
Copy the secrets:
* `registration_shared_secret` to `registration`
* `macaroon_secret_key` to `macaroon`
Regeneration of these secrets should also work.

View File

@ -1,123 +0,0 @@
# -*- coding: utf-8 -*-
#
# Shared Secret Authenticator module for Matrix Synapse
# Copyright (C) 2018 Slavi Pantaleev
#
# https://devture.com/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
from typing import Awaitable, Callable, Optional, Tuple
import hashlib
import hmac
import logging
import synapse
from synapse import module_api
logger = logging.getLogger(__name__)
class SharedSecretAuthProvider:
def __init__(self, config: dict, api: module_api):
for k in ('shared_secret',):
if k not in config:
raise KeyError('Required `{0}` configuration key not found'.format(k))
m_login_password_support_enabled = bool(config['m_login_password_support_enabled']) if 'm_login_password_support_enabled' in config else False
com_devture_shared_secret_auth_support_enabled = bool(config['com_devture_shared_secret_auth_support_enabled']) if 'com_devture_shared_secret_auth_support_enabled' in config else True
self.api = api
self.shared_secret = config['shared_secret']
auth_checkers: Optional[Dict[Tuple[str, Tuple], CHECK_AUTH_CALLBACK]] = {}
if com_devture_shared_secret_auth_support_enabled:
auth_checkers[("com.devture.shared_secret_auth", ("token",))] = self.check_com_devture_shared_secret_auth
if m_login_password_support_enabled:
auth_checkers[("m.login.password", ("password",))] = self.check_m_login_password
enabled_login_types = [k[0] for k in auth_checkers]
if len(enabled_login_types) == 0:
raise RuntimeError('At least one login type must be enabled')
logger.info('Enabled login types: %s', enabled_login_types)
api.register_password_auth_provider_callbacks(
auth_checkers=auth_checkers,
)
async def check_com_devture_shared_secret_auth(
self,
username: str,
login_type: str,
login_dict: "synapse.module_api.JsonDict",
) -> Optional[
Tuple[
str,
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]],
]
]:
if login_type != "com.devture.shared_secret_auth":
return None
return await self._log_in_username_with_token("com.devture.shared_secret_auth", username, login_dict.get("token"))
async def check_m_login_password(
self,
username: str,
login_type: str,
login_dict: "synapse.module_api.JsonDict",
) -> Optional[
Tuple[
str,
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]],
]
]:
if login_type != "m.login.password":
return None
return await self._log_in_username_with_token("m.login.password", username, login_dict.get("password"))
async def _log_in_username_with_token(
self,
login_type: str,
username: str,
token: str,
) -> Optional[
Tuple[
str,
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]],
]
]:
logger.info('Authenticating user `%s` with login type `%s`', username, login_type)
full_user_id = self.api.get_qualified_user_id(username)
# The password (token) is supposed to be an HMAC of the full user id, keyed with the shared secret.
given_hmac = token.encode('utf-8')
h = hmac.new(self.shared_secret.encode('utf-8'), full_user_id.encode('utf-8'), hashlib.sha512)
computed_hmac = h.hexdigest().encode('utf-8')
if not hmac.compare_digest(computed_hmac, given_hmac):
logger.info('Bad hmac value for user: %s', full_user_id)
return None
user_info = await self.api.get_userinfo_by_id(full_user_id)
if user_info is None:
logger.info('Refusing to authenticate missing user: %s', full_user_id)
return None
logger.info('Authenticated user: %s', full_user_id)
return full_user_id, None

View File

@ -1,324 +0,0 @@
# Homeserver details
homeserver:
# The address that this appservice can use to connect to the homeserver.
address: {{ env "HOMESERVER_URL" }}
# The domain of the homeserver (for MXIDs, etc).
domain: {{ env "HOMESERVER_DOMAIN" }}
# Whether or not to verify the SSL certificate of the homeserver.
# Only applies if address starts with https://
verify_ssl: {{ env "VERIFY_SSL" }}
# What software is the homeserver running?
# Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here.
software: standard
# Number of retries for all HTTP requests if the homeserver isn't reachable.
http_retry_count: 4
# The URL to push real-time bridge status to.
# If set, the bridge will make POST requests to this URL whenever a user's Signal connection state changes.
# The bridge will use the appservice as_token to authorize requests.
status_endpoint: null
# Endpoint for reporting per-message status.
message_send_checkpoint_endpoint: null
# Maximum number of simultaneous HTTP connections to the homeserver.
connection_limit: 100
# Whether asynchronous uploads via MSC2246 should be enabled for media.
# Requires a media repo that supports MSC2246.
async_media: false
# Application service host/registration related details
# Changing these values requires regeneration of the registration.
appservice:
# The address that the homeserver can use to connect to this appservice.
address: http://signalbridge:29328
# When using https:// the TLS certificate and key files for the address.
tls_cert: false
tls_key: false
# The hostname and port where this appservice should listen.
hostname: 0.0.0.0
port: 29328
# The maximum body size of appservice API requests (from the homeserver) in mebibytes
# Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s
max_body_size: 1
# The full URI to the database. SQLite and Postgres are supported.
# However, SQLite support is extremely experimental and should not be used.
# Format examples:
# SQLite: sqlite:///filename.db
# Postgres: postgres://username:password@hostname/dbname
database: postgres://signalbridge:{{ secret "signal_db_password" }}@signaldb/signalbridge
# Additional arguments for asyncpg.create_pool() or sqlite3.connect()
# https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool
# https://docs.python.org/3/library/sqlite3.html#sqlite3.connect
# For sqlite, min_size is used as the connection thread pool size and max_size is ignored.
# Additionally, SQLite supports init_commands as an array of SQL queries to run on connect (e.g. to set PRAGMAs).
database_opts:
min_size: 1
max_size: 10
# The unique ID of this appservice.
id: signal
# Username of the appservice bot.
bot_username: signalbot
# Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty
# to leave display name/avatar as-is.
bot_displayname: Signal bridge bot
bot_avatar: mxc://maunium.net/wPJgTQbZOtpBFmDNkiNEMDUp
# Whether or not to receive ephemeral events via appservice transactions.
# Requires MSC2409 support (i.e. Synapse 1.22+).
# You should disable bridge -> sync_with_custom_puppets when this is enabled.
ephemeral_events: true
# Authentication tokens for AS <-> HS communication. Autogenerated; do not modify.
as_token: "{{ secret "signal_as_token" }}"
hs_token: "{{ secret "signal_hs_token" }}"
# Prometheus telemetry config. Requires prometheus-client to be installed.
metrics:
enabled: false
listen_port: 8000
# Manhole config.
manhole:
# Whether or not opening the manhole is allowed.
enabled: false
# The path for the unix socket.
path: /var/tmp/mautrix-signal.manhole
# The list of UIDs who can be added to the whitelist.
# If empty, any UIDs can be specified in the open-manhole command.
whitelist:
- 0
signal:
# Path to signald unix socket
socket_path: /signald/signald.sock
# Directory for temp files when sending files to Signal. This should be an
# absolute path that signald can read. For attachments in the other direction,
# make sure signald is configured to use an absolute path as the data directory.
outgoing_attachment_dir: /signald/attachments
# Directory where signald stores avatars for groups.
avatar_dir: /signald/avatars
# Directory where signald stores auth data. Used to delete data when logging out.
data_dir: /signald/data
# Whether or not unknown signald accounts should be deleted when the bridge is started.
# When this is enabled, any UserInUse errors should be resolved by restarting the bridge.
delete_unknown_accounts_on_start: false
# Whether or not message attachments should be removed from disk after they're bridged.
remove_file_after_handling: true
# Whether or not users can register a primary device
registration_enabled: true
# Whether or not to enable disappearing messages in groups. If enabled, then the expiration
# time of the messages will be determined by the first users to read the message, rather
# than individually. If the bridge has a single user, this can be turned on safely.
enable_disappearing_messages_in_groups: false
# Bridge config
bridge:
# Localpart template of MXIDs for Signal users.
# {userid} is replaced with an identifier for the Signal user.
username_template: "signal_{userid}"
# Displayname template for Signal users.
# {displayname} is replaced with the displayname of the Signal user, which is the first
# available variable in displayname_preference. The variables in displayname_preference
# can also be used here directly.
displayname_template: "{displayname} (Signal)"
# Whether or not contact list displaynames should be used.
# Possible values: disallow, allow, prefer
#
# Multi-user instances are recommended to disallow contact list names, as otherwise there can
# be conflicts between names from different users' contact lists.
contact_list_names: disallow
# Available variables: full_name, first_name, last_name, phone, uuid
displayname_preference:
- full_name
- phone
# Whether or not to create portals for all groups on login/connect.
autocreate_group_portal: true
# Whether or not to create portals for all contacts on login/connect.
autocreate_contact_portal: false
# Whether or not to make portals of Signal groups in which joining via invite link does
# not need to be approved by an administrator publicly joinable on Matrix.
public_portals: false
# Whether or not to use /sync to get read receipts and typing notifications
# when double puppeting is enabled
sync_with_custom_puppets: false
# Whether or not to update the m.direct account data event when double puppeting is enabled.
# Note that updating the m.direct event is not atomic (except with mautrix-asmux)
# and is therefore prone to race conditions.
sync_direct_chat_list: false
# Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false
# Servers to allow double puppeting from, even if double_puppet_allow_discovery is false.
double_puppet_server_map:
{{ env "HOMESERVER_DOMAIN" }}: {{ env "HOMESERVER_URL" }}
# Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth
#
# If set, custom puppets will be enabled automatically for local users
# instead of users having to find an access token and run `login-matrix`
# manually.
# If using this for other servers than the bridge's server,
# you must also set the URL in the double_puppet_server_map.
login_shared_secret_map:
{{ env "HOMESERVER_DOMAIN" }}: {{ secret "shared_secret_auth" }}
# Whether or not created rooms should have federation enabled.
# If false, created portal rooms will never be federated.
federate_rooms: true
# End-to-bridge encryption support options.
#
# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info.
encryption:
# Allow encryption, work in group chat rooms with e2ee enabled
allow: {{ env "SIGNAL_ENABLE_ENCRYPTION" }}
# Default to encryption, force-enable encryption in all portals the bridge creates
# This will cause the bridge bot to be in private chats for the encryption to work properly.
default: false
# Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data.
appservice: false
# Require encryption, drop any unencrypted messages.
require: false
# Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled.
# You must use a client that supports requesting keys from other users to use this feature.
allow_key_sharing: false
# What level of device verification should be required from users?
#
# Valid levels:
# unverified - Send keys to all device in the room.
# cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys.
# cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes).
# cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot.
# Note that creating user signatures from the bridge bot is not currently possible.
# verified - Require manual per-device verification
# (currently only possible by modifying the `trust` column in the `crypto_device` database table).
verification_levels:
# Minimum level for which the bridge should send keys to when bridging messages from Telegram to Matrix.
receive: unverified
# Minimum level that the bridge should accept for incoming Matrix messages.
send: unverified
# Minimum level that the bridge should require for accepting key requests.
share: cross-signed-tofu
# Options for Megolm room key rotation. These options allow you to
# configure the m.room.encryption event content. See:
# https://spec.matrix.org/v1.3/client-server-api/#mroomencryption for
# more information about that event.
rotation:
# Enable custom Megolm room key rotation settings. Note that these
# settings will only apply to rooms created after this option is
# set.
enable_custom: false
# The maximum number of milliseconds a session should be used
# before changing it. The Matrix spec recommends 604800000 (a week)
# as the default.
milliseconds: 604800000
# The maximum number of messages that should be sent with a given a
# session before changing it. The Matrix spec recommends 100 as the
# default.
messages: 100
# Whether or not to explicitly set the avatar and room name for private
# chat portal rooms. This will be implicitly enabled if encryption.default is true.
private_chat_portal_meta: false
# Whether or not the bridge should send a read receipt from the bridge bot when a message has
# been sent to Signal. This let's you check manually whether the bridge is receiving your
# messages.
# Note that this is not related to Signal delivery receipts.
delivery_receipts: false
# Whether or not delivery errors should be reported as messages in the Matrix room.
delivery_error_reports: true
# Whether the bridge should send the message status as a custom com.beeper.message_send_status event.
message_status_events: false
# Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run.
# This field will automatically be changed back to false after it,
# except if the config file is not writable.
resend_bridge_info: false
# Interval at which to resync contacts (in seconds).
periodic_sync: 0
# Should leaving the room on Matrix make the user leave on Signal?
bridge_matrix_leave: true
# Provisioning API part of the web server for automated portal creation and fetching information.
# Used by things like mautrix-manager (https://github.com/tulir/mautrix-manager).
provisioning:
# Whether or not the provisioning API should be enabled.
enabled: true
# The prefix to use in the provisioning API endpoints.
prefix: /_matrix/provision
# The shared secret to authorize users of the API.
# Set to "generate" to generate and save a new token.
shared_secret: generate
# Segment API key to enable analytics tracking for web server
# endpoints. Set to null to disable.
# Currently the only events are login start, QR code scan, and login
# success/failure.
segment_key: null
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!signal"
# Messages sent upon joining a management room.
# Markdown is supported. The defaults are listed below.
management_room_text:
# Sent when joining a room.
welcome: "Hello, I'm a Signal bridge bot."
# Sent when joining a management room and the user is already logged in.
welcome_connected: "Use `help` for help."
# Sent when joining a management room and the user is not logged in.
welcome_unconnected: "Use `help` for help or `link` to log in."
# Optional extra text sent when joining a management room.
additional_help: ""
# Send each message separately (for readability in some clients)
management_room_multiple_messages: false
# Permissions for using the bridge.
# Permitted values:
# relay - Allowed to be relayed through the bridge, no access to commands.
# user - Use the bridge with puppeting.
# admin - Use and administrate the bridge.
# Permitted keys:
# * - All Matrix users
# domain - All users on that homeserver
# mxid - Specific user
permissions: {{ env "SIGNAL_BRIDGE_PERMISSIONS" }}
relay:
# Whether relay mode should be allowed. If allowed, `!signal set-relay` can be used to turn any
# authenticated user into a relaybot for that chat.
enabled: false
# The formats to use when sending messages to Signal via a relay user.
#
# Available variables:
# $sender_displayname - The display name of the sender (e.g. Example User)
# $sender_username - The username (Matrix ID localpart) of the sender (e.g. exampleuser)
# $sender_mxid - The Matrix ID of the sender (e.g. @exampleuser:example.com)
# $message - The message content
message_formats:
m.text: '$sender_displayname: $message'
m.notice: '$sender_displayname: $message'
m.emote: '* $sender_displayname $message'
m.file: '$sender_displayname sent a file'
m.image: '$sender_displayname sent an image'
m.audio: '$sender_displayname sent an audio file'
m.video: '$sender_displayname sent a video'
m.location: '$sender_displayname sent a location'
# Specify a dedicated relay account. Must be a regular matrix account logged into this bridge
# and double puppeting working to auto-accept invites. When this user is invited to a room
# it will automatically be set as the relay user. May be overridden with `set-relay` or `unset-relay`
relaybot: '@relaybot:example.com'
# Format for generting URLs from location messages for sending to Signal
# Google Maps: 'https://www.google.com/maps/place/{lat},{long}'
# OpenStreepMap: 'https://www.openstreetmap.org/?mlat={lat}&mlon={long}'
location_format: 'https://www.google.com/maps/place/{lat},{long}'
# Python logging configuration.
#
# See section 16.7.2 of the Python documentation for more info:
# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema
logging:
version: 1
formatters:
colored:
(): mautrix_signal.util.ColorFormatter
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
normal:
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
handlers:
console:
class: logging.StreamHandler
formatter: colored
loggers:
mau:
level: ERROR
aiohttp:
level: ERROR
root:
level: ERROR
handlers: [console]

View File

@ -1,544 +0,0 @@
# Homeserver details
homeserver:
# The address that this appservice can use to connect to the homeserver.
address: {{ env "HOMESERVER_URL" }}
# The domain of the homeserver (for MXIDs, etc).
domain: {{ env "HOMESERVER_DOMAIN" }}
# Whether or not to verify the SSL certificate of the homeserver.
# Only applies if address starts with https://
verify_ssl: {{ env "VERIFY_SSL" }}
asmux: false
# Number of retries for all HTTP requests if the homeserver isn't reachable.
http_retry_count: 4
# The URL to push real-time bridge status to.
# If set, the bridge will make POST requests to this URL whenever a user's Telegram connection state changes.
# The bridge will use the appservice as_token to authorize requests.
status_endpoint: null
# Endpoint for reporting per-message status.
message_send_checkpoint_endpoint: null
# Whether asynchronous uploads via MSC2246 should be enabled for media.
# Requires a media repo that supports MSC2246.
async_media: false
# Application service host/registration related details
# Changing these values requires regeneration of the registration.
appservice:
# The address that the homeserver can use to connect to this appservice.
address: http://telegrambridge:29317
# When using https:// the TLS certificate and key files for the address.
tls_cert: false
tls_key: false
# The hostname and port where this appservice should listen.
hostname: 0.0.0.0
port: 29317
# The maximum body size of appservice API requests (from the homeserver) in mebibytes
# Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s
max_body_size: 1
# The full URI to the database. SQLite and Postgres are supported.
# Format examples:
# SQLite: sqlite:///filename.db
# Postgres: postgres://username:password@hostname/dbname
database: postgres://telegrambridge:{{ secret "telegram_db_password" }}@telegramdb/telegrambridge
# Additional arguments for asyncpg.create_pool() or sqlite3.connect()
# https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool
# https://docs.python.org/3/library/sqlite3.html#sqlite3.connect
# For sqlite, min_size is used as the connection thread pool size and max_size is ignored.
database_opts:
min_size: 1
max_size: 10
# Public part of web server for out-of-Matrix interaction with the bridge.
# Used for things like login if the user wants to make sure the 2FA password isn't stored in
# the HS database.
public:
# Whether or not the public-facing endpoints should be enabled.
enabled: false
# The prefix to use in the public-facing endpoints.
prefix: /public
# The base URL where the public-facing endpoints are available. The prefix is not added
# implicitly.
external: https://example.com/public
# Provisioning API part of the web server for automated portal creation and fetching information.
# Used by things like mautrix-manager (https://github.com/tulir/mautrix-manager).
provisioning:
# Whether or not the provisioning API should be enabled.
enabled: false
# The prefix to use in the provisioning API endpoints.
prefix: /_matrix/provision
# The shared secret to authorize users of the API.
# Set to "generate" to generate and save a new token.
shared_secret: generate
# The unique ID of this appservice.
id: {{ env "APP_SERVICE_ID" }}
# Username of the appservice bot.
bot_username: {{ env "APP_SERVICE_BOT_USERNAME" }}
# Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty
# to leave display name/avatar as-is.
bot_displayname: {{ env "APP_SERVICE_DISPLAY_NAME" }}
bot_avatar: mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX
# Whether or not to receive ephemeral events via appservice transactions.
# Requires MSC2409 support (i.e. Synapse 1.22+).
# You should disable bridge -> sync_with_custom_puppets when this is enabled.
ephemeral_events: false
# Authentication tokens for AS <-> HS communication. Autogenerated; do not modify.
as_token: "{{ secret "telegram_as_token" }}"
hs_token: "{{ secret "telegram_hs_token" }}"
# Prometheus telemetry config. Requires prometheus-client to be installed.
metrics:
enabled: false
listen_port: 8000
# Manhole config.
manhole:
# Whether or not opening the manhole is allowed.
enabled: false
# The path for the unix socket.
path: /var/tmp/mautrix-telegram.manhole
# The list of UIDs who can be added to the whitelist.
# If empty, any UIDs can be specified in the open-manhole command.
whitelist:
- 0
# Bridge config
bridge:
# Localpart template of MXIDs for Telegram users.
# {userid} is replaced with the user ID of the Telegram user.
username_template: "telegram_{userid}"
# Localpart template of room aliases for Telegram portal rooms.
# {groupname} is replaced with the name part of the public channel/group invite link ( https://t.me/{} )
alias_template: "telegram_{groupname}"
# Displayname template for Telegram users.
# {displayname} is replaced with the display name of the Telegram user.
displayname_template: "{displayname} (Telegram)"
# Set the preferred order of user identifiers which to use in the Matrix puppet display name.
# In the (hopefully unlikely) scenario that none of the given keys are found, the numeric user
# ID is used.
#
# If the bridge is working properly, a phone number or an username should always be known, but
# the other one can very well be empty.
#
# Valid keys:
# "full name" (First and/or last name)
# "full name reversed" (Last and/or first name)
# "first name"
# "last name"
# "username"
# "phone number"
displayname_preference:
- full name
- username
- phone number
# Maximum length of displayname
displayname_max_length: 100
# Remove avatars from Telegram ghost users when removed on Telegram. This is disabled by default
# as there's no way to determine whether an avatar is removed or just hidden from some users. If
# you're on a single-user instance, this should be safe to enable.
allow_avatar_remove: false
# Maximum number of members to sync per portal when starting up. Other members will be
# synced when they send messages. The maximum is 10000, after which the Telegram server
# will not send any more members.
# -1 means no limit (which means it's limited to 10000 by the server)
max_initial_member_sync: 100
# Whether or not to sync the member list in channels.
# If no channel admins have logged into the bridge, the bridge won't be able to sync the member
# list regardless of this setting.
sync_channel_members: {{ env "TELEGRAM_SYNC_CHANNEL_MEMBERS" }}
# Whether or not to skip deleted members when syncing members.
skip_deleted_members: true
# Whether or not to automatically synchronize contacts and chats of Matrix users logged into
# their Telegram account at startup.
startup_sync: true
# Number of most recently active dialogs to check when syncing chats.
# Set to 0 to remove limit.
sync_update_limit: 0
# Number of most recently active dialogs to create portals for when syncing chats.
# Set to 0 to remove limit.
sync_create_limit: 30
# Whether or not to sync and create portals for direct chats at startup.
sync_direct_chats: false
# The maximum number of simultaneous Telegram deletions to handle.
# A large number of simultaneous redactions could put strain on your homeserver.
max_telegram_delete: 10
# Whether or not to automatically sync the Matrix room state (mostly unpuppeted displaynames)
# at startup and when creating a bridge.
sync_matrix_state: true
# Allow logging in within Matrix. If false, users can only log in using login-qr or the
# out-of-Matrix login website (see appservice.public config section)
allow_matrix_login: true
# Whether or not to bridge plaintext highlights.
# Only enable this if your displayname_template has some static part that the bridge can use to
# reliably identify what is a plaintext highlight.
plaintext_highlights: false
# Whether or not to make portals of publicly joinable channels/supergroups publicly joinable on Matrix.
public_portals: true
# Whether or not to use /sync to get presence, read receipts and typing notifications
# when double puppeting is enabled
sync_with_custom_puppets: true
# Whether or not to update the m.direct account data event when double puppeting is enabled.
# Note that updating the m.direct event is not atomic (except with mautrix-asmux)
# and is therefore prone to race conditions.
sync_direct_chat_list: false
# Servers to always allow double puppeting from
double_puppet_server_map:
{{ env "HOMESERVER_DOMAIN" }}: {{ env "HOMESERVER_URL" }}
# Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth
#
# If set, custom puppets will be enabled automatically for local users
# instead of users having to find an access token and run `login-matrix`
# manually.
# If using this for other servers than the bridge's server,
# you must also set the URL in the double_puppet_server_map.
login_shared_secret_map:
{{ env "HOMESERVER_DOMAIN" }}: {{ secret "shared_secret_auth" }}
# Set to false to disable link previews in messages sent to Telegram.
telegram_link_preview: true
# Whether or not the !tg join command should do a HTTP request
# to resolve redirects in invite links.
invite_link_resolve: false
# Use inline images instead of a separate message for the caption.
# N.B. Inline images are not supported on all clients (e.g. Element iOS/Android).
inline_images: false
# Maximum size of image in megabytes before sending to Telegram as a document.
image_as_file_size: 10
# Maximum number of pixels in an image before sending to Telegram as a document. Defaults to 1280x1280 = 1638400.
image_as_file_pixels: 1638400
# Enable experimental parallel file transfer, which makes uploads/downloads much faster by
# streaming from/to Matrix and using many connections for Telegram.
# Note that generating HQ thumbnails for videos is not possible with streamed transfers.
# This option uses internal Telethon implementation details and may break with minor updates.
parallel_file_transfer: false
# Whether or not created rooms should have federation enabled.
# If false, created portal rooms will never be federated.
federate_rooms: true
# Settings for converting animated stickers.
animated_sticker:
# Format to which animated stickers should be converted.
# disable - No conversion, send as-is (gzipped lottie)
# png - converts to non-animated png (fastest),
# gif - converts to animated gif
# webm - converts to webm video, requires ffmpeg executable with vp9 codec and webm container support
target: gif
# Arguments for converter. All converters take width and height.
args:
width: 256
height: 256
fps: 25 # only for webm and gif (2, 5, 10, 20 or 25 recommended)
# End-to-bridge encryption support options.
#
# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info.
encryption:
# Allow encryption, work in group chat rooms with e2ee enabled
allow: {{ env "ENABLE_ENCRYPTION" }}
# Default to encryption, force-enable encryption in all portals the bridge creates
# This will cause the bridge bot to be in private chats for the encryption to work properly.
default: false
# Database for the encryption data. If set to `default`, will use the appservice database.
database: default
# Options for automatic key sharing.
key_sharing:
# Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled.
# You must use a client that supports requesting keys from other users to use this feature.
allow: false
# Require the requesting device to have a valid cross-signing signature?
# This doesn't require that the bridge has verified the device, only that the user has verified it.
# Not yet implemented.
require_cross_signing: false
# Require devices to be verified by the bridge?
# Verification by the bridge is not yet implemented.
require_verification: false
# Whether or not to explicitly set the avatar and room name for private
# chat portal rooms. This will be implicitly enabled if encryption.default is true.
private_chat_portal_meta: false
# Whether or not the bridge should send a read receipt from the bridge bot when a message has
# been sent to Telegram.
delivery_receipts: false
# Whether or not delivery errors should be reported as messages in the Matrix room.
delivery_error_reports: false
# Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run.
# This field will automatically be changed back to false after it,
# except if the config file is not writable.
resend_bridge_info: false
# When using double puppeting, should muted chats be muted in Matrix?
mute_bridging: false
# When using double puppeting, should pinned chats be moved to a specific tag in Matrix?
# The favorites tag is `m.favourite`.
pinned_tag: null
# Same as above for archived chats, the low priority tag is `m.lowpriority`.
archive_tag: null
# Whether or not mute status and tags should only be bridged when the portal room is created.
tag_only_on_create: true
# Should leaving the room on Matrix make the user leave on Telegram?
bridge_matrix_leave: true
# Should the user be kicked out of all portals when logging out of the bridge?
kick_on_logout: true
# Should the "* user joined Telegram" notice always be marked as read automatically?
always_read_joined_telegram_notice: true
# Settings for backfilling messages from Telegram.
backfill:
# Whether or not the Telegram ghosts of logged in Matrix users should be
# invited to private chats when backfilling history from Telegram. This is
# usually needed to prevent rate limits and to allow timestamp massaging.
invite_own_puppet: true
# Maximum number of messages to backfill without using a takeout.
# The first time a takeout is used, the user has to manually approve it from a different
# device. If initial_limit or missed_limit are higher than this value, the bridge will ask
# the user to accept the takeout after logging in before syncing any chats.
takeout_limit: 100
# Maximum number of messages to backfill initially.
# Set to 0 to disable backfilling when creating portal, or -1 to disable the limit.
#
# N.B. Initial backfill will only start after member sync. Make sure your
# max_initial_member_sync is set to a low enough value so it doesn't take forever.
initial_limit: 0
# Maximum number of messages to backfill if messages were missed while the bridge was
# disconnected. Note that this only works for logged in users and only if the chat isn't
# older than sync_update_limit
# Set to 0 to disable backfilling missed messages.
missed_limit: 50
# If using double puppeting, should notifications be disabled
# while the initial backfill is in progress?
disable_notifications: false
# Whether or not to enable backfilling in normal groups.
# Normal groups have numerous technical problems in Telegram, and backfilling normal groups
# will likely cause problems if there are multiple Matrix users in the group.
normal_groups: false
# Overrides for base power levels.
initial_power_level_overrides:
user: {}
group: {}
# Whether to bridge Telegram bot messages as m.notices or m.texts.
bot_messages_as_notices: true
bridge_notices:
# Whether or not Matrix bot messages (type m.notice) should be bridged.
default: false
# List of user IDs for whom the previous flag is flipped.
# e.g. if bridge_notices.default is false, notices from other users will not be bridged, but
# notices from users listed here will be bridged.
exceptions: []
# An array of possible values for the $distinguisher variable in message formats.
# Each user gets one of the values here, based on a hash of their user ID.
# If the array is empty, the $distinguisher variable will also be empty.
relay_user_distinguishers: ["🟦", "🟣", "🟩", "⭕️", "🔶", "⬛️", "🔵", "🟢"]
# The formats to use when sending messages to Telegram via the relay bot.
# Text msgtypes (m.text, m.notice and m.emote) support HTML, media msgtypes don't.
#
# Available variables:
# $sender_displayname - The display name of the sender (e.g. Example User)
# $sender_username - The username (Matrix ID localpart) of the sender (e.g. exampleuser)
# $sender_mxid - The Matrix ID of the sender (e.g. @exampleuser:example.com)
# $distinguisher - A random string from the options in the relay_user_distinguishers array.
# $message - The message content
message_formats:
m.text: "$distinguisher <b>$sender_displayname</b>: $message"
m.notice: "$distinguisher <b>$sender_displayname</b>: $message"
m.emote: "* $distinguisher <b>$sender_displayname</b> $message"
m.file: "$distinguisher <b>$sender_displayname</b> sent a file: $message"
m.image: "$distinguisher <b>$sender_displayname</b> sent an image: $message"
m.audio: "$distinguisher <b>$sender_displayname</b> sent an audio file: $message"
m.video: "$distinguisher <b>$sender_displayname</b> sent a video: $message"
m.location: "$distinguisher <b>$sender_displayname</b> sent a location: $message"
# Telegram doesn't have built-in emotes, this field specifies how m.emote's from authenticated
# users are sent to telegram. All fields in message_formats are supported. Additionally, the
# Telegram user info is available in the following variables:
# $displayname - Telegram displayname
# $username - Telegram username (may not exist)
# $mention - Telegram @username or displayname mention (depending on which exists)
emote_format: "* $mention $formatted_body"
# The formats to use when sending state events to Telegram via the relay bot.
#
# Variables from `message_formats` that have the `sender_` prefix are available without the prefix.
# In name_change events, `$prev_displayname` is the previous displayname.
#
# Set format to an empty string to disable the messages for that event.
state_event_formats:
join: "$distinguisher <b>$displayname</b> joined the room."
leave: "$distinguisher <b>$displayname</b> left the room."
name_change: "$distinguisher <b>$prev_displayname</b> changed their name to $distinguisher <b>$displayname</b>"
# Filter rooms that can/can't be bridged. Can also be managed using the `filter` and
# `filter-mode` management commands.
#
# Filters do not affect direct chats.
# An empty blacklist will essentially disable the filter.
filter:
# Filter mode to use. Either "blacklist" or "whitelist".
# If the mode is "blacklist", the listed chats will never be bridged.
# If the mode is "whitelist", only the listed chats can be bridged.
mode: blacklist
# The list of group/channel IDs to filter.
list: []
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!tg"
# Messages sent upon joining a management room.
# Markdown is supported. The defaults are listed below.
management_room_text:
# Sent when joining a room.
welcome: "Hello, I'm a Telegram bridge bot."
# Sent when joining a management room and the user is already logged in.
welcome_connected: "Use `help` for help."
# Sent when joining a management room and the user is not logged in.
welcome_unconnected: "Use `help` for help or `login` to log in."
# Optional extra text sent when joining a management room.
additional_help: ""
# Send each message separately (for readability in some clients)
management_room_multiple_messages: false
# Permissions for using the bridge.
# Permitted values:
# relaybot - Only use the bridge via the relaybot, no access to commands.
# user - Relaybot level + access to commands to create bridges.
# puppeting - User level + logging in with a Telegram account.
# full - Full access to use the bridge, i.e. previous levels + Matrix login.
# admin - Full access to use the bridge and some extra administration commands.
# Permitted keys:
# * - All Matrix users
# domain - All users on that homeserver
# mxid - Specific user
permissions: {{ env "TELEGRAM_BRIDGE_PERMISSIONS" }}
# Options related to the message relay Telegram bot.
relaybot:
private_chat:
# List of users to invite to the portal when someone starts a private chat with the bot.
# If empty, private chats with the bot won't create a portal.
invite: []
# Whether or not to bridge state change messages in relaybot private chats.
state_changes: true
# When private_chat_invite is empty, this message is sent to users /starting the
# relaybot. Telegram's "markdown" is supported.
message: This is a Matrix bridge relaybot and does not support direct chats
# List of users to invite to all group chat portals created by the bridge.
group_chat_invite: []
# Whether or not the relaybot should not bridge events in unbridged group chats.
# If false, portals will be created when the relaybot receives messages, just like normal
# users. This behavior is usually not desirable, as it interferes with manually bridging
# the chat to another room.
ignore_unbridged_group_chat: true
# Whether or not to allow creating portals from Telegram.
authless_portals: true
# Whether or not to allow Telegram group admins to use the bot commands.
whitelist_group_admins: true
# Whether or not to ignore incoming events sent by the relay bot.
ignore_own_incoming_events: true
# List of usernames/user IDs who are also allowed to use the bot commands.
whitelist:
- myusername
- 12345678
# Telegram config
telegram:
# Get your own API keys at https://my.telegram.org/apps
api_id: {{ env "TELEGRAM_APP_ID" }}
api_hash: {{ secret "telegram_api_hash" }}
# (Optional) Create your own bot at https://t.me/BotFather
bot_token: {{ secret "telegram_bot_token" }}
# Telethon connection options.
connection:
# The timeout in seconds to be used when connecting.
timeout: 120
# How many times the reconnection should retry, either on the initial connection or when
# Telegram disconnects us. May be set to a negative or null value for infinite retries, but
# this is not recommended, since the program can get stuck in an infinite loop.
retries: 5
# The delay in seconds to sleep between automatic reconnections.
retry_delay: 1
# The threshold below which the library should automatically sleep on flood wait errors
# (inclusive). For instance, if a FloodWaitError for 17s occurs and flood_sleep_threshold
# is 20s, the library will sleep automatically. If the error was for 21s, it would raise
# the error instead. Values larger than a day (86400) will be changed to a day.
flood_sleep_threshold: 60
# How many times a request should be retried. Request are retried when Telegram is having
# internal issues, when there is a FloodWaitError less than flood_sleep_threshold, or when
# there's a migrate error. May take a negative or null value for infinite retries, but this
# is not recommended, since some requests can always trigger a call fail (such as searching
# for messages).
request_retries: 5
# Device info sent to Telegram.
device_info:
# "auto" = OS name+version.
device_model: auto
# "auto" = Telethon version.
system_version: auto
# "auto" = mautrix-telegram version.
app_version: auto
lang_code: en
system_lang_code: en
# Custom server to connect to.
server:
# Set to true to use these server settings. If false, will automatically
# use production server assigned by Telegram. Set to false in production.
enabled: false
# The DC ID to connect to.
dc: 2
# The IP to connect to.
ip: 149.154.167.40
# The port to connect to. 443 may not work, 80 is better and both are equally secure.
port: 80
# Telethon proxy configuration.
# You must install PySocks from pip for proxies to work.
proxy:
# Allowed types: disabled, socks4, socks5, http, mtproxy
type: disabled
# Proxy IP address and port.
address: 127.0.0.1
port: 1080
# Whether or not to perform DNS resolving remotely. Only for socks/http proxies.
rdns: true
# Proxy authentication (optional). Put MTProxy secret in password field.
username: ""
password: ""
# Python logging configuration.
#
# See section 16.7.2 of the Python documentation for more info:
# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema
logging:
version: 1
formatters:
colored:
(): mautrix_telegram.util.ColorFormatter
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
normal:
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
handlers:
file:
class: logging.handlers.RotatingFileHandler
formatter: normal
filename: /data/mautrix-telegram.log
maxBytes: 10485760
backupCount: 10
console:
class: logging.StreamHandler
formatter: colored
loggers:
mau:
level: ERROR
telethon:
level: ERROR
aiohttp:
level: ERROR
root:
level: ERROR
handlers: [file, console]

15
turnserver.conf.tmpl Normal file
View File

@ -0,0 +1,15 @@
use-auth-secret
static-auth-secret={{ secret "coturn_shared_secret" }}
realm=turn.{{ env "DOMAIN" }}
log-file=stdout
pidfile=/var/tmp/turnserver.pid
userdb=/var/tmp/turnserver.db
no-cli
no-tls
no-dtls
prod
no-tcp-relay