Matrix: 通讯协议的服务端与客户端
Matrix是一个开放、去中心化的实时通讯协议,旨在提供安全、去中心化的即时通讯和协作解决方案。它允许用户通过分布式网络进行消息传递和实时通信。
服务端组件
- Homeserver
- 身份服务器
- 媒体存储服务
- 应用服务
客户端功能
- 消息收发
- 用户认证
- 房间管理
- 端到端加密
通讯协议
- HTTP传输层
- WebSocket实时通道
- JSON数据格式
- 安全信道建立
安全机制
- 公钥加密
- 身份验证令牌
- 会话管理
- 访问控制
技术架构
- 分布式网络
- 去中心化设计
- 联邦协议
- 状态同步机制
性能优化
- 缓存策略
- 消息压缩
- 异步处理
- 负载均衡
准备工作
-
一台 x86/amd64 架构的 Linux 服务器
- 性能要求:基本无性能要求,可用内存建议在 200M 以上。
-
安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh- 说明:若未安装可使用上述命令安装。
-
一个域名
- DNS 提供商:文中使用 Cloudflare,其他提供商也可。
-
一个邮箱
- 用途:可使用 SMTP,用于设置发信,自建邮局/Outlook 等均可。
-
一个 Cloudflare 账户
搭建过程
1. 使用 Docker Compose 搭建 Synapse
- 创建数据存储文件夹:在该文件夹下创建
docker-compose.yml
,内容如下:
version: "3.3"
services:
synapse:
image: "matrixdotorg/synapse:latest"
container_name: "matrix_synapse"
restart: unless-stopped
dns:
- 8.8.8.8
- 1.1.1.1
healthcheck:
test: ["CMD", "curl", "-f", "https://chat.xxxx.de"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
ports:
- '9090:80'
volumes:
- "./data:/data"
environment:
VIRTUAL_HOST: "chat.xxxx.de"
VIRTUAL_PORT: "80"
LETSENCRYPT_HOST: "chat.内部使用.de"
SYNAPSE_SERVER_NAME: "chat.xxxxxx.de"
SYNAPSE_REPORT_STATS: "no"
networks:
- matrix_net
networks:
matrix_net:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1450
ipam:
driver: default
config:
- subnet: 172.200.0.0/16
gateway: 172.200.0.1
- 生成配置文件:使用如下命令在
./data
中生成配置文件:
docker run -it --rm -v ./data/:/data/ -e SYNAPSE_SERVER_NAME=你的域名 -e SYNAPSE_REPORT_STATS=yes/no matrixdotorg/synapse:latest generate
- 修改生成的配置文件:生成成功后,
./data
中会出现homeserver.yaml
,将其修改,参照以下模板:
# Configuration file for Synapse.
#
# 这是一个 YAML 文件:请参阅 [1] 以获取快速介绍。注意缩进很重要:
# 列表或字典的所有元素应具有相同的缩进。
#
# [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
#
# 有关如何配置 Synapse 的更多信息,包括每个选项的完整说明,请访问:
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
server_name: "你的域名" # 服务器名称
pid_file: /data/homeserver.pid # PID 文件路径
listeners:
- port: 你的端口 # 监听端口
tls: false # 是否使用 TLS
type: http # 监听类型
x_forwarded: true # 启用 X-Forwarded-For
resources:
- names: [client, federation] # 资源名称
compress: false # 是否压缩
database: # 数据库配置
name: sqlite3 # 使用 SQLite 数据库
args:
database: /data/homeserver.db # 数据库文件路径
log_config: "/data/你的域名.log.config" # 日志配置文件路径
media_store_path: /data/media_store # 媒体存储路径
registration_shared_secret: "保留生成的 secret 即可" # 注册共享密钥
report_stats: false # 是否报告统计数据
macaroon_secret_key: "保留生成的 secret 即可" # Macaroon 密钥
form_secret: "保留生成的 secret 即可" # 表单密钥
signing_key_path: "/data/你的域名.signing.key" # 签名密钥路径
trusted_key_servers:
- server_name: "matrix.org" # 信任的密钥服务器
enable_registration: True # 是否启用注册
registrations_require_3pid: # 使用邮箱注册
- email
suppress_key_server_warning: True # 抑制密钥服务器警告
public_baseurl: https://你的域名 # 公共基础 URL
serve_server_wellknown: true # 启用 Well-Known 服务
block_non_admin_invites: false # 阻止非管理员邀请
allow_guest_access: false # 是否允许访客访问
email: # 邮件配置
smtp_host: 你的邮件服务器 # SMTP 服务器地址
smtp_port: 你的邮件服务器端口 # SMTP 服务器端口
smtp_user: "你的SMTP账户" # SMTP 用户名
smtp_pass: "你的SMTP密码" # SMTP 密码
enable_tls: true # 是否启用 TLS
require_transport_security: true # 是否要求传输安全
notif_from: "Matrix Notifications <notifications@yesterday.de>" # 验证邮件提示语
client_base_url: "https://你的element域名" # 客户端基础 URL
validation_token_lifetime: 15m # 验证邮件有效时长
invite_client_location: https://你的element域名 # 邀请客户端位置
subjects: # 提示消息主题
message_from_person_in_room: "%(person)s 在 %(room)s 聊天室中给你 发送了一条消息"
message_from_person: "%(person)s 给你发送了一条消息"
messages_from_person: "%(person)s 给你发送了多条消息"
messages_in_room: "你有一条来自 %(room)s 聊天室的消息"
messages_in_room_and_others: "你有一些来自 %(room)s 聊天室和其他人的消息"
messages_from_person_and_others: "[%(app)s] 你有一些来自 %(person)s 和其他人的消息"
invite_from_person_to_room: "%(person)s 邀请你加入 %(room)s 聊天室"
invite_from_person: "%(person)s 邀请你注册<>"
password_reset: "【】密码重置"
email_validation: "【】验证您的电子邮件"
# vim:ft=yaml
- 样例:
# Configuration file for Synapse.
#
# This is a YAML file: see [1] for a quick introduction. Note in particular
# that *indentation is important*: all the elements of a list or dictionary
# should have the same indentation.
#
# [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
#
# For more information on how to configure Synapse, including a complete accounting of
# each option, go to docs/usage/configuration/config_documentation.md or
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
server_name: "chat.xxxx.de"
pid_file: /data/homeserver.pid
listeners:
- port: 80
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
database:
name: sqlite3
args:
database: /data/homeserver.db
log_config: "/data/chat.xxxx.log.config"
media_store_path: /data/media_store
registration_shared_secret: "d6Ht+WZGxD8+Bu9NL3m::k~1xcixg_Qe5-"
report_stats: false
macaroon_secret_key: "2yfYf5iQlX2bjP1AGTzZG-Bdyh8tfaVZ8mS6"
form_secret: "uuDAscAd6qeY7sJzDI*4,SE2SXqi89W:wTZh*E"
signing_key_path: "/data/chat.xxxx.de.signing.key"
trusted_key_servers:
- server_name: "matrix.org"
enable_registration: True #若是私人服务器设置为false可关闭注册
registration_requires_token: true #使用token注册
- email
suppress_key_server_warning: True
public_baseurl: https://chat.xxxx.de
serve_server_wellknown: true
block_non_admin_invites: false
allow_guest_access: false
email:
smtp_host: smtp.larksuite.com #无需引号
smtp_port: 587 #无需引号
smtp_user: "no-reply@xxxx.de"
smtp_pass: "ZP56dOgiT"
force_tls: true
require_transport_security: true
enable_tls: true
notif_from: "Your Friendly %(app)s homeserver <no-reply@xxxx.de>"
app_name: my_branded_matrix_server
enable_notifs: true
notif_for_new_users: false
client_base_url: "https://xxxx.xxxx.de"
validation_token_lifetime: 15m
invite_client_location: https://app.element.io
subjects:
message_from_person_in_room: "[%(app)s] You have a message on %(app)s from %(person)s in the %(room)s room..."
message_from_person: "[%(app)s] You have a message on %(app)s from %(person)s..."
messages_from_person: "[%(app)s] You have messages on %(app)s from %(person)s..."
messages_in_room: "[%(app)s] You have messages on %(app)s in the %(room)s room..."
messages_in_room_and_others: "[%(app)s] You have messages on %(app)s in the %(room)s room and others..."
messages_from_person_and_others: "[%(app)s] You have messages on %(app)s from %(person)s and others..."
invite_from_person_to_room: "[%(app)s] %(person)s has invited you to join the %(room)s room on %(app)s..."
invite_from_person: "[%(app)s] %(person)s has invited you to chat on %(app)s..."
password_reset: "[%(server_name)s] Password reset"
email_validation: "[%(server_name)s] Validate your email"
# vim:ft=yaml
- 设置文件夹权限:使用以下命令设置
data
文件夹权限:
chmod -R +777 ./data
- 启动服务器:在含有
docker-compose.yml
的目录下使用以下命令启动服务器:
docker compose up -d
- 验证搭建正确性:若将服务器该端口映射到公网,访问
公网IP+端口
,应出现包含 "It works! Synapse is running" 的界面,证明搭建正确。
2. 使用 Nginx Proxy Manager 进行反向代理
-
打开 Nginx Proxy Manager,并添加 Proxy Host。
- 此处使用的域名是前文中 "你的域名"。
- IP 与端口则是前文中 Docker 容器映射到的 IP 与端口。
- 回源协议选择 HTTP,开启 TLS(如果使用 Cloudflare CDN 也可不开启 TLS)。
-
将域名解析至服务器公网 IP,若访问
https://你的域名
出现与上文一样的 "It works! Synapse is running" 的界面,证明搭建成功。
3. 接入 Cloudflare CDN(可选)
-
由于 Cloudflare CDN 会自行提供边缘 TLS 证书,若要接入 Cloudflare CDN,前文配置 Nginx Proxy Manager 时可不使用 TLS,或使用 Cloudflare 提供的 15 年有效期的源服务器证书。
-
另外一种方法是不使用 Nginx Proxy Manager,而直接使用 Origin Rules 将该域名解析至指定端口,但不推荐此种方式,因为 Cloudflare 免费计划中每个域名只有 10 条 Origin Rules,且使用此种方式需在公网上暴露端口。
4. 搭建 Synapse 时的一些注意事项
-
开启 TLS 十分重要
- Matrix 协议的加密与 TLS 有着密不可分的关系,若不开启 TLS 直接使用 HTTP 搭建 Home Server,在使用过程中会发现无法生成加密秘钥等问题。
-
接入 Cloudflare CDN 后的上传文件限制
- 在接入 Cloudflare CDN 后,由于免费版的限制,最大文件上传大小为 100MB,否则会返回 Error 413。
-
文件存储
- 文件会全部存储在搭建用服务器上,所以尽量使用硬盘较大的服务器作为 Home Server。
5. 使用 Cloudflare Pages 搭建 Element 客户端
由于 Element 客户端为纯前端页面,可以使用 Cloudflare Pages 进行搭建,而不必浪费服务器资源。以下是搭建的步骤:
-
获取代码
- 前往 Element GitHub 仓库。
- fork最新的分支/稳定分支。
-
修改配置
- 找到
config.simple.json
文件, 修改为 config.json。 - 修改
HomeServer
为你自己的 Home Server 地址。
"m.homeserver": {
"base_url": "https://xxx.xxxxx.de",
"server_name": "xxx.xxxxx.de"
}, - 找到
-
部署到 Cloudflare Pages
-
登录你的 Cloudflare 账户。
-
创建一个新的 Pages 项目,选择刚刚 fork 的 Element 项目名称。
-
在项目设置中,填写以下信息:
-
Build command:
yarn install --ignore-engines && yarn build
-
Build output directory:
webapp
-
-
-
定义变量和密钥
-
在项目设置中,定义以下变量:
Type Name Value Plaintext NODE_VERSION 20 Plaintext NPM_VERSION 10 Plaintext YARN_VERSION 1.22.22
-
-
域名解析
- 将你自己的客户端域名解析至 Cloudflare Pages 上,作为你在前文中提到的 "你的 element 域名"。
6. 选择 Matrix 客户端
在 Matrix 上选择自己喜欢的客户端,可以访问以下链接查看可用的客户端:
7. 使用命令行创建账户
如果您在注册账户时遇到问题,可以选择使用命令行创建账户。请使用以下命令:
docker exec -it matrix_synapse register_new_matrix_user -c /data/homeserver.yaml http://172.18.0.2:80
参数说明
-c /data/homeserver.yaml
:指定 Synapse 配置文件的路径。http://172.18.0.2:80
:指定 Synapse 服务器的 URL(请根据实际情况修改 IP 地址)。
使用此命令后,系统会提示您输入新用户的用户名和密码。确保记录下这些信息以便日后使用。