LINUX.ORG.RU
ФорумAdmin

iptables - xtables lock - waiting for it to exit

 


1

2

Есть скрипты в /etc/ppp/ip-up.d/*

В них есть правила для Iptables.

Во всех правилах используется ключ -w. При массовых реконектах всеравно сыпет в лог.

Another app is currently holding the xtables lock; waiting for it to exit...

И некоторые правила не выполняются. Как победить это?


1. Убедиться, что у команд iptables есть ключ ″-n″, DNS сильно тормозить работу.

2. Попатчить iptables на предмет смены алгоритма flock, наподобие https://www.spinics.net/lists/netfilter-devel/msg31867.html

3. Если это что-то серьёзное, то писать замену iptables, которая будет добавлять/удалять правила пачками, а не по одному.

mky ★★★★★
()
Ответ на: комментарий от vel

В /etc/ppp/ip-up.d/ есть скрипт.

#!/bin/bash

exec 1>> /var/log/pppd.log
exec 2>> /var/log/pppd.log

source /usr/net/vars

# Load net function
for func in $(ls /usr/net/net-func.d/*); do source $func; done

rt_tables_add $1

ip_rule_add $1 $4

ip_route_add $1 $4 $5 $5

ipset_add $1

iptables_add $1 $4

tc_add $1

exit 0

Через который вызываются функции с командами iptables и другими. Так же есть скрипты /etc/ppp/ip-down.d/ аналогичные для удаления правил.

В основном замечено что правила иногда не все удаляются с ошибкой xtables lock.

В связи с тем что iptables не следит за одинаковыми правилами приходится сначала выяснять есть ли правило в фаерволе или нет.

#!/bin/bash

iptables_add () {

table=$(cat /run/$1.table)
mark=$(cat /run/$1.fwmark)

  if [ -z "$(iptables -w -t nat -L POSTROUTING_SNAT | grep $2)" ]; then
    local com="iptables -w -t nat -A POSTROUTING_SNAT -o $1 -j SNAT --to-source $2"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L ${table})" ]; then
    local com="iptables -w -t mangle -N ${table}"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L ${table}_mark)" ]; then
    local com="iptables -w -t mangle -N ${table}_mark"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L PREROUTING_MARK | grep ${table}_mark)" ]; then
    local com="iptables -w -t mangle -A PREROUTING_MARK -m set --match-set ${table} src -j ${table}_mark"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L PREROUTING_INCOMING -v | grep $1)" ]; then
    local com="iptables -w -t mangle -A PREROUTING_INCOMING -i $1 -j CONNMARK --set-xmark ${mark}"
    echo "$com"
    eval $com
   fi

  if [ -z "$(iptables -w -t mangle -L ${table} | grep uplink_list_set)" ]; then
    local com="iptables -w -t mangle -I ${table} -m set --match-set uplink_list_set src -j RETURN"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L ${table} | grep "add-set ${table}")" ]; then
    local com="iptables -w -t mangle -A ${table} -j SET --add-set ${table} src"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L ${table}_mark | grep "add-set ${table}")" ]; then
    local com="iptables -w -t mangle -A ${table}_mark -j SET --add-set ${table} src --exist"
    echo "$com"
    eval $com
  fi

  if [ -z "$(iptables -w -t mangle -L ${table}_mark | grep CONNMARK)" ]; then
    local com="iptables -w -t mangle -I ${table}_mark -j CONNMARK --set-xmark ${mark}"
    echo "$com"
    eval $com
  fi

}

fet4
() автор топика
Ответ на: комментарий от mky

″-L″ без ″-n″ - это жесть!

А скрипты - жесть в двойне!

ipset уже несколько лет умеет маркировать пакеты, т.ч. если эту порнографию переписать, то все сведется в добавление в ipset адреса и метки.

vel ★★★★★
()
Ответ на: комментарий от vel

Я до ipset не дочитал, единственное подумал, что проще сразу пытаться создать цепочку, чем сначала вызывать iptables для определения, есть ли такая. Всё одно двух цепочек с одинаковыми именами iptables не создаст.

Скрипты жесть, хорошо, что ТС скрипт для удаления правил не показал :)

mky ★★★★★
()
Ответ на: комментарий от vel

Попробую с "-n"

Если не тяжело покажите как ipset-ом маркировать, в моем варианте.

Я учусь и написал как смог на коленке, логику выполняет, а что мне еще надо? Когда 10-20 линков от разных провайдеров нужно уже как-то это все дело автоматизировать особенно когда они по dhcp/ppp со статикой все проще.

Или подскажите как правильно это писать? Как проверять то же правило есть ли или нет в фаерволе, в Ipset понятно не добавится дубликат, а вот в iptable/iprule может столько надобавляться дубликатов, как выйти из положения, а хочется ж красоты? )))

У меня еще есть много такой писанины :)))

fet4
() автор топика
Ответ на: комментарий от fet4

Создаем набор с опцией skbinfo

ipset create xxx hash:ip  --skbinfo
#добавляем адрес с меткой
ipset -A xxx 10.0.0.1 skbmark 0x10
ipset -A xxx 10.0.0.2 skbmark 0x10
ipset -A xxx 10.0.0.5 skbmark 0x11 skbprio 1:11
#где-то в iptables
iptables -t mangle -A .... -j SET --map-set xxx src --map-mark
#Если src пакета есть в наборе, то пакет будет с меткой из набора.
#Если нужно маркировать conntrack то добавляем
iptables -t mangle -A .... -m mark ! --mark 0 -j CONNMARK --save-mark

кроме метки пакета можно задавать класс для шейпера через

iptables -t mangle -A .... -j SET --map-set xxx src --map-prio

Там много типов наборов, в т.ч. «hash:net,iface»

ipset create ccc hash:net,iface --skbinfo
ipset add ccc 0.0.0.0/0,ppp0 skbmark 0x20
ipset add ccc 0.0.0.0/0,ppp1 skbmark 0x21

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

Хм, самим ipset я знаю что можно добавлять марку.

А вот если добавлять через iptables

-A ... -j SET --add-set ... src

iptables -j SET -h

Говорит

SET target options:
 --add-set name flags [--exist] [--timeout n]
 --del-set name flags
                add/del src/dst IP/port from/to named sets,
                where flags are the comma separated list of
                'src' and 'dst' specifications.

fet4
() автор топика
Ответ на: комментарий от fet4

судя по хелпу - у тебя либо какая-то старая версия iptables (1.6.х оно есть, а в 1.4.х нужно было из бранча компилить), либо модули ядра ipset старые ( ipset --help | grep skb должен быть не пустой)

SET target options:
 --add-set name flags [--exist] [--timeout n]
 --del-set name flags
 --map-set name flags [--map-mark] [--map-prio] [--map-queue]
                add/del src/dst IP/port from/to named sets,
                where flags are the comma separated list of
                'src' and 'dst' specifications.

Про "-j SET --add-set ...".

Ты хочешь добавлять в набор адрес с меткой ? А метку откуда брать ?

vel ★★★★★
()
Ответ на: комментарий от vel

Видимо - iptables v1.4.21

ipset --help | grep skb - не пустой

Ну да можно добавлять сразу с меткой, тогда выкинуться правила типа

-A ... -j CONNMARK --set-xmark ...

У каждого аплинка своя заданная метка на основе номера таблицы маршрутизации в rt_tables.

Скину свой iptables-save -t mangle для понимания что куда, может еще что подскажите оптимизировать.


...

-A PREROUTING -m conntrack --ctstate NEW -j PREROUTING_NEW_CONN
-A PREROUTING -m ndpi  --all  -j PREROUTING_NDPI
-A PREROUTING -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A POSTROUTING -o vlan10 -j POSTROUTING_CLASSIFY
-A POSTROUTING_CLASSIFY -m set --match-set vlan7_257 dst -j vlan7_257_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp3_261 dst -j ppp3_261_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp4_262 dst -j ppp4_262_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp7_264 dst -j ppp7_264_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp2_260 dst -j ppp2_260_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp8_265 dst -j ppp8_265_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp9_266 dst -j ppp9_266_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp6_267 dst -j ppp6_267_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp5_263 dst -j ppp5_263_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp1_259 dst -j ppp1_259_classify
-A POSTROUTING_CLASSIFY -m set --match-set ppp0_258 dst -j ppp0_258_classify
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.27272727294 -j vlan7_257
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.10000000009 -j ppp0_258
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.11111111101 -j ppp1_259
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.12500000000 -j ppp2_260
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.14285714272 -j ppp3_261
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.16666666651 -j ppp4_262
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.20000000019 -j ppp5_263
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.25000000000 -j ppp6_267
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.33333333349 -j ppp7_264
-A PREROUTING_BALANCING -m statistic --mode random --probability 0.50000000000 -j ppp8_265
-A PREROUTING_BALANCING -m statistic --mode random --probability 1.00000000000 -j ppp9_266
-A PREROUTING_INCOMING -i vlan7 -j CONNMARK --set-xmark 0x101/0xffffffff
-A PREROUTING_INCOMING -i ppp3 -j CONNMARK --set-xmark 0x105/0xffffffff
-A PREROUTING_INCOMING -i ppp4 -j CONNMARK --set-xmark 0x106/0xffffffff
-A PREROUTING_INCOMING -i ppp5 -j CONNMARK --set-xmark 0x107/0xffffffff
-A PREROUTING_INCOMING -i ppp7 -j CONNMARK --set-xmark 0x108/0xffffffff
-A PREROUTING_INCOMING -i ppp2 -j CONNMARK --set-xmark 0x104/0xffffffff
-A PREROUTING_INCOMING -i ppp8 -j CONNMARK --set-xmark 0x109/0xffffffff
-A PREROUTING_INCOMING -i ppp9 -j CONNMARK --set-xmark 0x10a/0xffffffff
-A PREROUTING_INCOMING -i ppp6 -j CONNMARK --set-xmark 0x10b/0xffffffff
-A PREROUTING_INCOMING -i ppp1 -j CONNMARK --set-xmark 0x103/0xffffffff
-A PREROUTING_INCOMING -i ppp0 -j CONNMARK --set-xmark 0x102/0xffffffff
-A PREROUTING_MARK -m set --match-set vlan7_257 src -j vlan7_257_mark
-A PREROUTING_MARK -m set --match-set ppp3_261 src -j ppp3_261_mark
-A PREROUTING_MARK -m set --match-set ppp4_262 src -j ppp4_262_mark
-A PREROUTING_MARK -m set --match-set ppp5_263 src -j ppp5_263_mark
-A PREROUTING_MARK -m set --match-set ppp7_264 src -j ppp7_264_mark
-A PREROUTING_MARK -m set --match-set ppp2_260 src -j ppp2_260_mark
-A PREROUTING_MARK -m set --match-set ppp8_265 src -j ppp8_265_mark
-A PREROUTING_MARK -m set --match-set ppp9_266 src -j ppp9_266_mark
-A PREROUTING_MARK -m set --match-set ppp6_267 src -j ppp6_267_mark
-A PREROUTING_MARK -m set --match-set ppp1_259 src -j ppp1_259_mark
-A PREROUTING_MARK -m set --match-set ppp0_258 src -j ppp0_258_mark
-A PREROUTING_NDPI -m ndpi  --bittorrent  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --directconnect  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --fasttrack  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --edonkey  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --gnutella  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --filetopia  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --openft  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI -m ndpi  --soulseek  -j PREROUTING_NDPI_NEW
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x101/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.27272727294 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x102/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.10000000009 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x103/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.11111111101 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x104/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.12500000000 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x105/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.14285714272 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x106/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.16666666651 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x107/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.20000000019 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x10b/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.25000000000 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x108/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.33333333349 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x109/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 0.50000000000 -j RETURN
-A PREROUTING_NDPI_BALANCING -j CONNMARK --set-xmark 0x10a/0xffffffff
-A PREROUTING_NDPI_BALANCING -m statistic --mode random --probability 1.00000000000 -j RETURN
-A PREROUTING_NDPI_NEW -m set --match-set client_net src -m conntrack --ctstate NEW -j PREROUTING_NDPI_BALANCING
-A PREROUTING_NEW_CONN -m set --match-set client_net src -m set ! --match-set uplink_list_set src -j PREROUTING_BALANCING
-A PREROUTING_NEW_CONN -m set --match-set uplink_net_iface src,src -m connmark --mark 0x0 -j PREROUTING_INCOMING
-A PREROUTING_NEW_CONN -m set --match-set uplink_list_set src -m connmark --mark 0x0 -j PREROUTING_MARK

...

-A vlan7_257 -m set --match-set uplink_list_set src -j RETURN
-A vlan7_257 -j SET --add-set vlan7_257 src
-A vlan7_257_classify -j CLASSIFY --set-class 0001:2573
-A vlan7_257_classify -p icmp -j CLASSIFY --set-class 0001:2571
-A vlan7_257_classify -m set --match-set classify_port_prio_2 src -j CLASSIFY --set-class 0001:2572
-A vlan7_257_mark -j CONNMARK --set-xmark 0x101/0xffffffff
-A vlan7_257_mark -j SET --add-set vlan7_257 src --exist
COMMIT
# Completed on Thu Jun 22 14:08:01 2017

fet4
() автор топика
Ответ на: комментарий от fet4

У каждого аплинка своя заданная метка на основе номера таблицы маршрутизации в rt_tables.

Вся маркировка пакетов/соединений и классификация может быть сделана через ipset

Ну я не совсем понимаю надобность некоторых действий

-A PREROUTING_MARK -m set --match-set vlan7_257 src -j vlan7_257_mark
...
-A vlan7_257_mark -j SET --add-set vlan7_257 src --exist
в vlan7_257_mark мы попадаем из-за "-m set --match-set vlan7_257 src"

Зачем еще пытаться добавить в vlan7_257 src ? Или там есть timeout ?

А зачем в этой конструкции что-то изменять в iptables ? тут же все статика!

Есть полезный match «condition» из xtables-addons. При вкл/откл интерфейса достаточно изменять соответствующий «condition», а в iptables добавить эту проверку. Типа

-A PREROUTING_BALANCING -m condition --condition ppp1_on \
  -m statistic --mode random --probability 0.11111111101 -j ppp1_259
при подъеме ppp1 в proc/net/nf_condition/ppp1_on пишем 1, а при выключении пишем туда 0.

или проверять состояние интерфейса при помощи iface из xtables-addons.

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

Вся маркировка пакетов/соединений и классификация может быть сделана через ipset

Буду пробовать, спасибо что натолкнули.

Зачем еще пытаться добавить в vlan7_257 src ? Или там есть timeout ?

Да есть timeout. Нет трафика от пользователя нет его src в списке.

А зачем в этой конструкции что-то изменять в iptables ? тут же все статика!

Хороший вопрос. Надоело мне каждый раз ручками присоединять/удалять новый аплинк и тратить на это время, прописывать для него ручками все нужные правила в системе. А так все четко линк работает правила есть, линк выведен с работы правил нет, ничего лишнего не остается и непутает. Потом нужно еще учесть чтобы это все при перезагрузке поднялось. Тот же interfaces неудобен в поднятии всех линков в системе особенно на бордере, нереально поднять интерфейс с конфига его без передергивания всех линков дабы проверить правильность написания конфига, а то и перегружать систему нужно. Поэтому начал писать такие скрипты для автоматизации всего этого, сделал через функции, т.к. используются все типы подключений static/dhcp/ppp и у каждого свои нюансы при поднятии. Сейчас что мне остается при вводе нового линка это только внести в файл с переменными номер vlan и указать его реквизиты. И иниициализировать его самописным скриптом, который внесет все нужные данные для него в систему и проверит чтобы были остальные линки подняты которые есть в конфиге.

При вкл/откл интерфейса достаточно изменять соответствующий «condition», а в iptables добавить эту проверку

Не всегда вкл/выкл интерфейса означает его работоспособность или наоброт плюс придется каждый ppp привязать к определенному unit номеру чего тоже делать не хочется, т.к. были замечены глюки с этим. Плюс мало деактивировать правило

-A PREROUTING_BALANCING -m condition --condition ppp1_on \
  -m statistic --mode random --probability 0.11111111101 -j ppp1_259
Нужно пересчитать «весы/probability» дабы перераспределить клиентов вышедшего из строя аплинка на оставшиеся каналы. Поэтому есть скрипт который раз в 1 минуту проверяет все линки по пингу в мир и все это считает.

fet4
() автор топика
Ответ на: комментарий от fet4

Нихрена себе 18к правил.

Как бы да, но замедление в применении тоже ничего так.

AS ★★★★★
()
Ответ на: комментарий от AS

на 4.9 тормозит :(

хотят похоронить iptables в пользу nft ?

между 4.1 и 4.4 очень много коммитов. Делать бисект долго :(

vel ★★★★★
()
Ответ на: комментарий от fet4

ну там уже есть релиз nftables-0.7

nft - это косметическая переделка, не вижу смысла переходить на нее в ближайшие 3 года.

средства миграции с iptables на nftables еще только разрабатываются.

vel ★★★★★
()
Ответ на: комментарий от AS

хм. попробовал на ванильных ядрах - 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.4.23,4.4.73,4.9.33

нет проблемы. И от версии iptables (1.4.21 / 1.6.1 ) не зависит.

На 4.4 даже начинает работать чуть быстрее

vel ★★★★★
()
Ответ на: комментарий от vel

А можно ли выполнять один и тот же скрипт для каждого интерфейса из /etc/ppp/ip-up.d/* по очереди. Т.е. если запущен скрипт для другого интерфейса ждать пока он завершиться?

fet4
() автор топика
Ответ на: комментарий от fet4

Вы хотите сказать, что -w у вас работает некоректно? Ибо лог: «Another app is currently holding the xtables lock; waiting for it to exit...» - это же не ошибка, а предупреждение, что будем ждать.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Да. Есть скрипт допустим в Ip-down.d в нем 10 правил iptables c ключем -w.

Есть 10 ppp коннектов, если они все одновременно ложаться то получается 100 правил должно выполниться одновременно или дождаться своей очереди чего не происходит.

Вот и думаю как можно выполнять скрипт последовательно.

fet4
() автор топика
Ответ на: комментарий от fet4

Я тред читал. Сделать глобальный lock не проблема: man flock. (Особо обратить внимание на пример использования). Вопрос в том, что вы катите бочку на вполне тривиальный алгоритм, уже присутствующий в системной утилите. Это серьёзно утверждение, и если оно в самом деле так, то пишите авторам iptables :)

vodz ★★★★★
()
Ответ на: комментарий от vel

В man flock нашел такое

[ «${FLOCKER}» != «$0» ] && exec env FLOCKER=«$0» flock -x -w 60 «$0» «$0» «$@» || :

Можно ли использовать такое в начале скрипта для его блокировки?

fet4
() автор топика
Ответ на: комментарий от fet4

у flock есть разные варианты запуска - с указание файла и файлового десткриптора. Какой вариант использовать - выбирать тебе.

Если есть сомнения в том, что оно работает так как ты думашь, то напиши простенький тест.

vel ★★★★★
()
Ответ на: комментарий от AS

в 4.11.7 резко поднялась производительность вставки/добавления

на 4.9 и ниже 4к правил добавлялось ~90 сек.

на 4.11.7 - 12 секунд!

Но в 4.11 изменили внутренние струтуры и все сторонние модули придется исправлять.

vel ★★★★★
()
Ответ на: комментарий от vel

хм. попробовал на ванильных ядрах - 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.4.23,4.4.73,4.9.33
нет проблемы. И от версии iptables (1.4.21 / 1.6.1 ) не зависит.

Странно. Надо будет поэкспериментировать и конфиги ядер сравнить.

AS ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.