工作原理
你不需要理解这些也能用 Celium。但知道下面这四件事,很多"为什么它这样工作"的疑问会自然消失。
一、每台机器有自己的身份,而且对端能离线验证#
每台设备有一把长期机器密钥,每次启动生成一把临时节点密钥(这就是 WireGuard 的密钥)。协调服务器为节点密钥签名,形成一张"节点证书"。
于是当两台机器建立连接时,不需要回头问服务器"这个公钥真的是那台机器吗":签名随网络地图一起下发,对端自己就能验证。这样做有两个直接好处:服务器短暂不可用不影响已经建立的连接;被攻破的服务器也无法把某个公钥伪造成另一台机器。
二、先尝试直连,打不通才走中继#
两台机器 ──► 各自探测自己在 NAT 后面的公网地址
──► 通过发现协议互相告知,并同时"开洞"
──► 直连成功后,流量不再经过任何第三方
──► 网络变化导致直连失效时,自动回退到中继,链路不中断在 celium status 里,PATH 列显示的就是当前实际在用的路径:
NAME OS ADDRESS PATH RELAY LAST-HANDSHAKE
db-1 linux 100.64.0.12 direct - 12s ago
edge-3 linux 100.64.0.13 relay hkg 3s agodirect表示两台机器之间是点对点,中间的运营商、云厂商、中继都看不到内容也看不到流量形态。relay表示当前的网络条件下无法直连(常见于双方都在严格 NAT 后面)。中继只转发密文,
它知道自己转发了多少字节,却无法知道里面是什么协议、什么内容。
第一次连接某台对端时可能先走中继,几百毫秒到几秒之后打洞成功会自动切到直连——这是正常的,不需要干预。
三、名字是内网域名,不是 hosts 文件#
每台机器在网内获得一个名字,形如 web-1.vpn.example.com,短名 web-1 在网内唯一时可以直接用:
bash
ssh web-1 # 不需要知道它的虚拟 IP
curl http://db-1:5432解析由节点自己完成(内网域名不会、也不应该被发到公共 DNS 服务器去问)。在 TUN 模式下,节点会接管宿主机的解析配置;在用户态模式下,解析在进程内完成,供本地代理使用。
四、策略在执行点生效,默认拒绝#
谁能访问谁的哪个端口,用一份 JSON 描述,由协调服务器编译成规则下发到每台机器上,由机器自己在数据包路径上执行:
- 默认拒绝:没有写明放行的流量不放行。
- 双方各自执行:既是"你能连我",也是"我能连你"。
- 即时生效:改策略不需要重启任何服务。
详见访问策略。
控制面看得到什么,看不到什么#
| 协调服务器知道 | 协调服务器不知道 | |
|---|---|---|
| 身份 | 设备公钥、节点公钥、主机名 | 任何私钥 |
| 网络 | 虚拟地址、候选端点、中继拓扑 | 实际的通信内容 |
| 策略 | 谁被允许访问谁 | 谁实际访问了谁(除非你开启审计) |
| 流量 | 无 | 全部 |
一句话:它决定谁能进这张网,但它读不到网里的任何东西。中继同理——它转发密文,看不到明文。
这与"用 WireGuard 搭一个 VPN"有什么不同#
手工 WireGuard 需要你维护一张全网状的对端表:每加一台机器,所有机器的配置都要改一遍,而且NAT 后面的机器根本连不上。Celium 把这件事变成"加入一张网":服务器负责让机器互相知道、负责打洞、负责在打不通时提供中继,你只需要描述策略。