nftables

nftables 这里有张图 https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks nftables 是一个新式的数据包过滤框架,旨在替代现用的 iptables、ip6tables、arptables 和 ebtables 的新的包过滤框架。nftables 诞生于 2008 年,2013 年底合并到 Linux 内核,从 Linux 内核 3.13 版本开始大多数场景下 nftables 已经可以使用,但是完整的支持(即:nftables 优先级高于 iptables)应该是在 Linux 内核 3.15 版本。 nftables 旨在解决现有 {ip/ip6}tables 工具存在的诸多限制。相对于旧的 iptables,nftables 最引人注目的功能包括:改进性能、支持查询表、事务型规则更新、所有规则自动应用等等。 nftables 主要由三个组件组成:内核实现、libnl netlink 通信和 nftables 用户空间。其中内核提供了一个 netlink 配置接口以及运行时规则集评估,libnl 包含了与内核通信的基本函数,用户空间可以通过新引入的命令行工具 nft 和用户进行交互。 nft 可以通过在寄存器中储存和加载来交换数据。也就是说,它的语法与 iptables 不同。但 nft 可以利用内核提供的表达式去模拟旧的 iptables 命令,维持兼容性的同时获得更大的灵活性。简单来说,nft 是 iptables 及其衍生指令(ip6tables 和 arptables )的超集。 nftables 的特点 nftables 拥有一些高级的类似编程语言的能力,例如:定义变量和包含外部文件,即拥有使用额外脚本的能力。nftables 也可以用于多种地址簇的过滤和处理。 不同于 iptables, nftables 并不包含任何的内置表,需要哪些表并在这些表中添加什么处理规则一切由管理员决定。 表包含规则链,规则链包含规则。 nftables 相较于 iptables 的优点 更新速度更快 在 iptables 中添加一条规则,会随着规则数量增多而变得非常慢。这种状况对 nftables 而言就不存在了,因为 nftables 使用原子的快速操作来更新规则集合。 ...

Created 25256-05-25 · Updated 9096-10-09 · 4 min · 825 words · -

Rule Status 字段的设计取舍(2022)

2022 年 7 月,入职某防火墙自动化团队约一个月后,接到第一个独立功能需求:在 UI 上显示每条 Rule 的当前状态。 Rule 是用户在系统里下发的防火墙策略。每条策略在系统里会经历一系列流转节点:submit、approve、dryrun、commit、rollback、archive……这些节点对应不同的业务操作,最终需要在界面上展示"这条 Rule 现在处于哪个阶段"。 这是一个看起来不大的需求,但它要求先回答一个设计问题:Rule 的状态存在哪里? 两种方案 方案一:SQL 聚合 不新增字段。系统里本来就有 rule_dryrun、rule_commit 等操作记录表,查询当前状态时通过 JOIN 这些表、判断哪些记录存在来推算出状态。 改动量最小,现有表结构不动,在查询层加逻辑就够了。 方案二:状态归属 在 rules 表增加 status 字段,每次业务状态发生变更时在对应模块里写入新状态。Rule 的状态就存在 Rule 这里,查询时直接读取。 初期需要找到所有状态变更的节点,在分散在多个模块的代码里补齐“更新 Rule 状态”的逻辑,改动范围比方案一大。 讨论 两种方案都在组内讨论过。支持方案一的理由有几个:改动文件少,风险低;项目当时还不确定做多久,不必做太完善;另外我是新入职,对 Python 代码库不熟悉,方案一可以减少上手压力。 但是…我更倾向方案二,核心判断是:Rule 的状态是 Rule 本身的属性,有独立的业务名称和语义,它应该和 Rule 在一起,而不是分散在各操作记录表里通过 JOIN 聚合出来。方案一把复杂度延后了——每增加一个新的查询场景,都要重新写一次聚合逻辑;状态维度越多,维护代价越高。 讨论中有一个具体的质疑:如果用户对一条 Rule 操作三次,rules 表就要被修改三次,会不会太频繁?我的回应是:操作了三次,状态就变了三次,写入三次和业务行为是完全对应的,代码逻辑和业务逻辑是一致的。 讨论下来,同事们接受了这个方向。其中一位熟悉代码库的同事专门指导我:Rule 的状态会在哪些业务节点发生变化,应该在哪些地方插入状态更新代码。这个指导让我能在不熟悉代码库的情况下快速定位到所有需要修改的地方。 执行 功能在一个 sprint(约一个月)内完成开发、测试、上线。改动涉及多个模块,但每个模块的改动量不大,主要工作是把状态抽象出来、并在正确的节点写入。 上线前还准备了一份 migration.sql,对存量的历史 Rule 记录做 backfill——需要根据这些 Rule 在各操作表里的记录,推算出它们当前应该处于哪个状态。这份 SQL 写起来需要复杂的跨表 JOIN,刚好印证了方案一如果长期维护会是什么样子。 回看 这个字段上线后,后续三年里所有 Rule 状态机相关的功能——新的流转流程、状态过滤、统计报表、列表查询里的复杂过滤条件——大多都直接依赖这个 status 字段,没有因为最初的设计需要绕路。后来又陆续引入了更多流程,让 Rule 在更多角色之间流转;这些变化本质上都是状态转移,没有对应的操作历史记录。如果当初用聚合方案,这些新状态根本没有操作记录可以聚合,届时无论如何都要补加 status 字段,区别只是改动量更大、时机更被动。 ...

Created 4046-06-04 · Updated 5056-06-05 · 1 min · 172 words · -