6.5. 在 nftables 命令中使用 verdict 映射
判决映射(也称为字典),使
nft
能够通过将匹配条件映射到某个操作来根据数据包信息执行操作。
6.5.1. 在 nftables 中使用匿名映射
匿名映射是您直接在规则中使用的
{ match_criteria : action }
语句。这个语句可以包含多个用逗号分开的映射。
匿名映射的缺点是,如果要修改映射,则必须替换规则。对于动态解决方案,请使用命名映射,如 第 6.5.2 节 “在 nftables 中使用命名映射” 所述。
这个示例描述了如何使用匿名映射将 IPv4 和 IPv6 协议的 TCP 和 UDP 数据包路由到不同的链,以分别计算传入的 TCP 和 UDP 数据包。
过程 6.15. 在 nftables 中使用匿名映射
- 创建 example_table :
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add table inet example_table
# nft add table inet example_table
- 在 example_table 中创建
tcp_packets
链:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add chain inet example_table tcp_packets
# nft add chain inet example_table tcp_packets
- 向统计此链中流量的
tcp_packets
中添加一条规则:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule inet example_table tcp_packets counter
# nft add rule inet example_table tcp_packets counter
- 在 example_table 中创建
udp_packets
链:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add chain inet example_table udp_packets
# nft add chain inet example_table udp_packets
- 向统计此链中流量的
udp_packets
中添加一条规则:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule inet example_table udp_packets counter
# nft add rule inet example_table udp_packets counter
- 为传入的流量创建一个链。例如,要在过滤传入的流量的 example_table 中创建一个名为
incoming_traffic
的链:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
- 添加一条带有到
incoming_traffic
匿名映射的规则 :Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
匿名映射区分数据包,并根据它们的协议将它们发送到不同的计数链。 - 要列出流量计数器,请显示 example_table :
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft list table inet example_table
# nft list table inet example_table table inet example_table { chain tcp_packets { counter packets 36379 bytes 2103816 } chain udp_packets { counter packets 10 bytes 1559 } chain incoming_traffic { type filter hook input priority filter; policy accept; ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets } } }
tcp_packets
和udp_packets
链中的计数器显示两者接收的数据包和字节数。
6.5.2. 在 nftables 中使用命名映射
nftables
框架支持命名映射。您可以在表中的多个规则中使用这些映射。匿名映射的另一个好处在于,您可以更新命名映射而不比替换使用它的规则。
在创建命名映射时,您必须指定元素的类型:
- 匹配部分包含
IPv4
地址的映射的ipv4_addr
,如192.0.2.1
。 - 匹配部分包含
IPv6
地址的映射的ipv6_addr
,如2001:db8:1::1
。 - 匹配部分包含介质访问控制(
MAC
)地址的映射的ether_addr
,如52:54:00:6b:66:42
。 - 匹配部分包含互联网协议类型的映射的
inet_proto
,如tcp
。 - 匹配部分包含互联网服务名称端口号的映射的
inet_service
,如ssh
或22
。 - 匹配部分包含数据包的映射的
mark
。数据包标记可以是任意正 32 位整数值(0
到2147483647
)。 - 匹配部分包含计数器值的映射的
counter
。计数器值可以是任意正 64 位整数值。 - 匹配部分包含配额值的映射的
quota
。配额值可以是任意正 64 位整数值。
这个示例论述了如何根据源 IP 地址允许或丢弃传入的数据包。使用命名映射时,您只需要一条规则来配置这种场景,而 IP 地址和操作被动态存储在映射中。此流程还描述了如何从映射中添加和删除条目。
过程 6.16. 在 nftables 中使用命名映射
- 创建表。例如,要创建一个名为 example_table 的表来处理
IPv4
数据包:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add table ip example_table
# nft add table ip example_table
- 创建链。例如,要在 example_table 中创建一个名为 example_chain 的链:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
# nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
重要要避免 shell 认为分号作为命令结尾,您必须用反斜杠转义分号。 - 创建一个空的映射。例如,要为
IPv4
地址创建映射:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add map ip example_table example_map { type ipv4_addr : verdict \; }
# nft add map ip example_table example_map { type ipv4_addr : verdict \; }
- 创建使用该映射的规则。例如,以下命令向 example_table 中的 example_chain 添加一条规则,该规则将操作应用到 example_map 中定义的
IPv4
地址:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule example_table example_chain ip saddr vmap @example_map
# nft add rule example_table example_chain ip saddr vmap @example_map
- 向 example_map 添加
IPv4
地址和对应操作:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }
# nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }
这个示例定义了IPv4
地址到操作的映射。与以上创建的规则相结合,防火墙接受来自192.0.2.1
的数据包,丢弃来自192.0.2.2
的数据包。 - 另外,还可添加另一个 IP 地址和 action 语句来增强映射:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add element ip example_table example_map { 192.0.2.3 : accept }
# nft add element ip example_table example_map { 192.0.2.3 : accept }
- (可选)从映射中删除条目:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft delete element ip example_table example_map { 192.0.2.1 }
# nft delete element ip example_table example_map { 192.0.2.1 }
- 另外,还可显示规则集:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft list ruleset
# nft list ruleset table ip example_table { map example_map { type ipv4_addr : verdict elements = { 192.0.2.2 : drop, 192.0.2.3 : accept } } chain example_chain { type filter hook input priority filter; policy accept; ip saddr vmap @example_map } }
6.5.3. 相关信息
有关 verdict 映射的详情,请查看
nft (8)
手册页中的 Maps
部分。