Фильтры-ограничители трафика.

12.3. Фильтры-ограничители трафика.

Более сложные системы управления трафиком можно строить на основе фильтров, которые зависят от пропускной способности и загруженности канала. Вы можете объявить фильтр, который не будет срабатывать, если загрузка канала превысила некоторую величину или наоборот, срабатывать только в том случае, если пропускная способность превысила заданное значение.

Так, если вы решили ограничить 5 Мбитный канал величиной в 4 Мбит/сек, вы можете вообще прекратить прием пакетов, если загруженность канала превысит 4 Мбит/сек, либо отбросить 1 Мбит/сек, а 4 Мбит/сек передать заданному классу.

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

12.3.1. Способы ограничения.

Существует две основных возможности ограничения. Если вы собрали ядро с "функциями оценки" (estimators), то оно сможет более или менее точно измерять объем трафика, переданного тому или иному фильтру. Устройство функции оценки достаточно несложное -- 25 раз в секунду подсчитывается объем переданных данных, на основе которого вычисляется загруженность канала.

Другой способ -- Token Bucket Filter, который реализуется в пределах вашего фильтра. Это типичный шейпер, который может использоваться, если вам нужно просто ограничить полосу пропускания по какому-нибудь критерию.

12.3.1.1. Оценочная функция в ядре (estimator).

Тут все очень просто и имеется всего один параметр: avrate. Либо объем трафика остается ниже avrate и фильтр классифицирует его как сконфигурированный classid, либо, в случае превышения заданной границы, выполняется указанное действие, которое по-умолчанию выполняет переклассификацию.

Для оценки загруженности канала, ядро использует экспоненциальное взвешенное смещенное среднее значение, которое менее чувствительно к коротким пикам.

12.3.1.2. Token Bucket Filter.

Используются следующие параметры:

  • burst/buffer/maxburst

  • mtu/minburst

  • mpu

  • rate

Которые ведут себя идентично описанным в разделе Token Bucket Filter. Обратите внимание, если вы установите mtu слишком низким, то входящий трафик будет подавлен, в то время как исходящий TBF qdisc передаст с более низкой скоростью.

Еще одно важное отличие такого фильтра -- он может только либо пропустить пакет, либо отбросить. Он не может задержать пакет на какое-то время.

12.3.2. Действия в случае превышения ограничения.

Если правило "решит", что произошло превышение заданного предела, то оно выполнит соответствующее действие. Имеются четыре вида действий:

continue

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

drop

Очень жестокое действие, которое просто отказывает "в праве на жизнь" трафику, объем которого превысил заданную величину. Часто используется во входных фильтрах и имеет ограниченное применение. Например, представим, что имеется сервер имен, который не в состоянии работать при нагрузке выше чем 5Мбит/сек, в этом случае можно построить входной фильтр, который ограничит входящий трафик для нашего сервера.

Pass/OK

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

reclassify

Действие, заданное по-умолчанию. Наиболее часто сводится к переклассификации в Best Effort (в данном контексте фразу "Best Effort" следует понимать как -- "лучшее из оставшегося". прим. перев.)

12.3.3. Примеры.

Единственный, известный нам, реальный пример приведен в разделе Защита от SYN flood

Ограничение входящего icmp-трафика до 2 Кбит. При превышении предела -- пакеты отбросить.

tc filter add dev $DEV parent ffff: \
    protocol ip prio 20 \
    u32 match ip protocol 1 0xff \
    police rate 2kbit buffer 10k drop \
    flowid :1        
        
Ограничить размер пакетов (т.е. все пакеты, имеющие размер более чем 84 байта, будут сброшены)
tc filter add dev $DEV parent ffff: \
   protocol ip prio 20 \
   u32 match tos 0 0 \
   police mtu 84 drop \
   flowid :1        
        
Этот метод может использоваться для полного подавления icmp-трафика:
tc filter add dev $DEV parent ffff: \
   protocol ip prio 20 \
   u32 match ip protocol 1 0xff \
   police mtu 1 drop \
   flowid :1        
        
Фактически означает: "отбросить все icmp-пакеты, размер которых превышает 1 байт". Чисто теоретически, пакеты могут иметь размер в 1 байт, но на практике вы с ними никогда не встретитесь.