另一个应用当前正在持有 xtables 锁

另一个应用当前正在持有 xtables 锁

iptables多年来,我一直使用 bash shell 脚本来设置复杂规则。然而,Debian Stretch当我尝试使用脚本时,它变得很慢,并且使 iptables 处于糟糕的状态。

当我尝试执行此操作时,iptables -L -v它返回了错误......

Another app is currently holding the xtables lock; still -9s 0us time ahead to have a chance to grab the lock...

通过 Google 查找这个错误建议使用“-w”开关。手册页并没有真正说明此开关如何影响问题。

我的脚本为了方便管理使用了循环,这导致它对 iptables 进行大量调用。

# This actually sets the allowed incoming iptables lines
setincoming() {
    for port in ${2}; do
        for ip in ${1}; do
            if  [ `echo "$ip" | grep -P "(^|\s)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]*)*(\s*)$"` ]; then
                iptables -I INPUT  -p tcp  -s $ip --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
            else
                ip6tables -I INPUT  -p tcp  -s $ip --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
            fi
        done
    done
}

#####
# APIs
setincoming "123.123.123.10   123.123.123.11   fe80::xxxx:xxx:xxxx:xxxx" "4200 4300"

有人能帮助我理解如何使用“-w”来解决这个问题吗?

编辑: 为了澄清起见,我当然查看了手册页 - 并尝试使用开关-w和组合,-w -W1但这对问题没有影响(既没有修复它也没有改变症状)。

所以,我仍然不知道如何解决。

答案1

-w选项只会让 iptables 等待 xtables 锁,而不是在最初无法获取锁时退出。该选项可以解决多个进程竞争获取和释放 xtables 锁的竞争条件。如果另一个进程没有释放锁,或者如果太多进程竞争锁,则此选项可能无济于事。

正如 Tomek 所建议的,我会修改您的脚本以利用 ipset。它肯定会更加优化,因为它依赖于哈希表,而不是连续地检查您的 iptables 规则。它也可能解决您的锁定问题。类似于以下内容:

# Create ipset and connect it with iptables
ipset create foo hash:ip,port
iptables -I INPUT -m set --match-set foo src -j ACCEPT

# Add allowances as needed
ipset add foo 123.123.123.10,4200
ipset add foo 123.123.123.11,tcp:4300 # Specify protocol
ipset add foo 123.123.123.12,4400 timeout 600 # Set a timeout for this to disappear
ipset add foo 123.123.123.13,4500 -exist # Do not error if this already exists

由于您的示例中同时包含了 IPv4 和 IPv6,因此我还要提到您可以family在创建 ipset 时使用该参数来特别支持 IPv6。

相关内容