iptables 线程安全吗?

Is iptables thread safe?

在我看来这是一个基本问题,但是 google 和 SO 都没有给我答案。正如标题所说,iptables线程安全吗?如果我有多个进程调用 iptables,我应该为自己创建一个锁吗?

似乎有一些 2009 年的线程在查询 netfilter 是否 thread-safe,没有可靠的解决方案。我不愿意去检查实际代码

您正在调用 iptables,一个用户空间 linux 程序,因此线程甚至不会进入其中,它是每个调用的完全独立的进程。这些进程彼此隔离。 iptables 对内核进行的更新底层数据结构的调用将受到保护。

如果您有一个产生所有这些进程的多线程程序,那么您可能 运行 会遇到麻烦,这取决于您自己程序的逻辑。例如,如果您添加一条规则并立即将其删除,会发生什么情况?谁说规则添加会运行在规则删除之前?一种方法是添加规则,然后删除。反过来,规则被删除(因为它尚不存在而失败),然后添加(这有效,但最终结果是表有它们不应该的规则)。为了说明,这里有一个例子:

spawn iptables -A ... (process 1)
spawn iptables -D ... (process 2)
1: starting
2: starting
2: call kernel to delete rule (this is atomic)
1: call kernal to add rule (this is atomic)
2: done
1: done

换句话说,原子性是为了保护内核的内部数据结构。它无助于保护你的程序的逻辑。

iptables-restore

能否也推荐使用iptables-restore。然后,您可以将完整的规则集生成到一个文件中,并在单个原子操作中加载整个规则集。这意味着您永远不会进入您假设当前规则集与实际不同的状态。这也意味着您永远不会在更新规则的中途处于奇怪的中间状态。

为了保护 iptables 进程免受竞争条件的影响,您需要使用 -w 标志从 1.4.20 iptables 版本开始启用。 它首先检查是否有另一个 iptable 进程正在执行它的命令,如果是则退出或等待。

上述方案只解决原子性问题

-w, --wait
  Wait for the xtables lock.

为防止程序的多个实例并发 运行,将尝试在启动时获取独占锁。默认情况下,如果无法获得锁,程序将退出。该选项将使程序等待,直到可以获得独占锁。根据 http://ipset.netfilter.org/iptables.man.html

发布