Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nftables fullcone implementation #42

Open
wongsyrone opened this issue Apr 9, 2022 · 115 comments
Open

Nftables fullcone implementation #42

wongsyrone opened this issue Apr 9, 2022 · 115 comments

Comments

@wongsyrone
Copy link

wongsyrone commented Apr 9, 2022

Based on code from @Chion82 and @llccd , I implement fullcone support for nftables.

OpenWrt kernel module Package: Compile and run tested on Linux 5.15.32 OpenWrt master branch, not run tested thoroughly.
https://github.com/wongsyrone/nft-fullcone

OpenWrt firewall4, a.k.a. the new nftables-based firewall, patched repo listed below:
https://github.com/wongsyrone/openwrt-firewall4-with-fullcone

You have to patch libnftnl and nftables for the new 'fullcone' statement, patched repo listed below:
https://github.com/wongsyrone/libnftnl-1.2.1-with-fullcone
https://github.com/wongsyrone/nftables-1.0.2-with-fullcone

Sometimes you have to call autoreconf to regenerate configure script.

BONUS: luci-app-turboacc change listed below, I only use its shortcut-fe and fullcone NAT functionality, thus takes what you want.

wongsyrone/lede-1@a15fece

@fraybyl
Copy link

fraybyl commented Apr 18, 2022

Hi, I get the error
root@OpenWrt:~# /etc/init.d/firewall restart
nft_try_fullcone: cmd /usr/sbin/nft -c 'add table inet fw4-fullcone-test; add chain inet fw4-fullcone-test dstnat { type nat hook prerouting priority -100; policy accept; fullcone; }; add chain inet fw4-fullcone-test srcnat { type nat hook postrouting priority -100; policy accept; fullcone; }; ' 2>/dev/null
nft_try_fullcone failed, disable fullcone globally
Section @zone[0] (lan) fullcone is not enabled in default settings, ignore fullcone settings in zone
Section @zone[1] (wan) fullcone is not enabled by default, ignore zone fullcone setting

@wongsyrone
Copy link
Author

@fraybyl You need to patch nftables and libnftnl as well

@fraybyl
Copy link

fraybyl commented Apr 19, 2022

@wongsyrone

I spent quite a bit of time with this, but if I am not mistaken, I was able to change the repository for nftables and libnftnl.
Is there any way to check if nftables and libnftnl are built correctly?

@wongsyrone
Copy link
Author

@fraybyl

nft_try_fullcone failed disappears if everything is okay.

@fraybyl
Copy link

fraybyl commented Apr 19, 2022

@wongsyrone
I take openwrt/package/libs/libnftnl/Makefile and change the PKG_SOURCE_URL to yours, what am I doing wrong?

@wongsyrone
Copy link
Author

wongsyrone commented Apr 19, 2022

@fraybyl Please note the patches folder in libnftnl and nftables directory.

@wongsyrone
Copy link
Author

@fraybyl
Copy link

fraybyl commented Apr 19, 2022

@wongsyrone
Apparently I am very stupid!) thank you so much for your help and your efforts.

@debiansid
Copy link

can I patch it into 5.10.113?

@wongsyrone
Copy link
Author

can I patch it into 5.10.113?

Yes.

@debiansid
Copy link

can I patch it into 5.10.113?

Yes.

https://github.com/Chion82/netfilter-full-cone-nat#kernel-patch-optional
I want to build it into kernel like this link. would you please guide me to get that? thanks

@debiansid
Copy link

How to configure it on Linux ?

@debiansid
Copy link

debiansid commented May 12, 2022

Will this work ?

table inet my_nat {
     chain my_masquerade {
     type nat hook postrouting priority srcnat;
     oifname "pppoe0" masquerade fullcone
  }
}

@wongsyrone
Copy link
Author

Example from OpenWrt:

table inet fw4 {
	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
		iifname "pppoe-wan" jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "pppoe-wan" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
	}

	chain srcnat_wan {
		fullcone comment "!fw4: Handle wan IPv4/IPv6 fullcone NAT traffic"
	}

	chain dstnat_wan {
		fullcone comment "!fw4: Handle wan IPv4/IPv6 fullcone NAT traffic"
	}
}

@wongsyrone
Copy link
Author

If you use my OpenWrt firewall4 patch, you get these rules automatically.

@wongsyrone
Copy link
Author

https://github.com/Chion82/netfilter-full-cone-nat#kernel-patch-optional I want to build it into kernel like this link. would you please guide me to get that? thanks

You may modify the kernel source based on the link you refer to, I do not maintain a kernel patch.

@debiansid
Copy link

I understand it is implementation on openwrt. I want to get it work on Linux. I will keep trying, thanks

@paladin4fan
Copy link

Based on code from @Chion82 and @llccd , I implement fullcone support for nftables.

OpenWrt kernel module Package: Compile and run tested on Linux 5.15.32 OpenWrt master branch, not run tested thoroughly. https://github.com/wongsyrone/nft-fullcone

OpenWrt firewall4, a.k.a. the new nftables-based firewall, patched repo listed below: https://github.com/wongsyrone/openwrt-firewall4-with-fullcone

You have to patch libnftnl and nftables for the new 'fullcone' statement, patched repo listed below: https://github.com/wongsyrone/libnftnl-1.2.1-with-fullcone https://github.com/wongsyrone/nftables-1.0.2-with-fullcone

Sometimes you have to call autoreconf to regenerate configure script.

BONUS: luci-app-turboacc change listed below, I only use it's shortcut-fe and fullcone NAT functionality, thus takes what you want.

wongsyrone/lede-1@a15fece

Thanks for provide the solutions.
Should I compile these project along? Or is there a way to apply it to the openwrt package?
I just compiled an openwrt 22.03.0 build with the kmod-nft-fullcone you gave, but I'm confused how to add the rest 3 project into my build

@bitthief
Copy link

Hi,

@wongsyrone thank you very much for this, impressive work!

I was able to integrate all your repos etc. into a nice and clean solution for OpenWRT trees, including the libnftnl and nftables patches. autoreconf was needed, but PKG_FIXUP did the trick.

Please find attached a commit in one of my forks which basically patches everything etc. and you can generate ipkgs. Tested partially on an AX3600 build, no issues. There was an initialization error with existing rules from firewall3 though, which might or might not be related.

bitthief/openwrt@baa231c

@wongsyrone
Copy link
Author

There was an initialization error with existing rules from firewall3 though, which might or might not be related.

I should change that to info level instead of warning level.

@wongsyrone
Copy link
Author

autoreconf was needed, but PKG_FIXUP did the trick.

Indeed. PKG_FIXUP is OpenWrt-specific, I just want to notify the one using GNU/Linux distros.

@skill7899
Copy link

能出个教程,怎么用openwrt-firewall4-with-fullcone 和 libnftnl-1.2.1-with-fullcone nftables-1.0.2-with-fullcone这三个补丁,我看不像是feeds。

@wongsyrone
Copy link
Author

能出个教程,怎么用openwrt-firewall4-with-fullcone 和 libnftnl-1.2.1-with-fullcone nftables-1.0.2-with-fullcone这三个补丁,我看不像是feeds。

不是feeds,需要把带有 'add fullcone' 字样的commit给 git format-patch 然后在openwrt里面就可以用了,打给对应的包即可,如果有不能打的补丁,需要适配新版本

@escape0707
Copy link

https://serverfault.com/questions/1073400/how-to-prevent-netfilter-to-automatically-change-the-source-ports

@Ovear
Copy link

Ovear commented May 11, 2023

所以希望我们能以完整的理解为基础继续讨论

我看了你更新后的内容,但是之前的回复中我也说了,这个很高概率就是对RFC的误解。

首先我们抛开RFC因素,来看看三个支援RFC5780测试的工具行为:
stun-client: 一次性测试mappingfilter,且使用同一端口
NatTypeTester: rfc5780测试模式,一次性测试mappingfilter,且使用同一端口
STUNTMAN: 推荐分开测试mappingfilter,也有一次性测试模式;一次性测试中,使用同一端口

其中stun-client目前还在Debian系等发行版内的Package中;
NatTypeTester则是Windows流行的测试发行版本;
STUNTMAN我能查到曾经是在包内的,后来不明原因移除。

在这种情况下,不能够支撑你回复中提到的需要分开端口进行测试,或测试完之后弃置端口

其次我们再来看RFC:

首先我们讨论你不愿意讨论的rfc3489,其他的我就不多说什么了。
但是这进行的测试是预期内的测试,发生预期外的行为变更本身就是奇怪的。

我们再回到rfc5780

其中你截取的一段来自于RFC中的源地址选择,后面的补充说明也提到了,对要使用的端口进行测试,是理想/支持的行为
在这种叙述之下,不能支持测试后的端口需要丢弃,实际上先前提到的rfc后续的内容则是完全反驳了这种理解。
所以你引用的内容应当理解为:对程序将要使用的端口的要求;因为推荐对端口进行测试后,再进行使用,所以在同一个**未被使用过**的端口进行测试是预期内的

综上所述,分开端口进行测试,或者测试完丢弃端口是协议中推荐,或者定义的内容这个观点并未得到支撑。

实际上的测试也说明了,如果严格按照rfc5780叙述的测试方法进行测试,无论是否使用同一端口进行测试,测试结果都是能够维持一致的。

=================================================

然后再仔细的阅读rfc5780 的 4.3,会发现:

其中进行的测试和我之前叙述的相同,一开始只针对地址变更进行测试,于是rfc中就只有了三种mapping分类:

Endpoint-Independent
Address-Dependent Mapping
Address and Port-Dependent Mapping

唯独少了我们目前测试、研究的异常情况:Port-Dependent Mapping

结合你刚才补充的conntrack和反向NAT相关叙述:https://serverfault.com/questions/1073400/how-to-prevent-netfilter-to-automatically-change-the-source-ports

我得出的结论是:

如果是rfc5780中明确定义的行为,即同端口但是不同地址,netfilter会做特殊处理:在conntrack创建跟踪时候,反向连接跟踪优先使用原端口。
而对于rfc5780中未定义的行为,为了方便我称之为Port-Dependent Mappingnetfilter则采用了conntrack默认行为,即通过至少四元组跟踪:即(src, src_port, dst, dst_port)。根据上面回答中(我还没仔细看)的所说创建反向连接跟踪(conntrack的跟踪是双向的)。
后续因为nat依赖了conntrack,所以按照快取(preserve)原则,就直接取了变更后的src_port

综合以上信息和猜测,倾向支撑了netfilter的默认nat mapping行为设计希望做到Endpoint-Independent mapping

即:netfilter很可能只支持了rfc5780所定义的内容,而对rfc3489中的行为则进行了一定程度的舍弃/没有做处理。

=================================================

所以实情回到了原点,在获得了这种行为背后的理论猜测后,我们需要做下测试来确认刚才的猜想:

通过实测方式,借助脚本和云服务的特性,确认情况下双方即使在**不同端口和地址**的情况下,打通连接。

通过这个测试加上上述推测,就可以坚固支撑netfilter默认的nat mapping设计和行为倾向于维持rfc5780中叙述的Endpoint-Independent,并能通过测试

(我在想有什么简单的方法能做到这个测试吗?)

其次如果能够查询到源码中的相关内容,就更好了;
根据之前我打了fullcone补丁,但是关闭了fullcone的测试结果,本issue中的补丁有高度可能性改变了这个“异常”行为(以此符合rfc3489中定义的行为);

我们应该有很大机会找到问题的根源。

==================================================

最后netfilter这个行为果然最大可能是一个feature而不是bug)小声

昨天大半夜就一直在怀疑conntrack,但是神志不清没想明白。
今天一边打着第一段内容,一边仔细看rfc的时候,刚好看到你刚补充的serverfault连接(感谢Github的自动刷新),突然就有思路了。

@Ovear
Copy link

Ovear commented May 11, 2023

喜报,打洞成功

netfilter确实是严格/精确维持了rfc5780中所述的Endpoint-Independent MappingAddress and Port-Dependent Filtering

关键就是上面说到的,要要做到同时/接近同时

测试方法和结果

刚刚突然突发奇想,我们所需要的测试可以通过stun服务器完成。

只需要在往原始服务器发送ChangePortAndIP请求之前,向Changed IP/Port发送任意数据,就可以打通隧道。

抓包结果

# stun bind
13:09:21.967064 enp6s0 In  IP 10.25.96.4.11111 > 139.59.84.212.3478: UDP, length 20
13:09:21.967115 enp1s0 Out IP 111.111.111.111.11111 > 139.59.84.212.3478: UDP, length 20

# stun bind reply
13:09:22.071982 enp1s0 In  IP 139.59.84.212.3478 > 111.111.111.111.11111: UDP, length 68
13:09:22.072025 enp6s0 Out IP 139.59.84.212.3478 > 10.25.96.4.11111: UDP, length 68

# stun change ip and port
13:09:22.073900 enp6s0 In  IP 10.25.96.4.11111 > 139.59.84.212.3478: UDP, length 28
13:09:22.073914 enp1s0 Out IP 111.111.111.111.11111 > 139.59.84.212.3478: UDP, length 28

# 抢先对 changed ip and port 发送任意数据
13:09:22.073926 enp6s0 In  IP 10.25.96.4.11111 > 139.59.49.16.3479: UDP, length 1
13:09:22.073945 enp1s0 Out IP 111.111.111.111.11111 > 139.59.49.16.3479: UDP, length 1

# 客户端成功接收到 changed ip and port 发送的数据
13:09:22.179487 enp1s0 In  IP 139.59.49.16.3479 > 111.111.111.111.11111: UDP, length 68
13:09:22.179518 enp6s0 Out IP 139.59.49.16.3479 > 10.25.96.4.11111: UDP, length 68

补充测试

为了确认双方向隧道都通,将上述测试中的发送任意包到Changed IP/Port修改为:

Changed IP/Port发送Bind Request,发送时变更transaction-id,以免程序混淆。

测试结果说明双向隧道均已打通。

抓包结果

# stun bind
13:30:45.455410 enp6s0 In  IP 10.25.96.4.25555 > 139.59.84.212.3478: UDP, length 20
13:30:45.455454 enp1s0 Out IP 111.111.111.111.25555 > 139.59.84.212.3478: UDP, length 20

# stun bind reply
13:30:45.565092 enp1s0 In  IP 139.59.84.212.3478 > 111.111.111.111.25555: UDP, length 68
13:30:45.565122 enp6s0 Out IP 139.59.84.212.3478 > 10.25.96.4.25555: UDP, length 68

# stun change ip and port
13:30:45.566864 enp6s0 In  IP 10.25.96.4.25555 > 139.59.84.212.3478: UDP, length 28
13:30:45.566875 enp1s0 Out IP 111.111.111.111.25555 > 139.59.84.212.3478: UDP, length 28

# 同时对 changed ip and port 发送 bind(更换trans_id,以免程序混淆)
13:30:45.667365 enp6s0 In  IP 10.25.96.4.25555 > 139.59.49.16.3479: UDP, length 20
13:30:45.667400 enp1s0 Out IP 111.111.111.111.25555 > 139.59.49.16.3479: UDP, length 20

# 回复 stun change ip and port
13:30:45.682708 enp1s0 In  IP 139.59.49.16.3479 > 111.111.111.111.25555: UDP, length 68
13:30:45.682726 enp6s0 Out IP 139.59.49.16.3479 > 10.25.96.4.25555: UDP, length 68

# 回复对 changed ip and port 发送的 bind
13:30:45.782210 enp1s0 In  IP 139.59.49.16.3479 > 111.111.111.111.25555: UDP, length 68
13:30:45.782234 enp6s0 Out IP 139.59.49.16.3479 > 10.25.96.4.25555: UDP, length 68

@escape0707
Copy link

  • 来看看三个支援RFC5780测试的工具行为
  • 首先我们讨论你不愿意讨论的rfc3489

你不应该再提过时的 RFC 3489 了。我已经强调过原因了,这里总结一下:

  1. 它本身对 NAT 行为的分类就是模糊和有误导性的
  2. 它本身对 NAT 行为的检测建议是没有考虑 STUN2 发包但被拒绝后在 NAT 的防火墙上带来的副作用的,这是疏忽
    If no response is received, it performs test I again, but this time,
    does so to the address and port from the CHANGED-ADDRESS attribute
    from the response to test I.  If the IP address and port returned in
    the MAPPED-ADDRESS attribute are not the same as the ones from the
    first test I, the client knows its behind a symmetric NAT.
    
    而 RFC 5780 中建议的方法
    In test II, the client sends a Binding Request to the alternate
    address, but primary port.
    
    是可以避免这种副作用的
  3. 人思考问题需要依据的是依照优先级是理性、常识、还有历史。对于 RFC 3489 你在知道它的误导性和后续的 RFC 5780 提议的更准确的分类方法、以及 RFC 5128 指示的 udp 打洞常见实践以后,你应该可以独立得出为了设计可以 udp 打洞的 NAT 你需要什么 NAT 行为、NAT 行为测试,以及什么 udp 打洞算法。之所以我们先提这些 RFC、术语、工具,只是为了节省沟通时间、方便交换基于常识和历史的知识。但当我们的常识不一致的时候,我希望能够回归到理性去思考——比如 udp 打洞这个需求到底需要的什么。不要再过分拘泥于 RFC 和前人工具的实现了。

接下来我主要基于理性,辅以常识来解释我的意见:

  1. 根据我的思考、RFC 5128,当然还可以加上 tailscale 的讨论,容易的 udp 打洞最小只需要 EIM-NAT。所有 fullcone 之类的老名词、RFC 3489 的测试之类的统统不要再提了,要提的话也是要告诉后人这是以前经验不足的时候的错误经验。
  2. 要测试 EIM-NAT 与否,一个客户端只需要进行类似 RFC 5780 中的测试I和II能得出的结论即可。而实际 P2P 程序甚至不需要进行测试,只要按照 RFC 5128 的方法去打洞,你只要通了就是通了没通就是没通。
  3. 你所拘泥的类似所谓 Port-Dependent Mapping 的现象,其实已经不是你的 NAT 自己的现象了。你的 NAT 必须被 STUN2 主动连接过 NAT 上的端点并被影响过才会发生这种结果。而单纯并受控的 P2P 打洞中完全可以控制不让这种现象发生并顺利先发包完成打洞。所以这严格来说并不是 NAT 自己的行为,也不影响打洞。而是 NAT 对 STUN2 的提前主动交互的应对,对于 Linux 防火墙来说 NAT 内部客户端没有联系 STUN2 却从那边发来了包意味着 STUN2 很有可能是恶意第三方,所以触发什么保护措施都是合理的。不能非拘泥于你原来的自定义的模仿 RFC 3489 的测试流程。
  4. 根据我的思考、辅以 RFC 5780 4.5 的说法,你需要注意合并多次测试、合并 Mapping 和 Filtering 测试所带来的影响,特别是在防火墙状态中遗留的副作用。结合 2,你对于 NAT 类型的测试肯定只需要测出来 EIM-NAT 也就够了,并且你也已经测出来了。你只要按照我之前让你用 stun-server 测试的两条命令做就能得知你的 Linux 是 EIM-NAT。
  5. 对于 RFC 5780 提到的两个测试为什么也注意规避副作用换不同端口测试的论点,更易懂的,你要是先测 Mapping 后测 Filtering,再加上你之前自定义的往 STUN2 发 BIND 还是发和 Filtering 测试时想测的一样的端点的话,显然你会因为给 STUN2 发过包而一直测出来 EIF-NAT。(不知道为什么这种副作用的影响反过来你就不认可了

如果是rfc5780中明确定义的行为,即同端口但是不同地址,netfilter会做特殊处理

这里你的理解还是错误的,不是 NAT 映射行为在决定这个,而是你之前请求了 STUN1 从 STUN2:changedPort 给你发测试 Filtering 的包,在防火墙上带来了副作用才导致你连 STUN2:changedPort 的时候被分别了新的端口的。事实上你不要去连 STUN2:changedPort 而是去连除了 changedPort 以外的所有端口都不会被 NAT 改端口。实际上假设如果 STUN 服务器允许的话,如果你的 CHANGE-REQUEST 里不是设置 change-port and change-IP,而是只设置 change-IP 的话,那你测试的结果就正好反过来——连除了 STUN2:originalPort 以外的所有其他端点都不会被改端口,但连它会被改。

对于这个 STUN2 的提前到的数据包带来的副作用,才是我比较感兴趣的东西,我之前讨论的时候搜过一些关键词但是没有找到具体的文档或者源码指出是哪一部分设计带来的这种副作用、有没有什么开关可以控制。并且这个副作用对 P2P 打洞确实有一定的影响,需要双方约定好同时发包。这个是我前面也和你说过的,但这部分已经和 EIM-NAT 与否无关了,是 Linux 防火墙对于可能是恶意的发包的处理方式和对打洞的影响的问题。我们最好先得出 Netfilter 不用 random 确实是 EIM-EDF-NAT 的结论。

只需要在往原始服务器发送ChangePortAndIP请求之前,向Changed IP/Port发送任意数据,就可以打通隧道。

这不是理所当然的吗 🤦 人家 STUN2 服务器有公网IP,你先给有公网IP的机器发了,它又没设置屏蔽你的防火墙规则的话,当然能往回给你发啊这是 UDP 打洞中的基础。。我建议你看一下 RFC 5128 3.2 Connection Reversal

@Ovear
Copy link

Ovear commented May 11, 2023

我发现你的思考逻辑,有比较强烈的跳跃性;你提到的东西,很多都是额外附加的,讨论时并未列出来源,所以这块有差异很正常。

这不是理所当然的吗 人家 STUN2 服务器有公网IP

我们测试的本地路由的行为,和对端没有关系,我不知道你提对端时在这里的作用是什么。事实上,如果你仔细看过你之前发的内容,就知道nat映射是双向的。

是可以避免这种副作用的

但是这条也存在同样的疏忽,按照RFC的意见是没有Port-Dependent Mapping的,但是是理论上有可能存在的。

不要再过分拘泥于 RFC 和前人工具的实现了

如果没有实现规范中所说的内容,那规范的存在就没有意义;工具是对规范的实现,本质上对行为是实现快速测试,所以去复现也是很重要的一环。

容易的 udp 打洞最小只需要 EIM-NAT。所有 fullcone 之类的老名词、RFC 3489 的测试之类的统统不要再提了

我们应该思考EIM-Mapping究竟是什么,我认为本质是NAT匹配的元组数目,既然如此Port-Dependent Mapping是客观存在的。

所以这严格来说并不是 NAT 自己的行为,也不影响打洞

你没有考虑过丢包的情况,如果双方互相发送包的时候,一方丢包,对端就会退化进入Dependent Mapping,这是客观存在且会造成的影响。
也不能证明所以触发什么保护措施都是合理的,目前这种实现单纯只是netfilter严格按照rfc实现的结果罢了。

根据我的思考、辅以 RFC 5780 4.5 的说法,你需要注意合并多次测试、合并 Mapping 和 Filtering 测试所带来的影响,特别是在防火墙状态中遗留的副作用

这个说法我是同意的,所以我也一直在强调要严格按照RFC5780提供的方法测试,但是文章中很显然没说明一定不能,而且是推荐要做
除此之外RFC5780中有一句重要的话

This usage does not provide backward compatibility with RFC 3489 [RFC3489] for either clients or servers.

所以我在后面的回复,也说明了netfilter是没有考虑这个RFC3489规范的;这也是我们争论了这么久的一个内容。
但是这也不能证明RFC3489就是错误经验,这是一个规范而已,只有能不能符合而已。

对于 RFC 5780 提到的两个测试为什么也注意规避副作用换不同端口测试的论点

这个我也反复陈述过了,严格按照RFC5780进行测试是没问题的。你说的这些都不是规范中说明一定要这么做的。

实际上假设如果 STUN 服务器允许的话,如果你的 CHANGE-REQUEST 里不是设置 change-port and change-IP,而是只设置 change-IP 的话,那你测试的结果就正好反过来——连除了 STUN2:originalPort 以外的所有其他端点都不会被改端口,但连它会被改

这里你提醒我了,我确实漏了这个测试,测试后确实是如你所说的。也正因为这样,我发现了一个有趣的地方,也确认了映射关系被改变。

ipv4     2 udp      17 115 src=10.1.96.4 dst=198.211.120.59 sport=20002 dport=3478 src=198.211.120.59 dst=222.222.222.222 sport=3478 dport=20002 [ASSURED] mark=0 zone=0 use=2
ipv4     2 udp      17 23 src=111.111.111.111 dst=222.222.222.222 sport=3478 dport=20002 [UNREPLIED] src=222.222.222.222 dst=111.111.111.111 sport=20002 dport=3478 mark=0 zone=0 use=2
ipv4     2 udp      17 25 src=188.166.128.84 dst=222.222.222.222 sport=3478 dport=20002 [UNREPLIED] src=222.222.222.222 dst=188.166.128.84 sport=20002 dport=3478 mark=0 zone=0 use=2
ipv4     2 udp      17 27 src=10.1.96.4 dst=111.111.111.111 sport=20002 dport=3478 [UNREPLIED] src=111.111.111.111 dst=222.222.222.222 sport=3478 dport=41322 mark=0 zone=0 use=2

这里你的理解还是错误的,不是 NAT 映射行为在决定这个,而是你之前请求了 STUN1 从 STUN2:changedPort 给你发测试 Filtering 的包

没有看明白为什么是错误;我认为这不是副作用,是conntrack本身的作用。如果你注意conntrack本身行为,那就知道至少四元组匹配。
实际上nat功能就是严重依赖conntrack的,讨论conntrack的行为和nat映射本身行为的一部分。
如果要深入讨论这一行为,就必须去查看相关代码了。
不过,如果你能够理解conntracknat的关系的话,就会理解为什么src port会发生变化了。

我们最好先得出 Netfilter 不用 random 确实是 EIM-EDF-NAT 的结论

我得出的结论已经说过了,他是严格按照rfc5780实现的,符合rfc5780中对Endpoint-Independent mapping的定义,也能通过测试。

换句话说就是rfc5780明确说明之外的行为都不保证。

我的想法还是,有机会可以自己测试下,很多事情就会豁然开朗。学而不思则罔,思而不学则殆,最终还是要落到实践上的。

但你这里的命题是错误的,说明你对 UDP 打洞和 NAT 并没有理解。正确情况是只要打洞时双方都发包了,自己的 NAT 就会完成并记录这个映射

网络中任一段都有可能产生丢包的,发生这个命题的可能性有两段。

@escape0707
Copy link

escape0707 commented May 11, 2023

如果要深入讨论这一行为,就必须去查看相关代码了。

我现在就是在看这块儿的源码。直接个你指个路吧,按顺序一步步递进(原始博客看的是较老版本的仓库了,部分源文件已经重命名、合并):

https://www.hwchiu.com/iptables-masquerade.html
https://git.netfilter.org/iptables/tree/extensions/libxt_NAT.c?h=4c923250269f9ef4a7b4235f4dc127b04932a8eb#n286
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/xt_MASQUERADE.c#L35
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/nf_nat_masquerade.c#L28
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/nf_nat_core.c#L580
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/nf_nat_core.c#L504
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/nf_nat_core.c#L185
https://github.com/torvalds/linux/blob/105131df9c3b27673392a6b7ff356360188dc869/net/netfilter/nf_conntrack_core.c#L1299

你没有考虑过丢包的情况,如果双方互相发送包的时候,一方丢包,对端就会退化进入Dependent Mapping

你别的留言我还没有来得及看完,但你这里的命题是错误的,说明你对 UDP 打洞和 NAT 并没有理解。正确情况是只要打洞时双方都发包了,自己的 NAT 就会完成并记录这个映射,之后允许对方端点发到自己内部客户的端点的数据包顺利被 DNAT。对方的包只要没有早于自己发包就到达自己的 NAT 的话就不会影响自己的 EIM-NAT 行为。实际 P2P 应用开发中,这个环节也是从约定的时间开始同时向对方发包,并且发送多次以防止仅仅是丢包导致的打洞失败。并且如果只是为了防止自己发的包抢先与对方发包就到达了对方 NAT 破坏了打洞的条件,完全可以通过 TTL 来控制只让包发到自己的 NAT 或者 NAT 的下一跳为止。

我们测试的本地路由的行为,和对端没有关系,我不知道你提对端时在这里的作用是什么。

你原文用的是“打通隧道”,这是当然会“通”的,原因我解释了。既然你说的是打通隧道收到对方发进来的包,你的说法中就包含了“这次对方发进来的包并没有被 EDF-NAT 给过滤”这层含义。这个测试中当然是和这个特定对端有关的,因为你给这个对端发包了。另外你说你必须“抢先发包”,这就和我前面说的行为是一致的。你要是让对端先给你发包了,你再给他发包的时候映射端口就会被改变。一切和我说的是一致的。

如果没有实现规范中所说的内容,那规范的存在就没有意义

你这个就太想当然了,包括PCP和推荐的CGNAT的EIF+EIM都没有被广泛实现。要说规范应该被实现,人人都应该用上IPv6,不要再考虑这个所谓 FullCone 的问题才对。并且规范是会被修订的,5780就是修订的3489

既然如此Port-Dependent Mapping是客观存在的。

他不存在,如果你理解我给你留言说的副作用的事情,你就知道这不是因为你的 NAT 自己的性质,而是对端抢先发包干扰了你的 NAT。我之前之所以给你提这个词是在还没有搞明白你的NAT为什么会在你的自定义测试中改变你的端口的情况下,用 RFC 5780 的术语打了个比方。后面我已经说明了你的问题并不是 NAT 行为问题,所以这个比喻也完全不正确了。然后根据奥卡姆剃刀原理, RFC 5780 定义的 EIM 与否 和 EIF 与否的概念足以解决打洞所遇到的 NAT 类型判别问题了,所以不需要再琢磨创建一个新名词。

没有看明白为什么是错误;我认为这不是副作用,是conntrack本身的作用。
不过,如果你能够理解conntrack和nat的关系的话,就会理解为什么src port会发生变化了。

这不只是 conntrack 本身的作用,这更根本的原因是你逼着 STUN2 抢先给你这个端点发包。正常的 P2P 连接中就如我之前和刚刚所说,是可以也应该自己控制这种事情不发生。按照我刚刚看源码的过程的理解,你这个抢先发包的后果就是 conntrack 记录了来自 STUN2 的发包并创建了单独的 conntrack 来记录,之后你再给 STUN2 发包的时候 NAT 给你找端口的时候就觉得你这个连接和上面那个 conntrack 不是一个了,所以给你分配了新的。我认为这是很正常的行为。

但是文章中很显然没说明一定不能,而且是推荐要做。但是这也不能证明RFC3489就是错误经验
你说的这些都不是规范中说明一定要这么做的。

钻牛角尖就没有意义了。我们这整个讨论、issue、甚至仓库的中心都在于要不要给OpenWRT甚至是Linux加入 FullCone 来解决 打洞不便的问题。而这一点上现在和你最初回复我之前我的结论仍然一致,现在 Linux 的行为就已经足够了,并不需要改变。如果改变,也不可能是 Linux/Netfilter 的 bug。同时他们为了节约开源项目的人力物力也不会接受 Feature Request 和 Pull Request。但这并没有什么问题。

换句话说就是rfc5780明确说明之外的行为都不保证。

我前面也说明过了,正是因为除此以外的行为都不需要(除了 BT 这种没有会合服务器的情况),所以 Netfilter 才没有也不会去做多余的事情。如果你正确理解了 UDP 打洞的话,你也就能理解我这么说的原因了。包括我们这个话题开始的缘由——Linux 和 OpenWRT 不需要 “FullCone NAT“ 实现

你有一些言论说实话和讨论的问题关系也不大,我就先忽略了:

我发现你的思考逻辑,有比较强烈的跳跃性;你提到的东西,很多都是额外附加的,讨论时并未列出来源
我的想法还是,有机会可以自己测试下,很多事情就会豁然开朗。学而不思则罔,思而不学则殆,最终还是要落到实践上的。

@Ovear
Copy link

Ovear commented May 11, 2023

讨论到这里,我发现没有什么可以讨论的了;毕竟现在两种说法都说的通。

我不太熟悉内核,如果你能够看懂的话我期待一个分享。

另外我给个建议,尽量不要用缩写,用术语就好了。

但你这里的命题是错误的

这个我刚才编辑的时候回复过了,这是可能发生的,所以才要想方法解决。

你再给他发包的时候映射端口就会被改变

这个我就当我们达成一致了,一开始讨论的行为就是这个。

我们现在的讨论的应该是在原因,但是你下面的说法就需要源码支撑了。

他不存在,如果你理解我给你留言说的副作用的事情,你就知道这不是因为你的 NAT 自己的性质,而是对方抢先发包干扰了你的 NAT

钻牛角尖就没有意义了。

这个对你同样你也是的,你太过在意是不是通过一个端口去测试了,实际这些软件的实现也是一个端口的,但是不影响结果。

所以不需要再琢磨创建一个新名词。

实际上这个分类行为本身就是RFC5780做的。

按照我刚刚看源码的过程的理解来说,你这个抢先发包的后果就是 conntrack 记录了来自 STUN2 的发包并创建了单独的 conntrack 来记录,之后你再给 STUN2 发包的时候 NAT 给你找端口的时候就觉得你这个连接和上面那个 conntrack 不是一个了,所以给你分配了新的。我认为这是很正常的行为

你的描述有一点问题,我没太看懂。
但是后面conntrack方面这是看到的现象,也是我放出来的原因;在没有源代码的情况下,能观察的就这么多了,我这也是我强调conntrack的运作方式的原因。

正是因为除此以外的行为都不需要(除了 BT 这种没有会合服务器的情况)

这个就是我的看法了,现在的行为比我之前要预想的好;
但是还是没有能支持Linux 和 OpenWRT 不需要 “FullCone NAT“ 实现,因为你也说了是存在正常且无法覆盖的场景。
至于你后面发散的内容也并不是重点。
但是如果在社区底下要求社区无视这种需求的存在,跟他们说你们做的东西不需要,没有意义,这就不能接受了。

这不只是 conntrack 本身的作用,这是你逼着 STUN2 抢先给你这个端点发包导致的结果。并且正常的 P2P 连接中就如我之前和刚刚所说,是可以自己控制这种事情不发生,也应该控制的。

1.正常的P2P连接,是专指UDP打洞吗?其他的P2P连接方式,没有看见有这个限制。
2.如果你手动做了DNAT,就没有这个限制了。

在没有源代码支持的情况下,从目前给出的信息,只知道NAT映射被修改了,但是没办法知道原因。

现在看下来我的猜测也基本都得到验证了,如果能有源码方面的分析,期待分享。

@escape0707
Copy link

escape0707 commented May 11, 2023

这个我刚才编辑的时候回复过了,这是可能发生的,所以才要想方法解决。

我从来没说不可能发生丢包,但我要说的就是丢包恰恰不会导致你自己的 NAT 出现 EIM-NAT 的行为。如果你能理解就好了。

你太过在意是不是通过一个端口去测试了,实际这些软件的实现也是一个端口的,但是不影响结果。

我无语了。软件测出来你是 EIM 和 对称式NAT 的原因我前面都给你分析过了。也给你分析过了什么是能解决你的需求的,你要是不愿意去理解那就没办法了。不是我太过在意,是你没有理解发生了什么。

但是如果在社区底下要求社区无视这种需求的存在,跟他们说你们做的东西不需要,没有意义,这就不能接受了。

你可以继续做,本来要不是你引用了我的回复并提出了你发现的这个现象我这两天就会和别的订阅一样,是不会回复和测试的。

其他的P2P连接方式,没有看见有这个限制。

你不妨举一个非要抢先而不是同时来打洞的应用的例子。当然,除了BT这种没有会合服务器的。

手动做了DNAT

这不也是说了等于没说,DNAT就是端口转发了,你平时要是能给 CGNAT 做端口转发(PCP协议)那你也不用纠结了。。。

讨论到这里,我发现没有什么可以讨论的了;毕竟现在两种说法都说的通。

如果你哪天能理解我这条评论里第一句回复的话我们可以接着讨论,不然的话确实讨论下去也没有意义。

或许,我前面提的 tailscale 的那篇文章,你再仔细读一遍也许能帮助理解?

@Ovear
Copy link

Ovear commented May 11, 2023

网络中任一段都有可能产生丢包的,发生这个命题的可能性有两段。
这是可能发生的,所以才要想方法解决。

但我要说的就是丢包恰恰不会导致你自己的 NAT 出现 EIM-NAT 的行为

我说的很明白了,我再引用一下,我不知道你是没看到,还是发生什么了。

我无语了。软件测出来你是 EIM 和 对称式NAT 的原因我前面都给你分析过了。也给你分析过了什么是能解决你的需求的,你要是不愿意去理解那就没办法了。

没明白你的意思,在我的角度看来反倒是一直是我在和你解释,测试也是我做的,结果和结论(包括纠正)也是我发的。只是很可惜你提供的内容都是理论分析,而我更倾向于实际一些的东西。

并提出了你发现的这个现象我这两天就会和别的订阅一样,是不会回复和测试的

所以我们解决了这个疑问,至少是大部分,这是一件好事;你愿意参与我是很高兴的,没有的话我自己琢磨,或者等一个有缘人都是意料内的。刚好我也希望我们的讨论能帮到搜索过来的同学。

你不妨举一个非要抢先而不是同时来打洞的应用的例子。当然,除了BT这种没有会合服务器的。

这句话的意思让人看起来有种去除了正确答案,都是错误答案这种感觉。
排除BT这一常见应用也不能理解,没有会合服务器也很正常。
现实情况就是,这种需求无法得到满足,但是有方法可以获得,我想不到拒绝的理由。
更何况是在社区内有人愿意的情况下,我非常感谢他们的努力。

这不也是说了等于没说,DNAT就是端口转发了,你平时要是能给 CGNAT 做端口转发(PCP协议)那你也不用纠结了。。。

或许,我前面提的 tailscale 的那篇文章,你再仔细读一遍也许能帮助理解?

既然在现象上,我们达成一致了。
那么现在就差原因没有解决了,我提出这个问题也是希望后面有大佬能看到,刚好推进一下,那就最好了。

我当然理解理想情况;但是我们面对的是一个具体实现,我的疑问也是对这个具体实现来说的。当然也包括我之前说到的RFC中未提到的那种分类。
这个问题我们今天倒腾了这么久,还是没有解决是有点可惜。

祝晚安。

@escape0707
Copy link

escape0707 commented May 11, 2023

网络中任一段都有可能产生丢包的,发生这个命题的可能性有两段。这是可能发生的,所以才要想方法解决。

我说的很明白了,我再引用一下,我不知道你是没看到,还是发生什么了。

别的都不谈,我就是不明白你这里在说什么。当然是会有丢包,然后呢?你担心丢包导致什么不理想的后果?为什么你认为会有这样的结果?

排除BT这一常见应用也不能理解,没有会合服务器也很正常。
现实情况就是,这种需求无法得到满足,但是有方法可以获得,我想不到拒绝的理由。

如果你是 NetFilter 的维护者你确实可以去维护这个功能,但是你不能否认这一部分没有会合服务器的需求是小众的,并且是没有赞助商、商业公司等支持着开源社区去开发的。希望你之后能成为一个 Linux 内核代码、NetFilter 的维护者。

@Ovear
Copy link

Ovear commented May 11, 2023

别的都不谈,我就是不明白你再说什么。是会有丢包,然后呢?你担心丢包导致什么结果,为什么你认为会有这样的结果?

双方任意一方,包在到路由之前丢了,那这个端口的打洞就宣告失败了,因为行为改变了。

并不是你说的恰恰不会导致你自己的 NAT 出现 EIM-NAT 的行为

如果你还是没办法理解的话,那就再具体一点。

双方通过stun获取到WAN端的地址了,但是互相通信的时候就出现在路由丢包的问题了。

路由:指有这个行为,且有公网IP的路由。你可以假设是双方都用openwrt,都有公网ip,这是最简单的场景,希望能帮助你理解。

但是你不能否认这一部分没有会合服务器的需求是小众的,并且是没有赞助商等支持着开源社区去开发的。希望你之后能成为一个 Linux 内核代码、NetFilter 的维护者

我个人不认为BT是小众的;表达支持的方法也是多样的,这个社区中已经有人愿意站出来,并已经开发并维护了很长一段时间。

我很感激他们,我不认为他们做的事情是“无意义”的,“没有必要”的,这么去说他们是不妥的。

开源社区本来就是百花齐放的,有人愿意做,有人愿意用,有人愿意接手,有人愿意捐赠,这就是社区运作的模式。

@escape0707
Copy link

escape0707 commented May 11, 2023

包在到路由之前丢了

你说的路由是哪个路由?是你自己的 ISP NAT?是你自己家的路由器?还是对端的 NAT?

@escape0707
Copy link

escape0707 commented May 11, 2023

且有公网IP的路由。

也就是说,你也认可讨论打洞可能性的前提是忽略掉自己客户端机器到第一个能给你映射公网端点的NAT之间的丢包是吧。

那就好说了,我可以明确告诉你不会影响你打洞,因为当你和你的对端同时给对方的握手包在这段默认不丢包的网络传输上顺利传完并到达你的公网网关的时候,你们的公网网关NAT路由就已经给你们分配了映射,并且这个映射是被设置为可以接受来自你们对方的NAT的公网端点传来的数据的。这是NAT的基础中的基础的保证。

这样子,之后你们的握手包在互联网上的路由器之间传输的时候,即使任意一个地方发生了丢包,也至少有30秒的时间(这个是conntrack,RFC 对CGNAT的要求我没有细看,但只会更久不会更短)这个{协议、NAT后地址、NAT后端口、目的地址、目的端口}五元组是分配给你这个连接的。即使发生了丢包,只要你们重复发包,最终只要有包能到达,它就能被转发进来。

也就是说,其实只要你们的NAT是EIM-NAT,那么你们打洞的成功在你们两方的握手包到达各自的公网网关NAT路由的时候就已经成功了。一般情况下可以不用考虑对端的数据发到你们网关比你发到你们网关还快的情况。另外如果真的要考虑这种情况,你们双方可以用小 TTL 来控制,让握手包能通过自己的网关但是不到达对方的网关。

你再仔细想一想。

@Ovear
Copy link

Ovear commented May 11, 2023

看懂你为什么没明白了。。。

这段默认不丢包的网络传输上顺利传完并到达你的公网网关的时候

网络中任一段都有可能产生丢包的

@escape0707
Copy link

escape0707 commented May 11, 2023

这段默认不丢包的网络传输上顺利传完并到达你的公网网关的时候
网络中任一段都有可能产生丢包的

如果你连你自己的客户端机器到自己ISP公网网关的服务质量都不能保证,那你有比需要UDP打洞更大的问题要考虑了。你不要钻这个牛角尖。另外我和你早就说过了,你可以通过 TTL 来控制握手包能通过自己的网关但是不到达对方的网关。也就是说你有无限的重试的机会,即使你客户端到ISP的通信质量很差,也不会影响你打洞。你再仔细想想。。

@Ovear
Copy link

Ovear commented May 11, 2023

你不要钻这个牛角尖

将讨论问题时使用严谨的表达,用”钻牛角尖“这种说法来过度简化不好。
况且我们本身就是在讨论你说这里的命题是错误的是不严谨的。

如果这个你能理解的话,今天就先这样吧,也不早了。

至于你说没有遇到过类似的问题,可能是没这个场景,我可以给你几个我正在使用的场景你考虑下。

1.任何无线网络,涵4G/5G/WiFi
2.SDWAN,任何形式的(涵多层NAT)。如果不理解的话可以参考下我第一次测试的环境,这也是一种很常见的用法。
3.P2P同端口场景下,至少有一个IP出现问题的概率。

我们讨论的是问题存在,至于问题的解决方案,那是多种的。我也并不指望每一位相关开发者都能够如此完善处理这件本身就并不简单的事。

现在我们确认有这种场景就够了,我作为已经遇到过的用户将自己遇到的事情分享出来,那么就能帮助够遇到这种问题的同学。

千言万语汇成一句话,我支持并感谢这个项目以及参与或为项目贡献的所有人,包括你我。

@linepro6
Copy link

linepro6 commented May 17, 2023

首先感谢大佬编写的 fullcone 补丁。
想咨询一下大佬,如果我想在 OpenWRT 本机实现类似 FullCone NAT 的防火墙规则,我该如何做?具体来说就是在不主动开放端口的情况下,我使用 UDP 的某个源端口对外通信,在一定时间内(如 30 秒)任意 IP 任意端口的 UDP 流量都可以通过这个源端口顺利入站,而不被防火墙阻拦。
我尝试了给 output 链添加 fullcone 规则,但是提示不支持。

root@OpenWrt:~# nft add rule inet fw4 output_wan fullcone
Error: Could not process rule: Not supported
add rule inet fw4 output_wan fullcone
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@jjm2473
Copy link

jjm2473 commented Jul 13, 2023

仿佛在看学术论文

@94Bo
Copy link

94Bo commented Jul 17, 2023

首先感谢大佬编写的 fullcone 补丁。 想咨询一下大佬,如果我想在 OpenWRT 本机实现类似 FullCone NAT 的防火墙规则,我该如何做?具体来说就是在不主动开放端口的情况下,我使用 UDP 的某个源端口对外通信,在一定时间内(如 30 秒)任意 IP 任意端口的 UDP 流量都可以通过这个源端口顺利入站,而不被防火墙阻拦。 我尝试了给 output 链添加 fullcone 规则,但是提示不支持。

root@OpenWrt:~# nft add rule inet fw4 output_wan fullcone
Error: Could not process rule: Not supported
add rule inet fw4 output_wan fullcone
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

不是这个chain,而且需要从srcnat与dstnat两边都写入fullcone。具体哪个chain可以看luci中的Status-->Filewall,很清晰。

举个例子从shell添加的话需要:(以wan为output为例)

#Add if no Port Forward rules in fw4, fw4 won't add this automatically
nft insert rule inet fw4 input_wan ct status dnat accept
nft insert rule inet fw4 forward_wan ct status dnat accept

nft add rule inet fw4 dstnat_wan meta nfproto ipv4 fullcone
nft add rule inet fw4 srcnat_wan meta nfproto ipv4 fullcone
#Or we just want some IPs from lan using fullcone
#nft insert rule inet fw4 srcnat_wan ip saddr {192.168.1.2, 192.168.1.3} fullcone

或者写入配置文件,持久化。

# cat /etc/nftables.d/99-fullcone.nft

chain dstnat_wan {
    meta nfproto ipv4 fullcone
}

chain srcnat_wan {
    ip saddr { 192.168.1.2, 192.168.1.3 } fullcone
}

@Headcrabed
Copy link

各位好,我有一点疑惑,为何没有人把这个patch推到kernel上游呢?我想自己搞但奈何网络相关知识基本没有任何基础(之前给mainline提交的patch都是驱动相关)openwrt上游对于这个补丁态度我已经找到原文了,感觉只有kernel上游整合了fullcone支持他们才会去支持

@ysc3839
Copy link

ysc3839 commented Apr 8, 2024

@Headcrabed 此项目可以作为内核模块编译,不需要修改内核,所以可以自行编译然后安装到原版OpenWrt中使用。
参见 #42 (comment)

@Headcrabed
Copy link

@Headcrabed 此项目可以作为内核模块编译,不需要修改内核,所以可以自行编译然后安装到原版OpenWrt中使用。 参见 #42 (comment)

我更希望不需要单独维护这样一个内核模块,而是能够直接从上游内核代码获取这个功能,所以才希望能推到上游

@jjm2473
Copy link

jjm2473 commented Apr 12, 2024

@Headcrabed 我觉得还不如研究这个 bcm-fullconenat ,性能比较好,而且是在 masquerade 模块打的补丁,前端的iptables或者nftables只要加个参数支持就行,不再需要额外的内核模块。

https://github.com/coolsnowwolf/lede/blob/master/target/linux/generic/hack-5.10/982-add-bcm-fullconenat-support.patch

https://github.com/coolsnowwolf/lede/blob/master/package/network/utils/iptables/patches/900-bcm-fullconenat.patch

@Mosney
Copy link

Mosney commented May 13, 2024

@Headcrabed 此项目可以作为内核模块编译,不需要修改内核,所以可以自行编译然后安装到原版OpenWrt中使用。 参见 #42 (comment)

看起来维护到22.03就停止发布编译好的ipk了,目前看来GitHub CI也是删掉了,对于编译苦手来说想要在主线OpenWrt上实现fullcone还挺难搞的...

@jertoon
Copy link

jertoon commented Dec 5, 2024

ip saddr 192.168.1.3 oifname "enp1s0" masquerade

@alfred859
Copy link

flush ruleset

table inet filter {
chain input {
type filter hook input priority 0;
}

chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    ip saddr 172.16.0.0/26 oifname "enp1s0" accept
    ip saddr 172.16.1.0/24 ip daddr 172.16.0.0/26 tcp dport 3128 accept
}

chain output {
    type filter hook output priority 0;
}

}

table ip nat {
chain pre {
type nat hook input priority 0;
}

chain post {
    type nat hook output priority 0;
    ip saddr 172.16.0.0/26 oifname "enp1s0" masquerade
    ip saddr 172.16.1.0/24 oifname "enp1s0" masquerade
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests