Matrix-Synapse安装使用与注意事项

发布于 2022-11-08  2,278 次阅读



本篇的环境为Ubuntu20.04,使用PostgreSQL14,Python3.8运行,且使用apt方式安装,其他情况请不要直接套用。

Matrix-Synapse是目前最成熟的Matrix家庭服务器,也是应用最广的一个。全世界有数以千万计的人享受着Matrix-Synapse带来的便捷与安全。考虑到https://matrix.org 难以在国内访问,本篇文章同时也会简单说明一下安装步骤,详细的步骤还请访问GitHub上面Matrix官方的文档

安装

Ubuntu仓库中的很多软件并不是最新版本,Synapse也不例外。所以首先,你需要先将下载源调换为官方下载源(本文特指发行版,如需预发行版请自行设置)。
(你的服务器需要可以访问外网)

sudo apt install -y lsb-release wget apt-transport-https
sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" |
    sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt update
sudo apt install matrix-synapse-py3

安装完成?恭喜你,你已经安装好了Synapse!
不过这只是开始,安装完毕后是不能直接用的,你需要编辑位于/etc/matrix-synapse的文件(如果在别处编辑文件并且使用别处的文件且用systemd进行管理,请自行修改matrix-synapse.service中配置文件的路径)
现在让我们安装PostgreSQL,实际上Ubuntu仓库中的12版本是可以使用的,但是为了方便未来更新,我们还是直接一步到位使用新版本PostgreSQL作为数据库程序。请不要有长期使用SQLite3的想法,你不会获得任何好处。

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install postgresql

然后安装Redis

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update
sudo apt-get install redis

请注意,如果Redis通过systemd启动失败,请检查日志对应文件及其所有者。
(如果你想,你可以再设置Redis的访问密码,步骤简单,在这里不多赘述)

数据库

如使用宝塔,请注意不要使用宝塔内的PostgreSQL生成数据库,这不合规

首先我们进入postgres账户:

su - postgres
#or
sudo -u postgres bash

然后创建一个用户以及其下的一个数据库:

createuser --pwprompt username

createdb --encoding=UTF8 --locale=C --template=template0 --owner=username dbname

你可以为该用户设置一个强密码,准备完毕后就不再需要对数据库执行操作了。
数据库相关的配置如下(参考的整体配置在最后面)

database:
  name: psycopg2
  args:
    user: <user>
    password: <pass>
    database: <db>
    host: <host>
    cp_min: 5
    cp_max: 10

相关内容请自行替换。

基础配置

基础配置部分大多数无需改动,部分诸如"server_name"等请自行填写。请注意仔细填写,诸如server_name等项一经启动初始化便无法修改,唯一方法便是清空数据库重新开始。

如果你想让它变成如Haty一样同一域名既可以当做Matrix服务器又可以同时做其他事,请直接填写目标域名,例如,想要hashi.sbs同时成为Matrix服务器与运行Haty,请直接填写hashi.sbs。

接下来重点讲讲易踩坑部分

使日志占用降低

如果你打开log.yaml阅读过,你可以惊喜地发现Matrix贴心地默认将日志等级设置为INFO,而这意味着大量操作将被记录,空间占用将明显上升。建议调整为WARNING或ERROR,既可以定位问题,又不至于过度占用资源。

如何运行Synapse?

你可以在homeserver.yaml同目录下运行synctl start/stop/restart来操作Synapse且在本次开机(注意不是会话)期间有效,你也可以使用systemd实现开机自启,文件如下:

[Unit]
Description=Synapse master

# This service should be restarted when the synapse target is restarted.
PartOf=matrix-synapse.target
ReloadPropagatedFrom=matrix-synapse.target

[Service]
Type=notify
NotifyAccess=main
User=matrix-synapse
WorkingDirectory=/var/lib/matrix-synapse
EnvironmentFile=-/etc/default/matrix-synapse
ExecStartPre=/opt/venvs/matrix-synapse/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-synapse/homeserver.yaml --config-path=/etc/matrix-synapse/conf.d/ --generate-keys
ExecStart=/opt/venvs/matrix-synapse/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-synapse/homeserver.yaml --config-path=/etc/matrix-synapse/conf.d/
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=3
SyslogIdentifier=matrix-synapse

[Install]
WantedBy=matrix-synapse.target

为什么使用systemd启动时会启动失败?

请注意文件里面是通过matrix-synapse用户启动的,你需要更改日志所有者,并且保证配置文件可读。

为什么我在listener里面设置了TLS后出现了错误?

请不要在此处应用TLS,TLS需要应用于反向代理。

如果我不想与其他站互联,应该怎么做?

Matrix的一大亮点就是互联,不建议你这样做。
如果你执意如此,在resources下names里面去除federation项。

我的站点并没有过多使用,为什么数据库在膨胀?

在trusted_key_servers里删除matrix.org,此操作随时可以进行且不会影响正常使用。数据库膨胀是因为该服务器的信息同时同步到了你的服务器,即使你的服务器里的用户并没有加入它的房间。

其他内容请自行填写,如有非第三方服务(如reCaptcha)的秘钥,可以随意填写。

如有疑问,欢迎一起讨论

附加项

OSS

许多时候可能服务器并没有足够空间存储用户产生的文件,此时可以对接OSS解决存储问题。
OSS对接要求服务方需要兼容AWS S3协议。
这里我们使用一个额外工具Synapse-S3-storage-provider
由于通过apt安装是Synapse实际上是在一个虚拟环境内安装的pip库,所以该工具可以通过pip进行快速安装,在虚拟环境内执行pip install synapse-s3-storage-provider,然后在default.yaml内添加以下内容:

media_storage_providers:
- module: s3_storage_provider.S3StorageProviderBackend
  store_local: True
  store_remote: True
  store_synchronous: True
  config:
    #bucket: 
    # All of the below options are optional, for use with non-AWS S3-like
    # services, or to specify access tokens here instead of some external method.
    #region_name: ap-northeast-2
    #endpoint_url: 
    #access_key_id: 
    #secret_access_key: 
    # The object storage class used when uploading files to the bucket.
    # Default is STANDARD.
    #storage_class: "STANDARD_IA"
    # The maximum number of concurrent threads which will be used to connect
    # to S3. Each thread manages a single connection. Default is 40.
    #
    #threadpool_size: 20

相关部分请自行填写,其中如果你自行搭建了Minio,请注意endpoint_url填写的应为访问地址,如https://example.com/a/a.png可以访问到相关内容,就填写https://example.com

TURN服务

出于安全性与便利性等原因,我们应当设置一个TURN服务替换掉默认的服务器。
首先你需要:
- 另一个服务器
- 一个非Let's Encrypt之类的免费证书或Cloudflare的自签证书的证书(域名范围不限制,因为本操作仅需要一个域名)

首先,在另一台服务器上安装coturn:

apt install coturn

然后在/etc/turnserver.conf内进行设置。
必修改项:

use-auth-secret
static-auth-secret=随便填,建议生成
realm=你想反向代理出来的TURN域名(不带协议的那个)
# TLS certificates, including intermediate certs.
# For Let's Encrypt certificates, use `fullchain.pem` here.
cert=准备的证书的路径

# TLS private key file
pkey=准备证书的key的路径

# Ensure the configuration lines that disable TLS/DTLS are commented-out or removed
#no-tls
#no-dtls(这两项要注释)

你可以再去限制并发,限制IP,使用syslog进行记录等。
修改完毕后反向代理,例如turn.example.com
在Synapse的default.yaml内找到并修改相关选项,应为这样子:

turn_uris: [ "turn:turn.example.com?transport=udp", "turn:turn.example.com:443?transport=tcp", "turns:turn.example.com:443?transport=tcp" ]
turn_shared_secret: "你设置的秘钥“
turn_user_lifetime: 最长时间
turn_allow_guests: True

接下来,配置完毕后,开始运行自己的Matrix服务吧!
(客户端可能后面会再写)

配置示例(default.yaml,移除部分配置如OSS部分)

# 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://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
#
# This is set in /etc/matrix-synapse/conf.d/server_name.yaml for Debian installations.
server_name: example.com
pid_file: "/var/run/matrix-synapse.pid"
serve_server_wellknown: true
report_stats: false
suppress_key_server_warning: true
macaroon_secret_key: *
form_secret: *
listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['::1', '127.0.0.1']
    resources:
      - names: [client, federation, consent]
        compress: false
user_consent:
  template_dir: privacy_policy_templates
  version: 1.0
  require_at_registration: true
  policy_name: "Terms of Service"
  block_events_error: >-
    You can't send any messages until you consent to the privacy policy at
    %(consent_uri)s.

database:
  name: psycopg2
  args:
    user: *
    password: *
    database: *
    host: 127.0.0.1
    cp_min: 5
    cp_max: 10
log_config: "/etc/matrix-synapse/log.yaml"
media_store_path: /var/lib/matrix-synapse/media
signing_key_path: "/etc/matrix-synapse/homeserver.signing.key"
trusted_key_servers:
  - server_name: "matrix.org"
admin_contact: 'mailto:[email protected]'
mau_trial_days: 1
max_avatar_size: 5M
allowed_avatar_mimetypes: ["image/png", "image/jpeg", "image/gif", "image/webp"]
federation_client_minimum_tls_version: 1.2
max_upload_size: 25M
recaptcha_public_key: "*"
recaptcha_private_key: "*"
enable_registration_captcha: false
enable_registration: true
session_lifetime: 696h
track_appservice_user_ips: true
turn_uris: [ * ]
turn_shared_secret: "*"
turn_user_lifetime: 86400000
turn_allow_guests: True
email:
  smtp_host: smtp.example.com
  smtp_port: 587
  smtp_user: "*"
  smtp_pass: "*"
  require_transport_security: true
  enable_tls: true
  notif_from: "Your Friendly %(app)s Manage Group <*>"
  app_name: Hashi Chat--Haty
  enable_notifs: true
  notif_for_new_users: false
  client_base_url: "https://example.com"
  validation_token_lifetime: 15m
  invite_client_location: https://example.com

  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"
push:
  include_content: false
  group_unread_count_by_room: false
encryption_enabled_by_default_for_room_type: invite
user_directory:
    enabled: true
    search_all_users: true
    prefer_local_users: true
redis:
    enabled: true
    host: 127.0.0.1
    port: 6379
    password: *
auto_join_rooms:
  - "#a:example.com"
registration_shared_secret: *
url_preview_enabled: true
url_preview_ip_range_blacklist: false
sso:
  client_whitelist:
    - https://example.com/
enable_registration_without_verification: false
registrations_require_3pid:
  - email
enable_media_repo: true

反向代理与Delegation

首先,我们先配置好Synapse的反向代理,示例域名为server.example.com
设好配置,其中关键部分为:

location ~ ^(/_matrix|/_synapse/client) {
        proxy_pass http://localhost:8008;
        proxy_set_header X-Forwarded-For remote_addr;
        proxy_set_header X-Forwarded-Protoscheme;
        proxy_set_header Host $host;

然后是example.com,在正常配置的基础上添加:

  location /.well-known/matrix/server {
    return 200 '{"m.server": "server.example.com:443"}';
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
  }

  location /.well-known/matrix/client {
    return 200 '{"m.homeserver": {"base_url": "https://server.example.com"}}';
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
  }
  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-Protoscheme;
    proxy_set_header Host $host;

    # 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;
  }

至此,大功告成!

如果有什么疑问,欢迎提出来哦!