如何在 VPS 上自托管 SimpleX SMP 中继服务器
在 VPS 上部署自己的 SimpleX SMP 中继:固定版本安装,获取客户端所需指纹,配置端口、非特权服务用户、备份与 TLS,并了解中继的威胁模型。
自托管 SimpleX 聊天服务器的作用
要自托管 SimpleX 聊天服务器,您需要在 VPS 上运行一个守护进程:smp-server,即 SMP(simplex messaging protocol)的中继服务。它保存联系人写入和读取的消息队列。另一个名为 xftp-server 的可选守护进程负责中继文件传输。两者都来自同一个项目 simplexmq,各自都由一个二进制文件、一个配置文件和一个只追加日志组成。
本文面向运维人员,而不是应用用户。中继服务不保存账户、联系人列表或聊天记录。它保存消息队列、部分尚未投递的密文,以及用于标识自身的证书。您需要负责的是服务可用性、少量磁盘空间,以及经过您服务器的元数据。
下面的每条命令、路径、端口和标志都来自该项目的官方文档:SMP server hosting page、XFTP server page 和 protocol security document。涉及具体数字时,旁边会注明其来源页面。
为什么没有用户标识符的网络仍需要中继
SimpleX 没有用户名、电话号码或账户 ID。联系人是单向队列:位于某个中继上的地址,一方向其中写入消息,另一方从中读取。您的两个联系人之间没有任何可供服务器关联的共同标识符。
这些队列仍然必须存放在某处,原因很简单。两部手机很少会在同一秒在线。必须由某个组件先接收消息并暂存,直到另一台设备发起请求。这就是 SMP 中继的全部职责。这也意味着两台设备不会直接连接,因此任何一方都无法获知另一方的 IP(Internet Protocol)地址。中继会代替它们承担这一暴露风险。
中继的主机名是队列地址的一部分,因此它会出现在您从该中继发出的每个邀请链接中。阅读末尾的威胁模型时,请记住这一点。
中继能看到和不能看到的内容
项目在 protocol/security.md 中将此内容定义为威胁模型。安装任何组件前都值得阅读,因为完成本指南后,该中继将由您控制。中继(包括完全由攻击者控制的中继)无法获知消息的内容或类型,无法在不被察觉的情况下添加、复制或破坏单条消息,也无法通过主动攻击破解端到端加密。
同一页面还列出了中继能够执行的操作。中继可以获知队列接收者何时在线,可以统计有多少条消息经过队列,也可以获知接收者的 IP 地址。中继可以丢弃队列中今后的所有消息,也可以伪造该队列的状态。
因此,责任边界很明确。机密性由客户端负责,自托管不会影响这一点。元数据和可用性由中继运营者负责,而自托管会将这两项都交给您。
开始前的准备工作
- 一台运行 Ubuntu 22.04 或 24.04 的 VPS。该项目发布的二进制文件正是为这两个版本构建的,支持 x86-64 和 aarch64。
- 一个 A 记录指向 VPS 的域名。如果使用 IPv6,还需要一个 AAAA 记录。文档使用
smp1.example.com作为示例。 - Root 或
sudo访问权限。修改防火墙时,还应保持第二个 SSH 会话处于打开状态。 - 服务器外部的备份存储位置,因为配置目录就是服务器的身份信息。
在 ARM 实例上,请选择 aarch64 资源,而不是 x86-64。本指南的其他内容无需修改。选择 ARM 还是 x86 VPS 方案取决于价格和单核速度,而不是该软件是否能够运行。
安装固定版本,不要安装“latest”
项目提供了安装脚本。该脚本会拉取当前版本,并注册一个 simplex-servers-update 命令。脚本可以正常工作,但仍应固定版本:如果中继程序的二进制文件在运行期间自行变化,出现故障时就无法准确判断原因。
截至 2026 年 8 月,simplexmq 的当前版本是 v6.5.0,发布于 29 April 2026。请查看发布页面以确定所需标签,然后在下文的所有位置使用该标签。
sudo useradd -m smp
sudo install -d -o smp -g smp -m 755 /etc/opt/simplex /var/opt/simplexuseradd -m smp 不设置密码,因此任何人都不能直接以 smp 身份登录。运行其他命令前,请先手动创建这两个目录,因为 /etc/opt 属于 root,权限为 755,这会使 smp 用户没有位置写入自己的配置目录。
VER=v6.5.0
curl -fL "https://github.com/simplex-chat/simplexmq/releases/download/$VER/smp-server-ubuntu-24_04-x86-64" -o /tmp/smp-server
sha256sum /tmp/smp-server将该哈希值与发布说明中针对同一标签提供的 SHA2-256 校验和进行比较。项目还使用 SimpleX Chat 密钥 FB44AF81A45BDE327319797C85107E357D4A17FC 对发布校验和进行签名。相关信息记录在服务器页面中,因此您可以验证签名,而不是直接信任提供该哈希值的页面。
sudo install -m 755 -o root -g root /tmp/smp-server /usr/local/bin/smp-server请有意将其安装为 root 所有。服务以 smp 身份运行,因此即使服务遭到入侵,也无法改写它启动时使用的二进制文件。
初始化服务器,以及它输出的两个密钥
sudo su smp -c "smp-server init --yes --store-log --daily-stats --no-password --fqdn=smp1.example.com"--store-log(-l)将队列以追加方式记录到/var/opt/simplex/smp-server-store.log,因此中继服务重启后仍可恢复。没有它,重启会丢弃所有队列,所有经由你的中继路由的联系人都会停止工作。--daily-stats(-s)以 CSV 格式将计数器写入/var/opt/simplex/smp-server-stats.daily.log。--fqdn将你的域名写入生成的证书。如果没有域名,请改用--ip。--no-password允许任何人通过你的中继创建队列。若要将其设为私有,请在初始化完成后,在/etc/opt/simplex/smp-server.ini的[AUTH]下设置create_password,不要在此处传入--password,因为命令行在执行期间会显示在 shell 历史记录和进程列表中。
初始化会生成证书,并输出你必须保存的两个值。第一个是指纹,也是写入 /etc/opt/simplex/fingerprint 的 base64 字符串。第二个是完整的服务器地址,即指纹加上你的主机名。现在复制并保存这两个值。
初始化还会创建 /etc/opt/simplex/ca.key。文档建议将该文件移至离线存储。原因很重要:客户端会固定该证书颁发机构的指纹,因此持有 ca.key 的任何人都可以签发新的服务器证书,而客户端会将其接受为你的证书。之后只有在使用 smp-server cert 轮换服务器证书时,才需要将该文件取回。
将初始化视为一次性步骤。地址中的指纹来自初始化生成的颁发机构,因此重新生成该颁发机构会得到不同的地址,并使你之前发放的地址失效。
以非特权用户通过 systemd 运行
按文档中的原样写入 /etc/systemd/system/smp-server.service:
[Unit]
Description=SMP server systemd service
[Service]
User=smp
Group=smp
Type=simple
ExecStart=/usr/local/bin/smp-server start +RTS -N -RTS
ExecStopPost=/usr/bin/env sh -c '[ -e "/var/opt/simplex/smp-server-store.log" ] && cp "/var/opt/simplex/smp-server-store.log" "/var/opt/simplex/smp-server-store.log.bak"'
LimitNOFILE=65535
KillSignal=SIGINT
TimeoutStopSec=infinity
[Install]
WantedBy=multi-user.target上游 unit 还包含 AmbientCapabilities=CAP_NET_BIND_SERVICE。该行存在的原因是进程以 smp 身份运行,而 1024 以下的端口对非 root 进程不可用;没有这行时,守护进程无法绑定 80 或 443。如果要提供这些端口,请添加该行。LimitNOFILE=65535 很重要,因为每个订阅客户端都会保持一个打开的 TCP 连接,而默认限制远低于繁忙中继所需的数量。ExecStopPost 会在每次停止时将存储日志复制到 .bak 文件,从而为您提供一个可直接使用的回滚点。
sudo systemctl daemon-reload
sudo systemctl enable --now smp-server
sudo systemctl status smp-server
sudo journalctl -fu smp-server正常启动时会记录服务器地址。然后确认套接字确实已打开:
sudo ss -tlnp | grep -E ':(443|5223)'两行都应显示 smp-server。让守护进程以专用账户运行,且不授予 sudo 权限,这与 VPS 上的每服务账户 中介绍的做法相同。这样,某个网络守护进程中的漏洞就不会进一步导致 root shell。
要开放哪些端口,以及要保持关闭的端口
文档列出了3个端口:5223/tcp、443/tcp 和 80/tcp。端口5223用于SMP传输。随附配置在[TRANSPORT]下设置了port: 5223,443,因此同一协议也会在443上响应。这一点很重要,因为许多限制严格的网络只允许出站443流量。只有启用可选信息页及其到HTTPS的重定向时,才需要端口80。
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 5223/tcp
sudo ufw enable不要开放5224。该端口用于控制,文档通过nc 127.0.0.1 5224从服务器本机访问它。它会输出服务器状态并删除队列,因此应仅绑定到回环接口,并在[AUTH]下设置管理员密码和用户密码。如果您刚开始使用此工具,VPS上的ufw基础介绍了规则顺序,以及如何避免将自己锁在服务器外。
还有一个控制项容易被忽略。大多数服务商会在管理面板中运行网络防火墙,它与服务器上的ufw分开。即使端口已在ufw中开放,流量仍可能在到达服务器前被网络防火墙丢弃。
客户端所需的服务器地址
smp://<fingerprint>[:<password>]@<public_hostname>[,<onion_hostname>]这段字符串就是客户端的完整配置。将它粘贴到应用的服务器设置中,或让其他人扫描应用为它显示的二维码。文档指出,二维码中包含密码,因此扫描二维码的人也可以通过您的服务器接收消息。
有一项文档所述的行为会让所有人感到意外。在应用中添加服务器,只会影响此后创建的联系人。现有联系人仍保留在创建其队列的中继服务器上,不会迁移。这也是您在更换中继服务器后的第二天无法关闭旧中继服务器的原因。
添加 XFTP 文件中继
XFTP(SimpleX 文件传输协议)负责网络中的文件传输部分。它是一个独立的守护进程,使用自己的地址。根据项目的 XFTP 公告,中继完全看不到文件元数据:它们只能看到单个数据块,每个数据块大小为 256kb、1mb 或 4mb,访问权限通过匿名凭据授权。发送方可以将同一个文件的数据块分散到多个中继,因此您的服务器保存的是文件片段,而不是完整文件。
sudo useradd -m xftp
sudo install -d -o xftp -g xftp -m 755 /etc/opt/simplex-xftp /var/opt/simplex-xftp /srv/xftp
curl -fL "https://github.com/simplex-chat/simplexmq/releases/download/$VER/xftp-server-ubuntu-24_04-x86-64" -o /tmp/xftp-server
sudo install -m 755 -o root -g root /tmp/xftp-server /usr/local/bin/xftp-server
sudo su xftp -c "xftp-server init -l --fqdn=xftp1.example.com -q '20gb' -p /srv/xftp/"它的配置位于 /etc/opt/simplex-xftp/,状态数据位于 /var/opt/simplex-xftp/,文件数据块位于 -p 指定的路径。systemd 单元的结构相同,其中包含 User=xftp 和 ExecStart=/usr/local/bin/xftp-server start +RTS -N -RTS。初始化程序会以与 SMP 地址相同的格式输出一个 xftp:// 地址,其指纹位于 /etc/opt/simplex-xftp/fingerprint。
需要提前处理端口冲突。XFTP 服务器的文档端口是 443,SMP 配置也列出了 443。同一地址上的同一个端口不能由两个进程同时绑定,因此在一台 VPS 上必须调整其中一项。最简单的做法是在 SMP 的 [TRANSPORT] 部分设置 port: 5223,将 443 留给文件中继,但这样会失去面向受限网络客户端的 443 回退端口。另一种方案是在同一台 VPS 上配置第二个 IP 地址,或者使用第二台 VPS。
请根据实际情况设置配额。-q '20gb' 代表您承诺提供的磁盘空间。文件中继会主要消耗磁盘和带宽,消息中继几乎不会明显消耗这两项资源。
磁盘上保存哪些内容,以及备份可以恢复什么
有两个目录很重要。/etc/opt/simplex/保存身份信息:smp-server.ini、服务器证书和密钥、ca.key以及fingerprint。/var/opt/simplex/保存状态信息:smp-server-store.log保存队列;启用restore_messages: on时,还会保存未投递的消息,以及每日统计文件。
sudo systemctl stop smp-server
sudo tar czf /root/simplex-backup.tgz -C / etc/opt/simplex var/opt/simplex
sudo chmod 600 /root/simplex-backup.tgz
sudo systemctl start smp-server请明确该归档的用途。它不是消息归档:队列中的项目是使用中继从未持有的密钥加密的密文,而随附的 [STORE_LOG] 配置还会在 21 天后使消息过期。它是服务器身份的副本,其中包括 ca.key,因此取得该文件的任何人都可以向您的联系人冒充您的中继。请对其加密,并将其保存在服务器之外。
备份的价值在于恢复。将 /etc/opt/simplex 放回新的 VPS,将相同的 DNS 名称指向该 VPS,指纹就不会改变,因此您发出的每个地址仍然有效。如果丢失该目录,则无法恢复:重新安装会生成新的指纹,也会生成新的地址,这意味着所有经由您的中继路由的联系人都将失效。
TLS:两张证书,各自承担不同职责
SMP 传输不使用公共证书颁发机构。Init 会生成一个私有证书颁发机构和一张服务器证书,该颁发机构的指纹会包含在服务器地址中。客户端会将服务器提供的内容与固定的该指纹进行校验。项目将此描述为保护客户端到服务器的连接,防止机器中间人攻击。该端口不需要运行 ACME(自动证书管理环境)客户端,证书轮换需要手动执行 smp-server cert,并设置 SMP_SERVER_CFG_PATH。
可选的信息页面使用另一张证书。其 [WEB] 部分列出 static_path、https: 443、cert: /etc/opt/simplex/web.crt 和 key: /etc/opt/simplex/web.key。浏览器不认识您的私有证书颁发机构,因此只有这个位置需要使用受公共信任的证书。文档中的 Docker 快速入门正是为此在服务器前配置 Caddy,并自动签发证书。
通过 Tor 访问中继
文档包含 Tor 章节。该章节从 Tor Project 软件源安装 Tor,并在 /etc/tor/torrc 中添加隐藏服务:
SOCKSPort 0
HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1
HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443请仔细阅读这两行模式配置。单跳且不匿名,表示中继自身的位置不会隐藏。洋葱地址速度快,还能让客户端通过一种不会向您透露其 IP 地址的方式连接,但服务器本身仍可通过公网 IP 找到。将 /var/lib/tor/simplex-smp/hostname 提供的洋葱主机名放在服务器地址末尾,并以逗号分隔。如果还希望隐藏服务器位置,则需要采用不同的配置;在 VPS 上运行真正的洋葱服务介绍了其中的权衡。每种工具隐藏的内容不同,Tor 与 VPN 的比较对此进行了说明,该区别也直接适用于这里。
威胁模型:自托管带来的变化
自托管的收益。元数据(存在哪些队列、何时读取队列、哪些地址建立了连接)保存在您控制的机器上,保留时长也由您决定。您也不再属于一个可以被一次性调取大量数据的用户群体。
自托管无法解决的问题如下:
- 加密方式没有变化。在您搭建服务之前,消息已经采用端到端加密;搭建之后仍然采用端到端加密。自托管改变的是元数据归属,不是密码学机制。
- 您的 VPS 提供商可以看到发往您 IP 地址的网络流量,并持有您的账单信息。您只是将信任从消息服务运营方转移给了主机服务运营方,并没有消除信任。
- 您的中继节点覆盖的用户很少。如果它只服务于一个家庭,那么连接到该节点就能识别这个家庭;您从该节点发送的每个邀请链接中也都会包含它的主机名。繁忙的公共中继节点在这一点上能更好地隐藏您的身份,这正是两者之间的实际取舍。私有搜索服务器也存在同样的问题,因此 SearXNG 在您自己的 VPS 上实际隐藏了什么 取决于与您共享该实例的人数。
- 可用性现在由您负责。磁盘已满或设备停止运行都会导致消息无法继续投递,您的联系人也无法绕过您进行路由。
同样的判断适用于您部署在自有设备上的任何私有服务,无论是此中继节点,还是 您自己的 VPS 上的 WireGuard VPN。您是在选择由哪一方查看元数据,而不是让元数据消失。
无法正常工作时
服务启动后立即停止。 阅读 sudo journalctl -u smp-server -n 50。绑定失败信息会指出服务无法占用的端口。然后运行 sudo ss -tlnp | grep :443,查看哪个进程已经占用了该端口。在刚部署的服务器上,占用者通常是 nginx、Caddy,或您一小时前安装的 XFTP 服务器。
Init 无法写入配置。 在 /etc/opt/simplex 存在之前,以 smp 用户运行 smp-server init 会产生权限错误,因为 /etc/opt 归 root 所有。先创建目录并设置正确的所有者,然后重新运行 init。
客户端无法访问中继。 使用 dig +short smp1.example.com 检查名称是否解析到正确的地址。然后从笔记本电脑而不是服务器测试端口:nc -vz smp1.example.com 5223。如果从外部连接失败,而 ss 显示服务器上的套接字已打开,这说明问题出在服务提供商的网络防火墙上。它与 ufw 是两个独立的控制层。
联系人无法通过您的中继连接。 您分享的地址中的指纹必须与 /etc/opt/simplex/fingerprint 的当前内容一致。如果您在 [AUTH] 下设置了 create_password,地址也必须包含该密码,否则客户端无权创建队列。
在应用中添加服务器后没有任何内容传输。 这是预期行为。只有新联系人会使用新添加的中继。现有联系人会继续使用已有的队列。
FAQ
自托管 SimpleX 服务器会让我的消息更安全吗?
不会,这是设计如此。SimpleX 会在设备之间对消息进行端到端加密,因此无论中继由谁运行,中继都不会持有密钥。自托管改变的是谁可以观察这些消息的元数据:有哪些队列、何时读取队列,以及哪些 IP 地址建立连接。这是元数据方面的选择。如果您自托管的原因是需要更强的加密,那么原本就已经具备这种加密。
SimpleX 中继运营者实际能看到什么?
项目的 protocol/security.md 对此有明确说明。中继无法读取消息内容或类型,无法在不被发现的情况下修改单条消息,也无法通过主动攻击破解端到端加密。中继可以看到队列接收方何时在线,统计经过队列的消息数量,获知接收方的 IP 地址,丢弃队列中的后续消息,或伪造该队列的状态。中继归您所有后,您便拥有这些权限。
我需要域名和 TLS 证书吗?
可用的配置需要域名;如果确实没有域名,smp-server init 接受 --ip。消息端口不需要公共证书颁发机构签发的证书:init 会生成自己的证书颁发机构,客户端会固定您在 smp:// 地址中显示的指纹。只有可选的 Web 信息页面需要公有信任证书;该页面在 smp-server.ini 的 [WEB] 部分中配置为 cert 和 key。
如果我丢失 /etc/opt/simplex,会发生什么?
您发出的所有地址都会停止工作。该目录保存证书颁发机构,其指纹已嵌入服务器地址;因此重建后会生成不同的指纹,也就对应一台不同的服务器。队列位于该中继上的联系人无法从客户端修复。请将该目录加密备份到服务器之外,并按照文档说明将 ca.key 离线保存,因为持有它的人可以冒充您的中继。
我可以在同一台 VPS 上运行 SMP 中继和 XFTP 文件中继吗?
可以,但需要解决一个端口冲突。XFTP 服务器的文档端口是 443,而默认 SMP 配置列出 port: 5223,443,因此两者都会尝试使用同一个套接字。将 443 分配给其中一个:为 SMP 服务器设置 port: 5223,或将文件中继迁移到第二个 IP 地址或第二台 VPS。同时应根据实际可用磁盘容量设置存储配额,因为消耗磁盘和带宽的是文件中继。