本教程展示了如何使用 libp2p 的打孔机制来克服防火墙和 NAT。在我们开始之前,请阅读博文以熟悉 libp2p 在概念层面上的打孔机制。
我们将使用电路中继 v2和通过中继直接连接升级 (DCUtR)协议。
本教程需要 3 台机器:
-
中继服务器:
- 任何公共服务器都可以,例如云提供商 VM。
-
监听客户端:
- 任何连接到互联网但无法从其自身网络外部访问的计算机都可以工作。
- 例如,这可以是您的朋友在他们的路由器后面的笔记本电脑(防火墙 + NAT)。
- 例如,这可以是某个云提供商 VM,屏蔽传入连接,例如通过同一台机器上的 Linux UFW。
- 不要使用与拨号客户端在同一网络中的机器。(这需要 NAT 发夹。)
-
拨号客户端:
- 像上面一样,任何连接到互联网但无法从外部访问的计算机。
- 您的本地机器可能会满足这些要求。
一. 设置中继服务器
打孔需要一个公共中继节点供两个私有节点协调它们的打孔。为此,我们需要一个位于 Internet 某处的公共服务器。如果您还没有,任何云提供商 VM 都可以。
直接在服务器上,或在本地计算机上,编译示例中继服务器:
# Inside the rust-libp2p repository.
cargo build --example relay_v2 -p libp2p-relay
您可以在target/debug/examples/relay_v2. 如果您在本地构建它,请将其复制到您的服务器。
在您的服务器上,启动中继服务器二进制文件:
./relay_v2 --port 4001 --secret-key-seed 0
现在让我们确保服务器是公开的,换句话说,让我们确保可以通过 Internet 访问它。$RELAY_SERVER_IP首先,要么在以下命令中手动替换,要么在日常客户端和侦听客户端中export RELAY_SERVER_IP=ipaddr使用适当的中继服务器。ipaddr
现在,从拨号客户端:
- 测试您是否可以在第 3 层 (IP) 上连接。
ping $RELAY_SERVER_IP
- 测试您是否可以在第 4 层 (TCP) 上连接。
telnet $RELAY_SERVER_IP 4001
- 测试您是否可以通过 libp2p 使用libp2p-lookup.
# For IPv4
libp2p-lookup direct --address /ip4/$RELAY_SERVER_IP/tcp/4001
# For IPv6
libp2p-lookup direct --address /ip6/$RELAY_SERVER_IP/tcp/4001
libp2p-lookup 输出应类似于:
$ libp2p-lookup direct --address /ip4/111.11.111.111/tcp/4001
Lookup for peer with id PeerId("12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN") succeeded.
Protocol version: "/TODO/0.0.1"
Agent version: "rust-libp2p/0.36.0"
Observed address: "/ip4/22.222.222.222/tcp/39212"
Listen addresses:
- "/ip4/127.0.0.1/tcp/4001"
- "/ip4/111.11.111.111/tcp/4001"
- "/ip4/10.48.0.5/tcp/4001"
- "/ip4/10.124.0.2/tcp/4001"
Protocols:
- "/libp2p/circuit/relay/0.2.0/hop"
- "/ipfs/ping/1.0.0"
- "/ipfs/id/1.0.0"
- "/ipfs/id/push/1.0.0"
二. 设置监听客户端
直接在侦听客户端计算机上,或在本地计算机上,编译示例 DCUtR 客户端:
# Inside the rust-libp2p repository.
cargo build --example client -p libp2p-dcutr
您可以在target/debug/examples/client. 如果您在本地构建它,请将其复制到您的侦听客户端计算机。
在监听客户端机器上:
RUST_LOG=info ./client --secret-key-seed 1 --mode listen --relay-address /ip4/$RELAY_SERVER_IP/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN
[2022-05-11T10:38:52Z INFO client] Local peer id: PeerId("XXX")
[2022-05-11T10:38:52Z INFO client] Listening on "/ip4/127.0.0.1/tcp/44703"
[2022-05-11T10:38:52Z INFO client] Listening on "/ip4/XXX/tcp/44703"
[2022-05-11T10:38:54Z INFO client] Relay told us our public address: "/ip4/XXX/tcp/53160"
[2022-05-11T10:38:54Z INFO client] Told relay its public address.
[2022-05-11T10:38:54Z INFO client] Relay accepted our reservation request.
[2022-05-11T10:38:54Z INFO client] Listening on "/ip4/$RELAY_SERVER_IP/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p-circuit/p2p/XXX"
现在让我们确保监听客户端不是公开的,换句话说,让我们确保无法通过 Internet 直接访问它。从您无法在第 4 层 (TCP) 上连接的拨号客户端测试:
telnet $LISTENING_CLIENT_IP_OBSERVED_BY_RELAY 53160
三. 从拨号客户端连接到监听客户端
RUST_LOG=info ./client --secret-key-seed 2 --mode dial --relay-address /ip4/$RELAY_SERVER_IP/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN --remote-peer-id 12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X
您应该会看到以下日志出现:
拨号客户端通过中继服务器与监听客户端建立中继连接。请注意. /p2p-circuit_Multiaddr
[2022-01-30T12:54:10Z INFO client] Established connection to PeerId("12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X") via Dialer { address: "/ip4/$RELAY_PEER_ID/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p-circuit/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X", role_override: Dialer }
侦听客户端为新的中继连接启动直接连接升级。dcutr通过 报告Event::RemoteInitiatedDirectConnectionUpgrade。
[2022-01-30T12:54:11Z INFO client] RemoteInitiatedDirectConnectionUpgrade { remote_peer_id: PeerId("12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X"), remote_relayed_addr: "/ip4/$RELAY_PEER_ID/tcp/4001/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN/p2p-circuit/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X" }
直接连接升级,也称为打孔,成功。dcutr通过 报告 Event::RemoteInitiatedDirectConnectionUpgrade。
[2022-01-30T12:54:11Z INFO client] DirectConnectionUpgradeSucceeded { remote_peer_id: PeerId("12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X") }