Firewalld 报告 ‘python-nftables’ failed 的调试思路

刚刚把软路由从 Ubuntu 20.04 升级到 21.10,升级的时候告诉我会把 FirewallBackendiptables 改成 nftables。我正好想试一试,就让他改了。

结果重启之后 firewall-cmd --reload 会报错

上面的JSON 内容已经给出了出错的 nftables 操作列表,firewalld 在操纵 nftables 的时候,会将多个请求合并为一个发给 nftables,导致并不能知道上面哪一条出了问题。看到bugzilla相关的讨论,可以让firewalld 拆分请求。

https://bugzilla.redhat.com/show_bug.cgi?id=1869451#c6

set IndividualCalls=yes in /etc/firewalld/firewalld.conf. This will give a better indication of what rule fails to apply to nftables.

修复了一些我自己范的简单错误后,神奇的事情发生了,如果 IndividualCalls=no ,那么问题直接消失, reload 的时候直接success 了。经过分析发现,问题还是出在 firewalld 批量操作 nftables 上。

我的推测是:如果一批操作中任何一个指令失败,这批操作就会被回滚。那么如果这批操作中有新建 Chain 之类的操作,就会导致 Chain 没有被创建,然后后面就会出各种莫名其妙的问题,我们看到的错误并非根本原因。

我这个问题的最终原因是 ipset 中 条目有overlap.删除 ipset 并导入正确的ipset之后问题解决。

调试思路

本质上,firewalld 启动的时候是不应该有任何错误才对。那么我们可以在/etc/firewalld/firewalld.conf设置IndividualCalls=yes,然后重启firewalld。

请注意:在这种情况下,ipset 也会一条一条的插入,如果你有上万个IP,那么这个插入速度也会非常慢。导致你可能会觉得 firewalld 根本启动不起来。那你也可以选择不设置IndividualCalls,或者选择清空ipset以提升启动速度。

重启之后可以看看最新一次启动日志,第一个 python-nftables 相关错误是什么。如果你设置了IndividualCalls=yes,那么此时请按从早到晚的顺序依次排查错误并解决。如果你选择保持IndividualCalls=no,也需要查看第一个错误是什么,把 JSON blob:后面那一段Json 保存下来。

我这里提供一个小工具,能把一批操作拆解成一个个操作,然后执行nftables。

将刚才的 JSON 保存到 /tmp/failed-nft.json ,然后执行

就会把失败的指令和错误单独输出出来,方便调试。

原创文章,转载请注明: 转载自Comzyh的博客

本文链接地址: Firewalld 报告 ‘python-nftables’ failed 的调试思路

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据