cjdns 完整安装与配置指南:构建你的加密 IPv6 网络节点
cjdns 完整安装与配置指南:构建你的加密 IPv6 网络节点
导读
本文基于 cjdns 仓库的西班牙语版官方指南(README_ES.md)及其配套配置手册 doc/configure_ES.md,完整讲解如何在 Debian、macOS、Arch、Fedora、FreeBSD 等系统上安装 cjdns、生成配置文件、与朋友节点互联(outbound/inbound 双向连接)以及启动守护进程的全过程。读完本文,你将掌握 cjdns 配置文件中每一个核心参数(密钥、授权密码、UDP/ETH 接口、路由器、IP 隧道、安全沙箱)的含义与用法,并能结合源码理解其底层工作原理。
cjdns 是什么:用公钥密码学重塑网络
cjdns 实现了一个加密的 IPv6 网络,其两大核心技术是:
- 公钥密码学(public-key cryptography)用于地址分配:每个节点的 IPv6 地址由公钥安全哈希而来,地址即身份,无需中心化分配;
- 分布式哈希表(Distributed Hash Table, DHT)用于路由:节点间通过 DHT 寻路,无需集中式目录服务。
这两项设计带来了"近乎零配置"(near-zero-configuration)的网络体验,并规避了现有互联网中大量安全与扩展性问题。正如仓库根目录的英文说明 README.md 所总结的:cjdns 的目标不是成为旧互联网之上的 overlay,而是最终取代它——每一条连接最终都应被光纤、电缆或无线链路所替代。
从源码看,IPv6 地址的生成逻辑位于 crypto/AddressCalc.c:AddressCalc_addressForPublicKey() 对 32 字节公钥连续执行两次 SHA-512 哈希,取前 16 字节作为地址,并校验其落在 cjdns 保留的 fc 前缀空间内(AddressCalc_ADDRESS_PREFIX)。因此公钥、IPv6 地址三者之间的关系是确定性的——只要给定私钥,公钥与地址必然唯一对应。
相关文档与社区资源
官方指南建议先阅读以下仓库内文档(均为英文):
- 项目目标:doc/projectGoals.md
- 技术白皮书:doc/Whitepaper.md
- 高级配置之 NAT 网关:doc/nat-gateway.md
- 高级配置之 OpenIndiana 安装:doc/open-indiana.md
- 配置详解(本文的姊妹篇):doc/configure_ES.md 与 doc/configure.md
社区方面,cjdns 的用户与开发者活跃在 IRC 的 #cjdns 频道(EFnet 网络);Hyperboria 是最大的 cjdns 互联网络,可在该网络的地图服务上查看全球节点分布;此外还有 Project Meshnet 与 /r/darknetplan 等网格网络社区。加入社区是下一步"找到你的第一个朋友节点"的最快捷途径。
安装 cjdns
官方安装说明针对 Debian 系发行版与 macOS 编写,对其他发行版"具有参考价值但不能保证照搬可用"。
0. 安装依赖
在两种主流平台上,Node.js 都是构建工具链的一部分。注意:Node.js 虽然偏好安装,但并非严格必需——如果缺失或版本不可接受,构建脚本会自动下载并安装到源码树中。
| 平台 | 命令 |
|---|---|
| Debian 系 | sudo apt-get install nodejs git build-essential python2.7 |
| Fedora 22+ | sudo dnf install install nodejs git 与 sudo dnf install @development-tools |
| RHEL(需 EPEL 仓库) | 先安装 EPEL release 包,再 sudo yum install install nodejs git 与 sudo yum install @development-tools |
| Gentoo | emerge --ask nodejs sys-devel/gcc dev-lang/python:3.4 dev-vcs/git |
| macOS (Homebrew) | brew install cjdns |
| macOS (MacPorts) | sudo port install cjdns |
| OpenBSD(实验性) | pkg_add git node gcc gmake bash(选择 gcc-4.8.1p2 或更新版本) |
| FreeBSD | pkg install gmake node(ports 已预装好全部组件) |
| Arch | pacman -S cjdns;若源码编译则 pacman -S nodejs git base-devel,或使用 AUR 包 cjdns-git |
| Solus | sudo eopkg install nodejs git build-essential system.devel python gcc binutils kernel-headers xorg-server-devel |
笔记本用户注意:如果你的设备会休眠或挂起,cjdroute 唤醒后可能需要几分钟才能感知网络变化。通过以下命令可显著加速:
systemctl enable cjdns-resume
该 resume 服务会在系统从休眠恢复时自动重启 cjdns。
Arch 用户安装后,配置文件位于 /etc/cjdroute.conf,通过 systemd 管理服务:
systemctl start cjdns
systemctl stop cjdns
1. 获取源码
克隆仓库并进入源码目录:
git clone https://gitcode.com/gh_mirrors/cj/cjdns cjdns
cd cjdns
2. 编译
./do
等待输出 Build completed successfully, type ./cjdroute to begin setup. 字样,然后继续下面的配置步骤。
构建前提说明:当前仓库的构建体系(见根目录 README.md 与 node_build/)还额外需要 Rust 工具链、GCC 或 Clang C 编译器、Make 与 Git。若构建报错,请先确认这些工具齐备。
配置 cjdns:从生成配置到启动
直接运行 cjdroute 而不带任何参数,会输出完整的帮助信息:
./cjdroute
0. 确认 TUN 设备可用
cjdns 通过 TUN 虚拟网卡接入系统,先检查 /dev/net/tun 是否存在且可用:
LANG=C cat /dev/net/tun
- 如果输出
cat: /dev/net/tun: File descriptor in bad state——很好,设备正常。 - 如果输出
cat: /dev/net/tun: No such file or directory——需要手动创建设备节点:
sudo mkdir -p /dev/net &&
sudo mknod /dev/net/tun c 10 200 &&
sudo chmod 0666 /dev/net/tun
创建完成后再次执行 cat /dev/net/tun 验证。
- 如果输出
cat: /dev/net/tun: Permission denied——你很可能运行在基于 OpenVZ 虚拟化平台的 VPS 上,需要联系服务商开启 TUN/TAP 设备(这是标准协议,服务商应当清楚你的需求)。 - macOS 用户无需关心此步骤(macOS 使用原生 utun 接口)。
1. 生成配置文件
./cjdroute --genconf >> cjdroute.conf
务必保护你的配置文件! 配置文件中保存了私钥与授权密码:
- 配置文件丢失 = 丢失你的密码与所有已建立的连接,曾经连到你的人将再也无法连接;
- 配置文件被窃取 = 攻击者可以在网络上冒充你。
更安全的生成方式,是让新文件仅对你本人可读写:
(umask 077 && ./cjdroute --genconf > cjdroute.conf)
umask 077 确保生成的文件权限为 600(仅属主可读写)。
cjdroute 命令行参数速查(依据 client/cjdroute2.c 的 usage 输出整理):
| 参数 | 作用 |
|---|---|
--help / -h |
显示帮助信息 |
--genconf [--eth] |
生成配置并输出到 stdout;加 --eth 则启用 ETH 接口的信标(注意可能干扰 UDP 信标) |
--genconf-seed [--eth] |
从 stdin 读取 64 字节种子生成确定性配置 |
--version / -v |
打印软件版本与协议版本号 |
--cleanconf < conf |
输出去除注释后的纯净 JSON 配置 |
--nobg |
无论配置如何都以前台方式运行 |
从 cjdroute2.c 的 genconf() 实现可以看出,默认生成的配置包含:4 个随机 base32 密码、一个随机选定的监听端口(循环直至大于 1024)、一对新生成的密钥(Key_gen),以及默认的 admin.bind = 127.0.0.1:11234、admin.password = "NONE"、UDP 接口信标配置(beacon: 2、beaconDevices: ["all"]、beaconPort: 64512)、DNS 种子 seed.pns.cjdns.fr 等。这些默认值会在下文逐项解释。
2. 找到一个朋友
要接入现有网络(例如 Hyperboria),你必须与一位已经接入该网络的人建立连接。这并非故作玄虚,而是出于三个实际原因:
- 防止滥用:恶意者通常不愿滥用一个在善意帮助下获得访问权的系统;
- 网络愿景:cjdns 不打算作为"旧互联网"的 overlay 层,而是意图取代它,因此每条连接最终都应被实体链路(电缆、光纤、无线)替代;
- 纠纷仲裁:任何分歧发生时,都存在一条连接相关各方的"朋友链",为解决问题提供基础。
找到朋友的方式:前往 IRC 社区(#cjdns on EFnet),或在 Hyperboria 地图上查找离你较近的节点。
3. 将你的节点连接到朋友的节点
建立 OUTbound(出站)连接——在你的配置文件中找到 connectTo 段:
// Nodes to connect to.
"connectTo":
{
// Add connection credentials here to join the network
// Ask somebody who is already connected.
}
填入多个朋友节点的示例(注意 JSON 语法、逗号分隔):
// Nodes to connect to.
"connectTo":
{
//friend_1 (IPv4: 0.1.2.3; IPv6 fcaa:5bac:66e4:713:cb00:e446:c317:fc39)
"0.1.2.3:45678":
{
"login": "k.alexander"
"password": "thisIsNotARealConnection_1",
"publicKey": "thisIsJustForAnExampleDoNotUseThisInYourConfFile_1.k"
}
//friend_2 (IPv4: 5.1.2.3; IPv6 fcbb:5bac:66e4:713:cb00:e446:c317:fc39)
"5.1.2.3:5678":
{
"login": "k.alexander"
"password": "thisIsNotARealConnection_2",
"publicKey": "thisIsJustForAnExampleDoNotUseThisInYourConfFile_2.k"
}
}
connectTo 中可以按 JSON 语法添加任意数量的连接。虽然有些人会附带 node 等额外字段,但cjdns 实际只读取 password 与 publicKey 两个字段(见 doc/configure_ES.md)。
允许朋友建立 INbound(入站)连接——在你的配置文件中找到 authorizedPasswords 段:
"authorizedPasswords":
[
// A unique string which is known to the client and server.
{"password": "password001", "login": "default-login"}
// More passwords should look like this.
// {"password": "password002", "login": "my-second-peer"}
// {"password": "password003", "login": "my-third-peer}
// {"password": "password004", "login": "my-fourth-peer"}
...
// "your.external.ip.goes.here:45678":{"login": "default-login", "password": "password001","publicKey":thisisauniqueKEY_001.k}
],
为多个朋友配置入站授权的示例:
"authorizedPasswords":
[
// A unique string which is known to the client and server.
{"password": "thisisauniquestring_001", "user": "k.alexander"}
// More passwords should look like this.
//William Jevons (IPv4: 0.1.2.3; IPv6 fcaa:5bac:66e4:713:cb00:e446:c317:fc39)
{"password": "thisisauniquestring_002", "user": "William Jevons"}
//Marilyn Patel (IPv4: 5.1.2.3; IPv6 fcbb:5bac:66e4:713:cb00:e446:c317:fc39)
{"password": "thisisauniquestring_003", "user": "Marilyn Patel"}
// {"password": "thisisauniquestring_004"}
...
// "your.external.ip.goes.here:45678":{"password": "thisisauniquestring_001","publicKey":thisisauniqueKEY_001.k}
],
你需要提供给入站连接方(例如 William Jevons)以下 5 项信息:
-
你的外部 IPv4 地址;
-
配置中
bind声明的端口号:// Bind to this port. "bind": "0.0.0.0:yourportnumberishere", -
为他解注释或新建的唯一密码:
"password": "thisisauniquestring_002"; -
你的公钥:
"publicKey": "thisisauniqueKEY_001.k"; -
他的用户名:"William Jevons"。
对方拿到的登录凭据形如(包含你的 IPv4 与端口):
"1.2.3.4:56789": {
"login": "William Jevons",
"password": "thisisauniquestring_002",
"publicKey": "thisIsJustForAnExampleDoNotUseThisInYourConfFile_1.k"
}
请确保双方都能发起连接(你→朋友 与 朋友→你 各有一方发起即可),一旦连接建立,流量即双向流动。
更多配置细节(包括如何通过以太网与 Wi-Fi 接入其他 cjdns 节点)参见 doc/configure_ES.md。
4. 加固你的系统:检查监听服务
节点运行后,你的主机便成为了一台全新的 IPv6 主机,操作系统可能会自动让网络服务绑定到这个新地址。如果这并非你的本意,请检查当前提供了哪些网络服务,避免意外暴露超过预期的服务:
详见 doc/network-services.md(英文)。
5. 启动!
sudo ./cjdroute < cjdroute.conf
如需将日志写入文件:
sudo ./cjdroute < cjdroute.conf > cjdroute.log
停止 cjdns:
sudo killall cjdroute
遇到问题时,killall cjdroute 可让你恢复平静;使用 pgrep cjdroute 或 top 可确认进程是否仍在运行。
注意:上述方式以 root 身份启动 cjdns,以便它无权限顾虑地配置系统。若要以非 root 用户运行,参见 doc/non-root-user.md(英文)。
6. 登录 IRC
欢迎加入网络!现在你是一名网络管理员了。管理员身份伴随责任——包括在设备出问题时保持可联系。请常驻 IRC 频道(#cjdns on EFnet),以便他人能找到你。
深入解读 cjdroute.conf:每个配置项的含义
下面依据 doc/configure_ES.md(其英文更新版见 doc/configure.md)逐段解读配置文件。注意:配置是带注释的 JSON——严格来说不合 JSON 规范,但 cjdns 在解析前会剥离注释,因此无需担心。
密钥与地址(文件顶部)
{
// The path to the cjdns core executable.
"corePath": "/opt/cjdns/cjdns",
// Private key:
// Your confidentiality and data integrity depend on this key, keep it secret!
"privateKey": "823e4EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEc70",
// This key corresponds to the public key and ipv6 address:
"publicKey": "u2jf87mgqlxfzdnywp60z3tx6tkulvgh2nyc2jk1zc69zzt2s8u0.k",
"ipv6": "fcff:a215:1e7b:a4e9:c00d:0813:93b3:7c87",
corePath:cjdns 核心可执行文件的路径。若源码下载在 /opt/cjdns,默认值即可;若在别处(如 home 目录),需相应修改。privateKey:私钥负责加密进出你计算机的所有数据,必须保密,不得分享。publicKey:公钥是你提供给其他计算机用于加密数据的密钥,密文只能用你的私钥解密,从而保证数据在网络传输中无人能窥视。ipv6:你在 cjdns 网络中的 IP 地址,由公钥安全哈希生成,全球唯一。
publicKey 与 ipv6 字段仅为便利而提供,并非必需。若想移除,可以删掉——启动时私钥会推导出公钥,公钥会推导出 IPv6 地址。由于三者关系是确定性的(见前文 crypto/AddressCalc.c 的双重 SHA-512 实现),只保留最根本的属性反而能避免配置不一致的错误。
入站连接(authorizedPasswords)
authorizedPasswords 段用于允许他人连接你:任何提供有效密码的系统都会被放行。
注意:这些密码应当又长又随机。不要使用短小易记的单词——这些密码仅供 cjdns 使用,没有理由设置成人类可记忆的形式。
"authorizedPasswords":
[
// A unique string which is known to the client and server.
{"password": "zxl6zgxpl4stnuybdt0xlg4tn2cdl5h", "user": "default-login"}
// More passwords should look like this.
// {"password": "10ru8br0mhk25ccpvubv0sqnl7kuc6s", "user": "my-second-peer"},
// {"password": "y68jm490dztxn3d2gvuv09bz55wqmjj", "user": "my-third-peer"},
// {"password": "bnpphnq205v8nf2ksrs1fknfr572xzc", "user": "my-fourth-peer"},
],
password:其他系统连接你的节点时出示的密码,对应地要写入对方配置的password段。user(可选第二属性):运行peerStats脚本时,使用特定密码连入的节点会被关联到对应的user字符串,便于辨识。- 凭据模板
"your.external.ip.goes.here:33808":{...}是你发给朋友的入站凭据。建议额外添加"name":"so-and-so"字段(记得字段间用逗号分隔),方便查看谁被允许接入;若日后不再希望某用户连接,只需找到对应行删除或注释即可。
源码佐证:密码的管理在运行时通过 admin API 完成,对应 admin/AuthorizedPasswords.c 注册的 AuthorizedPasswords_add、AuthorizedPasswords_remove、AuthorizedPasswords_list 三个函数——它们直接操作底层 CA(Cryptographic Authority)模块的 Ca_addUser_ipv6 与 Ca_removeUsers。
管理接口(admin)
"admin":
{
// Port to bind the admin RPC server to.
"bind": "127.0.0.1:11234",
// Password for admin RPC server.
"password": "j6mukf2khplcgpbzz0kulb8hu0xq2v9"
},
bind:管理接口绑定的 IP 与端口。你当然不希望陌生人连上管理接口,保持默认绑定本地回环地址通常是最佳选择。password:调用部分管理功能所需的密码。若要把管理接口暴露到网络上,务必使用类似示例中的强密码;若只监听本地地址,可直接使用"NONE"(这是当前默认行为,便于开箱即用)。从 cjdroute2.c 可以看出,新生成的配置默认即"bind": "127.0.0.1:11234"与"password": "NONE"。
连接接口(interfaces)
这是节点对外连接接口的配置。目前绝大多数人使用 UDPInterface 通过互联网等传统网络连接其他 cjdns 节点;也可以使用 ETHInterface 物理连接另一台机器——注意这不是你熟悉的 TCP/IP 连接。
"interfaces":
{
"UDPInterface":
[
{
// Bind to this port.
"bind": "0.0.0.0:33808",
// Nodes to connect to.
"connectTo":
{
// Add connection credentials here to join the network
// Ask somebody who is already connected.
}
}
]
/* ETHInterface 默认被注释,可按需启用 */
},
UDPInterface 各字段:
bind:cjdns 监听连接的 IP 与端口。connectTo:填写你想连接的节点凭据,格式如下。注意他人可能附加node等字段,但 cjdns 只解析password与publicKey:"12.34.56.78:12345": { "password": "thisIsAnExampleOfAPassword", "publicKey": "z4s2EXAMPLEPUBLICKEYEXAMPLEPUBLICKEYEXAMPLEKEY4yjp0.k" },- IPv6 上的 UDP 互联:较新生成的配置会在
UDPInterface段内附带第二个块,用于 IPv6 UDP 互联,形如:"[2001:db8::2:1]:12345": { "password": "thisIsAnExampleOfAPassword", "publicKey": "z4s2EXAMPLEPUBLICKEYEXAMPLEPUBLICKEYEXAMPLEKEY4yjp0.k" }, beacon:控制节点自动发现。0禁用自动互联;1仅接收其他节点 beacon 消息中的广播互联密码并自动回连;2既发送也接收 beacon(默认)。实现方式是额外绑定一个端口发送包含主数据端口的 beacon 消息。beaconDevices:参与广播的设备名列表,可包含设备名(如eth0)、广播地址(如192.168.101.255)以及伪名"all"(表示使用所有接口的广播地址)。默认["all"]。beaconPort:发送 beacon 消息的 UDP 端口,所有要自动互联的节点必须使用相同的 beaconPort(默认 64512)。
ETHInterface 各字段:
bind:ETH 接口绑定的设备名(如eth0;"all"为伪名,尝试连接所有设备)。connectTo:与 UDP 版几乎相同,只是键从"IP:端口"换成 MAC 地址,例如"01:02:03:04:05:06":{"password":"a","publicKey":"b"}。beacon:含义同 UDP 版(0/1/2)。早期版本需要手动取消注释 ETHInterface 才能使用,现在默认已启用。
路由器(router)
"router":
{
// DNS Seeds, these will be used to add peers automatically.
"dnsSeeds": [
"seed.pns.cjdns.fr"
],
"publicPeer": {
// "id": "PUB_XXX",
// "ipv4": "1.2.3.4:56789",
// "ipv6": "[1234:5678::]:9012",
},
"supernodes": [
//"6743gf5tw80ExampleExampleExampleExamplevlyb23zfnuzv0.k",
],
"interface":
{
// The type of interface (only TUNInterface is supported for now)
"type": "TUNInterface"
//"tunDevice": "tun0"
},
},
dnsSeeds:配置后 cjdns 会对这些域名做 DNS TXT 记录查询以获取自动互联的节点与 supernode(首个种子被信任用于提供 snode)。不配置则必须手动添加节点。publicPeer:id:指定后 cjdns 会创建一个"公开"的 AuthorizedPassword,探测自身公网 IP,并把地址与密码上报给 supernode。约定俗成,以PUB_开头的 peerID 会被公开共享,否则仅被 snode 测试而不共享。不设置id则互联凭据完全私有。ipv4/ipv6:指定后覆盖自动探测的公网地址。取值规则:"x.x.x.x"用 IP 探测端口;"0.0.0.0:xxx"用端口探测 IP;"x.x.x.x:xxx"两者都用。
supernodes:强制指定 supernode;未指定则从 DNS 种子或你的节点处学习。interface:type:cjdns 接入网络的接口类型,目前仅支持TUNInterface。tunDevice:指定使用的 TUN 设备名,用于以独立用户身份启动 cjdroute,大多数用户不需要。
配置中还存在一个备选的 _disabled_interface("type": "SocketInterface",socket 路径默认 /var/run/cjdns.sock):若想用 UNIX socket 替代 TUN 设备收发数据包,可把上面的 TUN 接口改名为 _disabled_interface,再把这个接口改名为 interface 即可。
IP 隧道(ipTunnel)
IP 隧道允许你从 cjdns 网络连接到外部网络。该功能仍在完善中,但已可用——只是两端都需要一定手工配置才能发挥价值。
"ipTunnel":
{
"allowedConnections":
[
// {
// "publicKey": "f64hfl7c4uxt6krmhPutTheRealAddressOfANodeHere7kfm5m0.k",
// "ip4Address": "192.168.1.24",
// "ip4Prefix": 24,
// "ip6Address": "2001:123:ab::10",
// "ip6Prefix": 0
// },
],
"outgoingConnections":
[
// "6743gf5tw80ExampleExampleExampleExamplevlyb23zfnuzv0.k",
]
}
allowedConnections:允许连到我们节点的公钥清单,以及将分配给它们的 IP 地址与前缀长度。outgoingConnections:要连接的 cjdns VPN 出口节点公钥清单。
参数补充说明(依据 doc/configure.md 中的注释):
ip4Prefix/ip6Prefix:从 tun 侧可达的地址集合前缀长度。例如向公司内网(10.123.45.0/24)广告 VPN,则ip4Prefix应为 24。默认 IPv4 为 32、IPv6 为 128,即默认不安装路由。ip4Alloc/ip6Alloc:分配给客户端的地址块大小。例如要给客户端发 4 个地址(192.168.123.0~192.168.123.3),设置ip4Alloc为 30。默认 IPv4 为 32、IPv6 为 128(1 个地址)。- 也可以只指定一个地址,
prefix/alloc均可省略。
杂项与安全(security)
"security":
[
// Set number of open files to zero...
"nofiles",
// Change the user id to this user after starting up and getting resources.
{"setuser": "nobody"}
],
}
新版默认生成的安全配置更为精细(见 cjdroute2.c 的生成逻辑,非 macOS/Android 平台):
"security": [
{ "setuser": "nobody", "keepNetAdmin": 1 },
{ "chroot": "/var/run/" },
{ "nofiles": 0 },
{ "noforks": 1 },
{ "setupComplete": 1 }
],
各项含义:
setuser:启动并获取资源后切换用户,将 cjdns 进程沙箱化。keepNetAdmin: 1保留网络管理权限,使 IPTunnel 能设置 IP 地址、ETHInterface 能热添加接口;设为 0 则禁用这些能力。Android/macOS 默认{ "setuser": 0 }禁用。chroot:改变 cjdns 可见的文件系统根目录,将其封锁在沙箱内;用户无 chroot 权限时会静默失败。默认使用/var/run/,Android 默认禁用。nofiles(已弃用):阻止 cjdns 打开任何文件,会同时阻止设置 IP 与热添加 ETH 设备;不需要这些功能时可提供强力沙箱。默认禁用。noforks:阻止 cjdns 派生新进程或线程,防止大量漏洞攻击整个系统。默认启用。setupComplete:客户端通过一系列 RPC 调用完成核心配置后,向核心确认"安全规则已全部应用",核心方可运行;缺失时核心会在几秒内以退出码 232 退出。默认启用。
其他杂项配置(同样由 genconf 默认生成):
logging:默认通过 admin socket 提供日志;取消注释"logTo": "stdout"可改为输出到 stdout。noBackground:非零则 cjdns 不 fork 到后台,推荐与logTo: stdout配合使用。pipe:admin 控制管道路径,默认cjdroute.sock(Unix 下落在 /tmp/,Windows 下在\\.\pipe\)。version:设为 2 表示以严格模式解析配置,便于外部工具(如 cjdnsconf)编辑。
管理接口(Admin API)
cjdroute 启动运行后,管理接口位于 udp://localhost:11234(可在 cjdroute.conf 的 admin.bind 中修改)。更多接口信息见 doc/admin-api.md(英文)。仓库 contrib/ 目录下有多种可与该接口交互的工具,包括:
- Python 库:contrib/python/README.md
- Perl 库(由 Mikey 维护):contrib/perl/CJDNS/README
仓库根目录还自带 ./cjdnstool 可直接访问管理 API;tools/ 下的 cexec、cjdnslog、peerStats、sessionStats 等脚本也基于该接口工作。从 cjdroute2.c 可见,cjdroute 客户端启动时会先用管理接口对 admin.bind 地址执行 ping,以检测是否已有实例在运行。
报告问题与安全通告
报告问题的流程(原文摘录自 README_ES.md):
- 不要在仓库的 issue 区报告,请前往 hyperboria/bugs 项目提交;
- 上 IRC 与社区成员交流;
- 事情可能的走向:
- 有人愿意修复它;
- 你自己愿意修复它;
- 没人关心,它被遗忘一段时间,之后可能有人遇到并修复,或在一轮重构中被抹去;
- 暂时无人能修,但它对代码发展意义重大而被铭记,需要熟悉代码的人用技术语言记录,并向本仓库的 doc/bugs/ 目录提交 pull request。
安全问题:安全缺陷与普通 bug 一样在 IRC 上报。cjdns 没有封闭的"专家圈",因此默认的安全报告方式是完整披露(full disclosure)。在提交前,请先查阅 doc/security_specification.md(英文)确认一个疑似安全问题是否真的是安全问题——该文档定义了 cjdns 的安全模型与威胁边界。
小结
至此,你已完成从"安装依赖 → 编译 → 生成配置 → 建立双向互联 → 启动守护进程 → 接入管理接口"的完整闭环。回顾整个流程:./cjdroute --genconf 生成带注释的 JSON 配置,authorizedPasswords 决定谁能连你,connectTo 决定你连谁,interfaces 决定承载介质(UDP/ETH),router 与 ipTunnel 决定路由与 VPN 出口,security 段则把进程牢牢关进沙箱。如果希望进一步掌握每个配置项的底层实现,推荐继续阅读 doc/configure_ES.md 与 doc/configure.md,并对照源码 client/cjdroute2.c、admin/AuthorizedPasswords.c 与 crypto/AddressCalc.c 加深理解。