我有一台简单的台式机:装有模块的
Linux 机器nf_conntrack
。这台机器位于另外两台主机(A 和 B)之间,因此它在两个网络之间路由流量。当我通过 Linux“路由器”从 A 向 B 发送 ping 时,输出0 flow entries have been shown
中没有任何内容 ( ) 。 我应该怎么做才能使 conntrack 正常工作?conntrack -L
UPD:它是带有 Linux 内核 4.4、4.9 的 Debian 9(两者具有相同的行为)。
答案1
Linux连接跟踪模块随着内核版本而改变。
至少在 Debian 9 上的内核 4.9 中,该nf_conntrack
模块是 netfilter 的 conntrack 功能的核心模块:
$ /sbin/modinfo /tmp/lin/lib/modules/4.9.0-12-amd64/kernel/net/netfilter/nf_conntrack.ko
filename: /tmp/lin/lib/modules/4.9.0-12-amd64/kernel/net/netfilter/nf_conntrack.ko
license: GPL
depends:
retpoline: Y
intree: Y
vermagic: 4.9.0-12-amd64 SMP mod_unload modversions
parm: tstamp:Enable connection tracking flow timestamping. (bool)
parm: acct:Enable connection tracking flow accounting. (bool)
parm: nf_conntrack_helper:Enable automatic conntrack helper assignment (default 0) (bool)
parm: expect_hashsize:uint
这里不涉及 IPv4。因此 ICMP(IPv4 的一部分)不会触发任何操作。为此,您必须加载附加模块nf_conntrack_ipv4
。
$ /sbin/modinfo /tmp/lin/lib/modules/4.9.0-12-amd64/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
filename: /tmp/lin/lib/modules/4.9.0-12-amd64/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
license: GPL
alias: ip_conntrack
alias: nf_conntrack-2
depends: nf_conntrack,nf_defrag_ipv4
retpoline: Y
intree: Y
vermagic: 4.9.0-12-amd64 SMP mod_unload modversions
在较新的内核中,例如来自 stretch-backports 的 4.19.0-0.bpo.6-amd64,IPv4 和 IPv6 模块被合并,因为发现它总体上更便宜。相反,您有:
$ /sbin/modinfo /tmp/lin/lib/modules/4.19.0-0.bpo.6-amd64/kernel/net/netfilter/nf_conntrack.ko
filename: /tmp/lin/lib/modules/4.19.0-0.bpo.6-amd64/kernel/net/netfilter/nf_conntrack.ko
license: GPL
alias: nf_conntrack-10
alias: nf_conntrack-2
alias: ip_conntrack
depends: nf_defrag_ipv6,libcrc32c,nf_defrag_ipv4
retpoline: Y
intree: Y
name: nf_conntrack
vermagic: 4.19.0-0.bpo.6-amd64 SMP mod_unload modversions
signat: PKCS#7
signer:
sig_key:
sig_hashalgo: md4
parm: tstamp:Enable connection tracking flow timestamping. (bool)
parm: acct:Enable connection tracking flow accounting. (bool)
parm: nf_conntrack_helper:Enable automatic conntrack helper assignment (default 0) (bool)
parm: expect_hashsize:uint
因此,如果您遵循最新的文档,它就不会指出还要明确加载模块,nf_conntrack_ipv4
此外nf_conntrack
:不再有这样的模块。
适合您的内核版本的解决方案:
modprobe nf_conntrack_ipv4
关于依赖关系:
单独运行
conntrack -E
将nf_conntrack
作为依赖项加载。不是nf_conntrack_ipv4
!任何有状态的防火墙规则iptables或者不育系使用 ip 或 inet 系列将自动拉取
nf_conntrack_ipv4
在主机(初始网络命名空间)上,只需加载模块(
nf_conntrack
在最近的内核上,但conntrack -E
会自行执行,或者nf_conntrack_ipv4
在较旧的内核上)就足以运行conntrack -E
。在(非初始)网络命名空间上,conntrack(以及各种与 netfilter 相关的功能)被停用,直到它具有依赖性。这可以避免为主机(或给定网络命名空间)加载一个模块突然激活其他所有命名空间上的功能。一旦激活,如果不破坏网络命名空间,可能无法再次停用它。
上述观点也有例外。包括臭名昭著的
br_netfilter
直到最近,它才可以在所有网络命名空间上全局工作(即使通过非初始命名空间间接工作,当使用-m physdev
iptables 匹配)
答案2
只有当你的 iptables 或 nftables 规则集至少有一个基于 conntrack 的规则(例如 nftablesct
或 iptables -m state
,或 NAT/masquerade 规则,或可能 -j REJECT
),否则其 conntrack_ops 将被取消注册——很可能是为了避免额外的资源使用。
例如(如果您的规则当前尚未使用 conntrack),请在“输入”或“转发”链的顶部添加以下内容:
ct 状态 {已建立,相关} 接受
-A 输入 -m 状态 --状态已建立,相关 -j 接受