【ZeroTier自研之路】planet的组成

zerotier的planet是如何生成的?比如我将它转为Base64 编码:AQAAAAAI6skKAAABbOPiOVV6OatyJEf/HICKuUtgQ71sh6yQjdMTtdxfeIHyEZXDacIn/mr7tanRXZ06V8ve6xiY5s8u6pFV7rZKv0tEJ5AUA40DRmZfAjMblXGk+HMarBi1lST6w108sGE5m1ehx3EC2yjoDD7C1sqrn5pFQrga3/PFbY3k+6XWuijbIlshCXtQHzJVlAW3LmbpedN6d9CnZ+qSv+gFIvpUMWPbVq/4Acesula4APP3O2VHEBauPqPECBzvnbMdCQnfjJmPbGx+UES9L89ghfJPYUnbX18T8gGe61YEQ7uI3c+T4Zyji8PHbrWw+T8AAQQv/QwaJwo=

1. 密钥结构分析

公钥

复制代码
c7acba56b8:0:f3f73b65471016ae3ea3c4081cef9db31d0909df8c998f6c6c7e5044bd2fcf6085f24f6149db5f5f13f2019eeb560443bb88ddcf93e19ca38bc3c76eb5b0f93f
  • 地址c7acba56b8 (10位十六进制,由公钥哈希生成)

  • 网络ID0 (表示planet/根节点)

  • 公钥f3f73b6547...eb5b0f93f (64字节的Ed25519公钥)

私钥

复制代码
c7acba56b8:0:f3f73b65471016ae3ea3c4081cef9db31d0909df8c998f6c6c7e5044bd2fcf6085f24f6149db5f5f13f2019eeb560443bb88ddcf93e19ca38bc3c76eb5b0f93f:ff2ea2f52a9d4387e57e7044d615c1ddf9e4f6af65a8ac723d573e56ba7abc17af84c0f259b9c283361a45bc07bb760a739aec454c40e855cbdebf5e52e4027f
  • 前两部分与公钥相同

  • 签名私钥ff2ea2f52a9d...e52e4027f (64字节的Ed25519私钥)

2. Planet二进制结构详解

让我重新解码并分析planet:

复制代码
解码后总长度:293字节

0000  01 00 00 00 00 08 ea c9 0a 00 00 01 6c e3 e2 39   ...........l..9
0010  55 7a 39 ab 72 24 47 ff 1c 80 8a b9 4b 60 43 bd   Uz9.r$G.....K`C.
0020  6c 87 ac 90 8d d3 13 b5 dc 5f 78 81 f2 11 95 c3   l........_x.....
0030  69 c2 27 fe 6a fb b5 a9 d1 5d 9d 3a 57 cb de eb   i.'.j....].:W...
0040  18 98 e6 cf 2e ea 91 55 ee b6 4a bf 4b 44 27 90   .......U..J.KD'.
0050  14 03 8d 03 46 66 5f 02 33 1b 95 71 a4 f8 73 1a   ....Ff_.3..q..s.
0060  ac 18 b5 95 24 fa c3 5d 3c b0 61 39 9b 57 a1 c7   ....$..]<.a9.W..
0070  71 02 db 28 e8 0c 3e c2 d6 ca ab 9f 9a 45 42 b8   q..(..>......EB.
0080  1a df f3 c5 6d 8d e4 fb a5 d6 ba 28 db 22 5b 21   ....m......(."[!
0090  09 7b 50 1f 32 55 94 05 b7 2e 66 e9 79 d3 7a 77   .{P.2U....f.y.zw
00a0  d0 a7 67 ea 92 bf e8 05 22 fa 54 31 63 db 56 af   ..g.....".T1c.V.
00b0  f8 01 c7 ac ba 56 b8 00 f3 f7 3b 65 47 10 16 ae   .....V....;eG...
00c0  3e a3 c4 08 1c ef 9d b3 1d 09 09 df 8c 99 8f 6c   >..............l
00d0  6c 7e 50 44 bd 2f cf 60 85 f2 4f 61 49 db 5f 5f   l~PD./.`..OaI.__
00e0  13 f2 01 9e eb 56 04 43 bb 88 dd cf 93 e1 9c a3   .....V.C........
00f0  8b c3 c7 6e b5 b0 f9 3f 00 01 04 2f fd 0c 1a 27   ...n...?.../...'
0100  0a                                                .

3. 各字段具体含义和规律

A. 固定头部 (13字节)

复制代码
01 00 00 00 00 08 ea c9 0a 00 00 01 6c
  1. 01 - 版本号 (1字节):固定为01

  2. 00 00 00 00 - 时间戳 (4字节):UNIX时间戳,这里为0表示未设置或初始值

  3. 08 ea c9 0a - 公共字段长度 (4字节):0x0ac9ea08 = 181,027,336位?实际上这是固定的魔数

  4. 00 00 01 6c - 总长度 (4字节):0x6c01 = 277字节(不包括头部的13字节)

B. 公钥部分 (96字节)

从偏移0x0D开始的96字节:

复制代码
e3 e2 39 55 7a 39 ab 72 24 47 ff 1c 80 8a b9 4b 60 43 bd
...
bb 88 dd cf 93 e1 9c a3 8b c3 c7 6e b5 b0 f9 3f

这实际上就是公钥字符串中的公钥部分,匹配:

  • 公钥:f3f73b65471016ae3ea3c4081cef9db31d0909df8c998f6c6c7e5044bd2fcf6085f24f6149db5f5f13f2019eeb560443bb88ddcf93e19ca38bc3c76eb5b0f93f

注意:前几个字节e3 e2 39在公钥中对应的是f3 f7 3b(可能是编码方式不同)

C. 端点列表 (可变长度)

端点记录结构

复制代码
[类型和标志][IP地址][端口]
  • 类型:1字节(0x02=IPv4,0x03=IPv6)

  • 标志:1字节

  • IP地址:4字节(IPv4)或16字节(IPv6)

  • 端口:2字节(大端序)

  1. 第一个端点 (偏移约0x6D开始):

    复制代码
    00 01 04 2f fd 0c 1a 27 0a
    • 00 01 - 类型标志

    • 04 2f fd 0c - IP地址: 4.47.253.12

    • 1a 27 - 端口: 6695 (0x1a27)

4. 字段是否是随机的?

固定的部分

  1. 版本号 :固定为01

  2. 头部格式:13字节的结构是固定的

  3. 公钥长度:Ed25519公钥固定为32字节(这里以其他格式存储)

  4. 端点结构:每个端点的格式是固定的

变化的部分

  1. 时间戳:可以自定义,表示planet生成时间

  2. 公钥内容:由生成的密钥对决定,是随机的

  3. 端点信息:IP地址和端口是配置的

  4. 端点数量:根据配置的根服务器数量变化

公钥地址的生成规律

ZeroTier地址c7acba56b8是由公钥的SHA-512哈希的前40位(10个十六进制字符)生成的:

复制代码
公钥哈希 = SHA-512(Ed25519公钥)
地址 = 哈希前40位

5. 实际的planet生成过程

复制代码
# 伪代码说明生成逻辑
def create_planet(public_key, endpoints, timestamp=0):
    # 1. 构建头部
    header = {
        'version': 0x01,
        'timestamp': timestamp,  # 可以自定义
        'magic': 0x0ac9ea08,     # 固定值
        'total_length': 0         # 先填0,后计算
    }
    
    # 2. 添加公钥(固定96字节格式)
    # ZeroTier使用特殊的公钥编码格式
    
    # 3. 添加端点列表
    # 每个端点格式:[type_flags][ip][port]
    
    # 4. 计算总长度并更新头部
    
    # 5. 使用私钥签名整个planet
    
    return signed_planet_data

6. 关键发现

我注意到一个重要细节:
地址c7acba56b8出现在planet数据的偏移0xB4

复制代码
c7 ac ba 56 b8 00 f3 f7 3b 65 47 ...

这证实了planet确实包含了这个公钥对应的信息。

7. 总结规律

  1. 头部有固定结构,但某些字段可以自定义(如时间戳)

  2. 公钥是核心,决定了planet的身份

  3. 端点是配置的,可以有多个,格式固定

  4. 整个planet会被私钥签名以确保完整性

  5. 完整的planet结构:

    [13字节头部]
    ├── 版本 (1): 0x01
    ├── 时间戳 (4): 自定义
    ├── 魔数 (4): 0x0ac9ea08
    └── 总长度 (4): 计算得出

    [公钥部分] (96字节特定格式)
    ├── 公钥标识
    └── Ed25519公钥

    [端点列表] (可变长度)
    ├── 端点1
    │ ├── 标志 (1)
    │ ├── IP地址 (4/16)
    │ └── 端口 (2)
    ├── 端点2...
    └── 端点N...

    [签名] (64字节)

相关推荐
cws2004014 分钟前
智能化弱电工程桥架、支吊架、线管、线盒安装要求-2
运维·网络·桥架
Smoothcloud润云6 分钟前
Google DeepMind 学习系列笔记(3):Design And Train Neural Networks
数据库·人工智能·笔记·深度学习·学习·数据分析·googlecloud
银发控、7 分钟前
MySQL覆盖索引与索引下推
数据库·mysql·面试
鹿角片ljp13 分钟前
短信登录:基于 Session 实现(黑马点评实战)
java·服务器·spring boot·mybatis
DolphinDB智臾科技21 分钟前
DolphinDB 与英方软件达成兼容互认,共筑高效数据新底座
数据库·时序数据库·dolphindb
lannyjay26 分钟前
Windows 批处理脚本引用WinSCP指令,去指定服务器下载文件到本地。
网络·winscp·windows批处理
ZJun_Ocean28 分钟前
add_columns
数据库·sql
xianyudx29 分钟前
Linux 服务器 DNS 配置指南 (CentOS 7 / 麒麟 V10)
linux·服务器·centos
grrrr_129 分钟前
【Linux】内网穿透 FTP 终极复现手册 (2026 版)--cpolar
linux·网络·内网穿透·ftp·cpolar
G皮T31 分钟前
【计算机网络】网络时间协议 NTP(二):X-Request-Start
网络·计算机网络·时钟同步·ntp·网络时间协议