IPFW: ограничение скорости Internet (часть 2)
В первой части статьи IPFW: ограничение скорости Internet я описал основы построения каналов и потоков в сети DUMMYNET. Пришла пора рассмотреть конкретный пример работающей в небольшой сети, где все пользователи в равной степени делят один единственный канал связи.
Имеем DSL-соединение, потому канал асинхронный, скорость закачки - 5 Mbit/s, скорость отдачи - 512 Kbit/s.
Первым делом нам понадобится добавить поддержку DUMMYNET в ядро системы, заодно включим ядерный NAT и файрвол (считаю, что на шлюзе эти опции необходимы, в противном случае что это за шлюз такой получается):
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=100
options IPFIREWALL_FORWARD
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_NAT
options DUMMYNET
options HZ=1000
Подробно расписывать как собирать ядро я не буду - в блоге об этом уже писалось, да и в сети не проблема найти. Прейдем к настройке. В конфигурацию вашего файерволла /etc/rc.firewall добавляем наши правила:
${fwcmd} pipe 1 config bw 5Mbit/s
${fwcmd} pipe 11 config bw 512Kbit/s
${fwcmd} queue 1 config pipe 1 mask dst-ip 0xffffffff
${fwcmd} queue 2 config pipe 11 mask src-ip 0xffffffff
${fwcmd} add queue 1 ip from any to 192.168.1.0/24
${fwcmd} add queue 2 ip from 192.168.1.0/24 to any
Разберемся, что тут написано. Создаются два канала pipe 1 - 5 Mbit/s и pipe 11 - 512Kbit/s:
${fwcmd} pipe 1 config bw 5Mbit/s
${fwcmd} pipe 11 config bw 512Kbit/s
Следует отметить один важный и принципиальный момент при указании скорости pipe. Она должна соответствовать реальной пропускной способности канала, т.к. от этого напрямую зависит корректная работа всей системы разделения трафика.
К примеру, провайдером заявлена скорость 6 Mbit/s, однако для правильной работы pipe я установил 5 Mbit/s, т.к. это больше соответствует реальному значению скорости в канале. При большем значении скорости, чем может обеспечить канал, вся система разделения перестаёт работать.
Для каждого pipe создаются очереди queue:
${fwcmd} queue 1 config pipe 1 mask dst-ip 0xffffffff
${fwcmd} queue 2 config pipe 11 mask src-ip 0xffffffff
Так как стоит задача равномерного распределения канала Internet между всеми пользователями, необходимо создать очереди, соответствующие количеству этих самых пользователей, как для входящего, так и для исходящего траффика. Понятно, что делать это вручную, мягко говоря, утомительно. Потому мы создаем всего по одной очереди с маской для каждого канала, упростив тем самым себе задачу.
mask (маска) - это значение по которому разделяются очереди (queue):
- src-ip - распределение по ip отправителя
- dst-ip - аналогично по ip получателя
- src-addr - mac адрес отправителя
- dst-addr - mac адрес получателя
Осталось запустить в эти очереди наш траффик:
${fwcmd} add queue 1 ip from any to 192.168.1.0/24
${fwcmd} add queue 2 ip from 192.168.1.0/24 to any
Как видите, все довольно просто и логично. Работу pipe с очередями можно просмотреть командой:
# ipfw pipe show
00001: 5.000 Mbit/s 0 ms burst 0
q131073 50 sl. 0 flows (1 buckets) sched 65537 weight 0 lmax 0 pri 0 droptail
sched 65537 type FIFO flags 0x0 0 buckets 0 active
00011: 512.000 Kbit/s 0 ms burst 0
q131083 50 sl. 0 flows (1 buckets) sched 65547 weight 0 lmax 0 pri 0 droptail
sched 65547 type FIFO flags 0x0 0 buckets 0 active
Эта команда может сильно помочь при отладке ваших правил. При тестировании и добавлении новых правил IPFW не плохо производить очистку старых правил:
# ipfw -f flush
# ipfw -f pipe flush
# ipfw -f queue flush
При использовании firewall (если он не открытый), необходимо присвоить переменной sysctl - net.inet.ip.fw.one_pass значение 0 (по дефолту "1"). Это нужно для того, чтобы пакеты не "выпадали" на pipe из файрволла (как на разрешающем правиле).
Чтобы изменения не терялись при перезагрузке пропишите переменную net.inet.ip.fw.one_pass в файле /etc/sysctl.conf.
P.S.: Я привел лишь один пример настройки DUMMYNET для распределения скорости Internet. Конечно можно делать более продвинутые конфигурации - выделять фиксированные каналы с заданной скоростью для приоритетных задач, отдельных протоколов и т.д.
Статья не претендует на полное описание, а лишь дает толчок к пониманию и дальнейшему изучению богатейших возможностей DUMMYNET. Надеюсь, что кому-то мой опыт пригодится. Оставляйте комментарии и дополнения.
P.P.S.: не плохая статья по теме - подробнее об использовании pipe-s в IPFW
Если считаете статью полезной,
не ленитесь ставить лайки и делиться с друзьями.