P2P 网络库 iroh 1.0 稳定版发布:用密钥取代 IP 地址、由 Rust 编写

P2P 网络库 iroh 1.0 — 用密钥取代 IP 地址,Rust 编写

发布时间: 2026年6月16日
来源: OSCHINA / GitHub: n0-computer/iroh
Stars: 9.3k

iroh P2P 网络栈架构图

概述

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 穿透成功率、以及灵活的传输层抽象,为下一代去中心化网络应用提供了坚实的基础设施。

苏ICP备19018690号-1