这里的高级程序员,但讨厌linux网络的限制,这使得事情比所有编程语言困难。
实际上,我需要使基于policy的路由允许特定的lan ip地址选择特定的传出接口(例如eth5)。在我的情况下,就连ipset也不够强大。我想让所有局域网ips的第一个八度是"10“,最后一个八度是"9”。这将是10.*.*.??9或javascript if(ip.match("\10\..*\.(\d+9|9)\g")) ...USE eth5中的
有没有人知道什么技巧来达到这个目的?如果我们必须坚持CIDR,那可能就是IP CIDR的麻烦了,这是精神错乱。
谢谢
发布于 2023-06-01 23:00:21
我不会将我的答案限制在算法的一小部分上,因为OP也达到了实现限制。答案必须与他们合作。
路由协议栈是Linux网络栈的一部分,它仅限于处理相当于33个CIDR网络面具 ( /32,/255.255.255.255)到/0 (/0.0.0.0)的路由堆栈。
网络堆栈的其他部分,例如一些防火墙设施,并不是那么有限。通过使用诸如255.0.0.255这样的网络掩码,可以忽略IPv4地址中的两个中间数字部分。遗憾的是,网络掩码可以轻松地处理2的幂,或者剩余的除以2的幂,它无法帮助模块10 (除以10的剩余部分),并且分组处理中无法使用10的除法。因此,仍然有25个值在9到249之间进行检查,并且需要为这些值列出一个列表。唉,另外,ipset也被限制为CIDR网络掩码.和iptables的使用ipset也不允许使用无约束的网络掩码:完全不能使用ipset。
要么使用~25个iptables规则(这并不多),要么在设置中使用更加灵活的nftable。
带有iptables的
只使用255.0.0.0的网络掩码来检查IPv4地址是从10.开始的,并检查最后一部分的25种可能性。可以根据具体的问题来解决,可以为输入的接口添加额外的限制。
iptables -t mangle -N specialrouting
iptables -t mangle -A PREROUTING -s 10.0.0.0/255.0.0.0 -j specialrouting要使用以下25种可能性填充用户链specialrouting,请使用以下bash脚本:
#!/bin/bash
iptables -t mangle -F specialrouting # for idempotence
for i in {9..255..10}; do
    iptables -t mangle -A specialrouting -s 10.0.0.$i/255.0.0.255 -j MARK --set-mark 0xcafe
done最后,2^16 (对于两个被忽略的中间字节)x25= 1638400的可能性将得到一个标记。
如果模块为16 (幂为2),从而过滤16值9、25、41、57……249而不是25模10值,那么上面的所有内容都可以用一条规则来代替,因为网络掩码可以处理任何幂为2的模块。在这里,net掩码255.0.0.15 (0xff00000f)可以与下面的单一规则一起使用:
iptables -t mangle -A PREROUTING -s 10.0.0.9/255.0.0.15 -j MARK -set-mark 0xcafe使用类似于上面的脚本预先计算了集合的元素列表,使用模块化10种情况的规则集将是(用nft -f specialrouting.nft加载):
specialrouting.nft:
table ip specialrouting         # for idempotence
delete table ip specialrouting  # for idempotence
table ip specialrouting {
    set modulo10 {
        type ipv4_addr
        flags constant
        elements = { 10.0.0.9, 10.0.0.19,
                 10.0.0.29, 10.0.0.39,
                 10.0.0.49, 10.0.0.59,
                 10.0.0.69, 10.0.0.79,
                 10.0.0.89, 10.0.0.99,
                 10.0.0.109, 10.0.0.119,
                 10.0.0.129, 10.0.0.139,
                 10.0.0.149, 10.0.0.159,
                 10.0.0.169, 10.0.0.179,
                 10.0.0.189, 10.0.0.199,
                 10.0.0.209, 10.0.0.219,
                 10.0.0.229, 10.0.0.239,
                 10.0.0.249 }
    }
    chain prerouting {
        type filter hook prerouting priority -150; policy accept;
        ip saddr & 255.0.0.255 == @modulo10 meta mark set 0xcafe
    }
}对于模块16,单个nftable规则(没有其锅炉板)将与上面的单个iptable规则相似:
ip saddr & 255.0.0.15 == 10.0.0.9 meta mark set 0xcafe然后,包上设置的标记(仅在Linux网络堆栈中此数据包的内部生命周期期间)可以用作路由堆栈的消息,并与路由规则匹配使用备用路由表:
ip rule add fwmark 0xcafe lookup 100其次是表100中的路由,其中包括dev eth5在内的最重要路由,此外还包括从主路由表复制的任何其他相关路由:
ip route add ... dev eth5 table 100
...来自eth5的返回流量应该使用相同的表:
ip rule add iif eth5 lookup 100至少在测试时,为了避免由于路由不完整而导致流量下降,不应该启用SRPF,即rp_filter (如果发行版默认启用它):
for i in $(sysctl -N -ar 'net\.ipv4\.conf\..*\.rp_filter'); do sysctl -w $i=0; done在使用标记时还有其他可能性,例如将标记存储在流的连接轨迹条目中,但是如果没有对设置的精确描述,我就无法知道这里需要什么。这个博客有几个例子:到Linux和更远的地方!Netfilter连接。
请注意,使用一个标记来重新路由本地发起的(或相同的本地终止的)通信量,而不是转发/路由通信量会碰到拐角情况( UDP的流量比TCP的流量更多),所以我甚至没有尝试解决这种情况。
https://unix.stackexchange.com/questions/747763
复制相似问题