Расширенная конфигурация IPFWОбычная конфигурация Большинство примеров в интернете показывают "плоскую" конфигурацию файрвола
Плоская, потому что любой трафик проходит ВСЕ! правила файрвола, даже через те правила, которые не предназначались для данного пакета. Например в 1-м примере для пакета 4.4.4.5 -> I.N.E.T который получен с интерфейса rl2 и будет направлен в интернет пройдёт 6 проверок (75% всех правил) из который нужных только 2 (25%). И ответ I.N.E.T -> 2.2.2.2 (I.N.E.T -> 4.4.4.5 после undiverta) пройдёт все правила (100%), из которых нужная только одна (12%). Для сравнения в примере 2 эффективность файрвола ещё меньше. Для пакета 192.168.0.4 -> I.N.E.T делается 13 проверок (68%), из которых 2 полезных (10%). И для ответа I.N.E.T -> 192.168.0.4 19 проверок (100%), из которых нужных тоже 2 (10%). Также обратите внимание что в оригинале пропущен обратный диверт, нет правила ${ipfw} add 511 divert natd ip from any to ${REAL_IP} in via ${ifout} где ${REAL_IP} это ИП адрес на ${ifout} интерфейсе (в данном случае rl0) Без этого правила трафик не сможет вернуться обратно и будет отвергнут 65535-м правилом. Учитывая тот факт, что файрвол имеет тенденцию разрастаться, то со временем количество ненужных проверок будет расти и соответственно производительность падать. А это ненужные задержки... Как бы то нибыло с задержками можно ещё смирится или например поставить более производительное железо. Но с фактом быстрого роста сложноcти файвола Вы не поспорите никак. Очень частая ошибка будет свзяна с тем, что Вы будет забывать указывать in recv/out xmit/via ${iface} и трафик будет дропаться/дивертиться/форвардится не туда куда нужно и Вы будете тратить часы сидя с tcpdump'ом, чтобы найти куда же ушел пакет или почему он не возвращается. Открытый файрвол VS Закрытый файрвол По умолчанию при загрузке системы firewall находится в режиме "никому ничего нельзя", т.е. весь трафик блокируется. Я бы не советовал пересобирать ядро с опцией IPFIREWALL_DEFAULT_TO_ACCEPT. Т.к. в этом случае Ваш файрвол будет похож на большую дыру =) и, фактически, в этом случае Вы ничего не контролируете. Каждый более менее продвинутый пользователь сможет получить халявный трафик! Вы можете попытаться блокировать не нужный трафик, тогда у Вас выйдето что-то вроде:
Поверьте всё не заблокируете. Также давайте будем исходить из того факта, что если у Вас что-то не работает. Т.е. Вы забыли разрешить нужный трафик, то пользователи Вашей сети или сотрудники предприятия обратятся к Вам с этой проблемой и Вы сможете исправить ситуацию. Однако злобный пользователь, который юзает Ваш роутер для своих мерзких целей никогда НИКОГДА не прийдёт к Вам и не скажет, что мол вот у тебя дырочка и ты терпишь убытки. Поэтому предпочтение лучше отдать закрытому файрволу. т.е. по умолчанию блокируем любой трафик
Разделяй и властвуй Идея построения улучшенного файрвола базируется на принципе "Разделяй и властвуй". Нужно разделить трафик по интерфейсам и рулить "потоком" отдельно на каждом интерфейсе.
Таким образом мы получаем что трафик с разных интерфейсов не пересекается и также получаем возможность работать с каждым интерфейсом как бы изолированно. Диапазон 00001-99998 можно использовать по своему усмотрению. Например мы не используем сеть 10.0.0.0/8 и поэтому блокируем её на ВСЕХ интерфейсах. Или например мы хотим заблокировать icmp трафик на всех интерфейсах, поэтому мы пишем
Также этот диапазон можно использовать для счётчиков. ВАЖНО!!! Всегда считайте до того, как Вы заблокируете какой либо вид трафика. Иначе Вы рискуете потерять часть статистики.
В данном случае Вы не посчитатете трафик на 135 порту от клиента, хотя по сути клиент загрузил часть канала. В итоге Вы не дополучаете некоторую сумму, когда клиент расчитывается с Вами за интернет. Распределение диапазона 00001-09999 00001- 00089 зарезервировано. Всегда нужно иметь такой пустой диапазон. Обычно использую для тестирования или когда необходимо на гарячую что-то сделать с трафиком. Например остановить флуд:
00090 - 00099 для глобальных (на всех интерфейсах) блокировок. ЗАМЕТЬТЕ: Трафик заблокированный здесь НЕ БУДЕТ посчитан! 00100 - 00899 использую для подсчёта трафика. 00900 - 00999 Для глобальных блокировок. ЗАМЕТЬТЕ: Трафик заблокированный здесь БУДЕТ посчитан. 01000 - 09998 Испольуйте этот диапазон на своё усмотрение 09999 Служит для деления трафика по интерфейсам. По умолчанию последнее должно быть
10000 - 10999 Правила для интерфейса lo 11000 - 11999 Правила для интерфейса 1 11000 - 11999 Правила для интерфейса 2 ... 64000 - 64999 Правила для интерфейса 2 65000 - 65534 Правила блокировки по умолчания и/или логирования 65535 блокировка по умолчанию ЗАМЕТКИ: а) 5 цифр в номере использую только для визуального оформления, поэтому 00001 0001 001 и 1 это одно и тоже. б) Последнее правило для каждого интерфейса хх999 должно быть
Это нужно для того, чтобы проверить правильность конфигурации правил для интерфейса. Запомните! через это хх999 правило не должен проскользнуть ни один пакет и поэтому если коунтер на этом правиле не равен нулю, что значит что-то Вы упустили. Как узнать, что именно было сделано не верно я раскажу ниже. (см. хх998 правило) Написание правил для интерфейса И так для правил интерфейса у нас имеется диапазон xx000 - xx998. xx999 правило должно быть ipfw add хх999 skipto 65000 ip from any to any Каждое сотое правило зарезервировано ххy00: хх100, хх200, ..., хх900 хх000 - хх099 зарезервировано. Также как и для правил 00001- 00089 используется для "гарячих" целей или тестирования. хх101 - хх199 блокируем весь нежелательный трафик здесь. Например если на интерфейсе висит сеть 192.168.0.0/24, то дропаем всё, что не с этой сети:
хх201 - хх299 этот диапазон идеален для правил подсчета (count) трафика для исхода, тк. здесь трафик ещё не попал в диверт (виден src-ip) xx301 - xx399 здесь можно расположить skipto xx500 правила, если мы не хотим чтобы они попадали в очередь и/или шейпер. Однако этого я бы не рекомендовал делать. (см Как не нужно делать) хх401 - хх499 ложим исходящий трафик в очередь и/или канал. Вы должны сделать это до диверта, тк. после диверта весь исходящий трафик получит Ваш внешний ИП и Вы не сможете распределить канал между локальными пользователями. А до виверта Вы можете сделать это по src-ip. хх501 - хх599 дивертим входящий/исходящий трафик тут. хх601 - хх699 этот диапазон идеален для правил подсчета (count) трафика для входа, тк. здесь трафик ещё уже прошел диверт (виден dst-ip) хх701 - хх799 здесь можно расположить skipto хх900 правила, если мы не хотим чтобы они попали в очередь и/или шейпер. Однако этого я бы не рекомендовал делать. (см. Как не нужно делать) хх801 - хх899 ложим входящий трафик в очередь и/или канал. Вы должны сделать это после диверта, тк. до диверта весь входящий трафик имеет Ваш внешний IP и Вы не сможете распределить канал между локальными пользователями. А после диверта Вы можете сделать это по dst-ip. (см. Недостатки ALTQ) хх901 - хх997 разрешающие правила. Т.к. у нас файрвол закрытый, то это обязательная часть файрвола, где мы должны указать какой трафик разрешен. Если это внешний интерфейс, то разрешаем трафик на Ваш реальный IP I.N.E.T:
Если это внутренний интерфейс 192.168.0.1/255.255.255.0 (ака локальная сеть), то разрешаем сеть:
Здесь я использую один номер для всех правил, для экономии номеров. Кроме экономии я ещё показываю однотипность правил, показываю то, что все эти правила выполняют одинаковую работу, то, что не важно в каком порядке они выполняются. Такие логические блоки можно отделять друг от друга с шагом 5 или 10. В зависимости от количества таких блоков. Обычно 6-8 блоков хватает, поэтому для каждого выделяю номера (шаг10) ххх03, ххх13, ххх23 и тд. Сплошную нумерацию лучше не делать: ххх01, ххх02, ххх03, т.к. если Вам понадобиться срочно добавлять/удалять какое-либо правило между ххх01 и ххх02, Вам прийдется помучатся с передобавлением ххх01 правил. Чего Вы избежите, когда у Вас будут пустые номера между группами. По мере заполнения этого пространства не забывайте каждые месяц/пол года перенумеровывать правила с шагом 5/10. Это избавит Вас от лишней работы в критические ситуации. хх998 здесь должно быть правило: deny log all from any to any via IFACE Этим правилом мы облегчаем себе жизнь в разы. Любой трафик который мы не учли будет попадать в лог /var/log/security. Jun 21 15:58:02 kes kernel: ipfw: 10998 Deny ICMP:5.1 10.0.16.3 172.16.128.61 in via rl0 Jun 21 15:58:02 kes kernel: ipfw: 10998 Deny ICMP:5.1 10.0.16.3 172.16.128.61 in via rl0 И если у Вас правильно настроена ротация лог файлов /etc/newsyslog.conf, стандартный конфиг это: /var/log/security 600 10 100 * JC то можно не боятся что файловая система будет переполнена =) хх999 здесь должно быть правило: skipto 65000 ip from any to any Весь трафик который вы не учли попадёт на 65000 - 65535 правила. НЕ ЛЕНИТЕСЬ НАПИШИТЕ ЭТО ПРАВИЛО. ДАЖЕ ЕСЛИ ВЫ УВЕРЕНЫ, ЧТО хх998 ПРАВИЛО ОБРАБОТАЕТ ВСЕ СЛУЧАИ. ПОТОМУ ЧТО БОГ ЗНАЕТ В КАКОМ СОСТОЯНИИ ПРИЙДЕТСЯ ВАМ ПРАВИТЬ ФАЙРВОЛЛ =) ВНИМАНИЕ!!! Также обязательно в конце правила обязательно указывайте направление и интерфейс. Это съэкономит время на ловке ошибок при конфигурации файрвола. Поверьте, это экономит время! Ну и последнее правило должно быть: 65534 ipfw add deny log all from any to any Собираем всё до кучи. Для удобства, правила для каждого интерфеса ложите в отдельный файл называнный именем этого интерфейса: rl0, rl1, em0, ng*. Здесь ng* это VPN пул. Для того чтобы не писать кучу одинаковых ng0, ng1 ... ngX я назвал этот общий файл "ng*", можно было назвать "ng". Но это на любителя =) Теперь создадим файл файрвола:
И сам скрипт:
Если Вы захотите перезагрузить файрвол с помощью этого скрипта удалённо, то ОБЯЗАТЕЛЬНО добавьте в конец команды знак & чтобы скрипт выполнялся в фоне. Иначе когда удалятся правила Ваша сессия сбросится и выполнение скрипта остановится. Таким образом вы отрежете себе путь к серверу. Теперь по поводу правил для интерфейсов:
Обязательная шапка для всех файлов:
Если присваивать имя интерфейса переменной и не писать имя интерфейса в каждом правиле, то мы экономим время, если меняется имя интерфейса, например с rl2 -> em0, а логически подключение остаётся тоже. Тогда просто заходим и меняем имя в одном месте ;-) Значения переменных $fwcmd и $num устанавливаются в скрипте firewall Итак кусочек файрвола для ng* f_ng
f_rl0
f_tun0
Файл пайпов и очередей f-pipes.ipfw
Неслько слов о порядке обработки пакетов * Пакеты обрабатываются в порядке их поступления и с максимально возможной скоростью. * Пакеты, которые не могут быть отправлены/обработаны в данный момент ложатся в буфер. По умолчанию queue 50, т.е. 50 пакетов максимальной длины 1500 байт. * Если пакет попал в пайп, то он отправляется со скоростью указанной для пайпа * Если необходимо чтобы пакеты от разных источников отправлялись поочерёдно (roundrobin), то нужно чтобы пакеты с нескольких очередей попадали в один пайп(очередь?) и вес этих очередей должен быть одинаков. Иначе очередь с меньшим весом будет обрабатываться только тогда, когда в очереди с большим весом не будет пакетов.
В этом примере пакеты будут выбираться по одному с каждой очереди по порядочку: * пакет с очереди 1 * пакет с очереди 2 * пакет с очереди 3 * пакет с очереди 1 * пакет с очереди 2 * пакет с очереди 3 * и тд. Если в данный момент есть трафик только на одной очереди, то пакеты с этой очереди будут выбиратся со скоростью в 512Кбит. Однако если две очереди загружены по максимуму, то каждая получит 256Кбит. Если же работают все 3 очереди, одна на 128Кбит, а остальные две пытаются загрузить по максимуму, то эти две получат по (512-128)/2 =192Кбита Для того чтобы не создавать кучу очередей, можно использовать маску. По умолчанию она равна 0х00000000 и дополнительные очереди не создаются. Если же задать mask src-ip 0xffffffff, то для каждого нового источника (IP) будет создана новая очередь. Или же mask src-ip 0xffffff00 то для каждой подсети /24 будет создана новая очередь. Например: пакеты у которых источник 192.168.0.5, 192.168.0.17, 192.168.0.33 попадут в одну очередь (общая часть 192.168.0) а пакеты у которых источник 192.168.1.7, 192.168.1.15 попадут в другую (другая общая часть 192.168.7, поэтому другая очередь) даже для пакетов у которых источник 10.0.7.1, 10.0.7.3 также попадут в свою очередь (общая часть 10.0.7) Таким образом 0 задаёт ту часть адреса, которая будет игнорироваться при создании новой очереди. Одним словом маска =) Рассмотрим очень простой пример:
Все пакеты будут обрабатываться в порядке roundrobin и для каждой подсети 255.255.255.0 будет выделен канал 512Кбит
ipfw vs pf Недостаток ALTQ Я бы не использовал ALTQ в качестве шейпера только по одной причине: шейпится только исходящий трафик. Это самый большой минус, который можно придумать! Этот минус сводит на нет все достоинства ALTQ. Почти везде можно увидить: MB> потому что шейпить входящий трафик дурость =) На самом деле дурость - это НЕ ШЕЙПИТЬ входящий трафик!!! Простой пример. хост -- роутер -- шлюз -- инет Если пользователь ХОСТ и РОУТЕР будут качать, то НЕВОЗМОЖНО создать правило, которое будет обрабатывать пакеты предназначенные для ХОСТ и РОУТЕР поочерёдно (roundrobin). Т.е. НЕВОЗОМЖНО разделить канал от ШЛЮЗ к РОУТЕР на равные части между пользователем ХОСТ и РОУТЕР ПОЧЕМУ? Потому что для РОУТЕР исхода не будет (пакет когда попадёт в ядро сразу передастся приложению) и поэтому мы не сможем пропустить этот пакет через ALTQ. Поэтому пользователь РОУТЕР может загрузить канал в ущерб для ХОСТ. Некоторые могут возразить что мол мы не можем контролировать входящий поток. Я отвечу что можем! Наверное Вы просто ребята не читали работу протокола TCP/IP. То что не получится для входящего трафика, так это приоритезировать его по типам. Например www дать меньше приоритета, чем голосовому трафику. Тут уж как пришли к нам пакеты, так уж пришли. То что можно сделать, так это перенаправлять входящий трафик клиентам по очереди, таким образом разделив канал поровну между ними. Также можно ограничить потребление некоторым клиентом не более K% трафика. Что касается тупого флуда на Ваш интерфейс, то тут действительно кроме удара в голову флудеру ничего не поможет. Но это частный случай! Что не нужно делать 1. Берите люди интернет кто хотите:
2.Не ложите в один пайп входящий и исходящий трафик. Возьмите за правило: одно направление трафика - один пайп. К примеру если создать пайп на 115200bit и положить в него вход и исход, то получится канал как на Sirius. Кто работал через этот модем, тот уже представил какая лажа будет :-D 3. Если у Вас есть пайп на направление, то не пропускайте трафик мимо этого пайпа Т.к. некоторые алгоритмы шейпинга будут работать неверно (например RED) если реальная скорость канала (pipe) будет отличаться сконфигурированной. Например у нас на интерфейсе подключение 256Кбит и мы создали канал на 256Кбит и направили весть трафик в этот канал. Трафик отлично подрежится и будет бегать с задданой скоростью. Но в ситуации если вдруг Вы решили пустить трафик от какого-то хоста мимо пайпа, ничего работать не будет. Давайте посмотрим что произойдет, если этот хост загрузит канал на 128Кбит, а весь остальной трафик, который попадает в пайп, будет идти пытаться со скоростью 192Кбит. В итоге получим, что в канале пиковое значение 256Кбит достигнуто не будет и следовательно он не будет шейпится, а на выходе возникнут потери, т.к. наш интерфейс способен обработать только 256Кбит, а не 128+192=320Кбит!!! |
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо зайти на сайт под своим именем.