简单规则管理

添加新规则

要添加新规则,你需要指定正确的表名和链名,例如:

% nft add rule filter output ip daddr 8.8.8.8 counter

filter 是表名,output 是链名。上面的例子添加了一个规则,匹配 output 链中所有目的地址是 8.8.8.8 的数据包,并在匹配时更新规则计数器。注意在 nftables 中计数器是可选的。对于熟悉 iptables 的人来说,添加规则与 iptables 中的 -A 命令是一样的。

列出规则

你可以使用下面的命令列出一个表中的规则:

% nft list table filter
table ip filter {
    chain input {
        type filter hook input priority 0;
    }

    chain output {
        type filter hook output priority 0;
        ip daddr google-public-dns-a.google.com counter packets 0 bytes 0
    }
}

假设我们再使用 port 添加一个规则:

% nft add rule filter output tcp dport ssh counter

你可以使用 -n 选项关闭主机名解析:

% nft list -n table filter
table ip filter {
    chain input {
        type filter hook input priority 0;
    }

    chain output {
        type filter hook output priority 0;
        ip daddr 8.8.8.8 counter packets 0 bytes 0
        tcp dport ssh counter packets 0 bytes 0
    }
}

你也可以使用 -nn 选项关闭设备名解析:

% nft list -nn table filter
table ip filter {
    chain input {
         type filter hook input priority 0;
    }

    chain output {
         type filter hook output priority 0;
         ip daddr 8.8.8.8 counter packets 0 bytes 0
         tcp dport 22 counter packets 0 bytes 0
    }
}

测试你的规则

让我们使用简单的 ping8.8.8.8 测试这个规则:

% ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=64 time=1.31 ms

然后,如果我们列出规则集,会得到:

% nft -nn list table filter
table ip filter {
    chain input {
         type filter hook input priority 0;
    }

    chain output {
         type filter hook output priority 0;
         ip daddr 8.8.8.8 counter packets 1 bytes 84
         tcp dport 22 counter packets 0 bytes 0
    }
}

注意计数器已经更新了。

在给定位置添加规则

如果你想在给定位置添加规则,你需要使用 handle 作为引用:

% nft list table filter -n -a
table filter {
    chain output {
         type filter hook output priority 0;
         ip protocol tcp counter packets 82 bytes 9680 # handle 8
         ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7
    }
}

如果你想在句柄编号 8 后添加一个规则,你需要输入:

% nft add rule filter output position 8 ip daddr 127.0.0.8 drop

现在,你可以列出规则集来检查它的效果:

% nft list table filter -n -a
table filter {
    chain output {
         type filter hook output priority 0;
         ip protocol tcp counter packets 190 bytes 21908 # handle 8
         ip daddr 127.0.0.8 drop # handle 10
         ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7
    }
}

如果你想在句柄编号 8 之前插入一个规则,你需要输入:

% nft insert rule filter output position 8 ip daddr 127.0.0.8 drop

删除规则

你需要使用 -a 选项获得要删除规则的句柄。句柄是内核自动赋予的且独立的指代规则。

% nft list table filter -a
table ip filter {
    chain input {
             type filter hook input priority 0;
    }

    chain output {
        type filter hook output priority 0;
        ip daddr 192.168.1.1 counter packets 1 bytes 84 # handle 5
    }
}

你可以使用下面的命令删除句柄号是 5 的规则:

% nft delete rule filter output handle 5

注意:有计划支持通过下面的命令删除规则:

% nft delete rule filter output ip saddr 192.168.1.1 counter

但是现在还没有实现。所以现在还需要使用句柄来删除规则。

删除链中的所有规则

你可以使用下面的命令删除一条链中的所有规则:

% nft delete rule filter output

你也可以使用下面的命令删除一个表中的所有规则:

% nft flush table filter

在首部添加规则

使用 insert 命令在首部添加规则:

% nft insert rule filter output ip daddr 192.168.1.1 counter

这在首部添加了一个规则,它会在目标地址是 192.168.1.1 时更新数据包和字节计数器。

这在 iptables 中等价于:

% iptables -I OUTPUT -t filter -d 192.168.1.1

注意 iptables 总是为每条链提供了计数器。

替换规则

你可以使用 replace 命令并指明规则句柄来替换任何规则。因此,你首先需要做的是使用 -a 选项获取规则句柄。

% nft list ruleset -a
table ip filter {
    chain input {
        type filter hook input priority 0; policy accept;
        ip protocol tcp counter packets 0 bytes 0 # handle 2
    }
}

假设你想替换句柄 2 的规则,你需要指定这个句柄号和你想用于替换的新规则:

% nft replace rule filter input handle 2 counter

然后,当你列出规则集时:

# nft list ruleset -a
table ip filter {
    chain input {
        counter packets 0 bytes 0 
    }
}

可以看到规则被一个简单的对所有数据包计数的规则替代了,而不是之前的对 TCP 包计数的规则了。