流表是一种nftables
将流量卸载到“快速路径”的功能,一旦建立连接,该路径就会跳过典型的转发路径。需要配置两件事来设置流表。首先是它flowtable
本身,它被定义为表的一部分。其次是一个flow offload
陈述,这就是我的问题。手册nft
页说:
FLOW STATEMENT
A flow statement allows us to select what flows you want to accelerate
forwarding through layer 3 network stack bypass. You have to specify
the flowtable name where you want to offload this flow.
flow add @flowtable
这维基页面包括这个完整的配置示例:
table inet x {
flowtable f {
hook ingress priority 0; devices = { eth0, eth1 };
}
chain forward {
type filter hook forward priority 0; policy drop;
# offload established connections
ip protocol { tcp, udp } flow offload @f
ip6 nexthdr { tcp, udp } flow offload @f
counter packets 0 bytes 0
# established/related connections
ct state established,related counter accept
# allow initial connection
ip protocol { tcp, udp } accept
ip6 nexthdr { tcp, udp } accept
}
}
这就是我感到困惑的地方。该示例ip protocol { tcp, udp }
对accept
流量和它使用相同的条件 ( ) flow offload
。这是因为flow offload
将隐式地accept
添加到流表中是一个流,这意味着这些条件应该始终匹配?或者这个例子只是巧合,accept
规则可能会更严格?
具体来说,假设我只想转发来自 的入站 SSH 流量eth0
,并且我想启用流量卸载。我应该像这样配置转发链吗?
chain forward {
type filter hook forward priority 0; policy drop;
# offload established connections
ip protocol { tcp, udp } flow offload @f
# established/related connections
ct state established,related counter accept
# allow initial connection
iif eth0 tcp dport 22 accept
}
或者像这样? (只是flow offload
规则改变了)
chain forward {
type filter hook forward priority 0; policy drop;
# offload established connections
iif eth0 tcp dport 22 flow offload @f
# established/related connections
ct state established,related counter accept
# allow initial connection
iif eth0 tcp dport 22 accept
}
答案1
我首先想从wiki上指出几个关键句子:
您可以通过流表达式从前向链中选择要卸载的流。
创建状态后,流量将被卸载。这意味着通常第一个回复数据包将创建流表条目。需要接受初始流量的防火墙规则。前向链上的流表达式必须与初始连接的返回流量相匹配。
更具体地说,它指出:
这也意味着如果您使用特殊的 ip 规则,您需要确保它们与回复数据包流量以及原始流量匹配。
根据我的经验,我发现确定回复方向、是否建立、初始等等太难了。
还要从他们的例子中,密切关注他们的评论;流程语句卸载已建立的负载,并且进一步向下,您必须接受初始连接。
在我看来,卸载一般来说是一件好事,所以我只使用一个广泛的流程语句,如下所示:
ip6 nexthdr { tcp, udp } flow add @f counter
ip protocol { tcp, udp } flow add @f counter
然后我像平常一样允许进出:
ct state established,related counter accept
iif $DEV_INSIDE counter accept
iif $DEV_OUTSIDE ip6 daddr <mail server> tcp dport { smtp } counter accept
流语句绝对不只是接受所有内容,尽管它看起来是这样。看看上面的 ASCII 图,应该更有意义。
巴勃罗·内拉·阿尤索 (Pablo Neira Ayuso) 指出略有不同的方式:
一旦流处于已建立状态,“流卸载”操作就会根据连接跟踪定义添加流条目,即。我们看到了两个方向的交通。因此,只有流的初始数据包遵循经典转发路径。
总而言之,是的,您可以在flow add
声明中获得更具体的信息,但是当最终流量遵循 ESTAB 状态时,为什么还要麻烦,并且您可以在其他地方使用正常的、有状态的规则来维护保护。
这个资源也相当有深度和精彩。
我会用你的第一个例子,然后通过nmap
扫描进行仔细检查。另请注意,您可以使用 检查是否成功conntrack -L
。