Главная Карта сайта                                

 

 

Ограничение пропускной способности инета у пользователей

Автор: lissyara.

 


    Наступил такой интересный момент - порнуха у пользователей зарезана, приличная часть сайтов развлекательного назначения тоже заразана, баннеры режутся, короче, зарезано очень и очень много. А вот потребление траффика больше не снижается :( Народ припугнутый "драконовскими" методами, типа по 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
 

После чего пересобираем ядро. Если у Вас до этого ядро было без файрволла - то будте готовы к тому, что после перезагрузки он заработает, и в нём будет только одно правило:

deny all from any to any
 

Если файрволл есть, то в него надо добавить следующие строки (в самом верху):

# Сбрасываем ранее установленные правила:
${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.
После чего перезапускаем файрволл следующей командой:

sh /etc/rc.firewall &
 

(при условии, что конфиг файрволла у Вас в файле /etc/rc.firewall). Для просмотра существующих pipe пользуемся командой
 

ipfw pipe show
 

Только не забудьте & в конце - иначе может так получиться, что старые правила сбросятся, а новые не успеют примениться (в момент запуска этой команды соединение по ssh почти всегда обрывается.)

 
 

<<пред след>>

Сайт управляется системой uCoz