开个脑洞想了一个结合软硬路由优点的方案

2023-11-18 22:06:57 +08:00
 s82kd92l

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 爱怎么玩都行了?

应用场景:

  1. ip 段分流/wireguard/zerotier

    静态 ip 段路由表管理挺繁,要是 BGP 级别的话,ip 段文件不小,很多老古董 nand 甚至存不下。复杂一点的动态路由要搭建 bird/frr 服务,很麻烦。而我的方案里,nfqueue-controller 可以根据包的内容直接给包打上 mark, 再通过策略路由就很简单实现了分流。x86 可以搭建 wireguard/zerotier ,灵活度有保证。

  2. 无污染 dns 服务/fakedns/根据域名分流

    传统域名分流很多是搞 ipset/nftables set ,要是路由器内核不支持就很难搞。nfqueue-controller 可以强行把所有 udp53 的包通过 mark 路由到自己 x86 节点,自己走 doh/dot. 也可以把 fakedns/vpn 的 IP 段通过 mark 路由到自己节点.根据请求域名的判断可以在 x86 端用户态维护一个 ipset,在下一次 tcp 请求中自动分流。

  3. fullcone nat

    可以把硬路由器自己的 nftables/iptables masquerade 都干掉,在 nfqueue 里进行 snat/dnat.不过这个我不太确定会和 linux conntrack 系统有什么化学反应

  4. multiwan 负载均衡

    用户态控制逻辑,想怎么分配就怎么分配

  5. 软路由节点 down 后 fallback

    一旦硬路由上的 nfqueue agent 发现软路由超时未回复,立刻断开 nfqueue 绑定, 则所有网络设置恢复到单硬路由状态,不会引起断网。

  6. 大量新连接、路由表很长很复杂

    这时候每个新连接的包都要经过网络给 controller 处理,可能会造成一些压力,不过可以在硬路由里利用 nftables 里面自定义 set/map 的功能可以缓存处理结果 mark ,例如连接五元组 30 分钟有效期内复用上次的 mark. 如果路由器只有 iptables 且没有 ipset, 也可以在路由器的 nfqueue-agent 里缓存结果。 不需要所有的都经过控制服务器,

这样只要支持 nfqueue 的硬路由器有可能这样来控制,可能很多官方固件也能玩,有点 sdn 的意思。

实现需要的具体工作:

  1. agent: 收到什么就转发什么,类似 socat , 只不过是 netlink socket -> tcp socket.

  2. controller: 用户态的 firewall 处理逻辑,最好是能复用 nftables/iptables 的语法与代码,这样学习、迁移成本更低,但把内核的代码在用户态用上应该是非常难的。或者把这个封装成 python/golang/java 库,用户可以写简单脚本控制, 也可以让社区继续发挥。

大家看看价值与可行性如何?

2185 次点击
所在节点    宽带症候群
9 条回复
tomczhen
2023-11-18 22:13:18 +08:00
dpdk 好像都快 10 年了。
icy37785
2023-11-18 22:14:15 +08:00
你是在找 RouterOS 吗?
s82kd92l
2023-11-18 22:19:15 +08:00
@tomczhen
@icy37785 这俩都是 x86 世界的啊,dpdk 还要专用硬件支持,得花不少银子把。我这个方案是想把硬路由价值最大化,不刷固件也好用那种。
RecursiveG
2023-11-18 23:53:31 +08:00
多此一举,不如想想怎么提升你软路由的稳定性。
icy37785
2023-11-19 02:46:34 +08:00
@s82kd92l #3 RouterOS 怎么就成 x86 的世界了。算了,你自己瞎琢磨去吧。
sentivcn
2023-11-19 02:53:43 +08:00
三层交换机 ospf 线速分流,路由器只拨号
huoshen
2023-11-19 04:02:24 +08:00
你是否在查找: FPGA
好吧不开玩笑的说, 这个已经有在搞的, 思科有相当多的交换机就是 ASIC+FPGA, 然后部分包剩下的交给 cpu 处理, 只是个人用户想搞一个可能有点难, 毕竟各个厂家路由设计都不太一样, 现有固定的硬件上是否可行也有待商榷
povsister
210 天前
<来自楼主的召唤链接>

我看你描述的这个操作,其实和 dae 思路是一样的。
可以看看这里,其实你想的大部分操作 dae 都已经实现了 https://github.com/daeuniverse/dae/blob/main/docs/zh/how-it-works.md

不过不存在“路由器大多基于 linux”,“外包 nfqueue 这个说法“,同机器上用户态处理尚可接受,跨机器甚至要 RPC 的情况下,复杂度和可用性都会爆炸的。
而且高性能的路由器例如 ROS 这种,其都是使用的裁剪+高度定制化的 linux 内核,定制程度达不到你说的这么高。
s82kd92l
210 天前
@povsister 其实只是最初几个包需要跨机器 ipc, 也就是 iptables nat table 要处理的那些包,其他都是硬件转发。 内网的 rtt 一般 1ms 左右,比起访问公网服务器基本 20+ms 的 rtt ,这个延迟是可以忽略不计的吧。

> 定制程度达不到你说的这么高。

这个现状是真的,但支持硬件转发的 openwrt 最近越来越多了,尤其 mtk 的机子,还是有一定潜在应用空间的。

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

https://www.v2ex.com/t/993126

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

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

© 2021 V2EX