Files
2024-06-02 00:34:12 +08:00

147 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# N4
N4 是针对双方均为 “端口递增型 NAT” 的一种打洞测试工具。
> “端口递增型 NAT” 不限制 NAT 种类。
> 也就是说,即使双方均为对称型 NAT(NAT4 - NAT4),只要满足端口递增,也可使用此工具成功打通。
## 快速开始
公网服务器运行:
```bash
python3 n4.py -s
```
需要打洞的两个 NAT4 客户端运行:
```bash
python3 n4.py -c -h 服务器IP
```
客户端日志显示:
```
[2024-06-01 12:38:56,438] INFO [n4.py:375] ==================
[2024-06-01 12:38:56,439] INFO [n4.py:376] Source port: 30000-30025
[2024-06-01 12:38:56,459] INFO [n4.py:287] <= Hello
[2024-06-01 12:38:56,471] INFO [n4.py:293] => Ready
[2024-06-01 12:38:56,472] INFO [n4.py:302] <= Exchange
[2024-06-01 12:38:56,486] INFO [n4.py:312] => Peer: 203.0.113.12:5793
[2024-06-01 12:38:56,486] INFO [n4.py:313] [ Target: 203.0.113.12:5813 ]
[2024-06-01 12:38:56,487] INFO [n4.py:321] <= Punch
[2024-06-01 12:39:06,498] INFO [n4.py:386] [ LOSE ]
[2024-06-01 12:39:06,500] INFO [n4.py:375] ==================
[2024-06-01 12:39:06,500] INFO [n4.py:376] Source port: 30025-30050
[2024-06-01 12:39:06,514] INFO [n4.py:287] <= Hello
[2024-06-01 12:39:06,526] INFO [n4.py:293] => Ready
[2024-06-01 12:39:06,527] INFO [n4.py:302] <= Exchange
[2024-06-01 12:39:06,541] INFO [n4.py:312] => Peer: 203.0.113.12:5434
[2024-06-01 12:39:06,541] INFO [n4.py:313] [ Target: 203.0.113.12:5454 ]
[2024-06-01 12:39:06,542] INFO [n4.py:321] <= Punch
[2024-06-01 12:39:06,556] INFO [n4.py:334] => Punch from peer
[2024-06-01 12:39:08,559] INFO [n4.py:342] <= Punch
[2024-06-01 12:39:08,560] INFO [n4.py:379] ------
[2024-06-01 12:39:08,560] INFO [n4.py:380] Local port: 30040
[2024-06-01 12:39:08,560] INFO [n4.py:381] Peer address: 203.0.113.12:5454
[2024-06-01 12:39:08,560] INFO [n4.py:382] ------
[2024-06-01 12:39:08,560] INFO [n4.py:383] [ WIN ]
[2024-06-01 12:39:08,560] INFO [n4.py:385] > nc -u -p 30040 203.0.113.12 5454
```
日志出现 `[ WIN ]` 字样,表示两者打通。
双方运行日志中提示的 `nc` 命令,即可互相进行 P2P 通信。
## 打洞过程
服务端监听 `TCP/1721``UDP/1721`
- TCP 端口用于与客户端通信;
- UDP 端口仅用于获取客户端公网上的IP、端口信息,只接收不发送。
打洞过程共有 5 步:
```
1. Hello client --TCP-> server
2. Ready client <-TCP-- server
3. Exchange client --UDP-> server
4. Peerinfo client <-TCP-- server
5. Punch client <-UDP-> client
```
解释说明:
1. 客户端向服务端发送 Hello 包;
2. 服务端收到两个客户端的 Hello 包后,同时向两方发送 Ready 包;
3. 客户端收到 Ready 包,使用 UDP 向服务器发送 Exchange 包,表示交换两客户端 UDP 公网信息;
4. 服务端收到一客户端的 Exchange 包,向另一客户端发送 Peerinfo 包,携带前者 UDP 公网信息;
5. 客户端收到 Peerinfo 包,根据对方地址 `IP:PORT`
预测对方将来的地址会有 `IP:PORT + peer_port_offset`
客户端从自身端口 `src_port_start` ~ `src_port_start + src_port_count` 范围,
使用 UDP 逐一向 `IP:PORT + peer_port_offset` 固定地址发送 Punch 包。
如果客户端收到 Punch 包,代表打通。否则,增加源端口值,再次尝试。
## 示例说明
下面是一个示例,假设有以下设定值。
```
src_port_start = 30000
src_port_count = 8
peer_port_offset = 5
```
括号内为 NAT 转换后的地址。该地址只对目标可见,对来源不可见。
客户端A
```
---(Exchange)---
192.168.1.101:30000 --> (198.51.100.3:1801) --> 192.0.2.2:1721
----(Punch)-----
192.168.1.101:30000 --> (198.51.100.3:1803) --> 203.0.113.12:3028
192.168.1.101:30001 --> (198.51.100.3:1804) --> 203.0.113.12:3028
192.168.1.101:30002 --> (198.51.100.3:1807) --> 203.0.113.12:3028
192.168.1.101:30003 --> (198.51.100.3:1806) --> 203.0.113.12:3028 [*]
192.168.1.101:30004 --> (198.51.100.3:1810) --> 203.0.113.12:3028
192.168.1.101:30005 --> (198.51.100.3:1812) --> 203.0.113.12:3028
192.168.1.101:30006 --> (198.51.100.3:1817) --> 203.0.113.12:3028
192.168.1.101:30007 --> (198.51.100.3:1814) --> 203.0.113.12:3028
```
客户端B
```
---(Exchange)---
192.168.0.112:30000 --> (203.0.113.19:3023) --> 192.0.2.2:1721
----(Punch)-----
192.168.0.112:30000 --> (203.0.113.12:3025) --> 198.51.100.3:1806
192.168.0.112:30001 --> (203.0.113.12:3029) --> 198.51.100.3:1806
192.168.0.112:30002 --> (203.0.113.12:2030) --> 198.51.100.3:1806
192.168.0.112:30003 --> (203.0.113.12:3031) --> 198.51.100.3:1806
192.168.0.112:30004 --> (203.0.113.12:3028) --> 198.51.100.3:1806 [*]
192.168.0.112:30005 --> (203.0.113.12:3032) --> 198.51.100.3:1806
192.168.0.112:30006 --> (203.0.113.12:3033) --> 198.51.100.3:1806
192.168.0.112:30007 --> (203.0.113.12:3034) --> 198.51.100.3:1806
```
在以上打洞组合中,`[*]` 标记的一对尝试,成功打通。
客户端 A 运行:
```
nc -u -l 30003
```
客户端 B 运行:
```
nc -u -p 30004 198.51.100.3 1806
```
两者即可 P2P 通信。
## License
GNU General Public License v3.0