|
ru.unix.bsd- RU.UNIX.BSD ------------------------------------------------------------------ From : Vadim Guchenko 2:5020/400 12 Oct 2004 17:23:49 To : Anton Barabanov Subject : Re: ipfw table -------------------------------------------------------------------------------- Hello, Anton! You wrote to All on Mon, 11 Oct 2004 22:58:40 +0400: AB> Есть список формата ip / mask. Как его подключить к ipfw для AB> создания правил на основании сетей из этого списка? Hедавно я разрабатывал систему скриптов для атомарной загрузки правил в файрвол ipfw2 с использованием списков адресов, которые могут периодически меняться, например, формироваться раз в минуту по данным биллинга. Система при запуске выполняет минимум действий, т.е. если был изменен лишь один файл со списком адресов, она сгенерирует только пару правил для его изменения/добавления в файрвол, а остальные правила останутся нетронутыми. Система написана на sh+perl+c. Работает у меня на всех серверах. Отлаживал я ее аккуратно, ошибок в работе не обнаружил. Если кого-то заинтересует, могу выложить исходники. Вот README к ней: ============================================================ СИСТЕМА ЗАГРУЗКИ ПРАВИЛ В ФАЙРВОЛ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Для загрузки правил в файрвол после изменения файла с правилами или изменения списков адресов как в ручном, так и в автоматическом режиме, следует запускать файл /etc/firewall/load. Для загрузки правил в файрвол после старта операционной системы, либо после выполнения команды файрвола flush следует запускать файл /etc/firewall/load_full. Правила файрвола находятся в файле /etc/firewall/rules, списки адресов в каталоге /etc/firewall/addrs/. Остальные файлы не предназначены для редактирования. Описание работы системы ~~~~~~~~~~~~~~~~~~~~~~~ Имена всех каталогов и файлов указаны относительно базового каталога /etc/firewall/. tmp/ Каталог для временных файлов. addrs/ Каталог со списками адресов. Предназначен для ручного или автоматического редактирования. Каждый список адресов находится в отдельном текстовом файле. Каждая строка файла содержит ровно одно определение. Лидирующие и завершающие пробельные символы игнорируются. Пустые строки игнорируются. Все, что идет начиная с первого символа '#' и до конца строки, считается комментарием и игнорируется. Максимальная длина строки - 256 символов. Определения могут быть следующими: <a.b.c.d> Задает отдельный ip-адрес. Пример: 10.0.0.1 <a.b.c.d/n> Задает блок ip-адресов с маской, записанной в CIDR-нотации. Значение n должно быть в диапазоне от 1 до 32 включительно. Пример: 10.0.0.1/24 any Задает все ip-адреса. include <addr_list> Указывает, что определения из списка адресов с именем <addr_list> нужно добавить к определениям в текущем списке адресов. Пример: include group.internal Списки адресов могут использоваться для разрешения или запрещения доступа определенных пользователей к различным сетевым сервисам, для указания адресов, на которых работают эти сервисы, и т.д. В зависимости от назначения списков адресов рекомендуется использовать следующие имена файлов: ip.<service> Задает один или несколько адресов, на которых работает сетевой сервис <service>. Примеры: ip.ssh, ip.pop3, ip.http_internal. allow.<service> Задает список адресов пользователей, которым разрешен доступ к услуге <service>. Примеры: allow.ssh, allow.internet, allow.http_internal. deny.<service> Задает список адресов пользователей, которым запрещен доступ к услуге <service>. Примеры: deny.ssh, deny.smtp, deny.http_internal. group.<group_name> Задает перечень блоков адресов, объединенных в группу исходя из некоторых критериев. В качестве групп могут быть все внутренние адреса сети, адреса, по которым ведется учет трафика и т.д. Можно создавать иерархию групп, включая более мелкие группы в более крупные с помощью определения include. Примеры: group.internal, group.account, group.trusted. <prefix>.auto Показывает, что список адресов генерируется автоматически. Обычно включается в соответствующий файл allow.<service> с помощью определения include. Примеры: allow.http_internal.auto, allow.internet.auto. process_addr Программа компилирует список адресов. В качестве единственного параметра командной строки передается имя списка адресов. Программа ищет в каталоге addrs/ файл с именем, соответствующим имени списка адресов, считывает его и анализирует. Все адресные определения, считанные из списка адресов, объединяются с помощью ключевого слова "or" и при необходимости заключаются в фигурные скобки так, чтобы в результате получилось выражение, допустимое с точки зрения ipfw для подстановки в качестве src ip или dst ip. В случае успешного выполнения программы (код возврата 0) результат выводится в виде текстовой строки на stdout. Выводимая строка содержит не более 10 адресных определений, объединенных ключевым словом "or". Если требуется вывести больше 10 адресных определений, выводится несколько строк с количеством адресных определений в каждой не более 10. Каждая выводимая строка не зависит от других строк и является допустимой с точки зрения ipfw для подстановки в качестве src ip или dst ip. Считываемые из списка адресов определения обрабатываются следующим образом. Если встречается блок ip-адресов в формате <a.b.c.d/n>, то он выводится без изменений. Повторы и пересечения блоков ip-адресов не проверяются. Максимальное число обрабатываемых блоков ip-адресов - 256. Если встречается отдельный ip-адрес в формате <a.b.c.d>, то он выводится в составе набора ip-адресов вида <a.b.c.0/24{d}>. Все ip-адреса, имеющие одинаковые части <a.b.c>, выводятся в составе одного набора через запятую. Три и более смежных ip-адресов одного набора объединяются через дефис. Если набор содержит всего один ip-адрес, то он выводится в формате <a.b.c.d>. Повторы ip-адресов внутри наборов отбрасываются. Вхождение ip-адресов из наборов в блоки ip-адресов не проверяется. Максимальное число обрабатываемых наборов ip-адресов - 256. В случае комбинирования в исходном списке адресов блоков ip-адресов и отдельных ip-адресов, сначала выводятся все блоки ip-адресов в порядке их обработки, затем все наборы ip-адресов, упорядоченные по возрастанию. Если в исходном списке адресов встречается ключевое слово "any", все остальные адресные определения игнорируются и на stdout выводится единственная строка "any". Если в исходном списке адресов встречается определение "include <addr_list>", то в каталоге addrs/ ищется файл с именем <addr_list> и его определения добавляются к текущему списку адресов. Обработка всех подключаемых списков адресов производится в порядке следования ключевых слов "include" и только после того, как текущий список адресов будет обработан до конца. Вложенность определений "include" не ограничена. Максимальное число подключаемых списков адресов - 128. В случае обнаружения повторного подключения одного и того же списка адресов выдается ошибка. Таким образом достигается гарантия отсутствия циклов. В ходе обработки файлов со списками адресов, анализируется время их последней модификации. При успешном выполнении программы время модификации самого свежего файла выводится в файловый дескриптор с номером 3 в формате time_t (число секунд с 00:00:00 1 января 1970 года). Анализ времени модификации происходит у всех включаемых файлов независимо от того, закончено формирование результата на stdout или нет. В случае обнаружения любой ошибки программа завершает свое выполнение с ненулевым кодом возврата и выводом ошибки на stderr. При этом состояние stdout и файлового дескриптора с номером 3 может быть произвольным. tmp/addrs/ Каталог, в котором находятся скомпилированные программой process_addr списки адресов. Файлы не предназначены для редактирования и представляют собой адресные определения, подготовленные для загрузки в файрвол. При удалении любого из файлов он будет построен заново при очередной загрузке правил в файрвол. rules Файл c правилами файрвола. Предназначен для ручного редактирования. Файл является исполняемой программой и может быть написан на любом языке программирования (обычно sh). Программа должна удовлетворять следующим требованиям: * При успешном выполнении (код возврата 0) на stdout должны быть выведены все правила файрвола, по одному на строке. Правила должны иметь формат, понимаемый ipfw. При этом: - Строка запуска файрвола (путь, имя файла и ключи) не выводится. Любое правило начинается сразу с ключевого слова. Hапример: pipe 1 config bw 500Kbit/s add 10000 allow ip from any to any - Hе разрешается выводить правила, манипулирующие наборами. Это означает, что в правилах не должно встречаться ключевое слово set ни в каком контексте. Все правила должны относиться к нулевому набору (по умолчанию). - Все правила должны быть явно пронумерованы. Это касается случаев, где нумерация вообще применима, например, после ключевого слова add. Hомера правил должны идти строго по возрастанию. Hе допускается вывод двух правил с одинаковыми номерами. - Для ссылки на список адресов используется знак '%', после которого должно идти имя списка адресов, представляющее собой любую ненулевую последовательность непробельных символов. Между знаком '%' и именем списка адресов не должно быть пробелов. Окончанием имени списка адресов служит пробельный символ. Максимальная длина имени - 64 символа. В именах не рекомендуется использовать символы, имеющие специальное значение для операционной системы. В противном случае могут возникнуть ошибки при обращении к списку адресов с таким именем. В любом правиле не может встречаться более двух ссылок на списки адресов. Пример: add 10000 allow tcp from %allow.http to %ip.http 80 add 10100 deny tcp from any to %ip.http 80 * В случае обнаружения любой ошибки программа должна сразу же завершить свое выполнение с ненулевым кодом возврата. При этом состояние stdout может быть произвольным. tmp/rules Промежуточный файл, в котором сохраняются правила файрвола в формате их вывода программой rules. Файл не предназначен для редактирования. Файл может отсутствовать, если последний запуск программы rules закончился ошибкой. В случае удаления файла, он будет создан заново при очередной загрузке правил в файрвол. process_rules Программа компилирует правила файрвола. В качестве единственного параметра может передаваться ключевое слово "full", что указывает на необходимость полной перестройки файрвола. Если программа была запущена без параметров, то подразумевается частичная перестройка файрвола. Программа считывает с stdin правила файрвола в формате их вывода программой rules, модифицирует их нужным образом и выводит окончательные правила на stdout. При выводе каждого правила в его начало добавляется путь, имя файла и ключи для запуска файрвола. Если в теле правила встречаются символы '%', после которых указаны имена списков адресов, то они заменяются скомпилированными адресными определениями, считанными из соответствующих файлов в каталоге tmp/addrs/. Если один из скомпилированных списков адресов содержит несколько адресных определений, то программа выводит столько правил, сколько определений в списке адресов. При этом в каждом правиле используется очередное адресное определение. Если в теле правила имеются ссылки на два списка адресов и каждый из скомпилированных списков адресов содержит несколько адресных определений, то программа выводит количество правил, равное произведению числа определений в первом списке адресов на число определений во втором списке адресов. При этом в каждом правиле определения из каждого списка адресов комбинируются по принципу "каждое с каждым". При обработке любой ссылки на список адресов, соответствующий список адресов компилируется программой process_addr (но не более одного раза в ходе работы программы). При этом содержимое stdout записывается в файл tmp/addr.tmp, а содержимое дескриптора 3 - в файл tmp/addr.time. После этого время последней модификации файла tmp/addr.tmp изменяется на значение из файла tmp/addr.time и файл tmp/addr.time удаляется. Таким образом время последней модификации файла tmp/addr.tmp становится равным времени последней модификации самого свежего файла, который участвовал в компиляции данного списка адресов. Если в результате файл tmp/addr.tmp оказывается новее, чем соответствующий ему файл в каталоге tmp/addrs/, либо соостветствующий файл в каталоге tmp/addrs/ отсутствует, то файл tmp/addr.tmp заменяет собой соответствующий файл в каталоге tmp/addrs/, в противном случае он удаляется. Факт обновления скомпилированного списка адресов запоминается, чтобы использовать его при последующих ссылках на этот же список адресов без необходимости повторной компиляции. Различие между полной и частичной перестройкой файрвола заключается в следующем. При частичной перестройке файрвола выводятся только те правила, в которых есть ссылки на списки адресов, и только в том случае, если хотя бы один из этих списков адресов был обновлен в результате компиляции. При этом перед выводом каждого правила выводится команда файрвола, перемещающая правило с соответствующим номером из набора 1 в набор 2. При полной перестройке файрвола выводятся все правила без исключений. tmp/rules.load Исполняемый файл, в котором сохраняются окончательные правила файрвола в формате их вывода программой process_rules. Файл не предназначен для редактирования. Файл может отсутствовать, если последний запуск программы process_rules закончился ошибкой. В случае удаления файла, он будет создан заново при очередной загрузке правил в файрвол. load_rules Программа непосредственно изменяет правила файрвола. Программа сначала определяет время последнего изменения файла rules. Если файл свежее, чем файл tmp/rules, либо tmp/rules отсутствует, то принимается решение о полной перестройке файрвола. При этом программа rules запускается на выполнение и ее вывод записывается в файл tmp/rules. Если файл rules старее, чем tmp/rules, то принимается решение о частичной перестройке файрвола. Hа втором этапе происходит запуск программы process_rules для компиляции правил файрвола. Программа запускается с параметром "full", если нужно выполнить полную перестройку файрвола, и без параметров в случае частичной перестройки файрвола. Hа stdin программы подаются правила из файла tmp/rules, вывод с stdout программы записывается в файл tmp/rules.load. Hа последнем этапе происходит попытка запуска скрипта tmp/rules.load, в котором содержатся инструкции для непосредственного изменения правил файрвола. Файл запускается только в том случае, если он не пустой. Принцип загрузки правил в файрвол следующий. Работающие в текущий момент правила находятся в активном наборе 1. Все новые правила загружаются в неактивный набор 0. Если загрузка новых правил прошла успешна, то в случае полной перестройки правил наборы 0 и 1 меняются местами. В случае частичной перестройки в ходе добавления новых правил в набор 0 соответствующие им по номерам правила из набора 1 переносятся в активный набор 2. После завершения загрузки новых правил наборы 0 и 2 меняются местами, после чего набор 2 добавляется к набору 1. В начале и в конце загрузки новых правил наборы 0 и 2 пусты. Благодаря таким манипуляциям с наборами переключение на новые правила происходит атомарно. В случае успешного выполнения программа завершает работу с нулевым кодом возврата. В случае обнаружения любой ошибки программа завершает свое выполнение с ненулевым кодом возврата. При этом правила файрвола остаются неизменными, набор 0 очищается. В случае частичного обновления правил файрвола правила из набора 2 переносятся обратно в набор 1. load Программа инициирует процесс загрузки правил в файрвол. Программа в течение 30 секунд пытается получить эксклюзивный доступ к файрволу с помощью файла блокировки tmp/firewall.lock. Если это удается, то управление передается программе load_rules, в противном случае происходит выход с ненулевым кодом возврата и выводом ошибки на stderr. load_full Программа инициирует процесс загрузки правил в файрвол. Программа в течение 30 секунд пытается получить эксклюзивный доступ к файрволу с помощью файла блокировки tmp/firewall.lock. Если это удается, то управление передается программе load_rules, в противном случае происходит выход с ненулевым кодом возврата и выводом ошибки на stderr. Отличается от программы load тем, что перед запуском программы load_rules удаляет файл tmp/rules, что заставляет выполнить полную перестройку файрвола даже если файл rules не изменился. Программа предназначена для загрузки правил в файрвол после старта операционной системы, либо после выполнения команды файрвола flush. tmp/firewall.lock Файл блокировки файрвола, создаваемый программой load. Удаление файла может допустить одновременный запуск нескольких процессов, манипулирующих файрволом, и привести к непредсказуемым результатам. ============================================================ Правила файрвола на одном из серверов выглядят следующим образом: ============================================================ #!/bin/sh -e fwcmd="echo" # Интерфейс, подключенный к клиентскому сегменту iface_clients=fxp0 # Интерфейсы VPN iface_vpns=ng* ############################################################################ ### ## Разделение трафика в зависимости от направления (нумерация с 100) ############################################################################ ### # Трафик через интерфейс lo0 $fwcmd add 100 allow ip from any to any via lo0 # Исходящий трафик $fwcmd add 200 skipto 30000 ip from any to any out ############################################################################ ### ## Входящий трафик (нумерация с 500) ############################################################################ ### # Открываем доступ к DHCP-серверу с незарегистрированных адресов, запрещаем # с них любой другой трафик $fwcmd add 500 allow udp from %group.clients_unreg to %ip.dhcp 67 $fwcmd add 600 allow udp from %group.clients_unreg to 255.255.255.255 67 $fwcmd add 700 deny ip from %group.clients_unreg to any ##-------------------------------------------------------------------------- - --- ## Антиспуфинг (нумерация с 1000) ##-------------------------------------------------------------------------- - --- # Интерфейс клиентов $fwcmd add 1000 skipto 5000 ip from 0.0.0.0 to any recv $iface_clients $fwcmd add 1100 skipto 5000 ip from %group.clients to any recv $iface_clients $fwcmd add 1200 deny log ip from any to any recv $iface_clients # Интерфейсы VPN $fwcmd add 1300 skipto 5000 ip from %group.clients to any recv $iface_vpns $fwcmd add 1400 skipto 5000 ip from any to any verrevpath recv $iface_vpns $fwcmd add 1500 deny log ip from any to any recv $iface_vpns ##-------------------------------------------------------------------------- - --- ## Разделение трафика в зависимости от получателя пакета (нумерация с 5000) ##-------------------------------------------------------------------------- - --- # Трафик, адресованный серверу $fwcmd add 5000 skipto 10000 ip from any to me # Броадкасты $fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255 $fwcmd add 5200 skipto 20000 ip from any to %group.backbone_broadcast $fwcmd add 5300 skipto 20000 ip from any to %group.clients_broadcast # Мультикасты $fwcmd add 5400 skipto 25000 ip from any to 224.0.0.0/4 ##-------------------------------------------------------------------------- - --- ## Трафик, идущий транзитом (нумерация с 6000) ##-------------------------------------------------------------------------- - --- # Запрещаем трафик на закрытые адреса магистрали $fwcmd add 6000 deny log ip from any to %group.backbone_private # Разрешаем остальной трафик $fwcmd add 6100 allow ip from any to any ##-------------------------------------------------------------------------- - --- ## Трафик, адресованный серверу (нумерация с 10000) ##-------------------------------------------------------------------------- - --- # Разрешаем установленные TCP-соединения $fwcmd add 10000 allow tcp from any to any established # Разрешаем фрагменты IP-пакетов $fwcmd add 10100 allow ip from any to any frag # Разрешаем пакеты, удовлетворяющие динамическим правилам $fwcmd add 10200 check-state # Разрешаем OSPF-пакеты $fwcmd add 10300 allow ospf from %group.backbone to any # Разрешаем GRE-пакеты $fwcmd add 10400 allow gre from any to any ##-------------------------------------------------------------------------- - --- ## Службы сервера (нумерация с 12000) ##-------------------------------------------------------------------------- - --- # SSH $fwcmd add 12000 deny tcp from %deny.ssh to %ip.ssh 22 $fwcmd add 12100 allow tcp from %allow.ssh to %ip.ssh 22 # DHCP $fwcmd add 12200 deny udp from %deny.dhcp to %ip.dhcp 67 $fwcmd add 12300 allow udp from %allow.dhcp to %ip.dhcp 67 # PPTP $fwcmd add 12400 deny tcp from %deny.pptp to %ip.pptp 1723 $fwcmd add 12500 allow tcp from %allow.pptp to %ip.pptp 1723 # Netbios $fwcmd add 12600 deny udp from %deny.netbios to %ip.netbios 137,138 $fwcmd add 12700 allow udp from %allow.netbios to %ip.netbios 137,138 $fwcmd add 12800 deny tcp from %deny.netbios to %ip.netbios 139 $fwcmd add 12900 allow tcp from %allow.netbios to %ip.netbios 139 ##-------------------------------------------------------------------------- - --- ## Завершающие правила для трафика, адресованного серверу (нумерация с 18000) ##-------------------------------------------------------------------------- - --- # Разрешаем ICMP-пакеты $fwcmd add 18000 allow icmp from any to any # Разрешаем работу traceroute $fwcmd add 18100 unreach port udp from any to any 33434-33584 # Запрещаем соединения на 80 порт (samba) $fwcmd add 18200 reset tcp from any to any 80 # Запрещаем соединения на 113 порт (ident) $fwcmd add 18300 reset tcp from any to any 113 # Запрещаем соединения на 1080 порт (socks check) $fwcmd add 18400 reset tcp from any to any 1080 # Запрещаем остальной трафик $fwcmd add 18500 deny log ip from any to any ##-------------------------------------------------------------------------- - --- ## Броадкасты (нумерация с 20000) ##-------------------------------------------------------------------------- - --- # Разрешаем SNMP trap'ы от ИБП $fwcmd add 20000 allow udp from %group.backbone to any 162 # Разрешаем поиск DHCP-сервера $fwcmd add 20100 allow udp from %allow.dhcp to any 67 # Разрешаем Netbios $fwcmd add 20200 allow udp from %allow.netbios to %group.clients_broadcast 137,138 # Запрещаем остальной трафик $fwcmd add 20300 deny log ip from any to any ##-------------------------------------------------------------------------- - --- ## Мультикасты (нумерация с 25000) ##-------------------------------------------------------------------------- - --- # Разрешаем OSPF-пакеты $fwcmd add 25000 allow ospf from %group.backbone to { 224.0.0.5 or 224.0.0.6 } # Запрещаем остальной трафик $fwcmd add 25100 deny log ip from any to any ############################################################################ ### ## Исходящий трафик (нумерация с 30000) ############################################################################ ### # Динамическое правило для доступа с данного сервера к внешним службам по UDP $fwcmd add 30000 allow udp from me to any keep-state ============================================================ With best regards, Vadim Guchenko. E-mail: s0lver@kraslan.ru -- Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru --- ifmail v.2.15dev5.3 * Origin: Talk.Mail.Ru (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.unix.bsd/6488290e7eb1.html, оценка из 5, голосов 10
|