当前位置:网站首页 > 技术博客 > 正文

实践为什么是认识的基础

翻译nftables的文档man nft - mankier.com ,加上实际的操作实践,满足基本的需求。

最后更新时间:2021/7/13


1. 简介

nft是一个命令行工具,用于在Linux内核的nftables框架中设置、维护和检查包过滤和分类规则。Linux 内核子系统称为 nf_tables,"nf"代表 Netfilter。

2. 地址簇

ip IPv4 地址簇
ip6 IPv6 地址簇
inet Internet (IPv4/IPv6) 地址簇
arp ARP 地址簇,处理 IPv4 ARP 数据包
bridge 网桥地址簇,处理通过网桥设备的数据包
netdev Netdev 地址簇,处理来自入口的数据包

如果指定的标识符没有地址族,则默认使用ip簇;

IPv4/IPv6/Inet 地址簇的hooks

Hook 描述
prerouting 所有进入系统的数据包都由prerouting钩子处理。它在路由过程之前调用,用于早期过滤或更改影响路由的数据包属性。
input 传送到本地系统的数据包由input钩子处理。
forward 转发到不同主机的数据包由forward钩子处理。
output 本地进程发送的数据包由output钩子处理。
postrouting 所有离开系统的数据包都由 postrouting 钩子处理。
ingress 所有进入系统的数据包都由这个钩子处理。它在第 3 层协议处理程序之前调用,因此在prerouting钩子之前调用,并且可用于过滤和监管。Ingress 仅适用于 Inet 系列(自 Linux 内核 5.10 起)。

其他地址簇不记录了。

3. 规则集ruleset

ruleset关键词被用来标识被放置在内核中的整套表、链、规则的集合。操作命令有list和flush,具体如下:

# 查询所有规则 nft list ruleset -a # 按照地址簇查询——只查询inet地址簇的规则集 nft list ruleset inet -a # 清空规则集【危险操作】 【nft flush ruleset】 # 按地址簇清空规则 【nft flush ruleset arp】 【nft flush ruleset ip】 【nft flush ruleset ip6】 【nft flush ruleset bridge】 【nft flush ruleset inet】 【nft flush ruleset netdev】 

4. 表table

  • table是链、集合和有状态对象的容器。
    通过地址簇与命名区分。地址簇是ip ip6 inet arp bridge netdev六个其中之一,若未指定,默认为ip地址簇。inet是dummy虚拟的簇,代表IPv4/IPv6的混合hybrid。
  • 元表达式nfproto关键字可用来测试 正在处理的包属于哪个地址簇上下文(ipv4 或 ipv6)
  • add和create的唯一的区别是若表已经存在,前者不会报错,后者会报错Error: Could not process rule: File exists;因为add命令可以修改表的状态。

具体操作如下:

# 以交互模式启动nft 后面就不用一直输入nft命令,当远程服务器有堡垒机的root用户限制时候,可以更为方便的使用 nft --interactive nft --i # 创建表 不指定协议簇 默认ip协议 nft add|create table [地址簇] [表名] nft create table nat nft add table nat # 查看运行结果 nft list ruleset table ip nat { 
    } # 增加链prerouting postrouting nft -- add chain nat prerouting { 
    type nat hook prerouting priority -100 \; } nft add chain nat postrouting { 
    type nat hook postrouting priority 100 \; }  即使您没有向prerouting链添加规则,nftables框架也要求此链与传入的数据包回复匹配。  请注意,您必须将--选项传递给nft命令,以避免shell将负优先级值解析为nft命令的选项 # 查看运行结果 nft list ruleset table ip nat { 
    chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; } } # 增加规则 # 源IP是10.11.0.0/16的伪装成wg0网卡的流量 nft add rule nat postrouting ip saddr 10.121.0.0/16 oifname wg0 counter masquerade # 从tun0网卡进来的流量伪装成wg0网卡的流量 nft add rule nat postrouting iifname tun0 oifname wg0 counter masquerade # 查看运行结果 nft list ruleset table ip nat { 
    chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade } } nft add rule filter input tcp dport 22 accept # 向链中增加一个计数器 nft add rule nat postrouting counter # 查看运行结果 nft list ruleset table ip nat { 
    chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade counter packets 0 bytes 0 } } # 暂时禁用表,规则会失效 nft add table nat { 
    flags dormant\; } # 查看运行结果 nft list ruleset table ip nat { 
    flags dormant chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade counter packets 0 bytes 0 } } # 激活表 nft add table nat # 查看运行结果 nft list ruleset # 发现flags dormant消失了 # 为了测试表的删除需要新建表test nft add table inet mytable # 此时再用nft list ruleset查看就太多了 # 查询所有表 nft list tables # 结果是两行table ip nat和table inet test # 查询指定指定表 地址簇为inet表名为test nft list table inet mytable # 命令后加-a用于显示句柄handles 后面加-nn用于不解析ip地址和端口 # 为了测试清空 需要给表test增加链和规则 nft add chain inet mytable mychain { 
    type filter hook input priority 100\; } # 添加新的基础链:获取输入数据包 nft add rule inet mytable mychain counter # 给链增加计数器 # 查询结果 nft list table inet mytable table inet mytable { 
    chain mychain { 
    type filter hook input priority 100; policy accept; counter packets 60 bytes 13792 } } # 查询结果 nft list table inet mytable -a 可以查询规则的句柄 table inet mytable { 
    chain mychain { 
    type filter hook input priority 100; policy accept; counter packets 201 bytes 25718 # handle 2 } } # 清空表test 不会删除基础链 nft flush table inet mytable # 删除表 nft delete table inet mytable 

5. 链chain

链是规则的容器。

  • 有两种形式——基础链和常规链。基础链是来自网络堆栈的数据包的入口点,常规链可用作跳转目标并用于更好的组织规则。
  • 指定钩子和优先级值后,该链将被创建为基础链并链接到到网络堆栈。
  • 若基础链的类型填写了不匹配的钩子,会报错Error: Could not process rule: Operation not supported
# 新增 nft add chain [地址簇] [表名] [链名] { 
    type [类型] hook [钩子] priority [优先级值]\; } nft add chain inet mytable mychain { 
    type filter hook input priority 100\; } # 添加新的基础链:获取输入 nft add chain inet mytable forward { 
    type nat hook postrouting priority 150\; } # 添加新的基础链:转发给其他主机 # 查询结果 nft list table inet mytable -a table inet mytable { 
    chain mychain { 
    type filter hook input priority 100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 150; policy accept; } } # 修改链 rename nft rename chain [表地址簇] [表名] [旧链名] [新链名] nft rename chain inet mytable mychain mychain1 # 新增规则 nft add rule mytable postrouting iifname tun0 oifname wg0 counter masquerade 会报错Error: NAT is only supported for IPv4/IPv6 nft add rule nat postrouting iifname tun0 oifname wg0 counter masquerade nat表是ip地址簇的,就可以增加这个规则 # 新增常规链 nft add rule nat postrouting iifname tun0 oifname wg0 counter masquerade 

支持的链类型

类型 协议簇 钩子 描述
filter all all 使用的标准链类型
nat ip, ip6, inet prerouting, input, output, postrouting 这种类型的链根据 conntrack 条目执行本地地址转换。 只有连接的第一个数据包实际遍历此链 - 它的规则通常定义创建的 conntrack 条目的详细信息(例如 NAT 语句)。
route ip, ip6 output 如果数据包已经穿过这种类型的链并即将被接受,并且 IP 标头的相关部分已更改,则会执行新的路由查找。 这允许例如 在 nftables 中实现策略路由选择器。

除了上面说明的特殊情况,还有三个值得注意的怪癖:

  • netdev簇仅支持一种组合:即filter类型和ingress钩子。基本链还需要存在设备参数,因为他们仅存在于每个传入接口。
  • arp簇仅支持filter类型链的input和output钩子。
  • inet簇还支持ingress钩子,在与netdev链input钩子相同的位置过滤 IPv4 和 IPv6 数据包。这个inet hook允许你在preroutinginputforwardoutputpostrouting和这个ingress hook之间共享集合和映射。

priority参数接收有符号整数值或标准优先级名称,指定有相同钩子值得链的遍历顺序。该顺序是升序的,低值比高值对应的链优先级更高。

标准优先级值可以替换为易于记忆的名称。 并非所有名称在每个钩子的每个系列中都有意义(请参阅下面的兼容性矩阵),但它们的数值仍可用于确定链的优先级。

这些名称和值是根据 xtables 在注册其默认链时使用的优先级来定义和提供的。

大多数地址簇使用相同的值,但bridge使用与其他地址簇不同的值。 请参阅以下描述值和兼容性的表格。

  1. 标准优先级名称、地址簇和钩子兼容性矩阵:
名称 地址簇 钩子
raw -300 ip, ip6, inet all
mangle -150 ip, ip6, inet all
dstnat -100 ip, ip6, inet prerouting
filter 0 ip, ip6, inet, arp, netdev all
security 50 ip, ip6, inet all
srcnat 100 ip, ip6, inet postrouting
  1. bridge地址簇系列的标准优先级名称和钩子兼容性
名称 钩子
dstnat -300 prerouting
filter -200 all
out 100 output
srcnat 300 postrouting

使用这些标准名称也可以实现基本算术表达式(加法和减法)以简化相对优先级,例如 mangle - 5 代表 -155。 值也将像这样打印,直到值与标准值相差不超过 10。

基础链还允许设置链的策略,即在包含的规则中没有明确接受或拒绝的数据包会发生什么。 支持的策略值是接受(这是默认值)或丢弃。

6. 规则rule

规则被添加到指定表指定链中,由表达式和语句组成。操作有add insert replace delete,add和insert命令可支持用句柄handle或index(以0开始)新增规则

在内部,规则位置总是由handle标识,index的转换发生在用户空间。如果在翻译完成后发生并发规则集更改,这有两个潜在影响: 如果在引用的规则之前插入或删除规则,则有效规则index可能会更改。如果引用的规则被删除,则该命令将被内核拒绝,就像给出了无效句柄一样。

注释是单个单词或双引号括起来的多单词字符串,可用于对实际规则注释。注意:如果使用bash添加规则要对双引号进行转义。

# 创建规则—— add 将规则添加到链的末尾,insert 则将规则添加到链的开头。 nft insert rule nat postrouting oif eth0 snat to 1.2.3.5 # 将规则添加到链中指定位置有两种方法——利用handle或index,推荐handle,因为链中有其他规则增加到index之前,则index会发生变化 # add配handle,添加到对应handle后面; insert加handle添加到对应handle之前; # nft add rule [表名] [链名] handle 9 [规则] # nft insert rule [表名] [链名] handle 9 [规则] # 可以在创建规则时就获取到规则的句柄值,只需要在创建规则时同时加上参数 --echo 和 --handle nft add rule nat postrouting handle 9 oif eth0 snat to 1.2.3.7 nft insert rule nat postrouting handle 9 oif eth0 snat to 1.2.3.6 nft list table nat -a table ip nat { 
    chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; oif "eth0" snat to 1.2.3.5 # handle 10 ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade # handle 3 iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade # handle 4 counter packets 3172 bytes  # handle 5 ip saddr 10.121.0.3 iifname "tun0" oifname "eth0" counter packets 0 bytes 0 masquerade # handle 6 oif "eth0" snat to 1.2.3.6 # handle 12 oif "eth0" snat to 1.2.3.4 # handle 9 } } # 删除规则 nft delete rule nat postrouting handle 9 # 更新规则 nft replace rule nat postrouting handle 12 oif eth0 snat to 1.2.3.7 # 查询结果 nft list table nat -a table ip nat { 
    chain prerouting { 
    type nat hook prerouting priority -100; policy accept; } chain postrouting { 
    type nat hook postrouting priority 100; policy accept; oif "eth0" snat to 1.2.3.5 # handle 10 ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade # handle 3 iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade # handle 4 counter packets 3172 bytes  # handle 5 ip saddr 10.121.0.3 iifname "tun0" oifname "eth0" counter packets 0 bytes 0 masquerade # handle 6 oif "eth0" snat to 1.2.3.7 # handle 12 } } # 查询指定表nat的指定链postrouting nft list chain nat postrouting -a table ip nat { 
    chain postrouting { 
    type nat hook postrouting priority 100; policy accept; oif "eth0" snat to 1.2.3.5 # handle 10 ip saddr 10.121.0.0/16 oifname "wg0" counter packets 0 bytes 0 masquerade # handle 3 iifname "tun0" oifname "wg0" counter packets 0 bytes 0 masquerade # handle 4 counter packets 3172 bytes  # handle 5 ip saddr 10.121.0.3 iifname "tun0" oifname "eth0" counter packets 0 bytes 0 masquerade # handle 6 oif "eth0" snat to 1.2.3.7 # handle 12 } } 

7. 集合set

  1. 匿名集合

匿名集是没有特定名称的集。集合成员用花括号括起来,在创建使用集合的规则时用逗号分隔元素。一旦删除该规则,该集合也将被删除。它们无法更新,即一旦声明了匿名集,就不能再更改它,除非通过删除/更改使用匿名集的规则。

# 创建表filter nft add table filter # 创建表filter的链input nft add chain filter input # 用匿名集合创建规则 此处实际上匹配了四条规则 nft add rule filter input ip saddr { 
    10.0.0.0/8, 192.168.0.0/16 } tcp dport { 
    22, 443 } accept table ip filter { 
    chain input { 
    ip saddr { 
    10.0.0.0/8, 192.168.0.0/16 } tcp dport { 
    ssh, https } accept } } 
  1. 命名集合

命名集是需要先定义才能在规则中引用的集。与匿名集合不同,元素可以随时添加到命名集合或从命名集合中删除。使用集合名称前缀的@ 从规则中引用集合。

# 先定义命名集合 nft add set filter allowed_hosts { 
    type ipv4_addr \; } nft list sets nft list filter allowed_hosts table ip nat { 
    } table inet mytable { 
    } table ip filter { 
    set allowed_hosts { 
    type ipv4_addr } } # 集合添加元素 nft add element filter allowed_hosts { 
    192.168.1.2, 192.168.1.3 } nft list set filter allowed_hosts table ip filter { 
    set allowed_hosts { 
    type ipv4_addr elements = { 
    192.168.1.2, 192.168.1.3 } } } # 删除集合元素 nft delete element filter allowed_hosts { 
    192.168.1.2 } # 用命名集合创建规则 nft add set filter allowed_ports { 
    type inet_service \; } nft add element filter allowed_ports { 
    80, 443, 8000 } # 查看 nft list set filter allowed_ports table ip filter { 
    set allowed_ports { 
    type inet_service elements = { 
    http, https, 8000 } } } nft list set filter allowed_ports -nn table ip filter { 
    set allowed_ports { 
    type inet_service elements = { 
    80, 443, 8000 } } } # 使用命名集合 nft add rule filter input ip saddr @allowed_hosts tcp dport @allowed_ports accept # 查询 nft list chain filter input table ip filter { 
    chain input { 
    ip saddr { 
    10.0.0.0/8, 192.168.0.0/16 } tcp dport { 
    ssh, https } accept ip saddr @allowed_hosts tcp dport @allowed_ports accept } } 

设置规格

关键词 描述 类型
type 集合所有元素的数据类型 字符串: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark
typeof 集合元素的数据类型 派生数据类型的表达式
flags 设置标志 字符串: constant, dynamic, interval, timeout
timeout 元素停留在集合中的时间,如果从数据包路径(规则集)中添加集合,则是必需的 字符串, decimal followed by unit. Units are: d, h, m, s
gc-interval 垃圾收集间隔,仅在 timeout 或 flag timeout 处于活动状态时可用 字符串, decimal followed by unit. Units are: d, h, m, s
elements 集合包含的元素 set data type
size 集合中元素的最大数量,如果从数据包路径(规则集)中添加集合,则为强制性 unsigned integer (64 bit)
policy 制定政策 字符串: performance [default], memory
auto-merge 相邻/重叠集合元素的自动合并(仅适用于区间集合)

8. 字典map

使用不同类型的数据并将匹配条件映射到某一个规则上面,并且由于是哈希映射的方式,可以完美的避免链式规则跳转的性能开销。

设置规格

关键词 描述 类型
type 集合所有元素的数据类型 字符串: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark
typeof 集合元素的数据类型 派生数据类型的表达式
flags 设置标志 字符串: constant, dynamic, interval, timeout
elements 集合包含的元素 set data type
size 集合中元素的最大数量,如果从数据包路径(规则集)中添加集合,则为强制性 unsigned integer (64 bit)
policy 制定政策 字符串: performance [default], memory

匿名字典

# 创建一个表 nft create table ip mytable # 创建三个个链 nft create chain ip mytable tcpchain nft create chain ip mytable udpchain nft create chain ip mytable filterchain # 地址簇为ip的表mytable的filterchain链增加一条规则——从逻辑上将对 TCP 和 UDP 数据包的处理规则拆分开来 nft add rule ip mytable filterchain meta l4proto vmap { 
    tcp : jump tcpchain, udp : jump udpchain } # 查看 nft list chain ip mytable filterchain table ip mytable { 
    chain filterchain { 
    meta l4proto vmap { 
    tcp : jump tcpchain, udp : jump udpchain } } } 

命名字典

# 创建 nft add map ip mytable myvmap { 
    type ipv4_addr : verdict \; } # 添加元素 nft add element ip mytable myvmap { 
    192.168.0.10 : accept, 192.168.0.11 : drop } # 添加规则 nft add rule ip mytable filterchain ip saddr vmap @myvmap # 查看 nft list table mytable table ip mytable { 
    map myvmap { 
    type ipv4_addr : verdict elements = { 
    192.168.0.10 : accept, 192.168.0.11 : drop } } chain tcpchain { 
    } chain udpchain { 
    } chain filterchain { 
    meta l4proto vmap { 
    tcp : jump tcpchain, udp : jump udpchain } ip saddr vmap @myvmap } } 

9. 元素

语法规则

{ 
   add | create | delete | get } element [family] table set { 
    ELEMENT[, ...] } ELEMENT := key_expression OPTIONS [: value_expression] OPTIONS := [timeout TIMESPEC] [expires TIMESPEC] [comment string] TIMESPEC := [numd][numh][numm][num[s]] 

元素相关命令允许更改命名集合和命名字典的内容。

get命令可以检查一个元素是否包含在一个集合中。

选项 描述
timeout 带有标志超时的集合/映射的超时值
expires 给定元素到期之前的时间,仅对规则集复制有用
comment 每个元素的注释字段
# 创建表 nft create table filter # 用命名集合创建规则 nft add set filter allowed_ports { 
    type inet_service \; } nft add element filter allowed_ports { 
    80, 443, 8000 } # 查看 nft list set filter allowed_ports # 删除 nft delete element ip filter allowed_ports { 
   8000} # 判断某元素是否在集合中【此条未测试通过】 nft get inet_service filter allowed_ports { 
    8000 } 

10. 备份|恢复

# 备份 nft list ruleset >> backup.nft # 恢复(原子性) nft -f backup.nft 

11. 流表flowtable

flowtable允许在软件中加速数据包转发。其条目通过一个元组表示,元组由输入接口、原地址、目的地址、端口和3/4层协议组成。

12. 有状态对象【重要】

基础语法

{ 
   add | delete | list | reset} type [family] table object delete type [family] table handle handle list counters [family] list quotas [family] 

有状态对象是附加到表的并由唯一名称标识。它们将规则中的状态信息分组,以在规则中引用它们,使用关键字“类型名称”,例如“计数器名称”。

  1. CT Helper
    • 基础语法ct helper helper { type type protocol protocol ; [l3proto family ;] }
    • ct helper用于定义连接跟踪助手,可以将其与ct helper set语句结合使用。typeprotocol是强制性的,l3proto 默认派生自表簇,即在 inet 表中,内核将尝试加载 ipv4 和 ipv6 助手后端,如果内核支持它们。
  2. CT Timeout
    • 基础语法ct timeout name { protocol protocol ; policy = { state: value [, ...] } ; [l3proto family ;] }
    • ct timeout用于更新连接跟踪超时值。超时策略由ct timeout set语句指定。protocolpolicy是强制性的,l3proto 默认派生自表族。
    • conntrack 超时规格
      关键词 描述 类型
      protocol 字符串(例:ip)
      state 字符串(例:“established”)
      value 无符号整数
      l3proto 地址簇(例:ip)
    • 定义和分配ct timeout策略
      table ip filter { 
              ct timeout customtimeout { 
              protocol tcp; l3proto ip policy = { 
              established: 120, close: 20 } } chain output { 
              type filter hook output priority filter; policy accept; ct timeout set "customtimeout" } } 
    • 测试和更新超时策略

      yum install conntrack安装

      conntrack-tools的使用手册

      关于conntrack的一篇文章

      # 命令 显示流事件 conntrack -E # 结果 前两个值为 协议 剩余秒数 [NEW] icmp 1 30 src=10.121.6.6 dst=192.168.5.71 type=8 code=0 id=1 [UNREPLIED] src=192.168.5.71 dst=192.168.5.119 type=0 code=0 id=1 [UPDATE] icmp 1 30 src=10.121.6.6 dst=192.168.5.71 type=8 code=0 id=1 src=192.168.5.71 dst=192.168.5.119 type=0 code=0 id=1 # 晒选条件为tcp协议22端口 mark是更新标记 conntrack -U -p tcp --dport 22 --mark 10 # 结果 可以看到10.121.6.6访问了192.168.5.71的22端口、58.40.70.86访问了192.168.5.119的22端口 tcp 6  ESTABLISHED src=10.121.6.6 dst=192.168.5.71 sport=6401 dport=22 src=192.168.5.71 dst=192.168.5.119 sport=22 dport=6401 [ASSURED] mark=10 use=2 tcp 6 79 TIME_WAIT src=10.121.6.6 dst=192.168.5.71 sport=9890 dport=22 src=192.168.5.71 dst=192.168.5.119 sport=22 dport=9890 [ASSURED] mark=10 use=2 tcp 6 299 ESTABLISHED src=58.40.70.86 dst=192.168.5.119 sport=2526 dport=22 src=192.168.5.119 dst=58.40.70.86 sport=22 dport=2526 [ASSURED] mark=10 use=2 tcp 6  ESTABLISHED src=58.40.70.86 dst=192.168.5.119 sport=2528 dport=22 src=192.168.5.119 dst=58.40.70.86 sport=22 dport=2528 [ASSURED] mark=10 use=2 
  3. CT Expectation
    • 基础语法ct expectation name { protocol protocol ; dport dport ; timeout timeout ; size size ; [*l3proto family ;] }
    • ct expectation 用于创建连接期望。期望是用ct expectation set语句分配的。protocol, dport, timeoutsize是强制性的,l3proto 默认源于表簇。
    • conntrack 期望规格
      关键词 描述 类型
      protocol 期望对象的第四层协议 字符串(例:ip)
      dport 期望连接的目的端口 无符号整数
      timeout 期望的超时值 无符号整数
      size 期望的大小值 无符号整数
      l3proto 期望对象的第3层协议 地址簇(例:ip)
    • 定义和分配ct expectation策略
      table ip filter { 
              ct expectation expect { 
              protocol udp dport 9876 timeout 2m size 8 l3proto ip } chain input { 
              type filter hook input priority filter; policy accept; ct expectation set "expect" } } 
  4. Counter
    • 基础语法counter [packets bytes]
    • counter 规格
      关键词 描述 类型
      packets 数据包的初始计数 无符号整数 (64 bit)
      bytes 初始字节数 无符号整数 (64 bit)
  5. Quota
    • 基础语法quota [over | until] [used]
    • counter 规格
      关键词 描述 类型
      quota 配额限制,用作配额名称 两个参数,无符号整数 (64 bit)和字符串,bytes, kbytes, mbytes 需要在这些参数前写上 “over” 和"until"
      used 已用配额的初始值 两个参数,无符号整数 (64 bit)和字符串,bytes, kbytes, mbytes

13. 表达式Expression

表达式表示值,可以是网络地址、端口号等常量,也可以是在规则集评估期间从数据包中收集的数据。可以使用二进制、逻辑、关系和其他类型的表达式组合表达式以形成复杂或关系(匹配)表达式。它们还用作某些类型操作的参数,例如 NAT、数据包标记等。每个表达式都有一个数据类型,它决定了符号值的大小、解析和表示以及与其他表达式的类型兼容性。

# 描述命令 describe expression | data type nft describe tcp flags 

14. 数据类型

14种,暂时留空

15. 主要表达式

  1. 元表达式
meta { 
   length | nfproto | l4proto | protocol | priority} [meta] { 
   mark | iif | iifname | iiftype | oif | oifname | oiftype | skuid | skgid | nftrace | rtclassid | ibrname | obrname | pkttype | cpu | iifgroup | oifgroup | cgroup | random | ipsec | iifkind | oifkind | time | hour | day } 

元表达式类型

Keyword Description Type
length 数据包的长度(以字节为单位) 整数(32-bit)
nfproto 真正的钩子协议族,仅在 inet 表中有用 整数(32 bit)
l4proto 4层协议,跳过 ipv6 扩展标头 整数(8 bit)
protocol EtherType 协议值 ether_type
priority TC 报文优先级 tc_handle
mark 报文标记 mark
iif 输入接口索引 iface_index
iifname 输入接口名称 ifname
iiftype 输入接口类型 iface_type
oif 输出接口索引 iface_index
oifname 输出接口名称 ifname
oiftype 输出接口硬件类型 iface_type
sdif 从机输入接口索引 iface_index
sdifname 从设备接口名称 ifname
skuid 与原始套接字关联的 UID uid
skgid 与原始套接字关联的 GID gid
rtclassid 路由领域 realm
ibrname 输入桥接口名称 ifname
obrname 输出桥接口名称 ifname
pkttype packet type pkt_type
cpu 处理数据包的 CPU 编号 整数(32 bit)
iifgroup 传入设备组 devgroup
oifgroup 传出设备组 devgroup
cgroup 控制组标识id 整数(32 bit)
random 伪随机数 整数(32 bit)
ipsec 若数据包是 ipsec 加密的,则为 true 布尔值(1 bit)
iifkind 输入接口种类
oifkind 输出接口种类
time 接收包的绝对时间 整数(32 bit) 或 字符串
day 星期几 整数(8 bit) 或 字符串
hour 一天中的第几小时 字符串

元表达式特定类型

类型 描述
iface_index 接口索引(32 位数字) 可以用数字指定,也可以指定为现有接口的名称。
ifname 接口名称(16 字节字符串) 不一定存在。
iface_type 接口类型(16 位数字)
uid 用户 ID(32 位数字) 可以用数字或用户名指定。
gid 组 ID(32 位数字) 可以用数字或组名指定。
realm 路由领域(32 位数字)。可以用数字指定或作为 /etc/iproute2/rt_realms 中定义的符号名称指定。
devgroup_type 设备组(32 位数字)。可以用数字指定,也可以指定为 /etc/iproute2/group 中定义的符号名称。
pkt_type 数据包类型:主机(寻址到本地主机)、广播(对所有)、多播(对组)、其他(寻址到另一台主机)。
ifkind I接口种类(16 字节字符串)。有关列表,请参阅ip-link(8)中的TYPES 。
time ISO 格式的整数或日期。例如:“2019-06-06 17:00”。小时和秒是可选的,如果需要可以省略。如果省略,则假定为午夜。以下三个等效:“2019-06-06”、“2019-06-06 00:00”和“2019-06-06 00:00:00”。当给出一个整数时,它被假定为一个 UNIX 时间戳。
day 一周中的某一天(“Monday”、“Tuesday”等),或者 0 到 6 之间的整数。字符串不区分大小写匹配,并且不需要完全匹配(例如,“Mon”将匹配“Monday” )。当给出整数时,0 是星期日,6 是星期六。
hour 以 24 小时格式表示小时的字符串。可以选择指定秒数。例如,17:00 和 17:00:00 是等价的。
# 使用元表达式 # 合格的元表达式 filter output meta oif eth0 filter forward meta iifkind { 
    "tun", "veth" } # 【不合格的元表达式】 filter output oif eth0 # 传入的数据包经过 ipsec 处理 raw prerouting meta ipsec exists accept 
  1. 套接字表达式
  2. Osf表达式
  3. 路由表达式
  4. Numgen表达式
  5. 哈希表达式

16. 有效载荷表达式

留空待写

17. 语句

  1. Nat语句

语法规则

snat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS] dnat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS] masquerade [to :PORT_SPEC] [FLAGS] redirect [to :PORT_SPEC] [FLAGS] ADDR_SPEC := address | address - address PORT_SPEC := port | port - port FLAGS := FLAG [, FLAGS] FLAG := persistent | random | fully-random 

nat 语句仅对 nat 链类型有效。

待补充

18. 参考文档

  1. nftables用户手册 man nft - mankier.com
  2. golang库-nftableslib——lib文档
  3. nftables官方文档 nftables HOWTO documentation page——HowTo中文翻译
  4. 疑难问题解决和 FAQ
  5. 其他前辈的文章1
  6. 基佬杨写的教程
  7. 第七章是nftables入门 Red Hat Enterprise Linux 8 安全网络-配置安全网络和网络通信
  8. nftables家族介绍
  9. 官方故障排除文档
  10. 剖析语法文档——nftables相比iptables到底改变了什么
  11. ebpf防火墙GUI版本——ebpfsnitch

版权声明


相关文章:

  • javascript中switch用法列题2024-10-21 19:01:00
  • IDL实现相对辐射定标2024-10-21 19:01:00
  • html颜色代码大全(含图)2024-10-21 19:01:00
  • ece安装教程2024-10-21 19:01:00
  • 大学生计算机专业顶岗实习日记24篇2024-10-21 19:01:00
  • 前端计算器代码2024-10-21 19:01:00
  • iptables规则生成2024-10-21 19:01:00
  • js switch 多个选择条件2024-10-21 19:01:00
  • Nftables代替iptables2024-10-21 19:01:00
  • js switch分支语句与注意事项break2024-10-21 19:01:00