Ограничение пропускной способности инета у пользователей
Наступил такой интересный момент -
порнуха у пользователей зарезана, приличная часть сайтов
развлекательного назначения тоже заразана, баннеры режутся, короче,
зарезано очень и очень много. А вот потребление траффика больше не
снижается :( Народ припугнутый "драконовскими" методами, типа по 200
мегабайт инета на каждого протянул недолго - месяца полтора - потом
просекли, что если попросить то включают анлим :( (и, ввиду, дырявости
моей памяти, забывают выключить...) Короче, было принято решение
ограничить скорость работы с инетом. Мера проверенная ещё на старой
работе, и действенная (но там было вообще жестоко - 2kB/s). Можно было
ограничить скорость работы по протоколу HTTP средствами SQUID, но были
отдельные грамотные товарищщи, которые тянули всякий хлам по ftp -
поэтому нужно было зарезать все протоколы, для этого подходил DUMMYNET.
Сказано - сделано. Для начала правим конфиг ядра, туда надо добавить поддержку DUMMYNET, файрволла.
IPFIREWALL #enable ipfirewall (required for dummynet) IPFIREWALL_VERBOSE #enable firewall output IPFIREWALL_VERBOSE_LIMIT #limit firewall output DUMMYNET #enable dummynet operation NMBCLUSTERS #set the amount of network packet buffers HZ #set the timer granularity options IPFIREWALL options DUMMYNET options HZ=1000 # strongly recommended
| После
чего пересобираем ядро. Если у Вас до этого ядро было без файрволла -
то будте готовы к тому, что после перезагрузки он заработает, и в нём
будет только одно правило:
Если файрволл есть, то в него надо добавить следующие строки (в самом верху):
# Сбрасываем ранее установленные правила: ${FwCMD} -f flush # сбрасываем все pipe ${FwCMD} -f pipe flush # сбрасываем очереди ${FwCMD} -f queue flush
# DUMMYNET # учтите - чтобы пакеты не выпадали на трубе из файрволла (типа, # как на разрешающем правиле) надо поставить переменную sysctl # net.inet.ip.fw.one_pass в 0 (по дефолту - 1) и внести это в # файл /etc/sysctl.conf - иначе при перезагрузке потеряется ${FwCMD} add pipe 1 ip from ${IpOut} to ${NetIn}/${NetMask} ${FwCMD} pipe 1 config bw 100Mbit/s ${FwCMD} add pipe 2 ip from ${IpIn} to ${NetIn}/${NetMask} ${FwCMD} pipe 2 config bw 100Mbit/s # `спецтруба` для мелкиз пакетов типа ack - ибо если они теряются # то повторные пакеты будут большего размера ${FwCMD} add pipe 3 ip from any to any tcpflags ack iplen 0-128 ${FwCMD} pipe 3 config bw 100Mbit/s # Пропускаем следующие трубы - чтобы мелкие пакеты не лимитировались # пропускать надо до первого нормального (после труб) правила. # я ему присвоил жёсткий номер - файрволл раздаёт номера с последнего правила # (если номер жёстко не задан) с интервалом определяемым переменной sysctl # net.inet.ip.fw.autoinc_step - по дефолту - 100 ${FwCMD} add skipto 39999 ip from any to any tcpflags ack iplen 0-128
# запускаем счётчик i=4 # цикл по $i while [ $i != 252 ] do # добавляем трубу для IP адреса ${FwCMD} add pipe $i ip from not ${NetIn}/${NetMask} to 192.168.20.${i} # проверяем - часом не мой ли это IP if [ $i -eq 13 -o $i -eq 22 ] then # мой инет :))) ${FwCMD} pipe $i config bw 100Mbit/s else # не мой IP - режем скорость ${FwCMD} pipe $i config bw 64000 bit/s fi # увеличиваем $i на единичку i=$(($i+1)) done
# проверяем временные правила (перед этим правилом возврщаются мелкие # пакеты в файрволл) : ${FwCMD} add 40000 check-state
# разрешаем всё по интерфейсу lo0 (петля) ${FwCMD} add allow ip from any to any via lo0
| Где переменные:
${FwCMD} - /sbin/ipfw - собственно IPFW
${NetIn} - 192.168.20.0 - внутренняя сеть
${NetMask} - 24 - маска сети
${IpOut} - 222.222.222.222 - внешний IP сервака
Вкратце о том, что всё это делает: первые две pipe для того, чтобы не
ограничивалась скорость работы с самим серваком - на нём лежит почта,
кое какие файлы, и естественно от того, что почта принимается со
скоростью 64k никто в восторге не будет, тем более, что внутри офиса
довольно большой документооборот идёт именно по почте. Затем запускаем
цикл по всем IP-шникам (я сделал не одно правило, а целую кучу (больше
200!), чтобы была большая гибкость в использовании - есть люди которым
не надо ничего ограничивать, те же IT-шники, начальство...) В цикле (он
специально сделан не с начала диапазона и не до конца - у меня вверху и
внизу висят серваки - их ограничивать не надо вообще) добавляются
именованые каналы и в зависимости от IP выставляется скорость - в
примере приведено для 2-х адресов - 192.168.20.13 и 192.168.20.22 -
можно сделать не такое жёсткое деление, используя не else, а elif. Выглядеть это будет так:
if [ $i -eq 13 -o $i -eq 22 ] then ${FwCMD} pipe $i config bw 100000000 bit/s elif [ $i -eq 18 -o $i -eq 38 ] ${FwCMD} pipe $i config bw 128000 bit/s elif [ $i -eq 55 -o $i -eq 159 -o $i -eq 188 ] ${FwCMD} pipe $i config bw 256000 bit/s else ${FwCMD} pipe $i config bw 64000 bit/s fi
| В этом случае имеем всем скорость 64k, для адресов
192.168.20.13 и 192.168.20.22 - 100 мегабит,
192.168.20.18 и 192.168.20.38 - 128k,
192.168.20.55, 192.168.20.159 и 192.168.20.188 - 256k.
После чего перезапускаем файрволл следующей командой:
(при условии, что конфиг файрволла у Вас в файле /etc/rc.firewall). Для просмотра существующих pipe пользуемся командой
Только не забудьте &
в конце - иначе может так получиться, что старые правила сбросятся, а
новые не успеют примениться (в момент запуска этой команды соединение по
ssh почти всегда обрывается.)
Ссылка на обсуждение: http://forum.lissyara.su/viewtopic.php?f=8&t=363.
размещено: 2005-11-29,
последнее обновление: 2006-05-18,
автор: lissyara
|