这里的高级程序员但讨厌 linux 网络限制,与所有编程语言相比,这使事情变得困难。
实际上,我需要制定基于策略的路由,允许特定的 lan ip 地址选择特定的传出接口(比如 eth5)。在我的情况下,即使是 ipset 也不够强大。我想允许第一个八进制为“10”而最后一个八进制以“9”结尾的所有 lan ip。那将是10.*.*.??9
或在javascript中if(ip.match("\10\..*\.(\d+9|9)\g")) ...USE eth5
有谁知道实现这一目标的某种技巧?如果我们必须坚持使用 CIDR,那可能会有数千个 IP CIDR,这太疯狂了。
谢谢
我不会将我的答案限制在算法的一小部分,因为 OP 也达到了实现限制。答案必须与他们合作。
路由堆栈是 Linux 网络堆栈的一部分,仅限于处理相当于 /32 (/255.255.255.255) 到 /0 (/0.0.0.0) 的33 个 CIDR 网络掩码。
网络堆栈的其他部分,例如一些防火墙设施,则不受此限制。通过使用诸如 255.0.0.255 之类的网络掩码,可以忽略 IPv4 地址中的 2 个中间数字部分。las,网络掩码可以轻松处理二的幂或二的幂除法的余数,但无法帮助模 10(除以 10 的余数),并且除以 10 在数据包处理中不可用。所以仍然有 9 到 249 之间的 25 个值需要检查,并且需要这些值的列表。唉,另外ipset也被限制为 CIDR netmasks,并且iptables对ipset的使用不允许一起使用不受限制的网络掩码:根本不能使用ipset 。
要么使用 ~ 25 个iptables规则(不是那么多),要么使用更灵活的nftables和set。
使用iptables
仅使用网络掩码 255.0.0.0 来检查 IPv4 地址的开头
10.
并检查最后一部分的 25 种可能性。根据要解决的确切问题,可以添加对要考虑的传入接口的额外限制。要使用 25 种可能性填充用户链,
specialrouting
例如使用此bash脚本:最后,2^16(对于两个被忽略的中间字节)x 25 = 1638400 的可能性将得到一个标记。
如果模为 16(2 的幂),从而过滤 16 个值 9、25、41、57 ... 249 而不是 25 个模 10 值,那么上面的所有内容都可以用单个规则替换,因为网络掩码可以处理任何 2 的幂的模数。这里的网络掩码 255.0.0.15 (0xff00000f) 可以与下面的单个规则一起使用:
或者使用nftables
使用类似于上面的脚本预先计算的集合元素列表,具有模 10 案例的规则集将是(加载
nft -f specialrouting.nft
):specialrouting.nft
:对于模 16,单个nftables规则(没有样板)将类似于上面的单个iptables规则:
使用标记进行路由
数据包上设置的标记(仅在 Linux 网络堆栈中此数据包的内部生命周期内)可以用作路由堆栈的消息,并与路由规则匹配以使用备用路由表:
其次是表 100 中的路由,其中包括最重要的路由
dev eth5
,此外还包括从主路由表复制的任何其他相关路由:来自eth5的返回流量应该使用同一张表:
补充笔记
至少在测试时,为了避免由于路由不完整而导致流量下降,不应启用SRPF,即,以防分发默认启用它:
rp_filter
使用标记时还有其他可能性,例如将标记存储在流的 conntrack 条目中,但如果没有设置的精确描述,我不知道这里需要什么。这个博客有几个例子:到 Linux 及以后!Netfilter 康马克。
请注意,涉及重新路由本地启动(或相同的本地终止)流量而不是转发/路由流量的标记会遇到极端情况(UDP 比 TCP 更多),所以我什至没有尝试解决这种情况。