目前很多博客只简单讲述了如何搭建 Synapse 服务器,但实际搭建完,用户使用后会出现大量问题,本文旨在详细讲述 Synapse 服务器以及其他的配套服务搭建
Synapse 现状
Synapse 原本是由 Matrix基金会实现和维护的,是一个基于 Python 的 Matrix 协议实现服务,当然除此之外也有其他的服务端推荐,但是 Synapse 是其中最稳定,也是官方最为推荐的,在官网他们给出了其他的服务端
在2024年的八月份,Matrix基金会已经无力再维护 Synapse,而是将其转交给了 Element 维护
你或许会问了,Element 是什么?和 Matrix 又是什么关系?
坦率地讲,我觉得 Element 有点像一个商业公司,他们为一些客户提供了 Matrix 服务器的托管服务,同时将一些客户端和服务端开源,Matrix 让 Element 来接手 Synapse 的维护其中应该也有 Matrix 作为一个非盈利基金会资源不够用的窘境
对于我们普通用户来说,不管是 Matrix 还是 Element,他们所提供的 Synapse 都是开源的,因此对于我们来说没有影响,只管好好用就可以了
但是在一些细微的配置中,Element 为了更好的适配直接的客户端,我们需要做一些细微的调整,这些在后面的章节中会详细讲述
安装 Synapse
一个完整的 Synapse 包括以下部分:
- Synapse
- Postgres
- Sydent
- Sliding Sync
- TURN 服务
- 反代,在这里使用 Caddy
如果英文能力可以的话我极力推荐阅读官方的文档,目前最新的文档是由 Element 所维护:Welcome and Overview - Synapse
搭建基础服务
关于如何搭建 Synapse 基础服务器,我建议可以去看一看这位博主的文章,我第一次搭建就是跟着这个的:超详细 Matrix Synapse 部署教程:搭建去中心化加密聊天服务器 - 白鱼小栈
但是这个博主使用的是默认的 SQLlite 数据库,虽然简单但是性能十分拉垮,所以我们可以安装官方给出的文档将其切换成 Postgres
首先请按照我给的 docker-compose.yml
起好容器:
services:
synapse:
image: matrixdotorg/synapse:latest
container_name: synapse
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -s localhost:8008/health || exit 1"]
ports:
- "8008:8008"
volumes:
- ./data:/data
environment:
VIRTUAL_HOST: matrix.example.com
VIRTUAL_PORT: 8008
LETSENCRYPT_HOST: matrix.example.com
SYNAPSE_SERVER_NAME: matrix.example.com
SYNAPSE_REPORT_STATS: "no"
networks:
- matrix_network
db:
image: postgres13
container_name: synapse_db
restart: unless-stopped
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: synapse
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--locale=C --encoding=UTF8"
volumes:
- ./db_data:/var/lib/postgresql/data
networks:
- matrix_network
networks:
matrix_network: {}
之后需要修改 homeserver.yaml
,之后修改 database
字段为:
database:
name: psycopg2
args:
user: synapse
password: synapse
database: synapse
host: synapse_db
port: 5432
cp_min: 5
cp_max: 10
其他按照博主给的配置就可以了,之后打开 8008
端口,看看是否会出现欢迎界面
其返回的路径为:http://<ip>/_matrix/static/
配置反向代理
官方提供了 Nginx 和 Caddy 两种配置文件:Using a reverse proxy with Synapse
nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
# For the federation port
listen 8448 ssl default_server;
listen [::]:8448 ssl default_server;
server_name matrix.example.com;
location ~ ^(/_matrix|/_synapse/client) {
# note: do not add a path (even a single /) after the port in `proxy_pass`,
# otherwise nginx will canonicalise the URI and cause signature verification
# errors.
proxy_pass http://localhost:8008;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host:$server_port;
# Nginx by default only allows file uploads up to 1M in size
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
client_max_body_size 50M;
# Synapse responses may be chunked, which is an HTTP/1.1 feature.
proxy_http_version 1.1;
}
}
caddy,在这里我们不使用官方的配置文件,不大好用
matrix.example.com {
reverse_proxy 127.0.0.1:8008
}
官方提供的配置文件是:
matrix.example.com {
reverse_proxy /_matrix/* localhost:8008
reverse_proxy /_synapse/client/* localhost:8008
}
example.com:8448 {
reverse_proxy /_matrix/* localhost:8008
}
但在实际的使用中,路径并不会被正确路由,按照我自己使用的方法进行路由可能存在一些风险,还是建议用 Nginx 进行反代
在这里我们需要指定来自联邦(Federation)的流量
在这里我不打算使用 8448
端口,因此需要进行声明,要使用这种方法,需要配置 https://<server_name>
处的服务器为 https://<server_name>/.well-known/matrix/server
处的文件提供服务
在 homeserver.yaml
中,我们可以指定字段来提供服务
serve_server_wellknown: true
之后使用 curl
进行测试
$ curl -i https://<server_name>/.well-known/matrix/server
HTTP/2 200
alt-svc: h3=":443"; ma=2592000
content-type: application/json
date: Wed, 05 Feb 2025 03:27:35 GMT
server: Caddy
server: Synapse/1.123.0
strict-transport-security: max-age=31536000; includeSubDomains; preload
content-length: 34
{"m.server":"<server_name>:443"}%
配置 Sydent
Sydent 是 Matrix 协议中的身份服务器,它允许用户通过邮件和电话号码发现对方,尽管官方并不推荐用户自己搭建 Sydent 服务器,但是为了完整展示全过程,我还是在这里贴出参考步骤
直接使用 docker compose 进行部署
services:
sydent:
image: matrixdotorg/sydent:latest
container_name: matrix_sydent
environment:
- SYDENT_SERVER_NAME=
volumes:
- ./sydent_data:/data
ports:
- "8090:8090"
restart: unless-stopped
之后使用 Caddy 进行反代,在客户端中添加服务器
配置 Sliding Sync
在一些比较新的客户端,如 Element X 中,要求服务器必须支持 Sliding Sync,在这里我们还是使用 docker compose 来进行部署
services:
postgres:
image: postgres:13
container_name: sliding_sync_db
environment:
POSTGRES_DB: syncv3
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
volumes:
- ./data_db:/var/lib/postgresql/data
sliding_sync:
image: ghcr.io/matrix-org/sliding-sync:latest
container_name: sliding_sync
depends_on:
- postgres
ports:
- "8009:8009"
environment:
SYNCV3_SERVER: "https://matrix.example.com"
SYNCV3_DB: "postgres://postgres:${DATABASE_PASSWORD}@postgres:5432/syncv3?sslmode=disable"
SYNCV3_SECRET: ${SYNCV3_SECRET}
SYNCV3_BINDADDR: ":8009"
需要创建一个 .env
文件,在里面填入DATABASE_PASSWORD
和 SYNCV3_SECRET
DATABASE_PASSWORD=password
SYNCV3_SECRET=password
同样需要配置反代,除此之外,在 Synapse 服务器的 homeserver.yaml
中也要配置对于的字段,来让服务器在 https://matrix.example.com/.well-known/matrix/client
返回一个 JSON 数组,来声明服务器的 Sliding Sync 的服务
public_baseurl: "https://matrix.example.com"
extra_well_known_client_content : # 用来配置 /.well-known/matrix/client
org.matrix.msc3575.proxy: https://sliding.example.com
重启服务,使用 curl
进行检查
$ curl -i https://matrix.example.com/.well-known/matrix/client
HTTP/2 200
access-control-allow-headers: X-Requested-With, Content-Type, Authorization, Date
access-control-allow-methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
access-control-allow-origin: *
access-control-expose-headers: Synapse-Trace-Id, Server
alt-svc: h3=":443"; ma=2592000
cache-control: no-cache, no-store, must-revalidate
content-type: application/json
date: Wed, 05 Feb 2025 03:45:24 GMT
server: Caddy
server: Synapse/1.123.0
strict-transport-security: max-age=31536000; includeSubDomains; preload
{"m.homeserver":{"base_url":"https://matrix.example.com/"},"org.matrix.msc3575.proxy":"https://sliding.example.com"}%
至此,我们可以使用官方提供的工具来检查是否配置正常,能不能和 Matrix 联邦上的其他服务器进行通信:Matrix Federation Tester
TRUN 服务器
Matrix 是支持 VoIP 通话的,你可以尝试使用官方提供的 turn.matrix.org,但是这样有 IP 地址泄漏风险,而且该服务在大陆存在网络问题,因此我建议进行自建
官方文档也提供了相应的指导:Configuring a Turn Server - Synapse,在这里我使用 coturn 作为 TURN 服务器
coturn 提供了包管理、docker和本地编译三种方式,由于我使用的是 Debian,提供了包
sudo apt install coturn
配置文件在 /etc/turnserver.yaml
,在正式修改之前需要进行备份
cp /etc/turnserver.conf /etc/turnserver.conf.bak
基础配置如下:
# 填写你的 TURN 服务域名
realm=turn.example.com
# 启用服务器
listening-port=3478
tls-listening-port=5349
# 随机密码
cli-password=password
# 指定外网IP(重要!替换为你的公网IP)
external-ip=<ip>
# UDP端口范围(建议保留默认)
min-port=49152
max-port=65535
# 测试用户,实际使用需要删除!!
user=username:password
# 动态密钥 使用 pwgen -s 64 1 生成
use-auth-secret
static-auth-secret=password
# TLS证书配置(必须)
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
# 日志配置
log-file=/var/log/turn.log
verbose
# VoIP traffic is all UDP. There is no reason to let users connect to arbitrary TCP endpoints via the relay.
no-tcp-relay
# don't let the relay ever try to connect to private IP address ranges within your network (if any)
# given the turn server is likely behind your firewall, remember to include any privileged public IPs too.
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
# recommended additional local peers to block, to mitigate external access to internal services.
# https://www.rtcsec.com/article/slack-webrtc-turn-compromise-and-bug-bounty/#how-to-fix-an-open-turn-relay-to-address-this-vulnerability
no-multicast-peers
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
# special case the turn server itself so that client->TURN->TURN->client flows work
# this should be one of the turn server's listening IPs
allowed-peer-ip=10.0.0.1
# consider whether you want to limit the quota of relayed streams per user (or total) to avoid risk of DoS.
user-quota=12 # 4 streams per video call, so 12 streams = 3 simultaneous relayed calls per user.
total-quota=1200
启动服务:
systemctl start coturn
设置开机启动:
systemctl enable coturn
虽然有很多教程提出可以使用 Trickle ICE 测试服务是否可用,但是我在实际使用过程中发现不太好用,因此使用 coturn 提供的测试工具 turnutils_uclient
turnutils_uclient -v -y -u username -w password <ip>
链接成功的关键点:
- 成功的分配响应:多次发送的“allocate response received: success”表明客户端成功地从TURN服务器获得了中继地址。
- 通道绑定成功:输出中显示“channel bind sent”和“cb response received: success”,这表明通道绑定请求也成功。
- 消息传输统计:在消息客户端(mclient)部分,显示了发送和接收的消息数量,以及没有丢包(Total lost packets 0),这表明数据传输正常。
- 延迟和抖动:输出中提供的平均往返延迟和抖动值(Average round trip delay 250.75 ms; Average jitter 1.35 ms)也在合理范围内,表明连接质量良好。
之后需要设置 TLS/DTLS,不要使用来自 Let's Encrypt 的证书,因为所有使用 Chromium's WebRTC 的 Matrix 客户端都无法使用
申请 ZeroSSL 即可,ZeroSSL 提供了自动化工具:GitHub - zerossl/zerossl-bot: The repository for the ZeroSSL certbot wrapper
apt install certbot
bash <(wget -q -O - https://github.com/zerossl/zerossl-bot/raw/master/get-zerosslbot.sh)
sudo zerossl-bot certonly --standalone -m youremail@example.com -d turn.example.com
申请成功后证书会下放到 /etc/letsencrypt/archive/turn.example.com
中
直接运行会出现问题,因为 coturn 进程没有权限去读取相应的证书文件,在cannot start TLS and DTLS listeners because private key file is not set properly · Issue #1139 · coturn/coturn中可以看到
解决方法有两种,将文件所有权设置为 644
或者以 root
用户运行 coturn
修改服务配置:
sudo nano /lib/systemd/system/coturn.service
修改配置为:
[Unit]
Description=coTURN STUN/TURN Server
Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
After=network.target
[Service]
User=root
Group=root
Type=notify
ExecStart=/usr/bin/turnserver -c /etc/turnserver.conf --pidfile=
Restart=on-failure
InaccessibleDirectories=/home
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
重启服务:
sudo systemctl daemon-reload
sudo systemctl restart coturn
查看日志是否正常
sudo journalctl -u coturn -f
可以使用 openssl
测试 TLS 是否正常
openssl s_client -connect turn.example.com:5349
可以看到我这里的 CA 确实是 ZeroSSL
之后需要在 Synapse 中的 homeserver.yaml
配置
turn_uris: [ "turn:turn.example.com?transport=udp", "turn:turn.example.com?transport=tcp" ]
turn_shared_secret: "password"
turn_user_lifetime: 86400000
turn_allow_guests: true
官方文档可以参考:Configuring a Turn Server - Synapse
总结
Matrix 是一个很牛逼的东西,希望未来的发展越来越好,能加入和 tg 类似的贴纸包,各种功能能够更完善一下,管理集成是什么东西还是不知道
目前我这样配置还是不能支持 Element X 的创建用户,原因目前为止,还有待进一步解决
Comments NOTHING