TLDR 一句话: 硬路由利用 nfqueue 把关键包的处理逻辑外包给软路由
硬路由在专用芯片加持下,网络处理上的稳定性与性能上限是远高于软路由的,但我们很多人还是选择软路由当主力路由,不过是因为 x86 系统特别灵活,玩法很多。但仔细分析网络里的各个流程就可以发现,无论是软硬路由,灵活玩法大多来自于对各连接建立的包的处理,即 linux 里面的 iptables/nftables nat 表里的那些包。软硬路由都通过 cpu 处理这些包,其余的绝大部分包硬路由走专用芯片,软路由用 cpu 硬扛。
现在路由器大多基于 linux, linux 里面有各叫 nfqueue 的东西,可以把 iptables/nftables 里面感兴趣的包发到用户态进程里面,然后用户态可以进行一些操作,比如通过、丢包、拒绝、打 mark 、SNAT/DNAT. 但硬路由上由于 arm/mips 架构难搞、cpu 内存紧张等原因,这个机制像螺蛳壳里做道场,很鸡肋。
所以我在想是不是能在路由器上写个最轻量化的 nfqueue-agent, 把所有收到的包通过 tcp 转发到软路由的用户态 nfqueue-controller ,然后在 x86 上就可以 java/golang/python 爱怎么玩都行了?
应用场景:
ip 段分流/wireguard/zerotier
静态 ip 段路由表管理挺繁,要是 BGP 级别的话,ip 段文件不小,很多老古董 nand 甚至存不下。复杂一点的动态路由要搭建 bird/frr 服务,很麻烦。而我的方案里,nfqueue-controller 可以根据包的内容直接给包打上 mark, 再通过策略路由就很简单实现了分流。x86 可以搭建 wireguard/zerotier ,灵活度有保证。
无污染 dns 服务/fakedns/根据域名分流
传统域名分流很多是搞 ipset/nftables set ,要是路由器内核不支持就很难搞。nfqueue-controller 可以强行把所有 udp53 的包通过 mark 路由到自己 x86 节点,自己走 doh/dot. 也可以把 fakedns/vpn 的 IP 段通过 mark 路由到自己节点.根据请求域名的判断可以在 x86 端用户态维护一个 ipset,在下一次 tcp 请求中自动分流。
fullcone nat
可以把硬路由器自己的 nftables/iptables masquerade 都干掉,在 nfqueue 里进行 snat/dnat.不过这个我不太确定会和 linux conntrack 系统有什么化学反应
multiwan 负载均衡
用户态控制逻辑,想怎么分配就怎么分配
软路由节点 down 后 fallback
一旦硬路由上的 nfqueue agent 发现软路由超时未回复,立刻断开 nfqueue 绑定, 则所有网络设置恢复到单硬路由状态,不会引起断网。
大量新连接、路由表很长很复杂
这时候每个新连接的包都要经过网络给 controller 处理,可能会造成一些压力,不过可以在硬路由里利用 nftables 里面自定义 set/map 的功能可以缓存处理结果 mark ,例如连接五元组 30 分钟有效期内复用上次的 mark. 如果路由器只有 iptables 且没有 ipset, 也可以在路由器的 nfqueue-agent 里缓存结果。 不需要所有的都经过控制服务器,
这样只要支持 nfqueue 的硬路由器有可能这样来控制,可能很多官方固件也能玩,有点 sdn 的意思。
实现需要的具体工作:
agent: 收到什么就转发什么,类似 socat , 只不过是 netlink socket -> tcp socket.
controller: 用户态的 firewall 处理逻辑,最好是能复用 nftables/iptables 的语法与代码,这样学习、迁移成本更低,但把内核的代码在用户态用上应该是非常难的。或者把这个封装成 python/golang/java 库,用户可以写简单脚本控制, 也可以让社区继续发挥。
大家看看价值与可行性如何?
1
tomczhen 350 天前 via Android
dpdk 好像都快 10 年了。
|
2
icy37785 350 天前 via iPhone
你是在找 RouterOS 吗?
|
3
s82kd92l OP |
4
RecursiveG 350 天前
多此一举,不如想想怎么提升你软路由的稳定性。
|
6
sentivcn 349 天前
三层交换机 ospf 线速分流,路由器只拨号
|
7
huoshen 349 天前
你是否在查找: FPGA
好吧不开玩笑的说, 这个已经有在搞的, 思科有相当多的交换机就是 ASIC+FPGA, 然后部分包剩下的交给 cpu 处理, 只是个人用户想搞一个可能有点难, 毕竟各个厂家路由设计都不太一样, 现有固定的硬件上是否可行也有待商榷 |
8
povsister 194 天前
<来自楼主的召唤链接>
我看你描述的这个操作,其实和 dae 思路是一样的。 可以看看这里,其实你想的大部分操作 dae 都已经实现了 https://github.com/daeuniverse/dae/blob/main/docs/zh/how-it-works.md 不过不存在“路由器大多基于 linux”,“外包 nfqueue 这个说法“,同机器上用户态处理尚可接受,跨机器甚至要 RPC 的情况下,复杂度和可用性都会爆炸的。 而且高性能的路由器例如 ROS 这种,其都是使用的裁剪+高度定制化的 linux 内核,定制程度达不到你说的这么高。 |