kin · rendezvous + directory
会合与目录服务
它做两件事:让两个都在 NAT 后面的朋友互相知道对方当前的外部地址; 以及让你能按对方的 ID 找到他、给他发一条好友请求。 之后它就无事可做了 —— 隧道是两台设备之间直接建立的,一个字节都不经过这里。
为什么需要它
kin 是朋友之间互相提供网络出口的 VPN。要让两台设备直接相连,双方必须 同时 知道对方此刻的外部地址,才能同时朝对方发包、把 NAT 上的洞打开。
麻烦在于:双方都在 NAT 后面,谁也不可达 —— 没有人能把这个地址直接递给对方。 所以需要一个在公网上的、双方都能连上的撮合方,把两张名片放进同一个抽屉里。 这就是这个服务,也仅此而已。
按 ID 找人
原来加朋友要复制一串 200 字符的邀请码。现在还有一条路:你可以把自己登记进来
—— 一个公钥指纹、一把公钥、一个显示名 —— 对方知道你的指纹
(形如 4F0J-3Q4Y-NC8H-QBPQ-0SGG)就能查到你,并发来一条好友请求。
只能按指纹精确查。没有按名字搜索,没有列出所有人。 这不是还没做,是故意不做:指纹是 100 bit,不可枚举,所以 ID 本身就是凭据 —— 像电话号码,没有号码就找不到人,也翻不出号码簿。
好友请求带一个 MAC,是发送方用「自己的私钥 + 你的公钥」算出来的。 这个服务验证不了它(它没有任何人的私钥),验证在你自己的设备上做 —— 所以它也没有能力伪造一条「某人想加你」。
代价要说清楚:用了目录,这个服务就知道了「谁存在、谁的显示名、谁在找谁」, 这是纯邀请码方案没有的元数据。所以登记是可选的、24 小时就过期、 随时可以删掉;邀请码那条路也一直留着,给最在意的人。 它也不认识任何人 —— 知道你指纹的人能看到发给你的好友请求, 所以那里只放「谁想加你」这种东西。真正要紧的那道门在隧道上: 没有你亲手批准的公钥,谁也进不来。
它看得到什么,看不到什么
✓ 它看得到
- 一个随机的一次性
token(配对码里带的,不含任何身份信息) - 一个公钥指纹和一个 base64 公钥
- 最多 16 个
ip:port候选地址 - 一个你自己填的显示名,比如「哥哥的台式机」
- 如果你登记了目录:你的指纹、公钥、显示名,和谁在查谁
- 发给你的好友请求:对方的指纹、公钥、显示名和一句留言
✕ 它看不到
- 你的流量内容 —— 它不在数据路径上
- 你访问了什么网站、流量去了哪里
- 你是谁:没有账号、没有注册、没有用户表
- 这次握手最后成没成 —— 打洞是两端之间的事
它不留什么
会合记录的 TTL 是 300 秒,到点自己消失 —— 会合是短暂的,不该留痕。 目录登记 24 小时(停了就自动消失,所以它永远不会留着你早已不用的 那台机器),好友请求 7 天(够对方开机看一眼),处理完立刻删除。
它不记录客户端 IP,不写访问日志,没有分析脚本 —— 这一页连 JavaScript 都没有。 服务端的全部状态就是一个 KV namespace:没有数据库,没有队列,没有一个 secret, 因为它不需要知道任何需要保密的东西。
它也不能偷偷变成中继:这个服务只收发几条短 JSON, 不具备转发 UDP 的能力。流量要么直连,要么根本不通。
接口
就这些。超额或畸形的输入一律拒绝。
POST /api/rv
→ {"token":"…","endpoint":{"peer_id":…,"pub_key":…,
"candidates":["203.0.113.7:51820"],"name":…}}
← 200 {"ok":true}
GET /api/rv?token=…&self=…
← 200 {"ready":true,"endpoint":{…}} // 该 token 下不是你自己的那条
← 200 {"ready":false} // 对端还没来,等一会儿再问
POST /api/dir {"record":{…}} // 登记,24 小时后过期
DELETE /api/dir?fp=… // 注销
GET /api/dir?fp=… → {"record":{…}} / 404 // 按指纹精确查,没有别的查法
POST /api/req {"to_fp":…,"request":{…}} // 发一条好友请求,7 天后过期
GET /api/req?fp=… → {"requests":[…]} // 收件箱,每人最多 32 条
POST /api/req/ack {"fp":…,"id":…} // 处理完就删
自己跑一个
这个服务是开源的,也刻意做得很小 —— 小到你可以读完全部代码,
然后部署成你自己的那一个:只需要一个 Cloudflare 账号和一条
wrangler pages deploy。
不用相信别人的会合服务,是这件事里最重要的一部分。