Осенью 2009 года наша компания запустила новое техническое решение для предоставления доступа в сеть в виде услуги с названием «Прямой интернет». Суть заключается в более эффективной реализации доступа к интернету конечному пользователю.
Сервера сетевого доступа (NASы, или на жаргоне — аггрегаторы) выполняют функции терминирования клиента, шейпинга, сбор статистики по трафику, по необходимости натирования (трансляция сетевых адресов) и форвардинга наружу. Натирование, сбор статистики (netflow) и сам форвардинг работают достаточно эффективно.
Слабым звеном являются туннелирование и шейпинг большого количества клиентов. Решить проблему туннелирования просто — избавиться от неё. При использовании vpn-аггрегатора есть 2 приемущества: мы указываем куда надо подключаться и как надо подключаться, то есть даём адрес впн-сервера и требуем авторизацию в виде логина и пароля, без которых доступа никто не получит. Без впн-аггрегатора появляется необходимость решить эти 2 задачи. Первая задача решается колдовством на центральном маршрутизаторе сети, вторая — привязкой клиентского оборудования по ip,mac и порту. Вобщем эти 2 задачи здесь не описываются, так как выходят за рамки статьи.
Итак, мы имеет с одного конца канал в Интернет, с другого — абонентская сеть, жаждущая попасть в интернет канал. Между двумя этими сущностями суждено быть 2-ум и более независимым взаимозаменяемым роутерам на FreeBSD, которые будут отфильтровывать невалидный трафик, пропускать валидных клиентов через шейпер, давая им скорость, указанную в тарифе, собирать статистику с ip пакетов, транслировать (если надо) адреса из внутрисетевых «серых» в «белые», и пускать во внешний мир.
На стадии тестирования, решения этих задач пробовались несколькими способами. Шейпинг с помощью altq, dummynet, ng_car. Натирование — pf nat, ipfw nat. Сбор статистики — ng_netflow. Избыточность роутеров с помощью carp, синхронизация nat-сессий с помощью pfsync. Всё это тестировалось на стабильность и производительность, в сети было найдено много подобных тестов, которые мы пробовали и сравнивали, эксперементировали с настройками сетевой подсистемы FreeBSD, разные версии 7-ой и 8-ой ветки, разные аппаратные конфигурации. К сожалению, результатов всех тестов не осталось, зато есть конечный работоспособный вариант. А подобные тесты и примеры конфигураций можно найти в сети.
По окончанию тестирования стало ясно, что синхронизация nat-сессий — дело неблагодарное, на практике работает плохо. А нужно оно всего-лишь в тех случаях, если один из роутеров падает замертво, а его функции на себя автоматически берёт другой роутер, на котором есть nat-сессии всех пользователей. Таким образом никто бы не заметил падения роутера. Без синхронизации все существующие коннекты оборвутся, то есть надо просто пересоздать их заново (нажать F5 в браузере, подождать пока торрент-клиент переподключится и прочее в этом же духе).
Также мы приручили carp (реализация протокола VRRP от разработчиков OpenBSD). В итоге функции упавшего роутера берёт на себя любой из других работающих роутеров, приоритеты взятия этих функций можно регулировать вручную.
Шейпинг с помощью ng_car сначала обрадовал — он показывал самые интересные результаты, точную скорость и давал возможность управления каналами налету. Но большое количество клиентов порождало для каждого отдельный свой узел в подсистеме netgraph. Она получалась сильно ветвлённая и общая производительность системы резко падала.
Тестировались сетевые карты от Broadcom и Intel. Наилучший результат показали карты на чипах Intel 82576, которые обладают буфером входящих и исходящих пакетов в 4к и работают отложенными прерываниями (аппаратный polling).
В итоге мы остановились на использовании ipfw+dummynet для шейпинга, ng_netflow для сбора статистики, pf nat для трансляции адресов. Роутерами служат сервера Hewlett-Packard на указанных выше сетевых платах Intel. В каждом таком сервере стоит по одному четырёх-ядерному процессору Intel Xeon и 2-4 гб ОЗУ. В качестве операционной системы используется FreeBSD 8.0 Release p2 amd64.
Тестирование конечного варианта проводилось на канале 800мбит/с. Через роутер проходило до 180 тысяч пакетов в секунду. Не наблюдалось ни единого отброшенного пакета или пакета с ошибкой. После чего сервер был поставлен на реальную нагрузку в 300-400 мбит/с входящего и исходящего трафика по отдельности. Проработав стабильно больше недели, нагруженность каждого сервера «на глаз» оценивалась как 40-60%. После количество серверов увеличилось, то есть каждый стал работать в режиме 20-30% своих возможностей. Ниже приведены данные с одного из работающих сейчас роутеров.
# netstat -w1 -h -d input (Total) output packets errs bytes packets errs bytes colls drops 54K 0 33M 53K 0 33M 0 0 54K 0 32M 53K 0 32M 0 0 54K 0 32M 52K 0 32M 0 0 54K 0 33M 53K 0 32M 0 0 57K 0 35M 56K 0 35M 0 0 54K 0 32M 52K 0 32M 0 0
# top -SPH last pid: 71507; load averages: 0.43, 0.31, 0.26 up 41+06:17:06 23:16:07 101 processes: 6 running, 71 sleeping, 24 waiting CPU 0: 0.0% user, 0.0% nice, 12.8% system, 4.9% interrupt, 82.3% idle CPU 1: 0.0% user, 0.0% nice, 8.3% system, 27.8% interrupt, 63.9% idle CPU 2: 0.0% user, 0.0% nice, 13.2% system, 13.2% interrupt, 73.7% idle CPU 3: 0.0% user, 0.0% nice, 18.8% system, 1.1% interrupt, 80.1% idle Mem: 12M Active, 160M Inact, 528M Wired, 148K Cache, 418M Buf, 3229M Free Swap: 8192M Total, 8192M Free PID USERNAME PRI NICE SIZE RES STATE C TIME WCPU COMMAND 11 root 171 ki31 0K 64K CPU3 3 914.8H 97.07% {idle: cpu3} 11 root 171 ki31 0K 64K RUN 0 830.3H 84.38% {idle: cpu0} 11 root 171 ki31 0K 64K RUN 1 774.6H 78.47% {idle: cpu1} 11 root 171 ki31 0K 64K RUN 2 827.6H 64.26% {idle: cpu2} 13 root 50 - 0K 64K sleep 2 63.6H 4.05% {ng_queue2} 13 root 49 - 0K 64K sleep 2 62.0H 3.66% {ng_queue1} 13 root 50 - 0K 64K sleep 0 63.7H 2.88% {ng_queue0} 12 root -68 - 0K 400K WAIT 0 824:22 1.17% {irq259: igb1} 0 root -68 0 0K 144K - 3 17.9H 0.39% {igb0 taskq}
# netstat -i Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll igb0 1500 d8:d3:85:63:6d:1a 64828120893 15 60565734561 0 0 igb0 1500 172.16.0.0 dir5 3218463 - 914517644 - - igb1 1500 d8:d3:85:63:6d:1b 65338495263 607 67475218921 244 0 igb1 1500 77.232.141.0/ dir5 8597342 - 3267277473 - - lo0 16384 8487 0 8487 0 0 lo0 16384 your-net localhost 8487 - 2132159 - -
# vmstat -i interrupt total rate irq1: atkbd0 4 0 irq14: ata0 1562542 0 irq16: uhci0 22 0 irq18: ehci0 uhci3 2 0 cpu0: timer 7076740658 1982 irq256: igb0 18122121501 5077 irq257: igb0 24209686691 6783 irq258: igb0 2 0 irq259: igb1 21958424484 6152 irq260: igb1 25173771060 7053 irq261: igb1 270 0 cpu2: timer 7076707102 1982 cpu3: timer 7076707117 1982 cpu1: timer 7076715498 1982 Total 117772436953 33000
А теперь посмотрим, что в конфигах.
Собираем своё ядро:
добавляем options IPFIREWALL options IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_FORWARD options DUMMYNET options NETGRAPH options NETGRAPH_BPF options NETGRAPH_IFACE options NETGRAPH_KSOCKET options NETGRAPH_IPFW options NETGRAPH_SOCKET options NETGRAPH_NETFLOW options NETGRAPH_ETHER device pf и удаляем драйвера ненужных устройств
Тюнингуем систему:
# cat /boot/loader.conf hw.igb.rxd=4096 hw.igb.txd=4096 укажем максимальный размер буфера пакетов
# cat /etc/sysctl.conf net.inet.ip.forwarding=1 #включаем форвардинг пакетов net.inet.ip.fastforwarding=1 #эта опция действительно ускоряет форвардинг net.inet.tcp.blackhole=2 #ядро убивает tcp пакеты, приходящие в систему на непрослушиваемые порты net.inet.udp.blackhole=0 #как и выше, только не убивает ибо traceroute пакеты не покажут этот хоп net.inet.icmp.drop_redirect=1 #не обращаем внимания на icmp redirect net.inet.icmp.log_redirect=0 #и не логируем их net.inet.ip.redirect=0 #не реагируем на icmp redirect net.inet.ip.sourceroute=0 #отключение маршрутизации от источника net.inet.ip.accept_sourceroute=0 #старый и бесполезный механизм net.inet.icmp.bmcastecho=0 #защита от SMURF атак net.inet.icmp.maskrepl=0 #не отдавать по icmp паску своей подсети net.link.ether.inet.max_age=30 #переспрашиваем каждые 30 секунд mac адреса в своём arp пространстве net.inet.ip.ttl=226 #почему бы не поставить ttl побольше ;) net.inet.tcp.drop_synfin=1 #небольшая защита net.inet.tcp.syncookies=1 #от доса kern.ipc.somaxconn=32768 #увеличиваем размер очереди для сокетов kern.maxfiles=204800 #увеличиваем число открытых файловых дескрипторов kern.maxfilesperproc=200000 #кол-во ф.д. на каждоый процесс kern.ipc.nmbclusters=524288 #увеличиваем число сетевых буферов kern.ipc.maxsockbuf=2097152 # kern.random.sys.harvest.ethernet=0 #не использовать трафик и прерывания kern.random.sys.harvest.interrupt=0 #как источник энтропии для random'a net.inet.ip.dummynet.io_fast=1 #заставляет dummynet работать побыстрее net.inet.ip.dummynet.max_chain_len=2048 # net.inet.ip.dummynet.hash_size=65535 # net.inet.ip.dummynet.pipe_slot_limit=2048 # net.inet.carp.preempt=1 #включаем carp net.inet.carp.log=2 #пишем логи карпа kern.ipc.shmmax=67108864 #макс. размер сегмента памяти net.inet.ip.intr_queue_maxlen=8192 #размер очереди ip-пакетов net.inet.ip.fw.one_pass=0 #пакеты, прошедшие пайпы не вылетают из фаервола, а дальше идут по нему dev.igb.0.enable_lro=0 #отключение large receive offloading dev.igb.1.enable_lro=0 dev.igb.0.enable_aim=0 #так нет аномалий с работой сетевушек dev.igb.1.enable_aim=0 dev.igb.0.rx_processing_limit=2048 #адаптивный polling, разрешаем прерывания с сетевухи при достижении значения dev.igb.0.flow_control=0 #отключение контроля потока dev.igb.1.rx_processing_limit=2048 dev.igb.1.flow_control=0
Далее идёт скрипт создания графа в netgraph для сбора netflow статистики.
# cat /etc/rc.d/ngnetflow #!/bin/sh . /etc/rc.subr name="ngnetflow" rcvar=`set_rcvar` load_rc_config $name : ${ngnetflow_enable="NO"} : ${ngnetflow_src="0.0.0.0:5525"} : ${ngnetflow_dst="x.x.x.x:5525"} start_cmd="ngnetflow_start" stop_cmd="ngnetflow_stop" ngnetflow_start() { /usr/sbin/ngctl -f- <<-SEQ mkpeer ipfw: netflow 65534 iface0 name ipfw:65534 netflow connect ipfw: netflow: 65533 out0 msg netflow: setdlt { iface=0 dlt=12 } msg netflow: settimeouts { inactive=30 active=600 } mkpeer netflow: ksocket export inet/dgram/udp name netflow:export flow-sensor msg flow-sensor: bind inet/${ngnetflow_src} msg flow-sensor: connect inet/${ngnetflow_dst} SEQ } ngnetflow_stop() { /usr/sbin/ngctl -f- <<-SEQ shutdown netflow: SEQ } run_rc_command "$1"
Для автозапуска этого скрипта помещаем в /etc/rc.conf строку ngnetflow_enable="YES"
Наш граф выглядет вот так:
Если сделать ipfw add netgraph 65534 ip from any to me, то трафик, попадающий под это правило будет заворачиваться в netgraph на хук 65534, попадает в ноду netflow, где происходит сбор статистики с заголовков ip-пакетов, далее трафик возвращается по хуку 65533 обратно в фаервол. К ноде netflow подключен экспорт netflow-статистике ввиде udp дейтаграмм.
Если вместо ipfw add netgraph использовать ipfw add ngtee, то трафик, проходящий это правило, будет дублироваться(!), копия которого направляться на ng_netflow.
Теперь настроим NAT.
# cat /etc/pf.conf set limit states 16000000 set optimization aggressive set limit src-nodes 160000 set limit table-entries 160000 nat-anchor "ftp-proxy/*" nat on igb1 from 10.0.0.0/8 to any -> 77.232.142.0/24 source-hash #натирование пулом адресов
Конфиг фаервола, сделанный с любовью и без лишних замарочек
# cat /etc/ipfw.conf ipfw='/sbin/ipfw -q' if_in='igb0' if_out='igb1' #--- reseting --- ${ipfw} flush ${ipfw} pipe flush ${ipfw} table all flush #---------------- #--- red light--- ${ipfw} add deny ip from any to any 135,137,138,139,445 #fucking ports #----------------- #--- green light --- ${ipfw} add allow ip from any to me #me ${ipfw} add allow ip from me to any #me ${ipfw} add allow ip from 77.232.142.0/24,77.232.143.0/24 to any #адресное пространство натирующих подсетей ${ipfw} add allow ip from any to 77.232.142.0/24,77.232.143.0/24 #в них превращаются уже отфильтрованные пакеты ${ipfw} add allow ip from 77.232.128.0/20 to 10.0.0.0/8,172.25.0.0/16,77.232.128.0/20 #это на не надо, но сделано на всякий случай ${ipfw} add allow ip from 10.0.0.0/8,172.25.0.0/16,77.232.128.0/20 to 77.232.128.0/20 #чтобы вдруг не обсчитать заблудший не туда лок. трафик ${ipfw} add allow ip from any to table\(1\) #таблица 1 содержит адреса и подсети ${ipfw} add allow ip from table\(1\) to any #которые пускаем в инет в обход учёта в биллинге #---- TABLES ----- ${ipfw} table 1 add 77.232.128.0/28 #servers network ${ipfw} table 1 add 77.232.135.0/29 #servers network ${ipfw} table 1 add 77.232.128.64/27 #billing network ${ipfw} table 1 add 77.232.128.192/28 #admins network ${ipfw} table 1 add 62.231.13.168 #cyberplat #-------------------------- #--- valid abons --- ${ipfw} add pipe tablearg ip from any to table\(126\) out xmit ${if_in} #abons shape downstream ${ipfw} add netgraph 65534 ip from any to table\(126\) out xmit ${if_in} #abons netflow downstream ${ipfw} add allow ip from any to table\(126\) #out xmit ${if_in} #allow abons downstream ${ipfw} add pipe tablearg ip from table\(127\) to any in recv ${if_in} #abons shape upstream ${ipfw} add netgraph 65534 ip from table\(127\) to any in recv ${if_in} #abons netflow upstream ${ipfw} add allow ip from table\(127\) to any #in recv ${if_in} #allow abons upstream #------------------- #--- DENY ALL and ip.fw.one_pass=0 --- ${ipfw} add 65534 deny ip from any to any #по умолчанию фаерволл открытый делаем его закрытым, то есть всё что не описано в правилах выше - не пускаем #-------------------------------------
Эффективность работы dummynet достигается такой конструкцией:
${ipfw} add pipe tablearg
Это позволяет не плодить правила в фаерволе, из-за увеличения количества которых резко падает производительность шейпера.
Далее по крону отрабатывает скрипт, который формирует динамические пайпы с указанной пропускной способностью:
ipfw pipe $номер_пайпы config mask dst-ip 0xffffffff bw $скоростьkbits
Добавляет в таблицы №126 и 127 пары (ip-адрес клиента, номер пайпы):
ipfw table 126 add $ip $номер
Этот скрипт писал мой коллега на perl'e. Скрипт обеспечивает добавление новых и удаление старых пайп для тарифных планов. Добавление и удаление текущих клиентов из таблиц 126, 127 с изменением у клиента $номер в случае смены тарифа. IP-адреса и скорости клиентов выгружаются с биллинга и обрабатываются каждые 5-10 минут.
Теперь мы имеет оттюнингованную для роутинга систему, которая способна не просто прокачать через себя около гигабита в секунду, но и успев зашейпить каждого клиента, собрать с него netflow и занатировать. Один такой аггрегат способен успешно работать с 3000-4000 клиентами одновременно, 800/800 мбит/с трафика и пропускать через себя 180 килопакетов в секунду на каждом интерфейса. На впн-сервере (pptp под linux'ом) у нас бывает по 400-600 пользователей, сервер такой же аппаратной конфигурации более 100мбит/с выдаёт с трудом.
J.Bond
Posted 3 years ago.
Спасибо за статью - оч позновательно и полезно. Как раз на подобную задачу "наступил", платформы и задачи сопастовимы, а вот с платами пришлось пока остаться на bge 🙁
Правда при реализации под 8.1. всплыли некоторые моменты... Ну то, что у bge ключи другие и параметры другие - это понятно, а вот то, что в ipfw3 под 8.1 в соответствующей ветке отсутствует net.inet.ip.dummynet.max_chain_len это было сюрпризом.
И еще подскажите в вашей террминалогии if_in, if_out как соотносятся с более принятыми ext_if, int_if, т.е. кто из них смотрит в инет, а кто в сторону клиентов.
bonzo
Posted 3 years ago.
если требуется пропускать через роутер более, чем 150-200мегабит/с в каждом направлении (более 40kpps через каждую плату), лучше прикупить em'ки или igb'шки
тут if_in = int_if; if_out = ext_if
кстати, недавно приходилось чуть поднагрузить один такой сервер. Результат 860мбит/с входящая и 670мбит/с исходящая. На реальном абонентском трафике. Ошибок, дропов и коллизий на интерфейсах не было. Пинг до сервера вырос с 0.1мс до 1.5мс
drmin
Posted 2 years, 10 months ago.
Спасибо. Отличная статья.
Но у меня не получилось поднять бордер-роутер на FreeBSD 8.1 Release#7 и четырех портовой сетевой картой с чипом 82576 (igb).
Скопированы конфиги с рабочего бордера на 7.2 и с сетевыми em (двухпортовые 82571). Нат на ipfw , bgp, сетевые попарно в lagg, трафика проходит около 1.2 Гбпс.
Когда переключаюсь на 8.1 с igb сервер падает в "корку".
Вы не пробовали обновляться на 8.1? У вас не было подобных проблем на 8.0 с сетевыми igb?
J.Bond
Posted 2 years, 10 months ago.
На подходе новый сервер с igb и как раз будем ставить 8.1посмотрю.
Сейчас работает как раз с em - проблем нет, до этого стояло на bge.
connect
Posted 2 years, 10 months ago.
Добрый день bonzo! А биллинг каким образом выгружает даанные для скрипта на perl'e? Сам скрипт можно увидеть?
bonzo
Posted 2 years, 10 months ago.
drmin, всё работает на 8.0-p2 и igb без сбоев и ребутов уже полгода. Где-то через месяц будем добавлять еще несколько таких роутеров, тогда попробую 8.1
с транками на freebsd с продакшне у нас ничего нет, может быть вместо lagg попробовать netgraph (ng_one2many, ng_fec)?
J.Bond, какие задачи Ваш аггрегат выполняет? и как с показателями (pps, interrupts)
connect, По крону раз в 5 минут sql запросом получаем ip-адрес и скорости абонентов. Это записывается plain-text'ом в файл, который потом каждый из роутеров тоже по крону с помощью scp получает себе. Скрипт будет чуть попозже, всё таки небольшое описание для него требуется.
Igorlp
Posted 2 years, 7 months ago.
А почуму камни Intel Xeon, а операционка FreeBSD 8.0 Release p2 amd64?
napTu
Posted 2 years, 6 months ago.
Спасибо, поставил у себя пару костылей из статьи, оптимизировал фаервол и как то неожиданно нагрузка уменьшилась в два раза, а ППС увеличился в полтора раза. Теперь в чнн загрузка не более 50%, а трафик 70тыс ппс. Раньше на 40-50тыс страшно было смотреть.
Для оптимизации использовал утилитку pmcstat, из которой и выяснил что основную нагрузку несет ipfw
mlevel
Posted 2 years, 4 months ago.
А можно детальнее про CARP? Очень хочется увидеть пример...
bonzo
Posted 2 years, 3 months ago.
схему избыточности carp можно по разному сделать. Например:
1. при падении сервера, его задачу берёт на себя следущий по цепочке.
минусы: если нагрузка на каждый роутер более 50%, то взявший на себя нагрузку упавшего станет перегруженным
2. на несколько работающих роутеров ставить один ожидащий. Он возьмёт на себя работу любого упавшего роутера.
минусы: если упало более одного роутера с нагрузкой >50%, бекапный роутер будет в перегрузе. Но вероятность такого случая мала.
На примере 4-ёх роутеров (только для нижних интерфейсов) конфиг для 1-ого примера:
cloned_interfaces="carp0 carp1 carp2 carp3"
ifconfig_carp0="vhid 1 pass xxx1 advskew 0 172.16.255.1 netmask 255.255.0.0"
ifconfig_carp1="vhid 2 pass xxx2 advskew 60 172.16.255.2 netmask 255.255.0.0"
ifconfig_carp2="vhid 3 pass xxx3 advskew 40 172.16.255.3 netmask 255.255.0.0"
ifconfig_carp3="vhid 4 pass xxx4 advskew 20 172.16.255.4 netmask 255.255.0.0"
и так на каждом из 4-ёх только меняем значение advskew, это весы. У кого меньше, тот возмёт на себя работу в случае падения.
роутер1 (0-60-40-20) (мастер 172.16.255.1)
роутер2 (20-0-60-40) (мастер 172.16.255.2)
роутер3 (40-20-0-60) (мастер 172.16.255.3)
роутер4 (60-40-20-0) (мастер 172.16.255.4)
т.е., если упал роутер1, мастером 172.16.255.1 станет роутер 2. И так далее. Если упалт роутер4, его функции берёт роутер1.
Пример 2:
роутер1:
cloned_interfaces="carp0"
ifconfig_carp0="vhid 1 pass xxx1 advskew 0 172.16.255.1 netmask 255.255.0.0"
роутер2:
cloned_interfaces="carp0"
ifconfig_carp0="vhid 2 pass xxx2 advskew 0 172.16.255.2 netmask 255.255.0.0"
роутер3:
cloned_interfaces="carp0"
ifconfig_carp0="vhid 3 pass xxx3 advskew 0 172.16.255.3 netmask 255.255.0.0"
роутер4-бекапный:
cloned_interfaces="carp0 carp1 carp2"
ifconfig_carp0="vhid 1 pass xxx1 advskew 20 172.16.255.1 netmask 255.255.0.0"
ifconfig_carp1="vhid 2 pass xxx2 advskew 20 172.16.255.2 netmask 255.255.0.0"
ifconfig_carp2="vhid 3 pass xxx3 advskew 20 172.16.255.3 netmask 255.255.0.0"
bonzo
Posted 2 years, 3 months ago.
Igorlp
>>А почуму камни Intel Xeon, а операционка FreeBSD 8.0 Release p2 amd64?
http://ru.wikipedia.org/wiki/X86-64
napTu,
насчёт костылей: конструкцию ipfw add netgraph я заменил на ipfw add ngtee. netgraph - фаерволл перенаправляет трафик в нетграф на обсчёт, потом его снова получает. ngtee - фаерволл делает копию пакетов и шлёт в нетграф. Теоретически это более ресурсоёмки. На практике под 8.0-release эффект +2kpps на 70-80kpps. Возможно, что на таких нагрузках роутеру легче продублировать, чем успеть сделать обсчёт трафика.
Пробовал 8.1-release, потом 8.1-stable, 8.2-release. Netgraph ведёт себя странно.
И общая проблема, которая мещает сделать транк на 2 и более гигабита - однопоточная работа подсистемы dummynet. То есть, при нагрузке 92-94kpps в одну сторону, dummynet использует 100% одного ядра цп.
napTu
Posted 2 years, 2 months ago.
bonzo,
у меня фаервол вообще не занимается заворотом трафика в netflow, netflow скрипт просто включен на интерфесе и собирает весь трафик
mkpeer em0: tee lower left
connect em0: em0:lower upper right
mkpeer em0:lower netflow left2right iface0
name em0:lower.left2right netflow
connect em0:lower netflow: right2left iface1
mkpeer netflow: ksocket export inet/dgram/udp
msg netflow:export connect inet/127.0.0.1:4440
msg netflow: settimeouts { inactive=30 active=60 }
FreeBSD 8.1-RELEASE-p2
По dummynet сильно помогла просто оптимизация фаервола, до двух гигабит пока далековато, так что не скажу точно.
Сейчас dummynet не показывает нагрузку, хоть и набирает время использования cpu 132.9H.
Для сравнения, каждый из трех тредов em0_rx0 накопил 63.8H использования.
Есть опыт что при каком то пороговом значении ппс нагрузка dummynet сильно подскакивает и вот именно на этом моменте мне сильно помогла оптимизация фаервола..
что странно, сейчас net.inet.ip.dummynet.io_fast=0
Но это не дает пропуск пакетов для шейперов более 12/24 и т.д мегабит (каждые 12мегабит это каждая 1000 параметра ядра kern.hz )
2ihi
Posted 2 years, 2 months ago.
автору статьи спасибо, но хотелось бы посмотреть на полный вывод top -SCH в часы пиковых нагрузок, имею мнение что тормоза (или вернее затык на ~800мбс) вызваны процессом swi1:net, что собственно начинает расти из
${ipfw} add netgraph 65534 ip from any to table\(126\) out xmit ${if_in} #abons netflow downstream
так же при использовании add netgraph необходим ключик one_pass=1 что при добавлении и удалении шейпирующих правил в фаервол (без таблиц) вызывает панику ядра, да и пакетики начинают по фаерволу искать жестко deny или allow что соответственно так же вызывает увеличение нагрузки как минимум на 30% на пустом месте.
лично для себя, имея ввиду вышеописанное вижу уход от связки нетграфа с фаерволом, а именно снятие статы непосредственно с интерфейсов с применением минимума нод, натить на внешних ифейсах, а стату брать с внутреннего, вот правда проблема если маршрутизатор используется не только в качестве шлюза в инет, но и в различные пиринги - куда траф считать то и не нужно, и каналы там 10G, тогда можно ковырять схему снятия статы с целевого ифейса, где присутствует PF NAT, чем собственно и занимаюсь, проблема заставила меня загуглить и выйти к вам 🙂
вобщем если интересно будет чего получилось у меня, по окончании настройки и тестов поделюсь.
2ihi
Posted 2 years, 2 months ago.
Да, про тормоза dummynet - не поленитесь сделать:
#procstat -at | grep dummynet
0 100083 kernel dummynet 0 16 sleep -.
#cpuset -l 0 -t 100083
решает проблемы 100% cpu use на интелах. После ввода в строй сервер на ксеонах узнал что думми может жрать больше 15% одну корку, до этого сервер был на оптеронах.
2ihi
Posted 2 years, 2 months ago.
И так, друзья, решил я слушать все на локальном ифейсе без лишних заморочек стату брать с ng_iface (что бесспорно будет быстрее чем любые другие способы сбора), по внешним интерфейсам трафик будет софтверно разделяться на основе таблиц маршрутизации (у меня они оч длинные, порядка нескольких тыщ записей на каждом аплинке), если интересно - результат работы вышлю мылом, ну а всем на поругание придумал механизм анализа включения конкретного ИП адреса в сеть принятую с внешнего ифейса:
1. ИП из лога складываем по xor с ИП сети
2.результат по & множим с маской
если результат =0 то ИП принадлежит сетке, если не 0, то ип не из сетки..
кто что скажет, может оптимальней предложит и тд..
кусок на сях, писал прям тут, за работоспособность не отвечаю, но вроде должно работать:
main ()
{
int a=192,b=168,c=17,d=0;
int a1=192,b1=168,c1=17,d1=215;
int m1=255,m2=255,m3=255,m4=0;
a=((a ^ a1) & m1);
b=((b ^ b1) & m2);
c=((c ^ c1) & m3);
d=((d ^ d1) & m4);
int res=((a | b) | (c | d));
printf ("блаблабла если 0 то ип из сетки, если нет то ип НЕ из сети=%d",res);
}
stechkh
Posted 1 year, 6 months ago.
Полагаю 1Gbit/s для igb и 4 intel core @3GHz не предел, даже с маскарадингом.
(http://myfreebsd.ru/freebsd_as_server/uchet-kolichestva-sessij-translyacii-ip-adresov-sessii-nat)
А реально ли получить 10 Gbit/s чистой маршрутизации?
~NiX~
Posted 1 year, 5 months ago.
Да реально и это тоже далеко не предел ...
и не только чистой маршрутизацией у меня
шейпинг + роутинг это до 7 гигабит выше просто не хватает ресурсов роутера... а если брать 10Гигабит чистой маршрутизации то точно так же все будет работать если нормально система заточена ....
adsh
Posted 5 months, 21 days ago.
add deny ip from any to any 135,137,138,139,445
Номера портов могут быть только у UDP/TCP.
ivasian
Posted 5 months, 15 days ago.
А как можно протестировать шейпинг? Для этого требуется имитировать поток данных с разными ip source, чтобы создавалось требуемое количество очередей. Чем это можно сделать?
Источник : bonzo.me/freebsd-router