在过去的两年里,我一直在使用相同的配置的 nftables,前几天更新了程序,现在它抱怨我的配置无效,尽管所有的文档仍然表明它是正确的。也许有人能发现一个恶意符号或者什么东西?
这是我的配置:
flush ruleset
# `inet` applies to both IPv4 and IPv6.
table inet filter {
chain input {
type filter hook input priority 0;
# accept any localhost traffic
iif lo accept
# no ping floods:
ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets drop
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop
# accept traffic originated from us
ct state established,related accept
# ssh
tcp dport 22 accept
# http/https
tcp dport 80 accept
tcp dport 443 accept
# tftp/netboot
udp dport 4011 accept
udp dport 67 accept
tcp dport 69 accept
udp dport 69 accept
# listinator
tcp dport 8080 accept
tcp dport 4343 accept
# smb
tcp dport 139 accept
tcp dport 445 accept
udp dport 137 accept
udp dport 138 accept
# mc
tcp dport 25565 accept
# count and drop any other traffic
counter drop
}
chain output {
type filter hook output priority 0;
policy accept;
}
chain forward {
type filter hook forward priority 0;
nft add rule inet filter forward ct status dnat accept;
policy drop;
}
}
并且启动时出现错误:
Starting nftables...
/etc/nftables.conf:57:6-8: Error: syntax error, unexpected add
nft add rule inet filter forward ct status dnat accept;
^^^
nftables.service: Main process exited, code=exited, status=1/FAILURE
nftables.service: Failed with result 'exit-code'.
Failed to start nftables.
答案1
这是在nftables 脚本加载了命令nft -f
。nft
单词里面没有任何意义,不应该出现。但是在同一位置还有 1 1/2 个其他问题。让我们看看:
该命令抱怨的行周围nft
有:
chain forward { type filter hook forward priority 0; nft add rule inet filter forward ct status dnat accept; policy drop; }
nft
即将被删除,已在
inet filter forward
(链)块内所以
add rule inet filter forward
也必须删除。其实;
是多余的,因为后面有一个新行。ct status dnat accept
policy drop;
必须与基础链定义放在一起这次是
;
语法的强制部分。policy
关键字是链定义,不属于规则定义。虽然目前看来这已被接受,并通过规则将其与基本链定义分开,但这并不是可以依赖的:这可能会在以后的版本中发生变化。同样的评论适用于
output
链:不要policy accept;
与其基本链定义分离,以便您以后不会错误地在其中插入规则。
该forward
链条最终应被替换为:
chain forward {
type filter hook forward priority 0; policy drop;
ct status dnat accept
}
正确的语法(但并不是很有趣)是在脚本末尾定义规则,而不是在块内,而是完全在结构之外,如下所示:
chain forward {
type filter hook forward priority 0; policy drop;
}
}
add rule inet filter forward ct status dnat accept
无论如何,nft list ruleset
它将像以前一样在链块中显示出来inet filter forward
。
笔记:
虽然可以使用
ip protocol icmp
,但不能使用ip6 nexthdr ipv6-icmp
原因是,与 IPv4 不同,IPv4 报头中的协议始终是第 4 层协议,而 IPv6 的下一个标题并不总是第 4 层(icmp、udp、tcp……)标头:它可能是扩展头出现在 IPv6 报头和第 4 层(最终)报头之间。在这种情况下,规则将不匹配。
操作系统已经确定该数据包属于哪个第 4 层协议,因此该信息可作为元信息而不是数据包内容信息使用:
meta l4proto ipv6-icmp
。这也是手册页中记录了:
此表达式引用 ipv6 报头字段。使用时请小心
ip6 nexthdr
,该值仅引用下一个报头,即,ip6 nexthdr tcp
只有当 ipv6 数据包不包含任何扩展报头时才会匹配。碎片化的数据包或例如包含路由扩展报头的数据包将不会被匹配。meta l4proto
如果您希望匹配实际传输报头并忽略任何其他扩展报头,请使用。但实际上,由于同一行确实包含一行
icmpv6 type ...
,这已经过滤了第 4 层协议以匹配 ICMPv6,同时使用 ICMPv6 隐式设置第 3 层协议以匹配 IPv6:根本不需要做任何事就可以使它正确。同样,由于相同的原因,上一行也可以不做
ip protocol icmp
(但其当前行为仍然正常)。以下行:
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop
必须简单地替换为:
icmpv6 type echo-request limit rate over 10/second burst 4 packets drop
(无需添加
meta nfproto ipv6 meta l4proto icmpv6
)远程文件传输协议
-
TCP 端口 69 从未使用过,因此不需要规则来允许它。
TFTP 和状态防火墙
远程文件传输协议对于防火墙来说,这是一种和 FTP 一样困难的协议。经过初步查询,数据传输本身不再使用 UDP 端口 69。充分利用TFTP conntrack 助手
nf_conntrack_tftp
可能需要附加规则(应该自动加载内核模块),除非net.netfilter.nf_conntrack_helper
重新启用已弃用的 sysctl 设置。在这里讨论这个问题确实会偏离主题。请参阅我的回答的开头(仅供参考)CentOS 8 作为带有 nft 和firewalld 的 NAT 路由器-如何让它通过 TFTP?有一个可以复制来替换的示例 TFTP 规则集nftables wiki 中的 FTP 示例。
-
仅具有不同端口值的相同规则可以使用以下方法分解匿名集。nftables 版本 >= 1.0.2 甚至有
-o
(优化) 选项尝试自动完成此操作。