目前很多博客只简单讲述了如何搭建 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 包括以下部分:
如果英文能力可以的话我极力推荐阅读官方的文档,目前最新的文档是由 Element 所维护:Welcome and Overview - Synapse
搭建基础服务 关于如何搭建 Synapse 基础服务器,我建议可以去看一看这位博主的文章,我第一次搭建就是跟着这个的:超详细 Matrix Synapse 部署教程:搭建去中心化加密聊天服务器 - 白鱼小栈
但是这个博主使用的是默认的 SQLlite 数据库,虽然简单但是性能十分拉垮,所以我们可以安装官方给出的文档将其切换成 Postgres
首先请按照我给的 docker-compose.yml
起好容器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 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
字段为:
1 2 3 4 5 6 7 8 9 10 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 ,在这里我们不使用官方的配置文件,不大好用
1 2 3 matrix.example.com { reverse_proxy 127.0.0.1:8008 }
官方提供的配置文件是:
1 2 3 4 5 6 7 8 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
中,我们可以指定字段来提供服务
1 serve_server_wellknown: true
之后使用 curl
进行测试
1 2 3 4 5 6 7 8 9 10 11 $ 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 GMTserver: 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 进行部署
1 2 3 4 5 6 7 8 9 10 11 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 来进行部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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
1 2 DATABASE_PASSWORD=password SYNCV3_SECRET=password
同样需要配置反代,除此之外,在 Synapse 服务器的 homeserver.yaml
中也要配置对于的字段,来让服务器在 https://matrix.example.com/.well-known/matrix/client
返回一个 JSON 数组,来声明服务器的 Sliding Sync 的服务
1 2 3 public_baseurl: "https://matrix.example.com" extra_well_known_client_content : # 用来配置 /.well-known/matrix/client org.matrix.msc3575.proxy: https://sliding.example.com
重启服务,使用 curl
进行检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ 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 GMTserver: 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,提供了包
配置文件在 /etc/turnserver.yaml
,在正式修改之前需要进行备份
1 cp /etc/turnserver.conf /etc/turnserver.conf.bak
基础配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 realm=turn.example.com listening-port=3478 tls-listening-port=5349 cli-password=password external-ip=<ip> min-port=49152 max-port=65535 user=username:password use-auth-secret static-auth-secret=password 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 no -tcp-relay 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 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 allowed-peer-ip=10.0.0.1 user-quota=12 total-quota=1200
启动服务:
设置开机启动:
虽然有很多教程提出可以使用 Trickle ICE 测试服务是否可用,但是我在实际使用过程中发现不太好用,因此使用 coturn 提供的测试工具 turnutils_uclient
1 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
1 2 3 4 5 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
修改服务配置:
1 sudo nano /lib/systemd/system/coturn.service
修改配置为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [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
重启服务:
1 2 sudo systemctl daemon-reloadsudo systemctl restart coturn
查看日志是否正常
1 sudo journalctl -u coturn -f
可以使用 openssl
测试 TLS 是否正常
1 openssl s_client -connect turn.example.com:5349
可以看到我这里的 CA 确实是 ZeroSSL
之后需要在 Synapse 中的 homeserver.yaml
配置
1 2 3 4 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 的创建用户,原因目前为止,还有待进一步解决