Skip to content
Snippets Groups Projects
Commit e35dfc69 authored by jabertwo's avatar jabertwo
Browse files

WIP Matrix Tresstsetup

parent 7bf23cc6
No related branches found
No related tags found
No related merge requests found
---
- include_tasks: ../functions/get_secret.yml
with_items:
- { path: /srv/shared/noreply_email_pass, length: -1 }
- { path: /srv/ldap/secret/ldap_readonly_pass, length: -1 }
- { path: /srv/matrix/postgres_user_pass, length: 24 }
- { path: /srv/matrix/admin_access_token, length: -1 } # Get in Element fo an Admin User: Settings > Help > Advanced
- name: create folder struct for matrix
file:
path: "{{ item }}"
state: "directory"
owner: www-data
group: www-data
with_items:
- "/srv/matrix/"
- "/srv/matrix/ma1sd-config/"
- "/srv/matrix/ma1sd-data/"
- "/srv/matrix/synapse-data/"
- name: create folder struct for matrix db
file:
path: "{{ item }}"
state: "directory"
owner: "999"
group: "999"
with_items:
- "/srv/matrix/db/"
- name: Konfig-Dateien erstellen
template:
src: "{{ item }}"
dest: "/srv/matrix/{{ item }}"
with_items:
- docker-compose.yml
- rest_auth_provider.py
- ma1sd-config/ma1sd.yaml
- synapse-data/homeserver.log.config
- synapse-data/homeserver.yaml
register: configs
- name: Script-Dateien erstellen
template:
src: "{{ item }}"
dest: "/srv/matrix/{{ item }}"
mode: "ug+rwx"
with_items:
- purgemediacache.sh
- name: stop matrix docker
community.docker.docker_compose_v2:
project_src: /srv/matrix/
state: absent
when: configs.changed
- name: start matrix docker
community.docker.docker_compose_v2:
project_src: /srv/matrix/
state: present
the rest-auth_provider is from https://githubcom/ma1uta/matrix-synapse-rest-password-provider/
services:
# Datenbank Dump vor Upgrade (im Container)
# pg_dump --clean --create -d synapse -U synapse > /var/lib/postgresql/data/dump.sql
# Datenbank einlesen nach Upgrade (im Container)
# psql -U synapse -d synapse < /var/lib/postgresql/data/dump.sql
# Alternativer weg mit inplace-Upgrade (funktioniert nicht)
# https://github.com/tianon/docker-postgres-upgrade
db:
image: postgres:16
restart: always
volumes:
- /srv/matrix/db:/var/lib/postgresql/data
environment:
POSTGRES_DB: synapse
POSTGRES_USER: synapse
POSTGRES_PASSWORD: "{{ postgres_user_pass }}"
POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C
networks:
- default
synapse:
image: matrixdotorg/synapse:latest
restart: always
cpu_count: "1"
cpuset: "0"
depends_on:
- db
- ma1sd
volumes:
- /srv/matrix/synapse-data/:/data
# Python version can be found in the dockerfile: https://github.com/matrix-org/synapse/blob/develop/docker/Dockerfile check for tag to get the correct version
- /srv/matrix/rest_auth_provider.py:/usr/local/lib/python3.11/site-packages/rest_auth_provider.py
environment:
SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml"
TZ: "Europe/Berlin"
labels:
- traefik.enable=true
- traefik.http.routers.{{ servicename }}.rule=Host(`{{ domain }}`)
- traefik.http.routers.{{ servicename }}.entrypoints=websecure
- traefik.http.routers.{{ servicename }}.service={{ servicename }}
- traefik.http.services.{{ servicename }}.loadbalancer.server.port=8008
- traefik.http.routers.matrix_federation.rule=Host(`{{ domain }}`)
- traefik.http.routers.matrix_federation.entrypoints=matrix_federation
- traefik.http.routers.matrix_federation.service=matrix_federation
- traefik.http.services.matrix_federation.loadbalancer.server.port=8448
networks:
- default
- web
ma1sd:
image: ma1uta/ma1sd:2.5.0
restart: always
volumes:
- /srv/matrix/ma1sd-config/:/etc/ma1sd
- /srv/matrix/ma1sd-data/:/var/ma1sd
labels:
- com.centurylinklabs.watchtower.enable=false
- traefik.enable=true
- traefik.http.routers.{{ servicename }}-ma1sd.rule=((Host(`{{ domain }}`) && PathPrefix(`/_matrix/client/r0/login`)) || (Host(`{{ domain }}`) && PathPrefix(`/_matrix/identity`)))
- traefik.http.routers.{{ servicename }}-ma1sd.entrypoints=websecure
- traefik.http.services.{{ servicename }}-ma1sd.loadbalancer.server.port=8090
networks:
- default
- web
purgemediacache:
image: jsonfry/curl-cron:latest
restart: always
depends_on:
- synapse
volumes:
- /srv/matrix/purgemediacache.sh:/curl.sh
environment:
CRON_SCHEDULE: "0 7 * * *"
networks:
- default
networks:
web:
external: true
#######################
# Matrix config items #
#######################
# Matrix domain, same as the domain configure in your Homeserver configuration.
# NOTE: in Synapse Homeserver, the Matrix domain is defined as 'server_name' in configuration file.
#
# This is used to build the various identifiers in all the features.
#
# If the hostname of the public URL used to reach your Matrix services is different from your Matrix domain,
# per example matrix.domain.tld vs domain.tld, then use the server.name configuration option.
# See the "Configure" section of the Getting Started guide for more info.
#
matrix:
domain: 'matrix.warpzone.ms'
v1: true # deprecated
v2: true # MSC2140 API v2. Riot require enabled V2 API.
################
# Signing keys #
################
# Absolute path for the Identity Server signing keys database.
# /!\ THIS MUST **NOT** BE YOUR HOMESERVER KEYS FILE /!\
# If this path does not exist, it will be auto-generated.
#
# During testing, /var/tmp/ma1sd/keys is a possible value
# For production, recommended location shall be one of the following:
# - /var/lib/ma1sd/keys
# - /var/opt/ma1sd/keys
# - /var/local/ma1sd/keys
#
key:
path: '/var/ma1sd/keys'
# Path to the SQLite DB file for ma1sd internal storage
# /!\ THIS MUST **NOT** BE YOUR HOMESERVER DATABASE /!\
#
# Examples:
# - /var/opt/ma1sd/store.db
# - /var/local/ma1sd/store.db
# - /var/lib/ma1sd/store.db
#
storage:
# backend: sqlite # or postgresql
provider:
sqlite:
database: '/var/ma1sd/store.db'
# postgresql:
# # Wrap all string values with quotes to avoid yaml parsing mistakes
# database: '//localhost/ma1sd' # or full variant //192.168.1.100:5432/ma1sd_database
# username: 'ma1sd_user'
# password: 'ma1sd_password'
#
# # Pool configuration for postgresql backend.
# #######
# # Enable or disable pooling
# pool: false
#
# #######
# # Check database connection before get from pool
# testBeforeGetFromPool: false # or true
#
# #######
# # There is an internal thread which checks each of the database connections as a keep-alive mechanism. This set the
# # number of milliseconds it sleeps between checks -- default is 30000. To disable the checking thread, set this to
# # 0 before you start using the connection source.
# checkConnectionsEveryMillis: 30000
#
# #######
# # Set the number of connections that can be unused in the available list.
# maxConnectionsFree: 5
#
# #######
# # Set the number of milliseconds that a connection can stay open before being closed. Set to 9223372036854775807 to have
# # the connections never expire.
# maxConnectionAgeMillis: 3600000
###################
# Identity Stores #
###################
# If you are using synapse standalone and do not have an Identity store,
# see https://github.com/ma1uta/ma1sd/blob/master/docs/stores/synapse.md#synapse-identity-store
#
# If you would like to integrate with your AD/Samba/LDAP server,
# see https://github.com/ma1uta/ma1sd/blob/master/docs/stores/ldap.md
#
# For any other Identity store, or to simply discover them,
# see https://github.com/ma1uta/ma1sd/blob/master/docs/stores/README.md
ldap:
enabled: true
connection:
host: '{{ ldap_ip_ext }}'
port: 389
bindDn: '{{ ldap_readonly_bind_dn }}'
bindPassword: '{{ ldap_readonly_pass }}'
baseDNs:
- '{{ ldap_base_dn }}'
filter: '(&(objectClass=inetOrgPerson)(memberof=CN=active,OU=groups,DC=warpzone,DC=ms))'
attribute:
uid:
type: 'uid'
value: 'uid'
name: 'uid'
threepid:
email:
- 'mail'
msisdn:
- 'phone'
#################################################
# Notifications for invites/addition to profile #
#################################################
# This is mandatory to deal with anything e-mail related.
#
# For an introduction to sessions, invites and 3PIDs in general,
# see https://github.com/ma1uta/ma1sd/blob/master/docs/threepids/session/session.md#3pid-sessions
#
# If you would like to change the content of the notifications,
# see https://github.com/ma1uta/ma1sd/blob/master/docs/threepids/notification/template-generator.md
#
#### E-mail connector
threepid:
medium:
email:
identity:
# The e-mail to send as.
from: "matrix-identity@warpzone.ms"
connectors:
smtp:
# SMTP host
host: "{{ smtp_host }}"
# TLS mode for the connection
# Possible values:
# 0 Disable any kind of TLS entirely
# 1 Enable STARTLS if supported by server (default)
# 2 Force STARTLS and fail if not available
# 3 Use full TLS/SSL instead of STARTLS
#
tls: 1
# SMTP port
# Be sure to adapt depending on your TLS choice, if changed from default
port: "{{ smtp_port }}"
# Login for SMTP
login: "{{ noreply_email_user }}"
# Password for the account
password: "{{ noreply_email_pass }}"
#### MSC2134 (hash lookup)
#hashing:
# enabled: false # enable or disable the hash lookup MSC2140 (default is false)
# pepperLength: 20 # length of the pepper value (default is 20)
# rotationPolicy: per_requests # or `per_seconds` how often the hashes will be updating
# hashStorageType: sql # or `in_memory` where the hashes will be stored
# algorithms:
# - none # the same as v1 bulk lookup
# - sha256 # hash the 3PID and pepper.
# delay: 2m # how often hashes will be updated if rotation policy = per_seconds (default is 10s)
# requests: 10 # how many lookup requests will be performed before updating hashes if rotation policy = per_requests (default is 10)
### hash lookup for synapseSql provider.
# synapseSql:
# lookup:
# query: 'select user_id as mxid, medium, address from user_threepid_id_server' # query for retrive 3PIDs for hashes.
# legacyRoomNames: false # use the old query to get room names.
### hash lookup for ldap provider (with example of the ldap configuration)
# ldap:
# enabled: true
# lookup: true # hash lookup
# activeDirectory: false
# defaultDomain: ''
# connection:
# host: 'ldap.domain.tld'
# port: 389
# bindDn: 'cn=admin,dc=domain,dc=tld'
# bindPassword: 'Secret'
# baseDNs:
# - 'dc=domain,dc=tld'
# attribute:
# uid:
# type: 'uid' # or mxid
# value: 'cn'
# name: 'displayName'
# identity:
# filter: '(objectClass=inetOrgPerson)'
#### MSC2140 (Terms)
#policy:
# policies:
# term_name: # term name
# version: 1.0 # version
# terms:
# en: # lang
# name: term name en # localized name
# url: https://ma1sd.host.tld/term_en.html # localized url
# fe: # lang
# name: term name fr # localized name
# url: https://ma1sd.host.tld/term_fr.html # localized url
# regexp:
# - '/_matrix/identity/v2/account.*'
# - '/_matrix/identity/v2/hash_details'
# - '/_matrix/identity/v2/lookup'
#
# logging:
# root: error # default level for all loggers (apps and thirdparty libraries)
# app: info # log level only for the ma1sd
# requests: false # or true to dump full requests and responses
dns:
overwrite:
homeserver:
client:
- name: 'matrix.warpzone.ms'
value: 'http://synapse:8008'
session:
policy:
validation:
enabled: false
#!/bin/sh
set -e
echo "$(date) - Start"
TS_NOW=$(date +%s)
DELAY=$((30*24*60*60))
TS=$((TS_NOW-$DELAY))
curl -X POST --insecure --header "Authorization: Bearer {{ admin_access_token }}" https://{{ domain }}/_synapse/admin/v1/purge_media_cache?before_ts=$(($TS*1000))
echo "$(date) End"
\ No newline at end of file
# -*- coding: utf-8 -*-
#
# REST endpoint Authentication module for Matrix synapse
# Copyright (C) 2017 Kamax Sarl
#
# https://www.kamax.io/
#
# 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 <http://www.gnu.org/licenses/>.
#
import logging
from twisted.internet import defer
import requests
import json
import time
logger = logging.getLogger(__name__)
class RestAuthProvider(object):
def __init__(self, config, account_handler):
self.account_handler = account_handler
if not config.endpoint:
raise RuntimeError('Missing endpoint config')
self.endpoint = config.endpoint
self.regLower = config.regLower
self.config = config
logger.info('Endpoint: %s', self.endpoint)
logger.info('Enforce lowercase username during registration: %s', self.regLower)
@defer.inlineCallbacks
def check_password(self, user_id, password):
logger.info("Got password check for " + user_id)
data = {'user': {'id': user_id, 'password': password}}
r = requests.post(self.endpoint + '/_matrix-internal/identity/v1/check_credentials', json=data)
r.raise_for_status()
r = r.json()
if not r["auth"]:
reason = "Invalid JSON data returned from REST endpoint"
logger.warning(reason)
raise RuntimeError(reason)
auth = r["auth"]
if not auth["success"]:
logger.info("User not authenticated")
defer.returnValue(False)
localpart = user_id.split(":", 1)[0][1:]
logger.info("User %s authenticated", user_id)
registration = False
if not (yield self.account_handler.check_user_exists(user_id)):
logger.info("User %s does not exist yet, creating...", user_id)
if localpart != localpart.lower() and self.regLower:
logger.info('User %s was cannot be created due to username lowercase policy', localpart)
defer.returnValue(False)
user_id, access_token = (yield self.account_handler.register(localpart=localpart))
registration = True
logger.info("Registration based on REST data was successful for %s", user_id)
else:
logger.info("User %s already exists, registration skipped", user_id)
if auth["profile"]:
logger.info("Handling profile data")
profile = auth["profile"]
# fixme: temporary fix
try:
store = yield self.account_handler._hs.get_profile_handler().store # for synapse >= 1.9.0
except AttributeError:
store = yield self.account_handler.hs.get_profile_handler().store # for synapse < 1.9.0
if "display_name" in profile and ((registration and self.config.setNameOnRegister) or (self.config.setNameOnLogin)):
display_name = profile["display_name"]
logger.info("Setting display name to '%s' based on profile data", display_name)
yield store.set_profile_displayname(localpart, display_name)
else:
logger.info("Display name was not set because it was not given or policy restricted it")
if (self.config.updateThreepid):
if "three_pids" in profile:
logger.info("Handling 3PIDs")
external_3pids = []
for threepid in profile["three_pids"]:
medium = threepid["medium"].lower()
address = threepid["address"].lower()
external_3pids.append({"medium": medium, "address": address})
logger.info("Looking for 3PID %s:%s in user profile", medium, address)
validated_at = time_msec()
if not (yield store.get_user_id_by_threepid(medium, address)):
logger.info("3PID is not present, adding")
yield store.user_add_threepid(
user_id,
medium,
address,
validated_at,
validated_at
)
else:
logger.info("3PID is present, skipping")
if (self.config.replaceThreepid):
for threepid in (yield store.user_get_threepids(user_id)):
medium = threepid["medium"].lower()
address = threepid["address"].lower()
if {"medium": medium, "address": address} not in external_3pids:
logger.info("3PID is not present in external datastore, deleting")
yield store.user_delete_threepid(
user_id,
medium,
address
)
else:
logger.info("3PIDs were not updated due to policy")
else:
logger.info("No profile data")
defer.returnValue(True)
@staticmethod
def parse_config(config):
# verify config sanity
_require_keys(config, ["endpoint"])
class _RestConfig(object):
endpoint = ''
regLower = True
setNameOnRegister = True
setNameOnLogin = False
updateThreepid = True
replaceThreepid = False
rest_config = _RestConfig()
rest_config.endpoint = config["endpoint"]
try:
rest_config.regLower = config['policy']['registration']['username']['enforceLowercase']
except TypeError:
# we don't care
pass
except KeyError:
# we don't care
pass
try:
rest_config.setNameOnRegister = config['policy']['registration']['profile']['name']
except TypeError:
# we don't care
pass
except KeyError:
# we don't care
pass
try:
rest_config.setNameOnLogin = config['policy']['login']['profile']['name']
except TypeError:
# we don't care
pass
except KeyError:
# we don't care
pass
try:
rest_config.updateThreepid = config['policy']['all']['threepid']['update']
except TypeError:
# we don't care
pass
except KeyError:
# we don't care
pass
try:
rest_config.replaceThreepid = config['policy']['all']['threepid']['replace']
except TypeError:
# we don't care
pass
except KeyError:
# we don't care
pass
return rest_config
def _require_keys(config, required):
missing = [key for key in required if key not in config]
if missing:
raise Exception(
"REST Auth enabled but missing required config values: {}".format(
", ".join(missing)
)
)
def time_msec():
"""Get the current timestamp in milliseconds
"""
return int(time.time() * 1000)
version: 1
formatters:
precise:
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s- %(message)s'
filters:
context:
(): synapse.util.logcontext.LoggingContextFilter
request: ""
handlers:
console:
class: logging.StreamHandler
formatter: precise
filters: [context]
loggers:
synapse:
level: "WARNING"
synapse.storage.SQL:
# beware: increasing this to DEBUG will make synapse log sensitive
# information such as access tokens.
level: "WARNING"
root:
level: "WARNING"
handlers: [console]
server_name: "{{ matrix.domain }}"
pid_file: /tmp/homeserver.pid
public_baseurl: "{{ matrix.public_url }}/"
use_presence: false
allow_public_rooms_without_auth: false
allow_public_rooms_over_federation: true
forget_rooms_on_leave: true
listeners:
- port: 8448
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
admin_contact: 'mailto:verwaltung@warpzone.ms'
retention:
enabled: true
database:
name: "psycopg2"
args:
user: synapse
password: "{{ postgres_user_pass }}"
database: synapse
host: db
cp_min: 5
cp_max: 10
log_config: "/data/homeserver.log.config"
media_store_path: "/data/media_store"
max_upload_size: 10M
dynamic_thumbnails: false
thumbnail_sizes:
- width: 32
height: 32
method: crop
- width: 96
height: 96
method: crop
- width: 320
height: 240
method: scale
- width: 640
height: 480
method: scale
- width: 800
height: 600
method: scale
url_preview_enabled: true
url_preview_ip_range_blacklist:
- '127.0.0.0/8'
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '100.64.0.0/10'
- '192.0.0.0/24'
- '169.254.0.0/16'
- '198.18.0.0/15'
- '192.0.2.0/24'
- '198.51.100.0/24'
- '203.0.113.0/24'
- '224.0.0.0/4'
- '::1/128'
- 'fe80::/10'
- 'fc00::/7'
max_spider_size: 10M
enable_registration: false
default_identity_server: "{{ matrix.identity_server }}"
auto_join_rooms:
- "#warpzone:{{ matrix.domain }}"
report_stats: false
signing_key_path: "/data/homeserver.signing.key"
key_refresh_interval: 1d
suppress_key_server_warning: true
trusted_key_servers:
- server_name: "matrix.org"
email:
smtp_host: {{ smtp_host }}
smtp_port: {{ smtp_port }}
smtp_user: "{{ noreply_email_user }}"
smtp_pass: "{{ noreply_email_pass }}"
require_transport_security: false
notif_from: "Warpzone Matrix <matrix@{{ smtp_domain }}>"
enable_notifs: true
notif_for_new_users: False
password_providers:
- module: "rest_auth_provider.RestAuthProvider"
config:
endpoint: "http://ma1sd:8090"
encryption_enabled_by_default_for_room_type: invite
enable_group_creation: false
user_directory:
enabled: true
search_all_users: false
# new in 1.34 spaces
experimental_features: { spaces_enabled: true }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment