Я использовал сценарий оболочки bash для установки сложных iptables
правила годами. Однако на 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
но это не повлияло на проблему (не исправило и не изменило симптомы).
ТАК, я все еще не знаю, как решить.
В -w
опция просто заставляет iptables ждать блокировки xtables, а не завершать работу после первоначальной неудачи при ее получении. Эта опция может обойти условия гонки, когда несколько процессов конкурируют за получение и снятие блокировки xtables. Если другой процесс не снимает блокировку или слишком много процессов конкурируют за блокировку, этот вариант может не помочь.
Как рекомендовал Томек, я бы изменил ваш сценарий, чтобы использовать 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.