Распределение полосы пропускания для небольших сетей на основе классов

Максимально производительная сеть в основном работает хорошо. Однако, вы  можете

обнаружить, что у вашей сети существуют другие потребности. Например, для некоторых видов трафика -почты в частности и других необходимых сервисов,  может быть важно достичь базовой пропускной способности в любой момент  времени, в то время как для других сервисов, типа P2P, должны быть  установлены определённые ограничения на потребление пропускной способности.

Для решения такого рода требований или концепций, дисциплина очереди  на  основе классов (CBQ) предлагает намного больше возможностей. Чтобы проиллюстрировать, как используется CBQ, мы перейдём к следующему  примеру, который описрается на набор правил из предыдущих глав. Это  небольшая локальная сеть, и нам необходимо, чтобы пользователи в локальной сети подключали к заранее установленному набору сервисов за пределами своей сети, и кроме того, имели доступ к локальному web-серверу локальной сети.

Определение очереди

Здесь,  все  очереди  устанавливаются  на  внешнем  интерфейсе  выхода  в  Интернет. Главным образом, этот подход имеет смысл, поскольку пропускная  способность будет более ограничена на внешнем интерфейсе, чем на локальной сети. Однако, в принципе, распределение  очередей  и   балансировки   трафика  могут  быть  сделаны  на  любом интерфейсе.

Следующий пример настройки включает очереди CBQ для общей пропускной способности 2Мбит с шестью подочередями.

altq on $ext_if cbq bandwidth 2Mb queue { main, ftp, udp, web, ssh, icmp } queue main bandwidth 18% cbq(default borrow red)

queue ftp bandwidth 10% cbq(borrow red) queue udp bandwidth 30% cbq(borrow red) queue web bandwidth 20% cbq(borrow red)

queue ssh bandwidth 20% cbq(borrow red) { ssh_interactive, ssh_bulk } queue ssh_interactive priority 7 bandwidth 20%

queue ssh_bulk priority 0 bandwidth 80% queue icmp bandwidth 2% cbq

Подочередь main имеет 18% пропускной способности и определяется как  очередь по умолчанию. Это означает, что любой трафик, который  соответствует правилу pass, но явно не назначенный в остальные очереди, попадает сюда. Ключевые слова borrow и red означают,  что  очередь  может   "позаимствовать"  пропускную  способность  от  своей родительской очереди,  в  то время когда система будет пытаться избежать перегрузки, используя  алгоритм RED. Другие очереди, более или менее следуют той же схеме до подочереди ssh, которая сама имеет две подочереди с отдельными приоритетами. Здесь мы наблюдаем вариации на примере приоритетов ACK. Массовые передачи SSH, типичные для передачи файлов SCP, передаются с ToS указывающим пропускную способность, в то время, как интерактивный трафик SSH имеет флаг ToS установленный в указание низкой задержки (low delay), и пропускается прежде массовых передач. Интерактивный трафик, по  всей  вероятности,  будет  иметь  меньшие  затраты  полосы  пропускания  и  получит меньшую долю пропускной способности, но, одновременно с этим и большие  льготы, поскольку  он  имеет  более  высокий  приоритет.  Кроме  того  данная  схема  позволяет повысить скорость передачи файлов SCP, поскольку пакеты ACK для передачи SCP будут поставлены в подочередь с более высоким приоритетом.

Наконец, мы используем icmp очередь, которая резервирует 2% полосы пропускания от верхнего  уровня.  Это  гарантирует  минимальную  пропускную  способность  для  ICMP трафика,  который  соответствует  правилу  pass,  но  не  соответствует  критериям  для назначения в другие очереди.

Набор правил

Для того, чтобы достич желаемого результата, мы используем правила pass,  которые указывают какой трафик назначается в очереди и их критерии:

set skip on { lo, $int_if }

pass log quick on $ext_if proto tcp to port ssh queue (ssh_bulk, ssh_interactive) pass in quick on $ext_if proto tcp to port ftp queue ftp

pass in quick on $ext_if proto tcp to port www queue http pass out on $ext_if proto udp queue udp

pass out on $ext_if proto icmp queue icmp

pass out on $ext_if proto tcp from $localnet to port $client_out

Правила для ssh, ftp, www, udp и icmp назначают трафик на соответствующие очереди. Последнее правило пропускает весь прочий трафик из локальной сети направляя его в очередь main используемую по умолчанию.

Формирование трафика на основе HFSC

Простые планировщики, которые мы рассматривали до сих пор, могут быть достаточно эффективными в некоторых установках, однако сетевые  администраторы   с высокими

требования к формированию трафика склонны искать большей гибкости чем та, которую

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

Алгоритм очередей HFSC (hfsc в терминологии pf.conf) предлагает все эти возможности, но за дополнительную гибкость придётся заплатить: установка будет чуть более сложной, в  отличии  от  прочих  типов,  а  настройки  вашей  установки  (в  дальнейшем  я  буду использовать слово "развёртывание" –  п.п.)  для достижения оптимального результата могут превратится в занимательный процесс.

Определение очереди

Работая  с  той  же  конфигурацией,  которую  мы  использовали  раньше,   вставим определение этой очереди в начало файла pf.conf:

altq on $ext_if bandwidth $ext_bw hfsc queue { main, spamd }

queue main bandwidth 99% priority 7 qlimit 100 hfsc (realtime 20%, linkshare 99%) \

{ q_pri, q_def, q_web, q_dns }

queue q_pri bandwidth 3% priority 7 hfsc (realtime 0, linkshare 3% red )

queue q_def bandwidth 47% priority 1 hfsc (default realtime 30% linkshare 47% red) queue q_web bandwidth 47% priority 1 hfsc (realtime 30% linkshare 47% red)

queue q_dns bandwidth 3% priority 7 qlimit 100 hfsc (realtime (30Kb 3000 12Kb), \ linkshare 3%)

queue spamd bandwidth 0% priority 0 qlimit 300 hfsc (realtime 0, upperlimit 1%, \ linkshare 1%)

Как  вы  можете  видеть,  определение  очереди  HFSC  принимает   несколько   другие параметры, в отличии от простых дисциплин. Мы начнём с этой, сравнительно небольшой иерархии,  путём  разделения очереди  верхнего  уровня  на  две  части.  На  следующем уровне разобъём основную очередь на несколько подочередей, каждая из которых имеет определённый  приоритет.   Все   подочереди  имеют  заданное  значение  realtime;  это минимальная  гарантированная полоса пропускания выделенная очереди. Опциональная установка upperlimit определяет набор жёстких верхних пределов распределения полосы пропускания очереди. Параметр linkshare  устанавливает  распределение для очереди, которое будет доступно при её перегрузке; то есть, это начало её распределения в qlimit.

В случае возникновения заторов, каждая очередь по умолчанию имеет пул из 50 слотов, лимит  очереди  (qlimit),  для  сохранения  пакетов  в  период  когда  они  не  могут  быть немедленно переданы. В нашем примере очереди верхнего уровня main и spamd имеют большие, чем заданные по умолчанию, пулы установленные их qlimit; 100 для main и 300 для  spamd.  Значительное  повышение  размеров  очередей  означает,  что  мы  немного понизим потерю пакетов при достижение трафиком установленных лимитов, но это так же означает, что когда формирование трафика отваливается, увеличивается время ожидания соединения, что в конечном счёте связано с большими размерами пулов.

Иерархия очереди использует два знакомых приёма для эффективного  использования доступной полосы пропускания:

•     Используются вариации высокого и  низкого приоритетов показанные  в  ранних примерах с читым приоритетом

•     Мы повысили скорость практически всего остального трафика (и, безусловно, web- трафика,  имеющего  в  нашем  случае  основной   приоритет)  путём  выделения небольшой, но гарантированной чести  полосы пропускания для сервиса обзора имён. Для очереди q_dns мы  установили значение realtime c лимитом времени – после 3000  миллисекунд значение realtime снижается до 12Кб. Это может быть полезно для повышения скорости соединений которые передают  большую часть полезной нагрузки в начальной фазе.

Набор правил

Следующий шаг заключается в увязывании вновь созданной очереди в набор  правил. Если предположить, что у вас уже существует фильтрующий режим,  привязка будет на удивление простой и включает только добавление нескольких простых правил match:

match out on $ext_if from $air_if:network nat-to ($ext_if) queue (q_def, q_pri) match out on $ext_if from $int_if:network nat-to ($ext_if) queue (q_def, q_pri) match out on $ext_if proto tcp to port { www https } queue (q_web, q_pri) match out on $ext_if proto { tcp udp } to port domain queue (q_dns, q_pri) match out on $ext_if proto icmp queue (q_dns, q_pri)

Здесь, правила match ещё раз используют трюк с ускорением пакетов ACK  за счёт назначения очередей с высоким и низким приоритетом, аналогично  ранним примерам использующим  чистые  приоритеты.  Единственное  исключение  –  когда  мы  назначаем трафик на очередь с самым низким приоритетом, мы реально не заботимся о каком бы то ни было ускорении:

pass in log on egress proto tcp to port smtp rdr-to 127.0.0.1 port spamd queue spamd

Это  намеренное  замедление  спамеров  на  их  пути  к  spamd.  При   использовании иерархической системы очередей, systat так же показывает очереди и их трафик в виде иерархии:

2 users Load 0.22 0.25 0.25 Fri Apr 1 16:43:37 2011

QUEUE                  BW         SCH PRIO PKTS   BYTES     DROP_P DROP_B QLEN BORROW  SUSPEN P/S  B/S root_nfe0             20M       hfsc  0        0         0                0      0      0                                                    0     0

main

19M

hfsc 7

0

0

0

0

0

0

0

q_pri

594K

hfsc 7

1360

82284

0

0

0

11

770

q_def

9306K

hfsc

158

15816

0

0

0

0.2

11

q_web

9306K

hfsc

914

709845

0

0

0

50

61010

q_dns

594K

hfsc 7

196

17494

0

0

0

3

277

spamd

0

hfsc 0

431

24159

0

0

0

2

174

Корневая очередь (root) указывает присоединение к физическому интерфейсу – nfe0 и root_nfe0  в  данном  случае.  main  и  её  подочереди  q_pri,  q_def,  q_web  и  q_dns отображаются с их назначенной пропускной способностью,  количеством байт и числом прошедших   пакетов.   Колонки   DROP_P   и   DROP_B   показывают,   соответственно, количество сброшенных пакетов и байт, если мы будем вынуждены сбрасывать пакеты на данном этапе. Последние две колонки показывают живое обновление пакетов в секунду и байт в секунду, соответственно.


Очереди для серверов в зоне DMZ

Возвращаясь к главе 5, вспомним, что, мы установили сеть с одним  шлюзом, а все сервисы, видимые из вне сконфигурировали на отдельной сети DMZ. Таким образом, весь трафик на сервера, как из Интернет так и из внутренней сети должен проходить через шлюз. Схема сети показана на рисунке 7-1, и идентична рисунку 5-2.

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

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

В  нашем  примере,  что  вполне  вероятно,  пропускная  способность  интерфейса  DMZ составляет 100Мбит или 1Гбит, в то время как фактическая пропускная способность для соединений   со   стороны   локальной   сети   значительно   меньше.   Это   соображение отображено в наших определениях  очереди, где можно ясно видеть, что фактическая пропускная   способность    доступная   для   внешнего   трафика   является   основным ограничением в установке очереди.

Рисунок 7-1: Сеть с DMZ

total_ext = 2Mb total_dmz = 100Mb

altq on $ext_if cbq bandwidth $total_ext queue { ext_main, ext_web, ext_udp, \ ext_mail, ext_ssh }

queue ext_main bandwidth 25% cbq(default borrow red) { ext_hi, ext_lo } queue ext_hi priority 7 bandwidth 20%

queue ext_lo priority 0 bandwidth 80%

queue ext_web bandwidth 25% cbq(borrow red) queue ext_udp bandwidth 20% cbq(borrow red) queue ext_mail bandwidth 30% cbq(borrow red)

altq on $dmz_if cbq bandwidth $total_dmz queue { ext_dmz, dmz_main, dmz_web, \ dmz_udp, dmz_mail }

queue ext_dmz bandwidth $total_ext cbq(borrow red) queue { ext_dmz_web, \ ext_dmz_udp, ext_dmz_mail }

queue ext_dmz_web bandwidth 40% priority 5 queue ext_dmz_udp bandwidth 10% priority 7 queue ext_dmz_mail bandwidth 50% priority 3

queue dmz_main bandwidth 25Mb cbq(default borrow red) queue { dmz_main_hi, \ dmz_main_lo }

queue dmz_main_hi priority 7 bandwidth 20% queue dmz_main_lo priority 0 bandwidth 80% queue dmz_web bandwidth 25Mb cbq(borrow red) queue dmz_udp bandwidth 20Mb cbq(borrow red) queue dmz_mail bandwidth 20Mb cbq(borrow red)

Обратите внимание, что total_ext определяет распределение ограничения  пропускной способности для всех очередей которым доступна пропускная способность для внешних соединений. Для использования новой инфраструктуры очередей, нам необходимо внести некоторые изменения в правила фильтрации. Имейте в виду, что любой трафик, который вы явно не  назначаете в определённую очередь, попдает в очереди по умолчанию для интерфейса.   Следовательно,  это   важно   учитывать   при   настройке   ваших   правил фильтрации и определении очереди актуального трафика в вашей сети.

Основная  часть  правил  фильтрации,  после  добавления  очередей,  может  выглядеть примерно так:

pass in on $ext_if proto { tcp, udp } to $nameservers port domain \ queue ext_udp

pass in on $int_if proto { tcp, udp } from $localnet to $nameservers \ port domain

pass out on $dmz_if proto { tcp, udp } to $nameservers port domain \ queue ext_dmz_udp

pass out on $dmz_if proto { tcp, udp } from $localnet to $nameservers \ port domain queue dmz_udp

pass in on $ext_if proto tcp to $webserver port $webports queue ext_web pass in on $int_if proto tcp from $localnet to $webserver port $webports

pass out on $dmz_if proto tcp to $webserver port $webports queue ext_dmz_web pass out on $dmz_if proto tcp from $localnet to $webserver port $webports \ queue dmz_web

pass in log on $ext_if proto tcp to $mailserver port smtp

pass in log on $ext_if proto tcp from $localnet to $mailserver port smtp pass in log on $int_if proto tcp from $localnet to $mailserver port $email pass out log on $dmz_if proto tcp to $mailserver port smtp queue ext_mail pass in on $dmz_if from $mailserver to port smtp queue dmz_mail

pass out log on $ext_if proto tcp from $mailserver to port smtp \ queue ext_dmz_mail

Обратите внимание, что, в очереди будет назначаться только трафик,  который будет проходить либо через интерфейс DMZ или внешний интерфейс. В данной конфигурации, без внешнего доступа к внутренним сервисам  локальной сети, очереди на внутреннем интерфейсе не имеют большого смысла, поскольку вероятно, что часть нашей сети имеет меньшие ограничения на пропускную способность.

Источник: Книга о PF, by Peter N.M. Hansteen, Перевод выполнил Михайлов Алексей aka iboxjo

Похожие посты:

Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий