高级
架构、全部平台的二进制与校验、服务端组件的部署。只想装来用的话,首页就够了。
当前版本读取中…
架构
单个可执行文件,基于 libp2p。两台机器直接握手,中间的 signal 只负责互相介绍,介绍完就尽量退场。同一份代码跑在 Windows / Linux / ARM 上,CGO-free 交叉编译。
三个角色
| 角色 | 做什么 |
|---|---|
signal | 登记表:交换所在位置,必要时兼做中转;发布版本、带一个运维仪表盘 |
listener | 被连的一方:共享目录、决定谁能进来、开放哪些能力 |
dialer | 连接的一方:浏览远程目录、传文件、开本地端口和代理口 |
listener 与 dialer 的区别
同一个客户端二进制,角色是启动时选的,不是两个产物。无参数双击运行会开一个选择页(回环 127.0.0.1:34110),勾"记住选择"后下次直接进;-choose 强制重新选,-mode listener / -mode dialer 直接指定。
listener(共享端) | dialer(连接端) | |
|---|---|---|
| 谁先动 | 被连的一方,常驻等着 | 主动去连的一方 |
| 数量关系 | 一对多:一个 listener 同时接多个 dialer,每台设备在授权表里各占一行,逐个授权、逐个收回 | 一次对着一台 listener,可在已认识的机器之间切换(切换会关掉上一台的会话和端口转发) |
| 东西在谁那儿 | 共享目录、桌面、终端、出口网络都在它这台 | 自己不提供任何东西 |
| 登记 | 每 30 秒把自己的地址注册进 signal,并预约中转 | 不登记地址,只查询;signal 只把这次查询记下来给监控页看 |
| 权限 | 说了算的一方:签发邀请码、审批设备、七项能力逐格授权、随时收回 | 只能申请,拿到什么由对方决定;没授权的功能连页签都不显示 |
| 默认管理界面 | 127.0.0.1:34116 | 127.0.0.1:34115 |
| 典型部署 | 家里/公司那台常开的机器,或无人值守的 Linux 服务器 | 你手上正在用的这台 |
一次连接必须一头一个:两台都起 listener 谁也不会去连谁。同一台机器上分别起两个进程各当一头是可以的(两个角色的管理端口不同),常见于既要对外共享、又要去拿别处东西的机器。
三条独立路径,同时跑
- relay — 全程中转,最稳,任何网络都能用
- nat — 先借中转握手,再打洞升级成点对点直连
- lan — 同一局域网时直接走内网地址
三条路各自建连、各自测速,界面上同时显示延迟和吞吐,可以自己挑用哪条。实测同机 LAN 路径 278 MiB/s;打洞后的 NAT 直连约 20 MB/s,延迟从 80ms 降到 1ms 量级,打洞耗时约 0.6 秒。
七项能力,各自独立授权
| 文件传输 | 双栏文件管理器:上传下载、断点续传、完整性校验、目录同步、传输队列 |
| Win 桌面 | 把对方已有的 RDP 服务映射到本机 127.0.0.1 端口,用 mstsc 连;目标由对方列举,请求方不能指定端口 |
| VNC 桌面 | 同一条隧道,画面直接画在浏览器里,密码由被连方代答 |
| 代理服务 | 本机 SOCKS5 / HTTP 口。pivot(进对方网络)与 exit(借对方出网)分开,私有网段在 exit 下强制排除 |
| 终端 | 对方机器上的一个 shell,带窗口尺寸协商 |
| 消息 | 按对端分线程的文字通道,可直接发文件和整个目录,走同一套传输队列 |
capAdmin | 管理这台机器本身,和前六项同一张授权表、同一个四态、同一个删除按钮 |
安全模型
- 身份是密钥,不是 IP。每台机器一个稳定身份,授权跟着身份走。
- 默认全拒。一次性邀请码:10 分钟、只能用一次、只绑一台设备。
- 四态授权。拒绝 / 每次确认 / 一小时 / 永久。到点回到拒绝,不会退化成"每次问";没人在屏幕前 = 拒绝。
- 收回立刻掐断正在跑的连接。活动会话实时可见。
- 代理硬禁区。环回、链路本地、各家云的元数据地址(169.254.169.254 等)、6to4/Teredo/NAT64 包装的内网地址,任何配置都到不了;解析出的每个地址都要过审,不是任意一个过。
- 设备圈隔离。不在圈里的机器根本看不见对方。
无人值守
Linux 服务器上没有桌面时,管理界面可以开到网上。绑定非回环地址必须带密码(至少 6 位),否则拒绝启动:
QFILE_ADMINPASS='你的密码' ./qfile-linux-amd64 -mode listener -adminaddr 0.0.0.0:34116
那个端口能授予远控和代理,没有密码不是"弱一点的配置",是谁找到端口谁就能开这台机器。能用 ssh -L 34116:127.0.0.1:34116 就更好,端口留在回环上即可。
客户端:全部平台
| 产物 | 说明 |
|---|---|
qfile-wails-windows-amd64.exe | Windows 原生窗口。首页给的就是这个 |
qfile-windows-amd64.exe | Windows 控制台。要看日志、要进任务计划、要无人值守时用 |
qfile-linux-amd64 / -arm64 | Linux。默认起一个本机管理界面,浏览器打开它启动时打印的地址 |
读取 /api/release …
macOS 目前不发布二进制。源码是 CGO-free 的,可以自己 go build。
服务端:三种,按需要装
| 组件 | 做什么 | 要求 |
|---|---|---|
signal |
登记表 + 版本发布 + 运维监控。整套部署只需要一台,已经在 x.bofile.com 上跑着。 |
公网、域名、证书、443 |
relay |
中转:替打不通洞的两台机器转发流量。多加几台就是多几条更近的路。 | 公网、一个 tcp+udp 端口。不需要域名和证书 |
gateway |
浏览器的门:HTTPS 443,把 https://<token>.x.bofile.com/ 反代到对应的 listener。 |
公网、443、由 signal 下发的通配证书 |
relay 和 gateway 都是可选的扩容件,都不持有登记表,都不需要 ssh key、不需要仓库、不需要任何凭据:二进制从 signal 的公开发布端点取,并对着 signal 同时公布的 sha256 校验。两个脚本都可以重复运行 —— 再跑一次就是原地升级,身份密钥保留,别人已经认识的 peer id 不变。
服务端二进制
读取 /api/release …
部署 relay
在要当中转的那台机器上,用 root 跑。全程在那台机器上,不需要我们这边做任何事。
curl -fsSLO https://x.bofile.com/download/install_relay.sh
sudo bash install_relay.sh
可选参数(环境变量)
| 变量 | 默认 | 什么时候要设 |
|---|---|---|
PORT | 4002 | tcp 和 udp 用同一个号 |
ANNOUNCE | 自动探测的公网 IP | 机器在 NAT 后面,或者你有域名 |
REGION | 无 | 一个标签,signal 会公布它,客户端据此优先挑近的中转 |
DIR | /opt/qfile-relay | 换安装目录 |
PORT=4002 REGION=cn-shanghai sudo bash install_relay.sh
脚本做不了、必须你做的两件事
- 放行 tcp/PORT 和 udp/PORT —— 云上的安全组和机器本地防火墙都要。两个都要:QUIC 通常更快,少一条 UDP 规则的症状是"能用,但一直很慢",很难查。
- 把脚本最后打印的那行
-relay地址发给 signal 的运维。在它被加进 signal 的中转清单之前,没有任何客户端会用到这台机器。那行地址是脚本从跑起来的进程里读回来的,别手抄 —— peer id 抄错的报错是"无法预约中转",指不到原因。
备份 /opt/qfile-relay/qfile_relay.key。丢了就是换了一个新身份,signal 那边的配置会变成过期的。日常:systemctl status qfile-relay / journalctl -u qfile-relay -f / 卸载 systemctl disable --now qfile-relay。
部署 gateway
同样是在目标机器上用 root 跑。它要占 443,所以这台机器上不能有别的东西在用 443。
curl -fsSLO https://x.bofile.com/download/install_gateway.sh
sudo bash install_gateway.sh
流程
- 脚本装好二进制,先把这台机器的 peer id 打印出来,然后开始每 15 秒问一次 signal。
- 你把那一行 peer id 发给 signal 的运维 —— 只发这一行。不发证书、不发密钥、不发密码。
- 他们在 signal 监控页的 Gateways 里批准这个 id。批准的那一刻,证书通过已经建立的 libp2p 连接下发过来,gateway 自己开始服务。
证书不走 URL,也不用人肉传:那条连接两端都由 peer id 认证,signal 清楚自己在回答哪台机器,而且只回答批准过的。通配私钥一旦泄漏,就是给它覆盖的每个名字都发了一张新证书,而且撤不回来 —— 所以它不出现在任何链接、任何聊天窗口里。
可选参数
| 变量 | 默认 | 说明 |
|---|---|---|
ANNOUNCE | x.bofile.com | 这台 gateway 承载的域名,证书必须覆盖它。没被特别交代就别动 |
PORT | 4003 | libp2p 端口。同机有 relay 时不要和它的 4002 撞 |
DIR | /opt/qfile-gateway | 二进制、身份密钥和证书都在这里 |
验证
唯一要看的一条:/api/info 必须回报 signal 的 peer id。这一行同时证明 TLS 在本机终结、并且这台机器连上了 signal。
curl -sk -H 'Host: x.bofile.com' https://127.0.0.1/api/info
不改 DNS,从外面按名字测:
curl -k --resolve x.bofile.com:443:<这台机器的公网IP> https://x.bofile.com/api/info
超时几乎总是安全组:要放行 tcp/443 和 tcp+udp/4003。脚本不动 DNS —— 装完之后线上仍然是原来那台在服务,切换是另一个可回退的步骤。卸载:systemctl disable --now qfile-gateway。
不用脚本的话
脚本只是把下面这几步串起来。手工做也可以,包括在没有 curl 的机器上先下好再传过去。
# 1. 看清单,记下对应文件的 sha256
curl -s https://x.bofile.com/api/release
# 2. 下载
curl -fsSLO https://x.bofile.com/releases/qfile-relay-linux-amd64
# 3. 校验,一定要做:和清单里的那一行完全一致才继续
sha256sum qfile-relay-linux-amd64
# 4. 装成 systemd 服务(-install 会把当前这条命令行原样注册成开机自启的单元)
install -m755 qfile-relay-linux-amd64 /opt/qfile-relay/qfile
cd /opt/qfile-relay && ./qfile -mode relay -port 4002 -announce <公网IP> \
-key /opt/qfile-relay/qfile_relay.key -web https://x.bofile.com -install
| 接口 | 是什么 |
|---|---|
| /api/release | 发布清单:版本号,以及每个文件的 sha256 和字节数 |
/releases/<文件名> | 二进制本体。清单里没有的名字一律 404 |
| /download/ | 安装脚本和说明文档,目录里有什么就是什么 |
| /api/info | signal 的 peer id 和地址,客户端就是靠它找到 signal 的 |
几个常见问题
- 装 relay 或 gateway 需要给我 ssh 权限吗?
- 不需要。两个脚本都在你自己的机器上跑,取的是公开的二进制,唯一要交换的是一行文本:relay 是它的地址,gateway 是它的 peer id。
- 升级怎么做?
- 把同一个脚本再跑一遍。身份密钥保留,peer id 不变,别人的配置不用改。客户端在界面里自己有更新按钮。
- relay 会看到我传的内容吗?
- 看不到明文,它转发的是已经加密的流。但它确实知道谁在和谁通,以及转了多少字节 —— 中转的代价就是流量,以及这点元数据。
- 非要有 signal 吗?
- 要。两台机器得先有人给它们互相介绍。介绍完之后能打通洞的话,数据就不再经过它了。