[转载] 为什么我更想要 FullCone 网络

5 天前
 sxguka
本文针对移动等没有公网 V4 ,且 V6 不好用的用户
本人无此困扰,发出了是为了给大家分享
原贴: https://blog.eurekac.cn/p/daa17206.html
由于帖子长度有限制,我删除了部分图片,请点击原链接查看。


随心扯
February 15, 2024
为什么我更想要 FullCone 网络
What is NAT

NAT has 4 main types

Let us have a try - to build up a server with FullCone NAT

STUN - A formal protocol to detect NAT pair

NAT2NAT - If we all can not get a Public IP

How to Transform Home networks to get FullCone NAT

Disable Firewall

Enable DMZ host

Change to Bridge

So, why I prefer FullCone NAT

Export My Server to Public Internet

Get A HighID in P2P download

It is Hard to Get a FullCone NAT

ISP is Afraid of PCDN

FullCone 是什么?我是如何利用 FullCone 网络实现内网穿透的?为什么我会这么希望得到全锥网络?

寒假的时候几个高中同学凑一块,想联机玩 Minecraft 。然而我们几个同学都没有公网 ip ,想要联机必须要内网穿透。

为什么不用 IPV6 ?因为除了我之外其他人的路由器都是 NAT 在运营商给的智慧网关下,而智慧网关并不支持在 NAT 中分配 IPV6 。

传统内网穿透,本质上是用户之间无法直接连接,只能通过一台大家都能连上的服务器互相转发流量,达到穿透的目的。

显而易见,这种方式的互联受限于服务器的带宽和延迟,而且为了转发流量而单独购买一台服务器并不值得。

有没有一种方式,能让两个相互处于 NAT 网络的用户直接连接,而不需要服务器转发流量呢?

在这之前,我们不妨回过头来,聊聊生活中司空见惯的 NAT 技术。

What is NAT
NAT(Network Address Translation)是网络地址转换的缩写,是一种将私有网络地址转换为公有网络地址的技术,诞生的目的是为了解决 IPv4 地址不足的问题。其解决方案是将多个设备处于一个局域网内,通过共享一个公网 ip 地址来访问外部网络。

一个传统的网络链接,本质上是两个( ip 地址:端口)之间的通讯。NAT 通过类似中间人的方式,转发了(公网 ip:端口)和(内网 ip:端口)之间的通讯。

图源来自维基百科

不妨用我访问 https://baidu.com 的过程来举例:

路由器通过拨号上网,获取到了一个公网 ip 地址 39.0.0.1 。路由器网关为 192.168.1.0 ,我的电脑 ip 为 192.168.1.1 。
浏览器通过 DNS 解析获取到百度的 ip 为 110.242.68.66 ,由于我采用 https ,故默认访问端口为 443 ,则目标 pair 为 110.242.68.66:443
浏览器通过网卡,查询到本机 ip 为 192.168.1.1 ,并在本地打开了一个临时端口 12345 ,将数据包发送给网关 192.168.1.0
路由器接收到来自 192.168.1.1:12345 -> 110.242.68.66:443 的请求。
路由器在本地打开了一个临时端口 54321 ,将请求改写为 39.0.0.1:54321 -> 110.242.68.66:443 ,并将请求数据包发送给百度服务器。同时,路由器在本地记录了这个 pair 的映射关系 39.0.0.1:54321 -> 192.168.1.1:12345 。
路由器接收到来自百度的返回消息 110.242.68.66:443 -> 39.0.0.1:54321 ,通过查询映射关系,将返回消息改写为 110.242.68.66:443 -> 192.168.1.1:12345 ,并发送给 192.168.1.1 。
通过 NAT 技术,处在内网的用户能够主动向外部网络发起请求,并且由于路由器保持了映射关系,外部网络也能够向内网发送数据。

但是,在这一情况下外部网络并不能主动向内网发起请求。由于外部网络发出请求数据后,路由表内并没有对应的 pair 映射关系,路由器并不知晓将外部请求转发给哪个内网用户,会直接丢弃。这就造成了内网用户可以主动链接外部网络,而外部网络却不能主动链接内网用户的局面。

别急,让我们重新审视一下这个过程中最关键的部分:路由器在本地记录了映射关系,这才能允许外网向内网发送数据。

如果想要达到外网主动链接内网的目的,由于映射关系只能通过内网用户发起请求或者路由器主动打开,我们的思路应该着重于如何主动获取并保持这个映射关系。

映射关系在内网用户主动发起请求的时候建立,而销毁映射关系的策略则略有不同。由于 TCP 链接为有状态的链接,路由器会在链接主动关闭时自动销毁映射关系。而 UDP 链接则不同,由于 UDP 链接是无状态的,路由器并不知晓何时销毁映射关系,只能通过一定的策略来销毁。这一策略通常是在一段时间内没有数据包通过时销毁映射关系。换句话说,在建立映射关系后,只要不断地发送心跳包,这一映射关系就能够一直保持。

回头来看,这一问题的解决方案就显而易见了,在建立一个请求后通过不断发送心跳包,欺骗路由器,使其保持映射关系,就能够实现外网主动链接内网的目的。

…吗?

NAT has 4 main types
回头来看,事情的解决好像变得太过于简单了。固然,映射关系能够使发送至 39.0.0.1:54321 的数据包转发到 192.168.1.1:12345 ,在百度的视角来看,我就像是拥有了公网 ip ,能够主动向 39.0.0.1:54321 发送信息。

然而,NAT 技术很早就考虑到了这一点。映射关系的存在固然能够使外网主动链接内网,但这使得内网用户的( ip 地址:端口)彻底暴露在了外网之中。而 NAT 的本身是局域网,起到了与外部网络隔离的作用,这种暴露方式即不优雅,也不安全。

至此,NAT 根据转发策略和限制映射关系访问的方式,分为了 4 种类型( RFC3489 ):

FullCone 全锥,映射对能够被任意外部网络访问(也被称为 NAT A )
RestrictedCone 限制锥,映射对仅能被映射目标 ip 访问(丢弃除了来自 110.242.68.66 的所有数据包)
PortRestrictedCone 端口限制锥,映射对仅能被映射目标 ip 和端口访问(丢弃除了来自 110.242.68.66:443 的所有数据包)
Symmetric 对称,映射对仅能被映射目标 ip 和端口访问,并且当目的地 ip 和端口不同时,映射对也会不同(即使内网 ip:端口是相同的)
其中 全锥、限制锥、端口限制锥 最大的特征是同一个(内网 ip:端口)的映射请求会被映射为相同的(公网 ip:端口),无论目的地 ip 和端口是什么。而 对称 则会在目的地 ip 和端口不同时映射为不同的(公网 ip:端口)。

你可以用 Python 的 pystun3 来测试你的 NAT 类型:

SHELL
pip install pystun3
pystun3
pystun3 -H stun.qq.com #国内用户可以指定 qq 的 stun 服务器以加快测试速度
返回数据应该如下:

PLAINTEXT
NAT Type: Full Cone
External IP: 39.0.0.1
External Port: 12463
Let us have a try - to build up a server with FullCone NAT
知道了原理,不来试试怎么加深理解呢?

首先,以下操作需要一个拥有全锥 NAT 的网络环境。如果没有你可以看下一节内容尝试将自己的家庭网络改造为全锥 NAT 。

此外,需要一台拥有公网 ip 的服务器,以便于本地计算机能够探测出映射关系。

接下来,我将展示两个脚本,通过运行脚本,本地计算机能够探测出映射关系并在映射对上建立一个临时服务器,如果外部网络能够通过探测出来的映射对访问到这个临时服务器,那么就能证明 FullCone 内网穿透理论可行。

JAVASCRIPT
//server.js
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
const ip = req.connection.remoteAddress.match(/\d+\.\d+\.\d+\.\d+/)[0];
const port = req.connection.remotePort;
console.log(`Request from ${ip}:${port}`);
setInterval(() => {
try {
const req = http.request({
host: ip,
port: port,
method: 'GET'
})
req.end();
} catch (e) { }
}, 1000); //该定时器会每秒向客户端发送一个请求,使得映射关系不会因为长时间没有通信而被销毁,从而实现锁定映射关系
res.end(JSON.stringify({ ip, port }));
}).listen(13000);
JAVASCRIPT
//client.js
const http = require('http');
const localPort = 18000; //这是本地即将暴露的端口
const endpoint_url = '' //这是部署了 server.js 的服务器的 ip 地址
const endpoint_port = 13000 //这是部署了 server.js 的服务器的端口
const req = http.request({
host: endpoint_url,
port: endpoint_port,
method: 'GET',
localPort: localPort //http.request 可以通过 localPort 参数强制指定本地端口
}, (res) => {
res.on('data', (data) => {
const { ip, port } = JSON.parse(data.toString());
console.log(`127.0.0.1:${localPort} -> ${ip}:${port}`);
console.log(`http://${ip}:${port}`);
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Working at ${new Date()}`);
}).listen(localPort); //通过 server.js 探测到映射对,然后在本地启动一个服务器,外网访问 ip:port 会被映射到本地的 localPort ,从而实现了内网穿透
})
});
req.end();
先运行 server.js ,然后填入服务器的 ip ,再运行 client.js ,控制台内有如下输出

PLAINTEXT
127.0.0.1:18000 -> 39.1.1.1:12319
http://39.1.1.1:12319
脚本将会自动在 0.0.0.0:18000 启动一个测试服务器,我们直接点击链接访问 http://39.1.1.1:12319



如果显示了信息,说明我们的 127.0.0.1:18000 已经成功地被穿透到了 39.1.1.1:12319 。

并且,将 http://39.1.1.1:12319 分享给其他人,他们也能够访问到你的本地服务器。

请注意,从头到尾我并没有声明我拥有公网 ip ,事实上,无论是否为公网 ip ,只要 nat 类型为 FullCone ,都可以利用这种方式穿透。

使用 FullCone 穿透的地址可以直接被外网访问,其优点在于流量无需服务器中转,最终的访问是点对点的,目标用户是直接访问到内网的服务器,延迟和速率不受限制。探测服务器仅用于辅助内网用户获取到自己链路上的映射对,本身不参与网络连接。并且网络上存在大量的免费探测服务器,不一定需要自己搭建的服务器。

缺点也十分明显,映射对本身需要长时间的心跳包才能维持,一旦映射长时间无数据包通过,映射就会被断掉,并且重新映射的端口不固定。此外,如果作为长期暴露在公网上供他人访问,还是需要有其他方法将探测到的映射对共享出去(类似 DDNS )。

STUN - A formal protocol to detect NAT pair
事实上,上面的脚本只是一个简单的例子。然而,RFC5389 定义了一种更加正式的协议,STUN(Session Traversal Utilities for NAT)。STUN 协议定义了一种用于检测 NAT 类型和获取映射对的协议,其探测协议为 UDP 。由于基于 UDP 的探测对不会在断开连接后立刻销毁,STUN 协议能够有更大的成功率实现 NAT 互联。

需要注意的是,部分路由器在建立映射对的时候也会限制协议。如果内网内用户用 UDP 探测,则部分路由器只会允许 UDP 协议的映射对,而不会允许 TCP 数据包通过映射对。反之亦然。

如同上面的 Demo 中,我利用 TCP 协议来探测映射对,因此外网只能用 TCP 协议( HTTP 协议基于 TCP )访问到我的内网服务器,而外网服务器尝试向映射对发送 UDP 数据包,路由器则会直接丢弃。

然而,我们可以将 TCP 包装在 UDP 之中,从而绕过这一限制。这一技术被称为 TCP over UDP 。

从另一方面讲,基于 UDP 的 VPN 协议并不罕见,通过 STUN 打洞后完全可以建立一个基于 UDP 的虚拟局域网用于传递 TCP 数据包,例如传统的 Wireguard 协议。

此外,STUN 可以利用 TCP 作为探测协议,但是在实际网络环境中并非所有 NAT 均为全锥 NAT ,因此 TCP 探测的成功率并不高。

这是标准( RFC 3489 )中的利用 STUN 来探测映射对和 NAT 类型的过程:

图源来自维基百科

NAT2NAT - If we all can not get a Public IP
上面所讲述的内容,都是在拥有 FullCone 的前提下,内网穿透了自己的 ip 到公网上。然而在大多数使用场景内,我们并不需要把自己的 ip 暴露在公网上,而是需要两个内网用户之间能够直接链接。

而 NAT2NAT 技术可以很好的解决这一问题,N2N 并不依赖于 FullCone 就可以尝试在两个 NAT 用户间“打洞”,使得两个内网用户“直接”互相链接,无需经过服务器转发。

然而,拥有 FullCone 的打洞成功率接近 100%,而其他类型的 NAT 打洞成功率则相对较低。

这是一张表,阐述了不同类型 NAT 之间一般能否成功打洞

NAT 类型 FullCone RestrictedCone PortRestrictedCone Symmetric
FullCone √ √ √ √
RestrictedCone √ √ √ √
PortRestrictedCone √ √ √ X
Symmetric √ √ X X
打洞的成功率由大至小依次为:FullCone > RestrictedCone > PortRestrictedCone > Symmetric 。一般由打洞成功率高的 NAT 向打洞成功率低的 NAT 发起打洞请求,使弱势用户能够主动链接强势用户,便于弱势用户提前强势用户建立映射对。

受限锥-受限锥 受限端锥-受限端锥 需要任意一方在探测完后及时主动向对方发起链接,避免映射对被销毁。

对称型-端口受限锥型 NAT 之间的打洞成功率极低。(1/65535)。

而对称型 NAT 之间的打洞成功率几乎为 0 。(1/65535^2)

Ntop 的 N2N 项目 则是一个基于以上理论的开源项目,通过区分 Edge(Client)和 SuperNode(Server)的方式,方便了普通人的部署。

由于映射对本身只能在内网用户主动向外请求时才能建立,故如何将获取到的映射对及时传递给对方,是 N2N 的关键。而 SuperNode 在此时起到了关键作用,SuperNode 会记录下所有 Edge 的映射对并分享给对方,使得两个 Edge 能够及时知晓对方的映射对,从而建立联系。

正常情况下,SuperNode 并不参与数据传输,仅用于告知双方的映射对。然而,在双方 NAT 打洞成功率不高时,SuperNode 也会回退为 TURN 模式(即传统方式,利用服务器转发流量,篇幅所限不再赘述)。

Linux 用户可以直接下载 N2N 的二进制文件,Windows 与 Mac 用户则需要自行编译或使用第三方编译好的二进制文件。

对于我在 Windows 上的使用,我通常用 [灵工艺] 联机组网。其有 GUI 可以快捷配置,并且也很方便安装 TAP 适配器。主要是懒的敲命令行



首先搭建 N2N 需要有一台拥有公网 ip 的服务器,然后在服务器上运行 SuperNode 。尽管 SuperNode 正常情况下不参与数据传输,但是 N2N 无法主动禁用 TURN 模式,故不建议公开部署 SuperNode 。

搭建 SuperNode 可以直接安装 N2N 的二进制文件,配置文件存在/etc/n2n/supernode.conf

PLAINTEXT
# /etc/n2n/supernode.conf
-p=1234
运行 sudo systemctl start supernode 即可启动 SuperNode ,监听端口为 1234 。

如果需要开机自启动,可以运行 sudo systemctl enable supernode 。

如果当前运行环境(如 Docker 环境)不存在 systemctl ,可以自行下载 N2N 的项目源代码并自行编译:

SHELL
git clone https://github.com/ntop/n2n.git --depth=1
bash ./autogen.sh
bash ./configure
make
make install
然后采用./supernode 的方式运行。

针对 Edge ,可以直接运行二进制文件:

SHELL
sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777
-c 指定的链接组名,所有拥有相同链接组名的 Edge 会被视为同一组
-k 指定的链接组密码
-a 指定的内网 ip
-l 指定 SuperNode 的 ip 和端口
在另一台 Edge 上运行:

SHELL
sudo edge -c mynetwork -k mysecretpass -a 192.168.100.2 -f -l supernode.ntop.org:7777
两台 Edge 将会自动建立链接,SuperNode 会记录下两台 Edge 的映射对并分享给对方,使得两台 Edge 能够及时知晓对方的映射对,从而建立联系。

可以尝试在内网 ip 为 192.168.100.1 的 Edge 上运行:

SHELL
ping 192.168.100.2
应当会有相应的回应。

Ctrl+C 退出后,可以看到类似的输出:

PLAINTEXT
**********************************
Packet stats:
TX P2P: 10 pkts
RX P2P: 10 pkts
TX Supernode: 4 pkts (2 broadcast)
RX Supernode: 2 pkts (1 broadcast)
**********************************
其中 TX P2P 和 RX P2P 表示 Edge 之间的数据传输,TX Supernode 和 RX Supernode 表示 Edge 与 SuperNode 的数据传输。

SuperNode 的数据包应该远小于 Edge 之间的数据包,因为 SuperNode 仅用于告知双方的映射对,以及刚开始来不及打洞时通过 TURN 的数据传输。

如果经过一段时间后,P2P 的数据包数仍然为 0 ,说明 N2N 的打洞失败,应检查双方防火墙情况和 NAT 类型。

Tips:

N2N 的 SuperNode 默认允许了所有 Edge 的加入。尽管 N2N 官方有着专门的鉴权方式,但是配置及其麻烦,可以巧用限制通讯组的方式,约定一个确定的通讯组名,限制只有拥有相同通讯组名的 Edge 才能加入。

修改/etc/n2n/supernode.conf ,添加-c 参数:

PLAINTEXT
# /etc/n2n/supernode.conf
-p=1234
-c=/etc/n2n/communities.list
然后在/etc/n2n/communities.list 中添加通讯组名(允许采用正则表达式,一行一个):

PLAINTEXT
mynetwork
重启 SuperNode sudo systemctl restart supernode 即可生效。

How to Transform Home networks to get FullCone NAT
如果你已经拥有了公网 IPV4 ,那么请直接略过这一节。

Disable Firewall
控制面板进入高级安全 Windows Defender 防火墙,在入站规则添加规则,允许所有端口的 UDP 。在出站规则中也如法炮制。

为了安全性你也可以限定端口范围,但是这样会降低打洞成功率。

你不需要允许 TCP 协议,因为 N2N 默认采用的 STUN 探测协议为 UDP 。









如果你使用的是第三方防火墙,也请关闭防火墙或者添加规则。

Enable DMZ host
DMZ 技术,Demilitarized Zone 的缩写,是一种网络安全技术,用于将内部网络与外部网络隔离开来。而对于家庭网络而言,DMZ 主机的则是路由器将所有端口的流量都转发到这台主机上。

在严格意义上,DMZ 与内部网络是隔离的,但是在家庭网络中,DMZ 主机仍然可以访问内网,而内网用户也可以访问 DMZ 主机。

在路由器设置中,找到 DMZ 主机设置,将你的电脑 ip 设置为 DMZ 主机。

首先查询自己电脑的内网 ip 地址:

SHELL
ipconfig /all


记下地址为 192.168.31.215

以我的小米路由器为例,登录路由器后台,找到高级设置-端口转发-DMZ 主机,将地址填入:



保存即可。

如果你的路由器不支持 DMZ 主机设置,可以尝试将你的电脑设置为静态 ip ,并将所有的 UDP 端口转发到你的电脑上。

Change to Bridge
目前的家庭网络通常是 光纤入户 -> 运营商提供的智能网关 -> 用户路由器 -> 用户电脑的结构。其中智能网关通常是光猫+路由器+AP 的缝合怪。按照大部分地区的安装指导,光猫默认会工作在 NAT 模式下,以便于用户能够直接使用,而无需拨号。

然而,大部分光猫 NAT 的策略都默认设置为对称性 NAT ,即使光猫拥有 DMZ 主机设置,最终 NAT 类型也是对称性 NAT 。

因此,我们需要将智慧网关设置为桥接模式(工作在仅光猫状态),将路由器设置为拨号上网,再在路由器上设置 DMZ 主机。

是不是看起来很怪?事实上大部分家庭网络都是 FullCone NAT ,但是由于智慧网关的 NAT 策略,使得家庭网络的 NAT 类型变为了对称性 NAT 。

将智慧网关设置为桥接状态,通常需要获取光猫的超级管理员密码,然后删除原有的配置,新建新的桥接配置,并在下一级的路由器上设置拨号上网。

由于篇幅所限,这里不再赘述具体的操作步骤。光猫的具体破解方式各异,可以尝试自行搜索 XXX-XX 型号光猫改桥接。

通常来讲,设置好桥接 - 设置 DMZ 主机 - 关闭防火墙后,你的家庭网络应该已经变为了 FullCone NAT 。此时不妨利用 pystun3 测试一下你的 NAT 类型。如果已经为 FullCone ,那么恭喜你。如果没有,那么你当地的运营商很可能对网络进行了限制。

So, why I prefer FullCone NAT
第一个原因是,相对于公网 IPV4 ,FullCone 的改造更为廉价和安全。在大多数地区,公网 IPV4 的价格昂贵,而且公网 IPV4 的暴露会使得内网用户的安全性大大降低。此外,移动运营商由于本身 v4 资源匮乏,绝大多数地区已经不再提供公网 IPV4

此外,相较于 IPV6 ,传统的 IPV4 的网络设备更为成熟,出门在外想要连回家里的网络,如果没有 IPV6 ,那么还得要绕道服务器转发。

相对于传统服务器内网穿透,直接点对点链接的优势无疑是巨大的,最终双方的访问质量仅取决于双方的网络质量,而不再受到服务器的限制。(比如我在外就可以直接跑满家庭上行 100M ,而不是服务器龟速 5M 上行,这使得远程串流游戏成为了可能)

回到文章的刚开始,由于我拥有了 FullCone NAT ,当 MC 服务器启动在我电脑后,通过 N2N 软件,朋友的客户端能够直接链接到我的电脑上。由于我们过年回家都在台州,相互之间直接连接的质量也相较于内网穿透的质量高上不少。

尽管 N2N 不需要 FullCone 也有一定概率能够打洞,但是 FullCone 就是爽

然而除此之外,如果对 FullCone 网络进行恰当的改造,那么我就能在无法拥有公网 ip (毕竟是移动)的情况下,享受公网 ip 的待遇。访问效果上等同于拥有了一组公网 IP:端口。

Export My Server to Public Internet
先前我的脚本已经证明,FullCone 网络在通过恰当的方式打洞后,能够直接将内网 ip 暴露在公网上。事实上,Github 已经有类似的项目能够探测 FullCone NAT 的映射对的程序,例如 NATMAP 和 Natter 。

其中,NATMAP 基于 C++,暂时还不支持 Windows 。而 Natter 则是基于 Python 的,支持 Windows (但截至本文发稿时 Windows 上 UDP 穿透仍存在严重的问题),也支持流量转发(由于探测需要临时占用端口,而部分程序无法解除端口占用,故可以新开一个随机端口用于探测,然后将探测端口流量转发到目标端口即可)。

事实上,你可以利用 NATMAP 或 Natter 探测到的映射对记录映射对,并通过其他简易的内网穿透或者定时上传到公开网站的方式,实现一个简单的 DDNS 。

另一方面,DNS 记录中存在名为 SRV 的记录类型,可以指定端口。如果你拥有一个域名,那么你可以通过 SRV 记录将你的映射对共享出去。

与 DDNS 技术相比,通过 FullCone 打洞仅仅多了一个端口的记录。

此外,截至本文发稿时,Natter“固定”映射对的效果尚不如 NATMAP ,在关闭程序后映射对可能会发生改变,但是 Natter 的配置更加方便,也支持流量转发。

通过这种方式,我已经成功将我的服务器 Wireguard 入口暴露到了公网上,至此,我可以在不购买公网 IPV4 、无 IPV6 的情况下,在任何地方通过我的服务器访问到我的家庭网络。

至于其他的 RDP 、SSH 等服务,也可以通过类似的方式实现。不过建议还是只暴露 Wireguard 入口,然后通过 Wireguard 内网穿透到其他服务。毕竟安全第一

Get A HighID in P2P download
在电驴下载中,存在这 LowID 和 HighID 的概念。LowID 是指没有公网 IPV4 的用户,而 HighID 则是指拥有公网的用户。两个 LowID 之间无法直接链接,但是 HighID 可以直接链接到 LowID 和 HighID 。

在其他 P2P 下载中,也存在类似的概念。放到 PT 下载中,拥有一个 LowID 的用户,相对于 HighID 用户而言,下载速度会大大降低。同时,LowID 用户在做种时也无法主动链接到其他 LowID 用户,从而影响了共享效果,在 PT 上传中很难抢到上传流量。

然而,通过 FullCone NAT ,我可以将我的 PT 客户端的端口暴露在公网上,从而获得了 HighID 。但是在这其中存在一个问题,映射对中内网端口和外网端口通常是不一致的,而 PT 客户端向 Tracker 服务器报告的端口是内网端口,外网用户无法用(公网 ip:内网端口)访问到我的 PT 客户端。

因此,需要先随机探测一个映射对,记录(内网 ip:内网随机端口)和(公网 ip:外网端口)的对应关系,并新建一个转发,将(内网 ip:内网随机端口)的流量转发到(内网 ip:外网端口),并通过 BT 客户端的 API 修改 BT 程序监听端口为外网端口。通过这种方式,使 BT 客户端向 Tracker 服务器报告的端口为外网端口,从而获得了 HighID 。

这是我之前不知道在那个论坛抄下来的脚本,可利用 natmap 或 natter 的 script 功能自动修改 BT 客户端的监听端口并转发流量,出处已不可考。

到这里为止,FullCone NAT 好像已经变得完美无瑕,它拥有着相对于公网 v4 极高的性价比,并且有着丰富的 DIY 内容。这篇文章在这里应该已经结束了

…吗?

It is Hard to Get a FullCone NAT
你并没有那么容易获得全锥网络。由于大部分运营商的光猫已经被逐步替换为了智能网关,破解智能网关本身就具有这相当高的难度。

我知道你想说什么,花了 150 的租金,拿了个什么都缝合了、什么都没缝合好的电子垃圾。wifi 只有 2.4G 不支持 5G ,不支持在 NAT 中下发公网 IPV6 ,大部分功能被运营商锁定不让你用,甚至还有远控后门。

此外,不像我手上的移动 H3-2se 智能网关有着开启 telnet 的漏洞,大部分智能网关想要获取超管密码都极为困难,想要破解获得密码还得根据型号来选择方式。部分机型还需要替换备份包的方式刷机,稍有不慎就会出现意外,破解的难度极高。

另一方面,运营商显然是不希望用户改为桥接模式的。

首先,按照知乎上的普遍说法,改桥接意味着运营商将丢失对光猫的远程控制,一旦用户家庭网络出现问题,则无法远程解决,需要安装师傅上门,浪费人力物力。

事实上,相对于智能网关即插即用的特性,改为桥接需要用户在路由器或者在电脑上拨号。这对于不了解网络的用户来说是一件很麻烦的事情,免不了请人帮忙安装。

其次,桥接模式意味着用户可以自行选择路由器,而不再受限于运营商提供的智能网关,运营商则无法在终端网络上提供额外的审查能力。

此外,一旦改为桥接,部分地区的运营商还会降速,(尽管不排除光猫性能羸弱可能性)。

最重要的原因是,运营商它怕你占用了大量的上行带宽…

ISP is Afraid of PCDN
PCDN ,Peer-to-Peer Content Delivery Network ,即点对点内容分发网络。

这个名词在普通网络中并不常用,但国内诸多互联网厂商对此并不陌生。由于大陆政策的商宽补贴家宽的特性,相较于国外家宽的价格,国内家宽的价格极为便宜。

然而如此一来,宽带成本压力就转嫁到了商宽上,云服务厂商接入 ISP 的价格极其昂贵(国内网盘业务难以发展的原因之一)。类似视频分发等业务,如果全部由云服务厂商提供,那么运营成本将会难以负担。

于是各大国内服务商就走起了歪路,PCDN 这一邪门技术便应运而生。PCDN 的核心思想是,用户之间互相分享资源,从而减轻服务器的存储压力和带宽压力。

通常来讲,用户可以主动作为 pcdn 节点共享带宽,从而向服务商赚取少量佣金。服务商只要付出极少成本,就能够获得遍布在广大用户间海量存储和带宽资源。先前百度网盘试图开放闲置宽带优化计划,也是 PCDN 的一种。当然你白开一年 PCDN 换取到的奖励也是微乎其微的

服务商的打洞方式当然也包括 N2N 打洞。事实上服务商的客户端程序打洞的方式可能更多更狠,本文仅涉猎了其中一种方式。

然而,有一些软件可能会自己偷偷摸摸跑 PCDN ,用户很大概率是无感的(毕竟 XX 视频、XX 音乐、XX 网盘客户端上传都是限速的,以避免大量占用资源而被察觉)。太离谱了还是会被发现的

自然,运营商是极其不乐意的,PCDN 固然降低了服务商的压力,但这些压力分毫不少的转移到了运营商的头上,运营商从服务商收取的钱变少了,还承担了相同(甚至更多的)带宽压力。

但是,运营商的骨干网络通常没有做单独的限制,通过改造骨干网络来限制 PCDN 显得不太现实。因此运营商只能在终端网络上下手。而在智能光猫内植入限制,是最为方便的方式。

这就是为什么当我们解除了终端智能光猫的限制后,NAT 类型通常都还原回了 FullCone 。

但是,部分地区运营商检测到用户如果在偷跑 PCDN (不管是不是故意的)或者长时间大规模占用上行带宽,会针对性地对用户上行进行限速,或者将用户 NAT 降级为对称性 NAT 。

一旦开启桥接,诸多互联网厂商软件会直接开始吸血家宽。由于国内宽带通常计费方式是包年计带宽,不计流量,因此用户可能完全不会察觉到 PCDN 的开启,但运营商则会为此承担更多的带宽压力。

此外,运营商对 BT 等 P2P 下载也是深恶痛绝的,但是彻底根除显得并不现实,因此运营商只能通过劣化互联质量降低上传宽带的占用。

NAT 的发明极大减缓了全球 IPV4 地址枯竭的难题,它允许了多个网络设备共享一个公网 IPV4 地址。然而现如今,IPV6 的时代已经到来,NAT 却成为了 IPV6 发展的障碍。究其原因,是因为 NAT 设立之初并没有考虑计划淘汰 - 它可以一直永远的工作下去。

并且,NAT 通常也用于隔离内部网络和外网,即使是在 IPV6 中也会存在 NATv6 确保内网用户的安全性。

然而,由于 NAT 的设计阻碍了不同内部网络双方的直接通讯 - 即使双方并不想在内部网络,但由于 IPV4 的枯竭,他们不得不用,这使得类似于物联网、智能汽车等需要万物互联新兴技术受到了阻碍。即使物联网设备用上了 IPV6 - 你能确保走出门外,随便接入一个 wifi 都有 IPV6 吗?

一个听起来令人发笑的事实是,8 年前的无线路由器依旧在我家工作的很好 - 它支持 802.11ac(5GHz),提供了和外网带宽匹配的无线带宽速率。它只是不支持 IPV6 。

我有必要换它吗?我不认为,因为在我实际上网过程中,纯 IPV6 的网站并不多;家里人也不需要所谓的 IPV6 ,因为他们的需求仅仅是看视频和上网购物;家里设备也不需要 IPV6 ,因为这种小型家庭监控、冰箱、扫地机器人通常是通过物联网卡上网的,即使连接 WIFI ,也是通过云服务商提供的服务来访问的。

它只要能正常工作,这就够了。

现在我想在我家放一台 NAS ,我的需求是能在离开家之后随时随地访问这台 NAS 。那么,纯 IPV6 也不能满足我的需求,因为我不能保证我在外面的网络环境拥有 IPV6 - 是的,因为不支持 IPV6 的网络设施依旧能在纯 IPV4 的网络环境下工作,为什么一定要淘汰它呢?

纵然国家大力支持发展 IPV6 ,但是在实际民用网络应用中,IPV6 的普及率依旧很低,终端设备(家庭网关、无线路由器)的淘汰问题成为了 IPV6 普及的最大障碍。此外,部分地区运营商甚至把 IPV6 与公网 IPV4 对立,声称为了普及 IPV6 而开始对公网 IPV4 收费,并借机利用 NAT4444 实现假公网 V4 。



与其花 399 购买一个静态 FullCone 网络,不如免费白嫖动态 FullCone 网络

另外,正如我之前提到的,家庭网络绝大多都是 FullConeNAT ,如果有足够的折腾精神,改造光猫对我而言并不困难。

事实上,我现在在自己的 NAS 上就同时部署了两种穿透方案,一种是 FRP ,另一种是用利用 NATMAP 探测并将探测到的映射记录同步到 DNS 的 SRV 记录上。通过这种方式,我可以在任何地方直接用 Wireguard 连回家,除非遇到故障才会去用 FRP 。

这就是 FullCone NAT ,它一直存在于我们生活中,并且仍具有极高的利用价值。如果能够合理的利用它,我想节省下一笔关于公网 IPV4 的费用,也不是不可能的。

只是可惜,在如今运营商政策的收紧、光猫破解变得越来越难的趋势下,FullCone NAT 的普及率将只会变得越来越低。

在写下本篇文章的最后一段时,我想等到数年后 IPV6 彻底普及,会不会有人看完这篇文章会嘲笑,在 2024 年的时候,还有一个傻子拒绝公网 IPV6 ,还在尝试使用已经宣告缓刑的 IPV4 进行“万物互联”呢?

这里是 CyanFalse 的小站,一个小小的年更博客,感谢您的阅读。
2738 次点击
所在节点    宽带症候群
31 条回复
abc2xyz
5 天前
好长,用 DS 帮总结下:
--
这篇文章主要讨论了 FullCone NAT (全锥型 NAT )的优势及其在内网穿透中的应用,尤其是在没有公网 IPv4 地址的情况下如何通过 FullCone NAT 实现点对点连接。以下是文章的核心内容总结:

1. NAT 的基本概念
NAT (网络地址转换):用于将私有网络地址转换为公有网络地址,解决 IPv4 地址不足的问题。NAT 允许多个设备共享一个公网 IP 地址访问外部网络。

NAT 的四种类型:

FullCone (全锥型):映射对可以被任意外部网络访问。

RestrictedCone (限制锥型):映射对仅能被映射目标 IP 访问。

PortRestrictedCone (端口限制锥型):映射对仅能被映射目标 IP 和端口访问。

Symmetric (对称型):映射对仅能被映射目标 IP 和端口访问,且不同目标 IP 和端口会生成不同的映射对。

2. FullCone NAT 的优势
内网穿透:FullCone NAT 允许外部网络主动访问内网设备,通过保持映射关系,内网设备可以像拥有公网 IP 一样被访问。

点对点连接:通过 FullCone NAT ,两个内网用户可以直接连接,无需通过服务器中转流量,降低了延迟和带宽限制。

P2P 下载:FullCone NAT 可以提高 P2P 下载的效率,获得 HighID ,提升下载和上传速度。

3. 如何实现 FullCone NAT
关闭防火墙:允许所有端口的 UDP 流量通过。

启用 DMZ 主机:将内网设备的 IP 设置为 DMZ 主机,路由器会将所有外部流量转发到该设备。

桥接模式:将运营商提供的智能网关设置为桥接模式,使用自己的路由器拨号上网,并在路由器上设置 DMZ 主机。

4. NAT2NAT 技术
NAT2NAT ( N2N ):一种允许两个内网用户直接连接的技术,即使双方都没有公网 IP 。FullCone NAT 的 N2N 打洞成功率接近 100%,而其他类型的 NAT 打洞成功率较低。

SuperNode:N2N 中的服务器角色,用于记录和分享内网用户的映射对,帮助双方建立连接。

5. FullCone NAT 的挑战
运营商的限制:由于 PCDN (点对点内容分发网络)的存在,运营商对 FullCone NAT 的支持越来越少,很多地区的智能网关默认使用对称型 NAT ,限制了内网穿透的可能性。

光猫破解难度:大部分运营商的光猫已经替换为智能网关,破解难度高,且运营商不希望用户改为桥接模式。

6. FullCone NAT 的应用场景
内网服务器暴露到公网:通过 FullCone NAT ,可以将内网服务器暴露到公网,实现远程访问。

P2P 下载:通过 FullCone NAT ,可以获得 HighID ,提升 P2P 下载和上传的效率。

远程游戏联机:通过 FullCone NAT ,可以实现点对点的游戏联机,降低延迟。

7. IPv6 与 NAT 的未来
IPv6 的普及:IPv6 的普及将减少对 NAT 的依赖,但由于终端设备的更新滞后,IPv6 的普及仍然面临挑战。

NAT 的持续存在:即使 IPv6 普及,NAT 仍然会在某些场景下继续使用,尤其是在内网安全和隔离方面。

8. 总结
FullCone NAT 在没有公网 IPv4 的情况下,提供了一种廉价且高效的内网穿透解决方案。通过合理的网络配置,用户可以实现点对点连接,提升 P2P 下载和远程访问的效率。然而,随着运营商对 PCDN 的限制和智能网关的普及,FullCone NAT 的获取变得越来越困难。

这篇文章详细探讨了 FullCone NAT 的原理、优势、实现方法以及面临的挑战,适合对网络技术有一定了解的用户阅读。
---
wtks1
5 天前
n2n 是个好软件,唯一的遗憾是这个不支持 ipv6 互联
yuhaofe
5 天前
要求不高的话光猫桥接、路由器 UPNP 再加免费的蒲公英就能实现 P2P 异地组网,不过成功率不好说,失败后会走转发,速度感人
xqzr
5 天前
@Livid #1 AI
Livid
5 天前
@xqzr 谢谢,1 楼的账号已经被彻底 ban 。
wind1986
5 天前
这个文章排版一言难尽....
sxguka
5 天前
@wind1986 转载节选的,请看原文链接
zwy100e72
5 天前
按照我个人经验,Mikrotik 路由器想要达成 Full-Cone NAT 只需要两条出站规则,一条是对 udp 流量启用 endpoint-independent-nat ; 另一条是保底的 masquerade ;入站这边靠 Mikrotik 自带的 connection-tracking 就好

不需要关掉防火墙,也不需要全允许 UDP 入站和出站,也不需要 DMZ 主机
ponelyr
5 天前
@xqzr 这都要 ban 的嘛,1 楼只是节约大家时间
MacsedProtoss
5 天前
@ponelyr AI 就是浪费时间 需要的人自己去总结就好了
MeteorVIP
5 天前
去原文全部看完了。
需要 fullcone 来打游戏( ns 和 ps5 )。原来刷的 openwrt 自带 fullcone ,最近的版本没有了。要怎么让游戏机都 fullcone 呢?
SakuraYuki
5 天前
@MeteorVIP uu 插件,最不折腾的方法
WizardLeo
5 天前
点进去证书过期了,看 op 用的是 zerossl 的证书,是不是自动续期出问题了?
MeteorVIP
5 天前
@SakuraYuki #12 哈哈哈,最不想用 uu,只用 openwrt 来加速游戏机,其实裸联也不错的.
huihuilang
4 天前
太长了。。。
feitxue
4 天前
太长 并且没有排版,那就放弃深入看了。
sxguka
4 天前
@feitxue 一开头就提醒了建议看原链接,图文并茂
sxguka
4 天前
@yuhaofe nat3 到 nat3 同运营商成功率 90%,nat3 和 nat1 成功率 99%+,nat1 能兼容绝大多数网络。nat3 和 4 之间不行。所以如果在外极差,家里就只能极好。如果在外不错( nat3 ),家里也只需不错即可。
sxguka
4 天前
@MeteorVIP dmz ,为 nat1 ,效果最好。open 需要游戏机拨号且其他设备不能上网(多播除外)且很折腾还不一定成功。dmz 效果最好。
linlord
3 天前
@sxguka #17 但是你的证书过期了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/1109760

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX