AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 996037
Accepted
mvorisek
mvorisek
Asked: 2019-12-19 07:05:02 +0800 CST2019-12-19 07:05:02 +0800 CST 2019-12-19 07:05:02 +0800 CST

Nftables 时间戳图

  • 772

是否可以基于时间戳构建 nftables 映射?

目前我使用:

numgen random mod 2 map {
            0: 10.10.10.1,
            1: 10.10.10.2,
        }

但是如何将random mod 2表达式转换为,即每 30 分钟交替(timestamp / 1800) mod 2生成 map 的键0?1

iptables
  • 1 1 个回答
  • 338 Views

1 个回答

  • Voted
  1. Best Answer
    A.B
    2020-06-22T16:23:19+08:002020-06-22T16:23:19+08:00

    可以通过使用名为map的预先计算的查找来解决nftables的限制。

    必需的:

    • 内核> = 5.4:对于meta hour
    • nftables >= 0.9.4 表示可以使用的较新版本,typeof并且type这似乎是. 或者不会被接受,即使像旧的 nftables一样被读回。meta hourtype meta hourtype hourtypeof meta hourtype hour

    nftables不能进行任意算术(或逻辑等)运算。目前它仅限于对必须来自数据包路径或一些扩展的数据在左侧(LHS)执行一些操作numgen,并将其与恒定的右侧(RHS)进行比较,包括从集和地图。

    没有办法让nftables计算 LHS 中的任意除法(使用右移除以两个作品的幂,但请参见下文)。而且似乎也没有办法将这种计算的结果表示为命名映射中被接受为键的数据类型,因为通常是这种操作的结果的“非限定”整数类型不是有效的键类型一个命名的地图,至少目前是这样。例如,我不确定numgen表达式是否可以与命名地图一起使用,即使它与匿名地图一起使用。

    对于这种情况,Linux 内核 5.4在内核中引入了与数据包时间戳相关的元语句:

    • 在内核中为时间、日期和小时提交引入元匹配

    在这里,meta hour提供了缺少的必需操作“mod 86400”,这与 OP 的“timestamp / 1800”要求足够相关:给出了自一天开始以来数据包的时间。此外,它有一个特定的类型,允许它在命名地图中使用。

    作为一种类似于循环展开以简化复杂操作的方法,可以预先计算表达式中无法计算的值并将其存储在映射表中,只要该类型对命名映射有效即可。这是可以接受的,因为条目的数量是预先知道的,并且仍然是有限的:对于这种情况,一天有 48 个半小时。

    然后映射可以提供最终结果:IPv4 地址。


    负载均衡器(执行dnat )的示例规则集,它将wan0上接收的所有流量在每小时的前半小时转发到 10.10.10.1,在后半小时转发到 10.10.10.2:

    table ip mytable
    delete table ip mytable
    
    table ip mytable {
            map hour2ip {
                    typeof meta hour : ip daddr
                    flags interval
            }
            chain mylb {
                    type nat hook prerouting priority dstnat; policy accept;
                    iif wan0 dnat to meta hour map @hour2ip
            }
    }
    

    生成 nftables 命令以填充地图hour2ip的脚本(使用./script.sh | nft -f -):

    #!/bin/sh
    
    for h in $(seq 0 23); do
            for m in 0 30; do
            printf 'add element ip mytable hour2ip { "%02d:%02d:00"-"%02d:%02d:59" : %s }\n' $h $m $h $((m+29)) '$ip'
            done
    done |
            sed 's/$ip/10.10.10.X/g' |
            awk '{ printf "%s\n",gensub("X",(NR-1)%2+1,1) }'
    

    这将生成这种命令:

    add element ip mytable hour2ip { "00:00:00"-"00:29:59" : 10.10.10.1 }
    add element ip mytable hour2ip { "00:30:00"-"00:59:59" : 10.10.10.2 }
    [...]
    add element ip mytable hour2ip { "23:00:00"-"23:29:59" : 10.10.10.1 }
    add element ip mytable hour2ip { "23:30:00"-"23:59:59" : 10.10.10.2 }
    

    笔记:

    • 本地时区影响类型数据meta hour(它是模数)发送到内核或从内核显示回来的方式,通常只使用 UTC 时间。这就是为什么排序会根据当前时区发生变化,但会按预期运行。TZ=UTC您可以在显示时检查使用或不使用环境变量的效果nft list map ip mytable hour2ip以更好地理解它。
    • 00:29:59 和 00:30:00 之间没有间隔:时间戳向下舍入,因此例如 00:29:59.800ms 仍然匹配 00:29:59。

    如果您更喜欢使用标记来获得更大的灵活性(通过在其他地方重用标记,而不仅仅是dnat规则,包括将其保存到connmark),您可以使用例如两个映射:一个映射小时来标记,另一个映射标记为 IP 地址。

    为此,例如将之前的规则集替换为:

    table ip mytable
    delete table ip mytable
    
    table ip mytable {
            map hour2mark {
                    typeof meta hour : meta mark
                    flags interval
            }
    
            map mark2ip {
                    typeof meta mark : ip daddr
                    elements = { 1 : 10.10.10.1, 2 : 10.10.10.2 }
            }
    
            chain mylb {
                    type nat hook prerouting priority dstnat; policy accept;
                    iif wan0 meta mark set meta hour map @hour2mark  dnat to meta mark map @mark2ip
            }
    }
    

    并在生成条目的前一个脚本中替换:

            sed 's/$ip/10.10.10.X/g' |
    

    和:

            sed 's/hour2ip/hour2mark/;s/$ip/X/g' |
    

    创建填充hour2mark的命令,例如:

    add element ip mytable hour2mark { "00:00:00"-"00:29:59" : 1 }
    add element ip mytable hour2mark { "00:30:00"-"00:59:59" : 2 }
    [...]
    add element ip mytable hour2mark { "23:00:00"-"23:29:59" : 1 }
    add element ip mytable hour2mark { "23:30:00"-"23:59:59" : 2 }
    
    • 1

相关问题

  • OpenVPN 的 Linux IP 转发 - 正确的防火墙设置?

  • iptables 单个规则中的多个源 IP

  • 存储 iptables 规则的规范方法是什么

  • 使用 iptables 和 dhcpd 进行端口转发

  • 根据 Apache 日志数据自动修改 iptables 以阻止行为不良的客户端

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve