解决Linux nf_conntrack: helper分配错误 (安全指南)
2025-03-13 10:39:05
Linux 下 "nf_conntrack: default automatic helper assignment..." 问题的解决方法
直接说事,最近碰到个系统提示:nf_conntrack: default automatic helper assignment has been turned off for security reasons and CT-based firewall rule not found. Use the iptables CT target to attach helpers instead.
内核版本是 5.4.23,nftables 版本是 0.9.3。 这啥意思?怎么整?别急,下面咱们来捋一捋。
一、问题原因:内核安全策略变更
这个提示的出现,其实是 Linux 内核为了安全起见,关掉了 conntrack 模块的自动 helper 分配功能。
早些时候,内核会根据你的流量类型,自动给它匹配一个 “helper” 模块。这些 helper 模块是干啥的呢? 像 FTP、SIP 这类协议,一个连接可能会开多个端口,单靠端口过滤不行,就需要 helper 模块来识别、关联这些连接,方便管理。
但是,自动分配 helper 有安全风险。 攻击者可能利用某些 helper 的漏洞,搞事情。 所以,新的内核版本默认就把这个自动功能关掉了。 你得手动指定用哪个 helper。
二、解决方法:告别 “自动挡”,拥抱 “手动挡”
解决这个问题,核心思路就是手动指定需要的 conntrack helper。 下面介绍几个可行的方案。
2.1 方案一: 使用 nftables 的 CT target
nftables 提供了 ct helper
语句,可以直接在规则里绑定 helper。 这是官方推荐的搞法。
-
创建 helper 定义
首先,你要定义一个 helper 对象。 这个对象要指明它处理哪个协议,监听哪个端口。
nft add helper filter ftp-helper inet { type ftp dport 21 }
解释一下:
add helper
: 添加 helper 对象的命令。filter
: 自定义的名字,你可以改成你喜欢的。ftp-helper
: 这个 helper 的名字,也随意。inet
: 指定协议族, inet 表示 IPv4。如果是IPv6, 使用 inet6。type ftp
: 指明这个 helper 处理的是 ftp 协议。dport 21
: 指定监听端口,这里是 FTP 的默认端口。
-
在规则中使用 helper
定义好 helper 之后,在
input
链(或者你处理入站流量的其他链)里,用ct helper
语句,把它跟具体的流量绑定起来。nft add rule filter input tcp dport 21 ct helper set "ftp-helper"
这条规则的意思:对于 TCP 目标端口是 21 的流量,使用刚才定义的名为 "ftp-helper" 的 helper。
完整nftables配置示例:
table ip filter { helper ftp-helper { type ftp dport 21 } chain input { type filter hook input priority filter; policy accept; ct state established,related accept iif "lo" accept tcp dport 21 ct helper set "ftp-helper" #添加的helper规则 } chain forward { type filter hook forward priority filter; policy accept; } chain output { type filter hook output priority filter; policy accept; } }
然后用
nft -f <文件名>.nft
使配置生效
进阶技巧:
如果你要处理多个端口的同一个协议,可以在 dport
后面用大括号 {}
括起来,用逗号分隔。 比如:
nft add helper filter h323-helper inet { type h323 dport { 1719, 1720 } }
nft add rule filter input tcp dport { 1719, 1720 } ct helper set "h323-helper"
2.2 方案二: 使用 raw 表
如果方案一不奏效(某些情况下可能会这样),可以尝试使用 raw
表。 raw
表在 netfilter 框架里处理数据包非常靠前,甚至在 conntrack 之前。 可以在这里就设置好 helper。
-
添加 raw 表规则
nft add table raw nft add chain raw prerouting { type filter hook prerouting priority -300 \; } nft add rule raw prerouting tcp dport 21 ct helper set ftp
- 第一行:建立名为raw的表。
- 第二行: 建立名为prerouting的链, 类型为filter, hook到prerouting, 优先级为-300.
- 第三行:为 raw 表 prerouting 链添加一条规则: 对于 TCP 目标端口为 21 的数据包,设置 conntrack helper 为
ftp
。 - 注意:这里的helper 名字直接写
ftp
,而不是方案一种定义过的helper名字。
-
清空并重新加载规则 (根据情况)
nft flush ruleset
nft -f /path/to/your/nftables.conf # 如果你把配置写到了文件里
因为raw表处理非常靠前, 可能需要在修改后清空所有nftable的配置, 并重新载入.
(根据实际测试判断需不需要进行该步)
注意: 使用 raw
表直接写 ftp
这种,比方案一少了一层 “抽象”。 如果你有自定义需求,比如用非标准端口跑 FTP,方案一更灵活。
2.3方案三 启用自动辅助分配(不建议)
如果你确定自己知道风险,而且必须使用自动 helper 分配(比如某些旧的应用依赖这个),可以临时把它打开。
但是非常不建议,安全性有一定降低
-
修改内核参数
sysctl -w net.netfilter.nf_conntrack_helper=1
这行命令将
net.netfilter.nf_conntrack_helper
设置为 1,就开启了自动分配。 -
持久化设置(可选)
直接用
sysctl
修改是临时的,重启后会失效。 要永久生效,可以把这行加到/etc/sysctl.conf
文件里:net.netfilter.nf_conntrack_helper = 1
然后执行:
sysctl -p
再次强调,方案三仅仅是应急手段,不建议长期使用。 尽量用方案一或者方案二,安全第一。
三、安全建议
-
最小化原则: 只启用你真正需要的 helper。 没用的 helper 关掉,减少潜在风险。
-
定期检查: 定期看看系统日志,有没有跟 conntrack 相关的异常。
-
保持更新: 内核、nftables,能更新就更新,新版本通常会修复已知的安全问题。
-
端口管理 尽量使用标准端口,减少出现奇怪问题的几率.
如果对Linux 防火墙感兴趣,可以看看这几个:
-
nftables 官方文档: https://wiki.nftables.org/
-
netfilter 官方网站: https://www.netfilter.org/
搞定! 以后再碰到 nf_conntrack
报错,就不会懵了。