脚本的核心职责是将配置意图(如封禁ip、开放端口)编译为语义清晰、可验证、可原子加载的.nft文件,而非直接执行nft命令;它通过模板+数据驱动生成合法nftables语法,支持多源输入、集合管理、环境适配,并内置校验与安全边界。

用脚本自动化生成 nftables 复杂规则集合,核心不是“写更多命令”,而是把规则逻辑从命令行里抽出来,交给脚本控制结构、变量和数据源——最终输出一份语义清晰、可验证、可原子加载的 .nft 文件。
先明确脚本该做什么,而不是怎么执行
脚本真正的职责是:把配置意图(比如“封禁这 2000 个 IP”“开放 Dev 环境的 5 个端口”)翻译成符合 nftables 语法的规则文本。它不直接调用 nft add rule,而是生成一个完整、自洽的规则文件,再由 nft -f 一次性加载。这样既保原子性,又便于版本管理、diff 对比和回滚。
- 输入可以是 CSV、JSON、API 响应、日志提取结果,甚至环境变量
- 输出必须是合法的 nftables 语法:包含表定义、链声明、规则、集合创建与填充等
- 脚本本身不碰内核状态,只负责“编译”配置,降低人为误操作风险
用模板 + 数据驱动,避免拼接字符串
硬编码 echo "nft add rule ..." 容易出错,尤其带引号、空格、大括号时。推荐用模板引擎或 shell here-document 结合变量展开:
- 主模板定义结构(如
table inet filter { ... }),数据部分用占位符或子模板注入 - IP 黑名单、白名单端口、服务网段等,统一读入数组或字典,循环生成
add element或匿名集合内容 - 示例片段(bash):
nft -f table inet filter {<br> set blacklist { type ipv4_addr; flags interval; }<br> chain input { type filter hook input priority 0; policy drop; }<br> chain input { ip saddr @blacklist drop }<br> }<br> EOF<br> )
配合printf或jq注入动态数据,比逐行 echo 更可靠
结合集合(set)和 include 实现可维护性
脚本生成的重点不是“写出所有规则”,而是组织好可复用的组件:
- 让脚本生成独立的
/etc/nftables.d/blacklist.nft和/etc/nftables.d/whitelist.nft,主文件只用include引用 - 对需频繁更新的数据(如恶意 IP),脚本只重写对应 set 文件,主规则不变;更新后仍执行
nft -f /etc/nftables.conf全量加载 - 支持多环境:脚本根据
$ENV=prod变量选择加载不同 include 目录,或生成不同版本的主文件
校验与安全边界必须内置在脚本中
自动化带来效率,也放大错误影响。脚本应在生成后、加载前做几件事:
- 用
nft -c -f generated.nft预检语法和语义(-c 表示只校验不加载) - 检查关键字段:是否漏写
policy drop、是否重复定义同名表、集合类型是否匹配(ipv4_addr vs inet_proto) - 限制输入数据规模:例如单次注入 IP 超过 10 万条时,自动拆分或提示改用批量导入方式,避免命令行截断或内核参数限制
- 生成带时间戳和 Git commit hash 的注释头,方便追溯来源
不复杂但容易忽略:脚本不是替代人思考的黑盒,而是把人的策略决策固化为可重复、可审计的动作。只要输出文件能通过 nft -c,且加载后行为符合预期,它就完成了使命。











