如何通过Nftables Concat特性在Linux上一条规则内快速匹配源IP、目的端口及传输协议?

2026-05-20 13:321阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计564个文字,预计阅读时间需要3分钟。

如何通过Nftables Concat特性在Linux上一条规则内快速匹配源IP、目的端口及传输协议?

直接使用 nftables 的 concat 特性,可以将源 IP、目标 IP 等信息连接起来,形成复合规则。例如,以下规则将源 IP 和目标 IP 进行拼接:

构造支持三字段拼接的映射表

先建一个类型为 ipv4_addr . inet_service . inet_protocol 的映射,注意字段顺序和类型必须严格对应:

  • ipv4_addr 对应 ip saddr(4 字节)
  • inet_service 对应 tcp dportudp dport(2 字节)
  • inet_protocol 对应 ip protocol(1 字节),值为 6(TCP)或 17(UDP)

执行命令创建映射:

nft add map inet filter ipportproto_map { type ipv4_addr . inet_service . inet_protocol : verdict; }

插入带协议区分的复合规则

同一个端口(比如 8080)对 TCP 和 UDP 可以定义不同动作。例如只允许 TCP 8080,拒绝 UDP 8080:

  • 192.168.10.5 . 8080 . 6 : accept(TCP)
  • 192.168.10.5 . 8080 . 17 : drop(UDP)

一次性写入:

nft add element inet filter ipportproto_map { 192.168.10.5 . 8080 . 6 : accept, 192.168.10.5 . 8080 . 17 : drop }

在链中调用 concat 规则

在 input 链里添加一条规则,用 @ 引用映射,并按相同顺序拼接字段:

nft add rule inet filter input @ipportproto_map { ip saddr . tcp dport . ip protocol } counter

⚠️ 注意:这里 tcp dport 是协议敏感写法;若需同时覆盖 TCP/UDP,得改用通用字段 th dport 并确保映射中协议值一致,否则会不命中。

验证与排错要点

拼接类规则容易静默失效,建议三步确认:

  • nft list map inet filter ipportproto_map -n 查看实际插入的数值(如 0xc0a80a05 . 0x0318 . 0x06),避免字符串解析歧义
  • counter 后运行 nft monitor trace,观察是否真正查到了映射路径,而非 fallback 到下一条规则
  • 确认所有字段总长 ≤ 256 字节(本例仅 7 字节,安全)
标签:Linux端口

本文共计564个文字,预计阅读时间需要3分钟。

如何通过Nftables Concat特性在Linux上一条规则内快速匹配源IP、目的端口及传输协议?

直接使用 nftables 的 concat 特性,可以将源 IP、目标 IP 等信息连接起来,形成复合规则。例如,以下规则将源 IP 和目标 IP 进行拼接:

构造支持三字段拼接的映射表

先建一个类型为 ipv4_addr . inet_service . inet_protocol 的映射,注意字段顺序和类型必须严格对应:

  • ipv4_addr 对应 ip saddr(4 字节)
  • inet_service 对应 tcp dportudp dport(2 字节)
  • inet_protocol 对应 ip protocol(1 字节),值为 6(TCP)或 17(UDP)

执行命令创建映射:

nft add map inet filter ipportproto_map { type ipv4_addr . inet_service . inet_protocol : verdict; }

插入带协议区分的复合规则

同一个端口(比如 8080)对 TCP 和 UDP 可以定义不同动作。例如只允许 TCP 8080,拒绝 UDP 8080:

  • 192.168.10.5 . 8080 . 6 : accept(TCP)
  • 192.168.10.5 . 8080 . 17 : drop(UDP)

一次性写入:

nft add element inet filter ipportproto_map { 192.168.10.5 . 8080 . 6 : accept, 192.168.10.5 . 8080 . 17 : drop }

在链中调用 concat 规则

在 input 链里添加一条规则,用 @ 引用映射,并按相同顺序拼接字段:

nft add rule inet filter input @ipportproto_map { ip saddr . tcp dport . ip protocol } counter

⚠️ 注意:这里 tcp dport 是协议敏感写法;若需同时覆盖 TCP/UDP,得改用通用字段 th dport 并确保映射中协议值一致,否则会不命中。

验证与排错要点

拼接类规则容易静默失效,建议三步确认:

  • nft list map inet filter ipportproto_map -n 查看实际插入的数值(如 0xc0a80a05 . 0x0318 . 0x06),避免字符串解析歧义
  • counter 后运行 nft monitor trace,观察是否真正查到了映射路径,而非 fallback 到下一条规则
  • 确认所有字段总长 ≤ 256 字节(本例仅 7 字节,安全)
标签:Linux端口