IPTables для ограничения высокого «вызова -в -секунду» и перенаправления на другую программу (на той же машине)

Мое любимое использование hexdumpв этом формате:

hexdump -v -e '"%08_ax  "' -e '16/1 "%02X ""  "" "' -e '16/1 "%_p""\n"'

Это дает результат, аналогичный

% echo hello there everyone | hexdump -v -e '"%08_ax  "' -e '16/1 "%02X ""  "" "' -e '16/1 "%_p""\n"'
00000000  68 65 6C 6C 6F 20 74 68 65 72 65 20 65 76 65 72   hello there ever
00000010  79 6F 6E 65 0A                                    yone.

Было бы легко просто поставить echoперед этим:

echo hello there everyone | (echo '87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef' ; hexdump -v -e '"%08_ax  "' -e '16/1 "%02X ""  "" "' -e '16/1 "%_p""\n"')
87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef
00000000  68 65 6C 6C 6F 20 74 68 65 72 65 20 65 76 65 72   hello there ever
00000010  79 6F 6E 65 0A 

В качестве альтернативы мы могли бы «развернуть» вывод; например, поместите заголовок через каждые 16 строк с помощью простого awkфильтра:

cat x | hexdump -v -e '"%08_ax  "' -e '16/1 "%02X ""  "" "' -e '16/1 "%_p""\n"' | awk '(NR-1)%16 == 0 { print "\n87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef"} ; { print }' | less

87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef
00000000  54 68 69 73 20 69 73 20 6C 69 6E 65 20 31 0A 54   This is line 1.T
00000010  68 69 73 20 69 73 20 6C 69 6E 65 20 32 0A 54 68   his is line 2.Th
00000020  69 73 20 69 73 20 6C 69 6E 65 20 33 0A 54 68 69   is is line 3.Thi
00000030  73 20 69 73 20 6C 69 6E 65 20 34 0A 54 68 69 73   s is line 4.This
00000040  20 69 73 20 6C 69 6E 65 20 35 0A 54 68 69 73 20    is line 5.This 
00000050  69 73 20 6C 69 6E 65 20 36 0A 54 68 69 73 20 69   is line 6.This i
00000060  73 20 6C 69 6E 65 20 37 0A 54 68 69 73 20 69 73   s line 7.This is
00000070  20 6C 69 6E 65 20 38 0A 54 68 69 73 20 69 73 20    line 8.This is 
00000080  6C 69 6E 65 20 39 0A 54 68 69 73 20 69 73 20 6C   line 9.This is l
00000090  69 6E 65 20 31 30 0A 54 68 69 73 20 69 73 20 6C   ine 10.This is l
000000a0  69 6E 65 20 31 31 0A 54 68 69 73 20 69 73 20 6C   ine 11.This is l
000000b0  69 6E 65 20 31 32 0A 54 68 69 73 20 69 73 20 6C   ine 12.This is l
000000c0  69 6E 65 20 31 33 0A 54 68 69 73 20 69 73 20 6C   ine 13.This is l
000000d0  69 6E 65 20 31 34 0A 54 68 69 73 20 69 73 20 6C   ine 14.This is l
000000e0  69 6E 65 20 31 35 0A 54 68 69 73 20 69 73 20 6C   ine 15.This is l
000000f0  69 6E 65 20 31 36 0A 54 68 69 73 20 69 73 20 6C   ine 16.This is l

87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef
00000100  69 6E 65 20 31 37 0A 54 68 69 73 20 69 73 20 6C   ine 17.This is l
00000110  69 6E 65 20 31 38 0A 54 68 69 73 20 69 73 20 6C   ine 18.This is l

Я мог бы добавить туда несколько разделителей, чтобы было легче различать «заголовок» и содержимое.

Это легко превратить в скрипт:

% cat hex 
#!/bin/sh

hexdump -v -e '"%08_ax  "' -e '16/1 "%02X ""  "" "' -e '16/1 "%_p""\n"' | awk '(NR-1)%16 == 0 { print "\n87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef\n========  == == == == == == == == == == == == == == == ==   ================"} ; { print }'

Теперь можно делать

% hex < x

или

% cat x | hex

И подобные команды.

87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef
========  == == == == == == == == == == == == == == == ==   ================
00000000  54 68 69 73 20 69 73 20 6C 69 6E 65 20 31 0A 54   This is line 1.T
00000010  68 69 73 20 69 73 20 6C 69 6E 65 20 32 0A 54 68   his is line 2.Th
00000020  69 73 20 69 73 20 6C 69 6E 65 20 33 0A 54 68 69   is is line 3.Thi
00000030  73 20 69 73 20 6C 69 6E 65 20 34 0A 54 68 69 73   s is line 4.This
00000040  20 69 73 20 6C 69 6E 65 20 35 0A 54 68 69 73 20    is line 5.This 
00000050  69 73 20 6C 69 6E 65 20 36 0A 54 68 69 73 20 69   is line 6.This i
00000060  73 20 6C 69 6E 65 20 37 0A 54 68 69 73 20 69 73   s line 7.This is
00000070  20 6C 69 6E 65 20 38 0A 54 68 69 73 20 69 73 20    line 8.This is 
00000080  6C 69 6E 65 20 39 0A 54 68 69 73 20 69 73 20 6C   line 9.This is l
00000090  69 6E 65 20 31 30 0A 54 68 69 73 20 69 73 20 6C   ine 10.This is l
000000a0  69 6E 65 20 31 31 0A 54 68 69 73 20 69 73 20 6C   ine 11.This is l
000000b0  69 6E 65 20 31 32 0A 54 68 69 73 20 69 73 20 6C   ine 12.This is l
000000c0  69 6E 65 20 31 33 0A 54 68 69 73 20 69 73 20 6C   ine 13.This is l
000000d0  69 6E 65 20 31 34 0A 54 68 69 73 20 69 73 20 6C   ine 14.This is l
000000e0  69 6E 65 20 31 35 0A 54 68 69 73 20 69 73 20 6C   ine 15.This is l
000000f0  69 6E 65 20 31 36 0A 54 68 69 73 20 69 73 20 6C   ine 16.This is l

87654321  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff   0123456789abcdef
========  == == == == == == == == == == == == == == == ==   ================
00000100  69 6E 65 20 31 37 0A 54 68 69 73 20 69 73 20 6C   ine 17.This is l
1
03.05.2021, 23:02
1 ответ

Во-первых, давайте взглянем на схему Поток пакетов в Netfilter и общей сети :

Packet flow in Netfilter and General Networking

На этапе, когда OP пытается использовать:фильтр /INPUT, уже слишком поздно делать то, что задумано, повод для выполнения DNAT должен был быть выполнен до решения о маршрутизации, в nat /ПРЕДВАРИТЕЛЬНАЯ РАССЫЛКА.

Значит, это должно быть раньше, а для некоторых других случаев может потребоваться использование двух разных таблиц::mangle /PREROUTING для какого-то специального теста и nat /PREROUTING для перенаправление портов с отметкой на пакете для передачи намерения из таблицы mangle в таблицу nat . На самом деле такие случаи были бы очень сложными, вероятно, включали бы зоны conntrack в таблице raw и никогда не работали бы с простыми настройками (вот такой пример:IPTables перенаправляют все пакеты UDP, включая ESTABLISHED)


Здесь nat /PREROUTING будет достаточно. Это связано с тем, что только пакеты, начинающие новый поток (состояние НОВОЕ ), проверяются на случай OP, и это именно то, что уже происходит с таблицей nat :только пакеты в состоянии NEW видны (, как показано на схеме ), и все остальные пакеты будут следовать принятому решению NAT. Таким образом, этот блок:--match conntrack --ctstate NEWстановится избыточным в любом nat табличном правиле :, это всегда верно. Соответствие limit не имеет ограничений и может использоваться в любой таблице/цепочке.

В итоге:

  • добавить фильтр для UDP-порта 5060, чтобы он больше ни на что не влиял
  • здесь не требуется совпадение conntrack
  • напомню, что -j ACCEPTв таблице nat просто означает «не использовать NAT для этого случая»
  • DECLINE -INVITE на самом деле не нужен,но я оставлю его так, как он используется OP
  • , так как цель DNAT, используемая с портом, требует протокола, -p udpнеобходимо добавить снова, даже если этому правилу соответствуют только пакеты 5060/UDP.
  • вы не можете легко проверить результат из локальной системы :локальная система использует путь OUTPUT ->... loopback... -> PREROUTING -> INPUT. На этапе PREROUTING первый входящий пакет соответствует потоку, только что созданному в OUTPUT до того, как он был зациклен, поэтому он больше не будет отображаться в состоянии NEW и не будет видеть цепочку nat /PREROUTING и ДНКТ там делаться не будет. DNAT по-прежнему можно выполнить непосредственно в OUTPUT, продублировав (и соответствующим образом адаптировав )эти правила в nat /OUTPUT. Во всяком случае, я уверен, что есть дополнительные предостережения для местного случая. Выполняйте тесты удаленно (или из подключенного контейнера или сетевого пространства имен ).
iptables -t nat -N RATE-LIMIT
iptables -t nat -N DECLINE-INVITE

iptables -t nat -A PREROUTING -p udp --dport 5060 -j RATE-LIMIT
iptables -t nat -A RATE-LIMIT -m limit --limit 20/sec --limit-burst 20 -j ACCEPT
iptables -t nat -A RATE-LIMIT -j DECLINE-INVITE
iptables -t nat -A DECLINE-INVITE -p udp -j DNAT --to-destination :5090
1
28.07.2021, 11:35

Теги

Похожие вопросы