P2P 网络库 iroh 1.0 稳定版发布:用密钥取代 IP 地址、由 Rust 编写
P2P 网络库 iroh 1.0 — 用密钥取代 IP 地址,Rust 编写
发布时间: 2026年6月16日
来源: OSCHINA / GitHub: n0-computer/iroh
Stars: 9.3k
概述
P2P 网络库 iroh 正式发布了 1.0 版本。这个由 n0 团队历时四年多、跨越 65 个版本迭代打磨的 Rust 项目,提出了一个简洁到近乎激进的口号:Dial keys, not IPs(拨号用密钥,而不是 IP 地址)。
在互联网基础设施层面,这个口号指向的是一次根本性的范式转换——将设备寻址的基本单位从网络层分配的 IP 地址,替换为由用户自主控制的加密密钥对。
一、核心技术洞察
1.1 IP 地址的问题
IP 地址是临时租约:
- DHCP 会过期
- 设备会在 Wi-Fi 和蜂窝网络之间切换
- NAT 和防火墙让网络中的设备对其他网络完全不可见
- 每次 IP 变更都意味着连接中断、重连延迟和状态丢失
1.2 公钥即地址
iroh 的核心洞察:如果一个设备自己生成一对密钥,并用公钥作为永久标识符,那么无论设备在物理上如何移动、使用什么网络接入方式,其他设备都可以通过这个公钥找到它并建立加密连接。
公钥同时承担了四重职责:
| 职责 | 说明 |
|:----:|------|
| 地址 | 唯一标识设备位置 |
| 身份 | 验证通信方身份 |
| 权限 | 控制访问权限 |
| 归属 | 确认数据所有权 |
当你拨号给一个公钥时,你知道你在和谁通信。
二、技术架构
2.1 传输层
| 特性 | 说明 |
|---|---|
| 基础协议 | QUIC over UDP + TLS 1.3 |
| 多路径 | 单连接内使用多条路由,根据网络状况热切换,不中断上层连接 |
| NAT 穿透 | 成功率约 95%(显著优于 libp2p 的约 70%) |
| 中继兜底 | DERP(Designated Relay for Encrypted Packets)中继转发 |
| 端到端加密 | 中继节点只能看到公钥标识,无法解密内容 |
2.2 NAT 穿透
- 优先尝试 hole-punching(打洞) — 直接建立 QUIC over UDP 连接
- 失败时通过 DERP 中继节点 转发,始终保持加密
- 过去 30 天内公共中继注册了 超过 2 亿个端点
- 约 95% 的数据直接在设备间传输 — 中继成本和云出口流量费用极低
2.3 非 IP 传输层支持(可插拔)
iroh 对非 IP 传输层的支持是其独特之处:
| 传输方式 | 状态 |
|---|---|
| 蓝牙 LE | ✅ 可用 |
| LoRa 长距离无线电 | 🔄 开发中 |
| WiFi Aware | 🔄 路线图中 |
| Tor 路由 | 🔄 路线图中 |
| WebAssembly(浏览器) | ✅ 可编译运行 |
在所有物理介质之上,开发者看到的始终是同一个"拨号公钥"的抽象接口——底层是什么网络无关紧要。
三、三个生产级协议
iroh 1.0 同步发布了三个生产级协议:
3.1 iroh-blobs
内容寻址的二进制传输,类似 Git 的对象存储但面向任意 P2P 场景。基于 BLAKE3 哈希实现内容寻址,支持从 KB 到 TB 级别的数据块传输。
3.2 iroh-gossip
发布-订阅覆盖网络协议。支持建立可扩展的 P2P 覆盖网络,仅需普通手机级别的资源即可运行。
3.3 iroh-docs
最终一致性键值存储。基于 CRDT(Conflict-free Replicated Data Types)实现多端同步,数据本地优先,离线可用。
四、代码示例
连接端(拨号方)
const ALPN: &[u8] = b"iroh-example/echo/0";
let endpoint = Endpoint::bind().await?;
// 通过公钥连接目标设备
let conn = endpoint.connect(addr, ALPN).await?;
// 打开 QUIC 双向流
let (mut send, mut recv) = conn.open_bi().await?;
// 发送数据
send.write_all(b"Hello, world!").await?;
send.finish()?;
// 接收回显
let response = recv.read_to_end(1000).await?;
endpoint.close().await;
接收端(监听方)
let endpoint = Endpoint::bind().await?;
let router = Router::builder(endpoint)
.accept(ALPN.to_vec(), Arc::new(Echo))
.spawn().await?;
struct Echo;
impl ProtocolHandler for Echo {
async fn accept(&self, connection: Connection) -> Result<()> {
let (mut send, mut recv) = connection.accept_bi().await?;
let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
send.finish()?;
connection.closed().await;
Ok(())
}
}
五、仓库结构
iroh 的主仓库是一个 workspace,包含多个 crate:
| Crate | 说明 |
|---|---|
iroh |
核心库:打洞 + 中继通信 |
iroh-relay |
中继客户端和服务器实现(可自建) |
iroh-base |
公共类型(EndpointId、RelayUrl 等) |
iroh-dns-server |
DNS/Pkarr 地址解析(dns.iroh.link) |
配套生态
| 项目 | 说明 |
|---|---|
| iroh-blobs | 内容寻址二进制传输 |
| iroh-gossip | 发布订阅覆盖网络 |
| iroh-docs | CRDT 键值存储 |
| iroh-ffi | 其他语言的 FFI 绑定 |
| awesome-iroh | 生态项目列表(408 Stars) |
六、与 libp2p 的对比
| 维度 | iroh | libp2p |
|---|---|---|
| 语言 | Rust(原生) | 多语言实现 |
| 传输层 | QUIC over UDP | TCP/QUIC/WebSocket |
| NAT 穿透成功率 | ~95% | ~70% |
| 非 IP 传输 | 蓝牙/LoRa/Tor 已规划 | 有限 |
| 浏览器支持 | ✅ WebAssembly | ❌ 不原生支持 |
| 中继开销 | 极低(95%直连) | 较高 |
| 许可证 | MIT / Apache 2.0 | Apache 2.0 / MIT |
| 成熟度 | 1.0 正式版 | 成熟 |
七、应用场景
- 本地优先(Local-First)应用:离线优先、多端同步的协作应用
- IoT / 边缘计算:设备间直连,无需中心服务器
- 去中心化存储:基于 iroh-blobs 构建 P2P 文件共享
- 实时通信:基于 QUIC 的低延迟音视频传输
- 混合网络:跨蓝牙/Wi-Fi/蜂窝的无缝切换
八、总结
iroh 1.0 的发布标志着 Rust P2P 生态的一个重要里程碑。其"密钥即地址"的设计哲学、极高的 NAT 穿透成功率、以及灵活的传输层抽象,为下一代去中心化网络应用提供了坚实的基础设施。