Нарезаем трафик ломтиками Andrey Matveev Хакер, номер #087, стр. 087-130-4 [огненная дуга] В OpenBSD для ограничения пропускной способности используется ALTQ (Alternate Queueing, Альтернативная Организация Очередей). Как следует из названия, с ее помощью можно привязывать пакеты к заданным очередям. В реализации ALTQ важную роль играет планировщик, который предписывает алгоритм, используемый для выбора действия над пакетами (задержать/отбросить/отправить немедленно). В настоящее время существует три вида планировщиков очередей: CBQ (Class Based Queueing), PRIQ (Priority Queueing - наш случай) и HFSC (Hierarchical Fair Service Curve). Различные планировщики можно запускать на разных сетевых интерфейсах, к примеру, CBQ на внутреннем, а PRIQ на внешнем. Это дает поистине уникальные возможности для разграничения трафика. Особого внимания заслуживает определение полосы пропускания исходящего трафика. Данное значение следует выставлять очень аккуратно, так как если его завысить, то приоритезация будет неэффективна, а если занизить, то доступная ширина будет использована не полностью. В моем случае эта цифра весьма скромна - 100 kbps (провайдер выделяет скорость к абоненту/от абонента, которая равна 256/128 kbps, минус затраты, связанные с инкапсуляцией PPPoE): altq on pppoe0 priq bandwidth 100Kb queue { список очередей } Все точки над 'i' расставлены. В правилах файрвола остается выделить входящие и исходящие подключения, классифицировать очереди и произвести фильтрацию пакетов. Приступим. # vi /etc/pf.conf /* Для экономии динамически выделяемой памяти уменьшаем значения таймаутов в таблице состояния соединений */ set optimization aggressive /* Включаем нормализацию и дефрагментацию IPv4-пакетов на PPPoE-интерфейсе */ scrub in on pppoe0 all scrub out on pppoe0 all random-id max-mss 1452 /* Прохождение IPv4-пакетов на интерфейсе обратной петли и на внутренних сетевых интерфейсах разрешаем без ограничений */ pass quick on { lo0, vr0, ral0 } inet all /* Включаем ALTQ, в качестве планировщика выбираем PRIQ, назначаем 4 очереди с разными приоритетами */ altq on pppoe0 priq bandwidth 100Kb queue { q_max, q_hig, q_def, q_low } queue q_max priority 7 queue q_hig priority 5 queue q_def priority 3 queue q_low priority 1 priq(default) /* Производим трансляцию сетевых адресов */ nat on pppoe0 inet from 192.168.1.0/24 to any -> (pppoe0) /* Регистрируем заблокированные попытки соединения */ block return log(all) /* Нам нет дела до входящих ICMP-запросов, выставляем самый низкий приоритет */ pass in on pppoe0 inet proto icmp from any to (pppoe0) \ icmp-type 8 code 0 keep state (max 32) queue (q_low) /* Все ICMP- и UDP-соединения (кроме 53/udp, см. правило ниже) отнесем к дефолтной очереди */ pass out on pppoe0 inet proto { udp, icmp } from (pppoe0) to any \ keep state queue (q_def) /* Определение соответствия между именами хостов и их IP-адресами доверим очереди с приоритетом q_hig */ pass out on pppoe0 inet proto udp from (pppoe0) to any port domain \ |