Thursday, December 30, 2010

After doing some initial research and wasting time on test_beds i finally came to a test setup which is quite easy to do: i set up FreeBSD on my old x41tablet (on bare metal), and do testing between the old and new laptop.

So, at the moment a have some iperf stats: on clear system iperf shows 931mb/s, on the system with netflow2 865mb/s, on fisrt test system is 20% busy in interrupts and another 15% uses iperf. In the second, inerrupts cause about 72-80% and the system is 100% CPU-busy.

So i've got the first numbers, say 850mbit per second is about 106 Megabytes per second and thats about 70Kpps - so this is what PentiumM 1.5 Gz can do without classification.

Later i can swap setups and see what tests will show on my 2,4Gz i3-370m. Now it's not that interesting. I am much more interested is classifying expences.
Next setup will be 30-50 level bpf matching, what performance impact will be on that system.

I was looking for a packet generator, decided to use pktgen from linux kernel.
Using generator is anyway important to learn how to survive on flood, and not to overload the system on DoS or something.

Sunday, December 26, 2010

ng_bpf as classifier

What to do with unclassified traffic ?

It's something should be done with ng_netflow to prevent "unclassified loops", but as for now i just use special index=1 to mark traffic as unclassified when it comes from a "classificator" that way traffic goes to out1 iface.


ng_bpf test

First of all the idea of using ng_bpf will be pretty simple - doing match to first program, if it's not matched, then second, so on so force.
There is no need to use multiple ng_bpfs, one with looping links will be ok.

One thing for future consideration - to be really effective: recalculate time to time patterns and place according to frequency they are matched.
The other thing, which i already mentioned before is possibility of changing programs on fly.

Looks like a pretty simple task to generate and setup ng_bpf node according to file list with tcpdump signatures and some stats on signatures hit frequency.

Then, will need to check how an "old" bpf node can be switched to "new" one (need to check under heavy traffic processing).

Ok, up and running! Test version:


the biggest time waste was getting statistics about bpf, so the proper syntax is
ngctl msg bpf: getstats \"indata\"

where 'indata' is hook name.

So far so good.

Next:
  • - high load testing, for that i'll have to get a copy of real-world traffic and feed an interface with it I think that after 3-4 hours under 100mbps it could be concluded that new scheme is functional.
  • - code clean-up, remove debugging
  • - check generated netflow - to see if correct classes are recorded there.

First classifier run

I did a test bed with bunch of ng_tees, ifaces, dumps and so on.

Packets seem to be broken in tcpdump - on testbed, but that doesn't affect traffic flow, which means ip-eth mismatch (most likely proper set_dlt for ngX required)

It's working!

Next step will be adding ng_bpf to classification engine and creation of some tests (say, classify icmp/ssh to different classes)

I've added some logging to the module. So, classified ping looks like this:

Step further

Realised that it's not that difficult to translate tcpdump patterns to the bpf programs, very good.

The major thing to do will be finding patterns that will cover most of the traffic, to leave as small classified data as possible (my goal is to leave no more, then 5% of traffic unclassified and, eventually, when it starts to be more then 10% start to classify it.)
The question is still open, as another way will be classifying only p2p traffic and leaving other, the weak side of it - it's unknown how actually p2p traffic was unclassified

One more thing to keep in mind - is maintenance of traffic patterns - they should be adjustable "on line". Need to check how ng_bpf handles this.

And still no real ideas on catching p2p by behaviour - either there is lots of reprogramming of ng_netflow required (this is more likely), or making of new
node - which is possible, but will kill bunch of time to get real and efficient solution.

Actually, the biggest problem of using ng_netflow is need to dig deeper in flows processing and create a kind of messaging protocol to tell classifier to mark
required traffic

One more thought and test - try to alter ToS inside packet during processing - need to think about it.
Ng_carp policing is pretty cheap in terms of resources, and it might be more expensive to forward traffic then to drop it.
If it's not - then classifier might just change ToS of packets and send them
directly out, which save some CPU and simplify processing.

Looks like netflow2 is finished



Ripped some code, responsible for sending flows in opposite direction
Added functionality to process indexes as classes, which means that all data ifaces whoose index set to non-zero are used as learning nodes.



Added functionality to send classifed data out of outCLASS iface, if there is no such iface - data is sent via out1 (default iface)

Removed iface index from flow itself (to complete searches)
added class to flow statistics


to do: sent flow class as one of netflow fields (probably TOS or smth - need to look deepere of what a hell is inside of netflow5)

to do: testbed: netflow+ng_bpf

to do: prevent classified data to be send on newflows (actually, when there is a data iface and it's index set to 0, looping is very fucking possible

to do: learn how to use ng_bpf
The hardware:

After struggling with my old-good IBM x41 tablet, waiting a few hours for kernel compile, I decided not to waste my life on slow pc waiting, and instead go buy
something that would be a little bit faster.
It was pretty poor choice here, actually, as i wanted to get something really reliable, I decided that will be the Lenovo X series again.
They are pretty expensive and choice is poor, so i got an i3 370, as it is only 15% slower then the only alternative i5-520, but 25% cheaper. Changing disk drive to OCZ Vertex 2 and adding 4G memory did really good job.
There is nothing to talk about memory - it's just PLENTY of it (6G), but what really makes incredible things - is SSD drive.
Complete boot time to Ubuntu is 14 seconds, 7 of which as BIOS splash and devices testing. That's it, in 7 seconds device with OS is up and running.
The other thing - it's virtualization possibilities. I didn't found it immediately, VTD and some other virtualization features was off in BIOS by default.
Before switching them off virtual machine usually was using 100% of a core, after switching on - ten percent.
One more thing - win7 start-up - about 10 seconds, inside virtual machine
No lags, no waitings, or something.
Just great!

Wednesday, December 22, 2010

I've started the projects of processing and classifying p2p traffic on fly.

The goal is achieve at least 1gps fullduplex traffic processing and classify 95 % of traffic producing no significant delays (<10ms).

Idea

Process traffic based on flows and do recognition of class based on first N packets in a flow, and keep same class for the flow without any further processing.

Another way is to process traffic only using it IP behaviour, addresses, and if possible - ports.

In reality result will be a combination

What this is for ?

General, this is a way to reduce p2p traffic, but it might be used for other applications.

Monday, November 1, 2010


NG_STATE


Модуль ng_state – это полисер с элементами DPI и возможностью классификации траффика и обработки траффика в зависимости от класса.

Примененене – ограничение полосы с учетом типа траффика. Например, при организации доступа в интернет.

Основные функциональные возможности:


  • Управление полосой (Rate Limit) абонентов
  • Возможность назначения общей полосы на группу адресов
  • Классификация траффика и возможность наложения  политик на разные виды траффика
  • Экспорт статистики в Netflow v5
  • Возможность перенаправления WEB траффика для отображения сервисных сообщений
  • Защита от флуда и аттак 
  • Обнаружение P2P траффика по поведению


Типичная схема применение модуля – в разрыве IP или ethernet траффика для управления сервисом абонентов.

Возможно примененеие модуля на существующем сервере.

При существенных объемах траффика– лучше выделить отдельный сервер и установить его в “разрыв”.

Модуль реализует функционал обеспечиваемый устройствами типа Cisco SCE.


Что это такое / немного истории/ для кого это может быть интересно/экономика.

Немного экономики и здравого смысла.

Может быть интерестен при значительных объемах траффика для полисинга (>1Гбит), > 200 пользователей велико,  отсутствии готового решения либо требуются функции, озвученные выше.

95% что это ISP, возможно, крупные шлюзы корпоративного траффика

Для пусконаладки и интеграции требуется время и знания в администрировании FreeBSD и сопряжения сетевых систем.

Я рекомендую устанавливать и эксплуатировать решения от Cisco или подобные, которые в силу своей “железности” и отлаженности дают гаранированный результат при наличии хорошей документации и поддержки.

Тем не меннее, если вы находитесь в ситуации как я – быстрый рост, сжатые сроки невозможность купить/ждать готовое решения, очень большое количество траффика для обрабоки, для вас не представляет затруднений настройка nix, вы хорошо знаете FreeBSD и есть опыт работы с netgraph – то этот модуль может вам быть выгоден.

Возможно, модуль будет интересен в случае, если в текущей инсnаляции уже стоит шлюз на базе FreeBSD.

Время

Портебуется около 40 человеко-часов на запуск и тестирование и еще 40 на доведения его обвязки до продуктива. Целиком пусконаладка займет месяц.

Железо


Стоимость платформы для обработки 4-5G дуплексного траффика составляет примерно 2000$, с 10G картой.
Платформа для обработки 10G в дуплексе обойдется в 3200-3700$.

История


Одна из составляющих работ ISP – нарезка полос абонентам.  Исторически эта функция у нас была совмещена с NAS.

С появлением нового типа доступа, возникла необходимость резать скорости отдельным устройством, а также выполнять ряд сервисных функций – отсылать траффик на проксирование, показывать информационные сообщения, гибко управлять полосой P2P.

Наиболее подходящим устройством для этого казалось устройство Cisco SCE. Мы были готовы потратить в среднем 30к$ за каждый гигабит пропускаемого траффика и даже пожертвовать некоторыми функциями, и даже ждать по нескольку месяцев заказа, держа на складе 20-30% лишней емкости.
Устройство запросили на тест: прождали 2,5 месяца вместо обещанных двух недель. Получили, не понравилось - возможность прямого управления утсройством из собственного биллина отсутсвует, необходимо 3-4 отдельных машины для управления. Присланное на тест устройство не получилось запустить под нагрузкой (как потом выяснилось,  один порт в нем был нерабочим). Время потрачено много, результата нет, бизнес и задачи ждут.

К моменту окончания тестирования мы уже эксплуатировали свое решение на полной емкости услуги  на базе PC платформ, оно удовлетворяло нашим запросам, хоть и имело ряд претензий по функционалу и производительности.

Путь оптимизаций, поиска проблем, доработки функционала привел к разработке отдельного модуля, все недостатки/неоптимальносты были устранены.


Цифры

Количество пользователей - 65к.

Протестировано до 4млн одновременных потоков, что соответсвует примерно 5-7 Гбит.  При среднем пользовательском траффик, тариф на одного пользователя 10-15 мбит.

Теоретически ограничением на количество потоков является ядерная память (3ГБ максимум). При выделении 2,5 гбайт под потоки получится запас в примерно 40-50 млн потоков, что достаточно для обработки примерно 50-70 гбит в дуплексе.

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

Производительность

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

Зависит от конкретных условий:

  • от сетевых адаптеров,
  • процессоров, количества ядер, частоты. 
  • характера траффика
  • количество паттернов в классификации


Если в каждом направлении планируется обрабатывать более 500Мбит, то лучше всего использовать сетевые карты Intel с аппаратной обработкой траффика и несколькими очередями и многопоточные процессоры, меньшие нагрузки сможет переварить любое железо уровня Core2Duo и выше.


Пара примеров

При траффике  100к  пакетов в секунду (примерно 600 мБит траффика)  в каждую сторону  на процессоре Core2Duo 6800  утилизациия примерно  55-60%.

Машина с процессором CoreI7-960 и  Intel 10G адаптерами может обработать примерно 4-5 гигабит траффика в каждую сторону.

В случае, если классификация траффика, экспорт Netflow и перенаправления  не требуется и основной задачей является только полисинг, то можно и нужно отключить Flow-Engine (пока это можно сделать правкой исходных кодов). Ориентировочно прирост производительности составит до 5 раз. В такой конфигурации 1 гигабит дуплексно на Core2Duo6800 пропускается с утилизацией около 15%  каждого из ядер.

В данных примерах речь идет о среднем пользовательском интернет-траффике (40-50% http, 40% bittorrent).

Системные требования

ОС FreeBSD Ядро 8x. 2-4 Гб памяти, 64 битная ОС.

Инсталляция

Скопировать исходные коды. Собрать модуль, загрузить, собрать схему нетграф.

Схема включения

Пример 1. Отдельностоящая машина - с классификацией

Пример 2. Отдельностоящая машина - без классификации

Пример 3. Существующая машина

Пример 4. Организация резерва


Для резерва можно использовать включенный парралельно прямой линк “bypass” c завышенной стоимостью в STP/RSTP. Таким образом, при отсутсвии L2 связности через сервер траффик перейдет на bypass. Подобную схему можно реализовать и в рамках одного коммутатора, но на некоторых нужно отключить механизм обнаружения петель.

Примечание. Весь не-ip траффик проходит без ограничений по интерфейсам up1/down1 в обе стороны. Такой траффик также не попадает в полисер полосы по умолчанию. Таким образом все Link-State L2 протоколы будут прозрачно работать без ограничений (STP, RSTP).


Обратите внимание

Неразборчивый режим


Сетевые карты следует ввести в promisc когда работаем в “разрыве” чтобы отключить аппаратную фильтрацию траффика по мак,

Для всех интерфейсов:
ifconfig em0: promisc

Так как траффик обрабатывается в ядре


При критической загрузки машины она становится неуправляемой, так как не остается процессорного времени на обработку user-space приложений.

Фаервол IPFW


Траффик не доходит IP уровня ядра, а попадает в netgraph, ункционал фаервола для обработки транзитного L2 траффика сильно ограничен. Man ipfw.

MAC autorsrc для ng_ether


По умолчанию мак-адреса будут заменяться на мак-адреса сетевых карт, через которые проходит траффик. Чтобы оставить маки нетронутыми нужно отключить опцию autosrc в соответсвующих ng_ether

ngctl msg em0: setautosrc 0


Классификация

Модуль может получать информацию о классе траффика от внешних систем. Для классификации используется statefull предположение о траффике – то есть классификация производится по первым N пакетам в каждом  потоке.  После  удачной классификации все пакеты в рамках потока классифицирауются тем же классом, без даьнейшей пересылки в классификатор.

Внешним классификатором может быть ng_bpf модуль или их цепочка.  Возможности такой классификации

  • tcpdump выражения
  • длина пакета, заголовки
  • паттерны с анализом содержимого пакета


После прохождления классификаци траффик отправляется в модуль обратно с пометкой класса.

Схема - пример каскадной классификации в ng_bpf



Что делать с классификацией ?

Модуль отправляет классфицированный траффик  в направлении прохождения траффика с номером интерфейса, совпадающим с номером класса.
До удачной  классификации траффик отправляется по интерфейсам с инедксом 1. (up1/down1)

Примеры обработки:

  • послать в разные интерфейсы (например, можно отправить на интерфейс с прокси-сервером траффик на 80 порт)
  • поставить дополнительный полисер на какой либо класс
  • отправить P2P в медленный или дешевый канал



p2p

Определение p2p происходит по характеру траффика. Из определения исключается траффик, успешно прошедший классификацию.  Определение траффика по характеру использует анализ  веерности и интенсивности траффика. Каждые 5 секунд происходит расчет – использует ли клиент p2p. Если да – то следующие 5 секунд весь траффик p2p класса уходит из интерфейсов с индексом 2, если нет – то по умолчанию.

Защита от флуда

Не разрешается создавать более 4000 потоков на любой сервис, кроме сервиса по умолчанию. Таким образом отсекаются любые сканирования и пробы портов.  Направленность сканирования значения не имеет.
Мы протестировали работу P2P и использовать более 4000 соединений в повседневной работе не удавалось. Типичное значение для 4-5 закачек в p2p– 300-500 соединений. При большом количестве закачек и тюнинге клиента P2P удавалось получить до 3000 соединенй.

Информационные сообщения

Позволяют отобразить сообщения, например сервисного или предупредлающего характера.
В WEB – траффике запросы на 80 порт отправляются на другой сервер ( меняется IP   в заголовках ).


Управлене модулем

Для группировки нескольких IP адресов в одну группу,  используется понятие “сервиса”. Сервис хранит единые политики и ограничения, которые применяются на все адреса, относящиеся к этому сервису. Пример – несколько компьютеров у одного абонента. Адреса присвоенные в один сервис делят одну общую полосу выделенную на этот сервис. Одновременно один адрес может входить только в один сервис. При смене сервиса адрес удаляется из предыдущего сервиса.

Основные сообщения, поддерживаемы модулем
Управление сервисом и адресами
ngctl msg ng_state: setservice { userid=”” ip=192.168.0.1 cir_up=200000 cir_down=200000 fwd=1 fwd_ip=192.168.0.5 p2pdetect=2 }

Задать параметры предоставляемого сервиса для абонента “” (должно быть уникально для каждого абонента).  Cir_up,cir_down – ограничение полосы исходящей и входящей к абоненту соотвественно. Ip=192.168.0.5 – Добавить абоненту адрес 192.168.0.5. 

Если нужно с одним абонентом и сервисом ассоциировать много адресов – можно выполнить комманды
ngctl msg state: setservice { userid=”” ip=192.168.0.2 } 
для каждого IP адреса.

Fwd – перенаправить траффик на 80 порт на какой либо IP адрес (это подмена сайтов, используется для отображения каких-либо сообщений. Для проксирования использовать нельзя), отдельным параметром указывается IP сервера, на который будет отправлен траффик.

ngctl msg ng_state: getservice { userid=”” }
ngctl msg ng_state: getservice { ip=192.168.0.1 }

Показывает текущие параметры сервиса для абонента “” или для адреса ip, если нужно идентифицировать или найти имя абонента по адресу.

Статистика
ngctl msg state: servicestat { userid=”” }
ngctl msg state: servicestat { ip=192.168.0.5 }
Покажет статитстику по пакетам и потокам, в том числе по отброшенным пакетам.

Обратная связь – сверка скоростей
ngctl msg state: getspeeds N
Для сверки выставленных в модуле скоростей и скоростей в биллинге есть массовая обработка, возвращающая за один раз несколько скоростей, а именно столько, сколько влезает в 4 кб, начиная с пользователя N.

Описание хуков 
upX, downX. X означает номер класса. Траффик, классифицированный как класс X будет выходить из интерфейса up если он идет вверх (интернет) или down (к пользователю) с номером X. Если такой хук не подключен, то up1/down1.
Существует также возможность установить флаг “обучения классу” на любом up/down. Например, установив командой
ngctl msg ng_state: setifupclass (iface=18 class=14)
Весь траффик, входящий в up18 будет ассоциироваться с 14 классом. После получения пакета определенного класса поток маркируется этим классом и более не предпринимается попыток классифицировать пакеты в рамках одного потока. Пакеты 10 класса будут выходить из интерфейса down14.

Именно так устанавливаются классы для разных match правил bpf-классификатора.
newflows_up, newflows_down – интерфейсы, из которых выходят первые пакеты (до момента удачной классификации, но не более 10). Предполагается что пакеты проходят классификаторы и возвращаются через интерфейсы с установленным классом.
В случае, если класс остается неизвестным, следует установить класс потока в 10 (такой пакет не будет зациклен в классификатор, но следующий пакет в рамках потока опять попадет в классификацию). В случае любого другого класса номер класса будет ассоциирован с потоком и пакеты в таком потоке больше не будут классифицироваться.
Если классификация не смогла пройти удачно после 10 первых пакетов, то такому потоку присваивается класс 2 (возможный p2p траффик).
export – для экспорта netflow, работа хука 100% аналогичкна ng_netflow, предполагается использование ng_socket для отправки экспорта или локальное чтение через бибилиотеки netgrpah как из сокета.

Особенности управления сервисом, умолчания

“Сервис по умолчанию”:
Весь траффик, для которого не назначены сервисы и полосы проходит через “полосу по умолчанию”.
Задать параметры сервиса для такого траффика можно, пользуясь командой setservice без параметра userid для несуществующего в других сервисах адреса, например 127.0.02.

Чтобы узнать текущие параметры сервиса, необходимо выполнить коменду getservice для любого адреса, не входящего в уже присвоенные абонентам, например, для простоты можно использовать тот-же несуществующий адрес 127.0.0.2.

Установив размер полосы предельно малым, можно ограничить хождение траффика до тех адресов, которые не присвоены пользователям.


Netflow
Схема съема нетфлоу полностью аналогична схеме с ng_netflow.

Также в поле src_as приходит номер сервиса для потока. По номеру сервиса можно контроллировать корректность назначенного сервиса в УС.

Предопределенные классы
1 – класс по умолчанию, без ограничений
2 – возможный p2p траффик
10 – классификация невозможна

Скачать
тут