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。