自建节点:免费使用 Relayium 的中继与存储
最近更新: 2026-08-06
跨网络传输和存储型链接会消耗中继带宽和磁盘,这对我们是有成本的,所以它们按免费额度提供、超出后收费。但有个绕过办法:自己搭一个中继/存储节点,绑定到你的账号,之后你的传输就走你自己的节点而不是我们的——不计量、不收费。
这跟「自托管整套 Relayium 服务端」不是一回事。你依然用你平常的 relayium.com 账号、同样的客户端;只是多接了一个你自己名下的节点来承载你的流量。本指南带你从一台全新的 Linux 服务器,到节点上线,大约五分钟。
为什么要自建节点
两个理由。其一是成本:你自己的节点直接承载你的中继和存储流量,完全不碰我们的计量设施,也就没有任何可计费的东西——无论用量多大都免费。
其二是掌控:中继的字节和存储的数据块都落在你自己运行的硬件上,由你自己运维。实时传输全程端到端加密,所以即便是你自己的节点,看到的也只是密文。
安装节点并让它上线
开始之前你需要什么
- 一台能从公网访问到的 Linux 服务器——便宜的 VPS 或家里常开的机器都行。amd64 和 arm64 都支持。
- 那台服务器的 root 权限,或者 sudo。安装时需要一次;节点本身从不以 root 运行。
- 放通入站端口的能力——主机防火墙上要放,云 VPS 还要在服务商的安全组里放。
- 一个已登录的 relayium.com 账号。安装命令是在账号页现生成的,里面带着一次性令牌。
- 磁盘空间,仅当你希望节点在中继之外还负责存储时才需要。纯中继节点不需要——把 RELAYIUM_NODE_STORAGE_DIR 去掉即可。
按顺序做四件事:生成命令、跑它、放通端口、确认节点上线。全新机器上大约五分钟。
在 relayium.com 登录,打开账号页 /me。
滚动到「我的节点」,点「添加节点」。立刻复制那条安装命令——里面的令牌只显示这一次,之后再也拿不到。
把它粘到你的服务器上执行。它会下载 relayium-node 二进制、校验校验和、安装到 /usr/local/bin、写好 systemd 服务并启动。
curl -fsSL https://relayium.com/install-node.sh | sudo RELAYIUM_CENTRAL_URL=https://relayium.com RELAYIUM_NODE_TOKEN=<your-token> RELAYIUM_NODE_STORAGE_DIR=/var/lib/relayium-node/blobs sh确认服务已经起来,并且重启后还会回来。两个答案都重要:active 说明它现在在跑,enabled 才是重启后还在的那个。
systemctl is-active relayium-nodesystemctl is-enabled relayium-node在主机防火墙上放通入站端口。显示「在线」只需要出站访问,但对端要中继和存储,走的是这几个端口。
sudo ufw allow 3478/udp # TURN sudo ufw allow 8081/tcp # storage sudo ufw allow 49152:65535/udp # relay如果是云 VPS,还要在服务商的安全组里放通同样的端口。只配 ufw 的话它们在上游依然是封的,而节点全程看着都很健康。
回到 /me,看着节点变成「在线」——通常 30 秒左右。从此你账号的传输会自动优先走它。
可选:打开「只使用我自己的节点做中继/存储」,这样传输会直接失败,而不是悄悄退回我们的共享设施。
一个正常节点长什么样
systemd 报告服务同时是 active 和 enabled,并且节点在「我的节点」下显示为在线。光有 active 不够——没有 enabled 的节点下次重启就消失了。
$ systemctl is-active relayium-node
active
$ systemctl is-enabled relayium-node
enabled- 其中 <your-token> 会在账号页里替你填好——不要直接照抄上面的占位符。
- RELAYIUM_NODE_STORAGE_DIR 会同时开启存储(不只是中继)。如果你只想让节点中继、不存储,去掉这个变量即可。
- 确认已启动:systemctl status relayium-node(应为 active/running)。
- 确认开机自启:systemctl is-enabled relayium-node(应为 enabled)。
- 实时看日志:journalctl -u relayium-node -f。
- 3478/udp 是别人用来中继的 TURN 端口;8081/tcp 是存储的 HTTP 端口;49152–65535/udp 是中继媒体端口段。
- 在云 VPS 上,还要在服务商的安全组 / 网络防火墙里放通这些端口,不只是 ufw。
用 root 跑这个安装脚本安全吗?
先把最重要的一句说在前面:自建节点和我们自己机队的节点跑的是同一套代码、同一套加固——同一个签名发布里的同一个二进制、同一个安装脚本、同一份 systemd unit。唯一的差别是这台机器归谁。下面讲的东西对两者都成立。
把一个从网上拉下来的脚本管道给 root shell,值得警惕,也值得一个具体的回答,而不是一句「放心」。root 只用在安装这一步,节点后续运行完全用不到它。安装脚本会建一个叫 relayium-node 的系统账号(没有登录 shell、没有家目录),写好 systemd unit,启动服务,然后退出。节点本身从不以 root 运行:unit 里写死了 User=relayium-node,所以它一上线就是一个在你机器上什么都不拥有的低权限账号。(默认开启的自动更新确实会多装一个以 root 运行的 unit——下一节整节都在讲它能做什么、不能做什么。)
在这个账号外面,unit 还套了一层 systemd 沙箱。每一行都对着「节点进程万一被攻破,攻击者接下来会伸手去够什么」。这里没有任何东西对你隐藏:装完之后 cat /etc/systemd/system/relayium-node.service 就能看到完整的 unit。
| unit 里的配置 | 万一节点被攻破,它挡住了什么 |
|---|---|
User=relayium-node | 攻击者只是一个什么都没有的用户,不是 root。 |
ProtectHome=yes | /home、/root 完全隐身——偷不到 SSH 私钥,也拿不到别的项目的数据。 |
ProtectSystem=strict | 整个文件系统只读,改不了任何系统文件。 |
ReadWritePaths= | 唯一可写的只有节点自己的状态目录,以及你配置了存储时的那个存储目录。写别处一律失败。 |
NoExecPaths= | 存储目录里的东西跑不起来——上传的文件无法被执行。 |
NoNewPrivileges=yes | 没有回到 root 的路,常见的提权套路全被堵死。 |
CapabilityBoundingSet= | 留空——不给任何 Linux capability。 |
ProtectKernelTunables=yes、ProtectKernelModules=yes | 碰不到内核:改不了 sysctl,加载不了模块,种不了 rootkit。 |
- 只有真正开了存储的节点,ReadWritePaths 和 NoExecPaths 才会指向存储目录。纯中继节点这两行都没有,除了自己的状态目录哪儿都写不了。
- 正常情况下 capability 集合是空的。唯一的例外是把直连下载监听放在 1024 以下的端口时需要 CAP_NET_BIND_SERVICE 才能绑定;默认下载端口是 2053,在 1024 以上,所以什么都不会授予。
- 节点手里没有密钥。文件在上传之前就已由发送方加密,落到存储节点上的只是它读不了的密文——包括你自己的节点,也包括你自己。
自动更新能做什么、不能做什么
安装脚本还会装一个自动更新的 timer,默认开启:relayium-node-update.timer 大约每十分钟问一次 relayium.com「这台节点该跑哪个版本」。这是第二个 unit,而且以 root 运行,所以它也该向你交代清楚自己。
中央从不下发二进制。它的全部回答就是一个版本号、两个开关(这台节点现在能不能动、这是不是一次刻意的降级)和一句简短的理由——没有字节流,没有 URL,没有命令。之后是节点自己去取那个发布版本,把压缩包的 SHA-256 与该版本的 checksums.txt 比对,再用编译进「正在做这次校验的那个二进制」里的公钥,验证 checksums.txt 上的 ECDSA P-256 签名。这把钥匙的私钥半边并不在回答这些轮询的服务器上。所以中央即使被攻破,也只能报一个版本号,变不出一个能通过验签的二进制。
更新器和节点是两个权限恰好相反的进程。relayium-node.service 就是上面那个沙箱——在 ProtectSystem=strict 之下它根本无法写 /usr/local/bin,所以节点永远改不了任何二进制,包括它自己的。relayium-node-update.service 则是一个只做一件事的 oneshot unit,以 root 运行,并且刻意不套沙箱:因为替换 /usr/local/bin 里的文件,需要的正是节点沙箱存在的意义所要拒绝的那份权限。把「能改二进制」这件事收进这一个单一用途的 unit,而不是去松动节点本体的加固,正是这个拆分的全部意义:拿着 root 的那个进程只负责换二进制,笼子里的那个永远碰不到二进制。
更新出了问题会自己撤销。更新器会把旧二进制留在新二进制旁边,重启服务,然后最多盯十分钟等心跳;如果新版本在这个窗口里没能报健康,它就把旧二进制换回去、再重启一次,并记下这个坏版本不再重试。整个过程从头到尾都不会读、移动或删除存储的文件。
- 不想要它:带 RELAYIUM_NODE_AUTO_UPDATE=off 重跑一遍安装脚本。timer 和它的 service 会被停用并删除;节点照常运行,什么时候升级由你决定。
- 彻底不用这台节点了:见下面的「移除你的节点」。
移除你的节点
卸载只有一个脚本,无论这台节点只做中继还是也存文件,用的都是它。它会删掉 unit、二进制、配置和那个服务账号,并尽力(best-effort)通知 relayium.com 这台节点已经下线。这次调用失败的话,终端上只多一行提示,不是卸载出了问题——它会打印节点 ID,方便手工标记为已移除。
先下载、检查,再执行。直接管道给 sh 的话,一旦 404 或网络抖动,整条命令会什么都不打印、退出码却是 0,看起来和卸载成功一模一样。
它只删自己认得的东西:状态目录或存储目录里出现的意外文件会被保留并报告,而不是一并扫掉。
curl -fsSL https://relayium.com/uninstall-node.sh -o uninstall-node.sh && \
[ -s uninstall-node.sh ] && sudo sh uninstall-node.sh
- 只要存储目录里还有它认不出的文件,它就拒绝卸载——包括清理还没轮到的过期 blob——因为每个存储文件只存在于唯一一台节点上,没有副本。等这个数变成 0 再跑,或者加 RELAYIUM_NODE_FORCE=1 表示你接受那些文件从此不可达。
- 如果它判断不出你的 blob 在哪,它会停下来而不是猜。RELAYIUM_NODE_ASSUME_NO_STORAGE=1 是唯一的放行开关,而且它照样不会删任何认不出的东西。
- 存储目录本身会被保留,除非你另外加 RELAYIUM_NODE_PURGE_STORAGE=1。环境变量过不了 | sudo sh,要写成 sudo env RELAYIUM_NODE_PURGE_STORAGE=1 sh uninstall-node.sh。
- 卸完之后,systemctl status relayium-node 应该是 not-found,也不该再列出 relayium-node 的 timer。以后重装的话,你账号里得到的会是一台新节点:卸载把节点的身份文件删掉了,所以重装是注册一台全新节点,而不是把旧的那台救回来。
出问题时怎么办
几乎所有起不来的节点都逃不出这五种,其中三种从服务器上看一切正常:服务在跑,只有账号页或者一个监听端口会告诉你不对。
现象、检查、修复
- shell 回答「relayium-node: command not found」。
command -v relayium-node # 什么都没打印二进制根本没装。你从来不需要单独安装 relayium-node——账号页那条一行命令才是负责下载它、放进 PATH 并作为服务启动的东西。改跑那条命令。
- 服务是 active,但节点在账号页上始终不变成在线。
journalctl -u relayium-node -n 50 --no-pager在线与否是由出站心跳决定的,所以这里很少是防火墙的问题,而是注册失败。令牌是一次性的,已经用过的命令、或上一次尝试留下的旧命令都会失败。再点一次「添加节点」拿一条新命令重跑。
- 节点显示在线,但传输还是走我们的共享设施。
sudo ss -lunp | grep 3478在线只证明了出站心跳。对端需要的是入站端口:先确认节点确实在监听,然后在主机防火墙和云安全组里放通 3478/udp、8081/tcp 和 49152-65535/udp。想彻底排除悄悄回退,就打开「只使用我自己的节点」那个开关。
- 卸载命令什么都没打印、退出码 0,服务却还在。
systemctl status relayium-node # active (running)这正是把一次失败的下载管道给 sh 之后的样子:404 或网络抖动会什么都不打印、退出码 0,读起来和成功一模一样。先下载脚本、确认它非空、再执行——这也是本文那条命令写成三段而不是一条管道的原因。
- 存储目录里还有文件,卸载因此拒绝执行。
sudo ls /var/lib/relayium-node/blobs | wc -l这是刻意的。每个已存储的文件只存在于唯一一个节点上,没有副本,所以移除节点会让这些文件永远取不回来。要么等这些数据块过期、数量归零,要么用 RELAYIUM_NODE_FORCE=1 接受这个损失。环境变量无法穿过管道传给 sudo sh,所以要写成 sudo env RELAYIUM_NODE_FORCE=1 sh uninstall-node.sh。
常见问题
我遇到「relayium-node: command not found」,哪里错了?
你在安装之前就运行了 relayium-node 二进制。请用账号页给的那条一行安装命令(curl … | sudo … sh 形式):它会下载二进制、放到 PATH 上,并作为服务启动。你从不需要单独安装 relayium-node。
重启之后节点还会在线吗?
会。安装脚本注册了一个 systemd 服务,开机自启且设为 Restart=always,所以重启后会自动回来,崩溃也会自愈。无需额外操作。
这跟自托管 Relayium 有什么区别?
自建节点保留你平常的 relayium.com 账号和客户端,只是多接一个你自己的节点来承载流量。自托管则是在你自己的域名上运行整套服务端(账号、Web 应用、信令)——那个见「自托管 Relayium」指南。
别人能用我的节点或看到我的数据吗?
不能。节点通过令牌绑定到你的账号,只承载你账号的流量。实时传输端到端加密,存储的数据块是你的节点也读不了的密文。你的数据和节点配置只为你自己所用。
登录,打开账号页,一分钟内添加你的第一个节点。
打开账号页