2008-09-20 12 views
36

Мне нужно запросить существующие правила, а также легко добавлять и удалять правила. Я не нашел API для этого. Есть что-то, что мне не хватает?Как я могу программно управлять правилами iptables на лету?

Ближайший я пришел к решению с помощью iptables-save | iptables-xml для запроса и вручную вызова команды iptables для добавления/удаления правил. Другое решение, которое я рассмотрел, - это просто регенерировать весь набор правил из базы данных моего приложения и очистить всю цепочку, а затем снова применить его. Но я хочу избежать этого, так как я не хочу отказываться от каких-либо пакетов - если не существует способа атомизировать это. Мне интересно, есть ли лучший способ.

API в C будет отличным; однако, поскольку я планирую построить это в автономной suid-программе, библиотеки, которые делают это на ЛЮБОЙ язык, тоже прекрасны.

+0

По-видимому, можно перейти от XML к iptables-restore 'xsltproc iptables.xslt my-iptables.xml | Iptables-restore'. См. Справочную страницу 'iptables-xml'. – CMCDragonkai

ответ

3

Умышленно нет API для управления этими правилами. Вы не должны этого делать. Или что-то.

Если вам нужны правила, которые достаточно динамичными вы заботитесь о производительности выполнения/SBIN/IPTables, есть и другие способы сделать это:

  • Используя что-то вроде «недавнего» матча или IP Set соответствия , вы можете добавлять/удалять IP-адреса из черно-белых списков без изменения набора правил.
  • Вы можете передавать пакеты в пользовательское пространство для фильтрации с использованием NFQUEUE
+4

Мне кажется глупым, что для этого нет API. На самом деле, я не очень люблю работу, но вызов iptables выглядит как ужасно хакерский способ делать что-то. – Ycros

+0

Хмм, я мог бы использовать ipsets - и с точки зрения производительности это действительно хорошая идея. К сожалению, мне пришлось бы свернуть свое собственное ядро, и это невозможно, так как некоторые из мест, на которых запускается это программное обеспечение, находятся на виртуальных машинах, где я не могу без проблем работать с ядром. И они по-прежнему не обеспечивают хороший API. – Ycros

+0

ipt_recent - стандартная цель сопоставления iptables, которая позволяет динамически добавлять/удалять IP-адреса из набора, записывая файл в/proc без изменения правил. С другой стороны, он не предназначен для больших наборов IP-адресов и, как представляется, имеет фиксированный максимальный предел. – MarkR

0

правого MarkR, вы же не должны делать это. Самый простой способ - вызвать iptables из сценария или написать конфигурацию iptables и «восстановить» ее.

По-прежнему, если хотите, прочитайте источник iptables. iptables использует совпадения и таблицы как общие объекты. Вы можете использовать источник или их.

В Linux netfilter также есть некоторые файлы include в каталоге/usr/include/netfilter *. Это несколько низкоуровневые функции. Это то, что использует iptables. Это похоже на API, который можно получить без iptables.

Но этот API является «грязным». Имейте в виду, что он предназначен для использования только с помощью iptables. Это не очень хорошо документировано, вы можете столкнуться с очень специфическими проблемами, API может довольно быстро измениться без предупреждения, поэтому обновление будет разорвать ваш код и т. Д.

+2

Я могу согласиться с тем, что использование внутренних API-интерфейсов является плохим, но почему это так плохо, что они намеренно не включали публичный API? Я могу пойти с восстановлением, если смогу восстановить единственную цепочку - мне нужно будет провести некоторое тестирование. – Ycros

+0

Да, вы можете восстановить одну цепочку. :-) –

+0

Там, в ответ. – terminus

4

Насколько я понимаю (хотя ссылка не упоминается это), iptables-restore является атомарным. В конце, когда считывается строка COMMIT, iptables вызывает iptc_commit в libiptc (который во внутреннем интерфейсе вы не должны использовать), который затем вызывает setsockopt(SO_SET_REPLACE) с новыми наборами правил.

Это звучит так же атомно, как вы можете получить: с одним вызовом ядра. Однако более осведомленным сторонам предлагается оспаривать это. :-)

Редактировать: Я могу подтвердить, что ваше описание верное. iptables-restore выполняется как атомная операция в ядре.

Дополнительная информация Операция «только» является атомарной для каждого процессора. Поскольку мы сохраняем весь блок правил для каждого процессора (из-за оптимизации кеша).

16

Из netfilter FAQ:

Ответ, к сожалению, это: Нет

Теперь вы можете подумать 'но как насчет libiptc?'. Как неоднократно указывалось в списке рассылки, libiptc был NEVER, предназначенный для использования в качестве открытого интерфейса. Мы не гарантируем стабильный интерфейс, и его планируется удалить в следующем воплощении фильтрации пакетов linux. libiptc слишком низкоуровневый, чтобы использовать его в любом случае.

Мы хорошо знаем, что для такого API существует фундаментальный недостаток, и мы работаем над улучшением этой ситуации. До тех пор рекомендуется либо использовать system(), либо открыть трубу в stdin iptables-restore. Последний даст вам лучшую производительность.

+0

Интересно, почему в FAQ часто рассматривается проблема атомарности. Должно; Я пошел на поиски реализации iptables-restore, чтобы убедиться, что он атомный. Это важно для OP здесь, и у меня был проект, который тоже этого требовал. –

+1

В этом списке почтовых рассылок netfilter говорится, что iptables-restore является атомарным: http://www.mail-archive.com/[email protected]/msg00456.html –

+0

Для очень храбрых, которые все еще хотят это сделать, есть информация здесь: http://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-4.html#ss4.2 – Roman

12

Использование iptables-save и iptables-restore для запроса и регенерации правил - это самый эффективный способ сделать это. Однажды они были сценариями оболочки, но теперь они являются программами C, которые работают очень эффективно.

Однако я должен указать, что есть инструмент, который вы можете использовать, что упростит обслуживание iptables. Большинство динамических наборов правил действительно такое же правило повторяется много раз, например:

iptables -A INPUT -s 1.1.1.1 -p tcp -m --dport 22 -j ACCEPT 
iptables -A INPUT -s 2.2.2.0/24 -p tcp -m --dport 22 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 22 -j REJECT 

Вместо того, чтобы заменить те правила, каждый раз, когда вы хотите, чтобы изменить то, что порты могут получить доступ к порту 22 (полезно для скажем, порт стучит), вы можете используйте ipsets. Viz:

ipset -N ssh_allowed nethash 
iptables -A ssh_allowed -m set --set ssh_allowed src -p tcp -m --dport 22 -j ACCEPT 
ipset -A ssh_allowed 1.1.1.1 
ipset -A ssh_allowed 2.2.2.0/24 

Наборы могут содержать IP-адреса, сети, порты, адреса mac и иметь тайм-ауты в своих записях. (Когда-либо хотелось добавить что-то всего на час?).

Существует даже атомный способ обмена одним набором с другим, поэтому обновление означает создание нового временного набора, а затем его замену как имя существующего набора.

+0

Да, в верхнем ответе указан ipsets, но, как я уже сказал в комментарии, для него требуется модуль ядра, который по умолчанию не находится в Ubuntu, и это не то, что я могу установить на любую из виртуальных машин, которые я использую. – Ycros

+1

Да, я сообщил об ошибке в январе 2007 года. https://bugs.launchpad.net/ubuntu/+source/ipset/+bug/79182 – Jerub

+2

Ubuntu теперь поддерживает ipset. – Jerub

1

Сегодня утром я проснулся, обнаружив, что получил нападение с отказа в обслуживании (DOS) из России. Они ударили меня из десятков блоков IP. У них должен быть либо большой пул IP-адресов, либо какой-то список/служба прокси. Каждый раз, когда я блокировал IP-адрес, появился еще один. Наконец, я искал сценарий и нашел, что мне нужно написать собственное решение. Ниже приведена небольшая агрессия, но они выполняли мой TOP LOAD LEVEL до более 200.

Вот быстрый сценарий, который я написал, чтобы блокировать DOS в реальном времени.

cat **"output of the logs"** | php ipchains.php **"something unique in the logs"** 

==> PHP скрипт:

<?php 

$ip_arr = array(); 

while(1) 
{ 
    $line = trim(fgets(STDIN)); // reads one line from STDIN 
    $ip = trim(strtok($line, " ")); 

    if(!array_key_exists($ip, $ip_arr)) 
     $ip_arr[$ip] = 0; 

    $regex = sprintf("/%s/", $argv[1]); 

    $cnt = preg_match_all($regex, $line); 

    if($cnt < 1) continue; 

    $ip_arr[$ip] += 1; 

    if($ip_arr[$ip] == 1 ) 
    { 
//  printf("%s\n", $argv[1]); 
//  printf("%d\n", $cnt); 
//  printf("%s\n", $line); 

     printf("-A BLOCK1 -s %s/24 -j DROP\n", $ip); 

     $cmd = sprintf("/sbin/iptables -I BLOCK1 -d %s/24 -j DROP", $ip); 
     system($cmd); 
    } 
} 

?> 

Предположение:

1) BLOCK1 is a Chain already created. 
2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN 
3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file. 
4) You are familiar with PHP 
5) You understand web log line items/fields and output. 
0

Это пример использования Баша и IPTables динамически блокировать хакер злоупотребляющих SSHd на CentOS , В этом случае я настроил sshd для запрета ввода пароля (позволяет ключи). Я смотрю в/var/log/secure для записей «Bye Bye», который является вежливым способом sshd сказать f-off ...

IP=$(awk '/Bye Bye/{print $9}' /var/log/secure | 
    sed 's/://g' |sort -u | head -n 1) 

[[ "$IP" < "123" ]] || { 

    echo "Found $IP - blocking it..." >> /var/log/hacker.log 

    /sbin/iptables -A INPUT -s $IP -j DROP 

    service iptables save 

    sed -i "/$IP/d" /var/log/secure 

} 

Я запускаю это в цикле каждую секунду, минуту или что-то, что делает меня счастливым. Я проверяю значение $ IP, чтобы проверить, что оно найдено полезное значение, поэтому я вызываю iptables, чтобы его удалить, и я использую sed для очистки файла журнала $ IP, поэтому запись не добавляется снова.

Я немного предопределяю (не показан) в белый список некоторых важных IP-адресов, которые всегда действительны и которые могут иметь проблемы с подключением (из-за ошибки пользователя).

Время от времени я сортирую список фильтров iptables и создаю диапазоны IP-адресов из них (используя другой скрипт - и при проверке они обычно относятся к диапазонам IP из Индии, Китая и России). Таким образом, мой общий набор правил фильтрации iptables составляет от 50 до 500 записей; ipset на самом деле не сильно улучшает список, короткий.

+1

Каково значение номера 123? Если вы хотите проверить, что у вас есть действительный IP-адрес, изучив значение первого октета, это может быть что угодно до 223, я считаю. – tripleee

+0

Это не проверка каких-либо октетов. Если при разборе/var/log/secure вы попадаете в пустое или поврежденное поле, вы проверяете значение, чтобы не запускать команду iptables. Значение «123» было совершенно произвольным. При тестировании этого немного больше, я обнаружил, что вы, вероятно, должны заменить '123' на '1', чтобы включить полный диапазон IP. При тестировании IP менее чем «123» это будет верно для IP-адресов в диапазоне от 2.0.0 до 255.255.255.255, поэтому он не будет блокировать IP-адреса в диапазоне 1.x.x.x. При тестировании IP меньше, чем «1», оно соответствует 0.0.0.1 - 255.255.255.255. – Andrew

5

Вы можете использовать rfw, который является REST API для iptables. Он сериализует команды iptables из разных потенциально параллельных источников и удаленно запускает iptables «на лету».

rfw предназначен для распределенных систем, которые пытаются обновить правила брандмауэра на нескольких блоках, но могут также запускаться на одной машине на локальном интерфейсе. Тогда это позволяет избежать использования SSL и аутентификации, поскольку в этом случае он может быть запущен на простом HTTP.

Образец команды:

PUT /drop/input/eth0/11.22.33.44 

что соответствует:

iptables -I INPUT -i eth0 -s 11.22.33.44 -j DROP 

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

GET /list/input 

Отказ от ответственности: Я начал этот проект. Это открытый источник по лицензии MIT.

+0

Если это связано с HTTP, разве это не опасно для брандмауэра? –

+0

Как указано выше, по умолчанию используется протокол HTTPS. Существует возможность отключить SSL и использовать простой HTTP, полезный при работе на локальном хосте в среде с одним пользователем. –

+0

Все, что манипулирует брандмауэром «программно»/удаленно и/или автоматически, опасно. Тем не менее, надлежащая безопасность на месте может смягчить это, то есть sso tokens/2fa за шлюзом api (например, kong) проделали бы долгий путь для удовлетворения потребностей безопасности. –