You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python libnftables为nftables自定义链添加drop策略失败

问题

我尝试用Python结合libnftables的JSON接口,为nftables创建自定义表、链和白名单规则集,需求如下:

  • 创建默认策略为drop的链,丢弃所有不匹配白名单的出站数据包
  • 使用自定义表实现,确保与fail2ban等工具的现有规则共存

目前表、链、规则都能成功创建,但链的默认策略drop未生效,规则集输出中看不到该策略(推测默认是accept)。JSON配置通过了libnftables的验证,但策略就是不生效。

配置与输出信息

设置的JSON配置:

{'nftables':
    [{'add': {'table': {'family': 'ip', 'name': 'O365'}}}, 
     {'add': {'chain': {'family': 'ip', 'table': 'O365', 'name': 'O365WhiteList', 'policy': 'drop'}}}, 
     {'add': {'rule': {'family': 'ip', 'table': 'O365', 'chain': 'O365WhiteList', 
       'expr': [{'match': {'op': '==', 'left': {'payload': {'protocol': 'tcp', 'field': 'dport'}}, 'right': 22}}, {'accept': None}
               ]
     }}}]}

规则集输出:

# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
        chain f2b-sshd {
                counter packets 92105 bytes 13096562 return
        }

        chain INPUT {
                type filter hook input priority filter; policy accept;
                meta l4proto tcp tcp dport 22 counter packets 132201 bytes 15881220 jump f2b-sshd
        }
}
# Warning: table ip nat is managed by iptables-nft, do not touch!
table ip nat {
        chain POSTROUTING {
                type nat hook postrouting priority srcnat; policy accept;
                oifname "ens19" counter packets 983 bytes 70843 masquerade
        }
}
table ip O365 {
        chain O365WhiteList {
                tcp dport 22 accept
        }
}

完整代码

import json
import nftables

#some objects to be turned into json for nftables to apply as commands

delTable =  {"nftables": [{ "delete": { "table": { "family": "ip", "name": "O365" }}}]}


setupTablesCmds= """
  { "nftables": [
    { "add": { "table": { "family": "ip", "name": "O365" }}},
    { "add": { "chain": {
        "family": "ip",
        "table": "O365",
        "name": "O365WhiteList",
        "policy": "drop"
    }}},
    { "add": { "rule": {
        "family": "ip",
        "table": "O365",
        "chain": "O365WhiteList",
        "expr": [
            { "match": {
                "op": "==",
                "left": { "payload": {
                    "protocol": "tcp",
                    "field": "dport"
                }},
                "right": 22
            }},
            { "accept": null }
        ]
    }}}
  ]}
 """


nft = nftables.Nftables()
try:
    nft.json_validate(json.loads(setupTablesCmds))
except Exception as e:
    print(f"ERROR: failed validating initial setup json schema: {e}")
    exit(1)
print(" base config data passed validation, yay! " )
print()
print("Removing old O365 table")

rc, output, error = nft.json_cmd(delTable)
if rc != 0:
  # error here is probably  because table doesn't exist, which is fine, so no exit on error for now
  print(f"ERROR: running json cmd: {error}")

print(" setting up new O365 table " )
print( "json commands = :", json.loads(setupTablesCmds))

rc, output, error = nft.json_cmd(json.loads(setupTablesCmds))
if rc != 0:
  print(f"ERROR: running json cmd: {error}")
  exit(1)

if len(output) != 0:
   print(f"WARNING: output: {output}")

print("  Base config applied ok, O365 table created" )

原因与解决办法

核心原因

nftables中,只有"基础链"(Base Chain,即挂载到钩子点的链)才支持设置默认策略。你创建的O365WhiteList是一条"常规链"(Regular Chain),这类链没有默认策略,数据包匹配完所有规则后默认会return,而非遵循你设置的policy参数。

解决步骤

  1. 修改链为基础链
    要实现出站过滤,需把链设置为基础链,挂载到output钩子点,同时指定链类型为filter。修改链的JSON配置,添加type、hook、priority字段:

    { "add": { "chain": {
        "family": "ip",
        "table": "O365",
        "name": "O365WhiteList",
        "type": "filter",
        "hook": "output",
        "priority": 0,
        "policy": "drop"
    }}}
    

    各字段说明:

    • type: 链的类型,过滤规则用filter
    • hook: 指定挂载的钩子点,出站流量用output
    • priority: 钩子执行优先级,0为默认值,可根据需求调整
  2. 验证修改效果
    重新运行代码后,查看规则集,会看到链的定义中包含policy drop:

    table ip O365 {
            chain O365WhiteList {
                    type filter hook output priority filter; policy drop;
                    tcp dport 22 accept
            }
    }
    
  3. 可选:规则复用方案
    若想把白名单规则放在常规链中,再由基础链跳转,可以:

    • 创建带policy drop的基础链
    • 创建常规链存放白名单规则
    • 在基础链中添加跳转规则到常规链
      这样既实现默认丢弃,又能灵活复用规则。

内容的提问来源于stack exchange,提问作者user2512377

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:47:37