工作原理

你不需要理解这些也能用 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 ago
  • direct 表示两台机器之间是点对点,中间的运营商、云厂商、中继都看不到内容也看不到流量形态。
  • 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 把这件事变成"加入一张网":服务器负责让机器互相知道、负责打洞、负责在打不通时提供中继,你只需要描述策略