Динамический шейпер траффика (dummynet + PF + mrtg)
24.05.2011 - 08:43
Первым делом пересоберем ядро с поддержкой дамминета и PF:
Необходимо было настроит динамический шейпер для локальной сети. Выбор стал между ipfw+dummynet и pf+altq. В результате шейпер решили настроить на dummynet, а правила NAT и фильтрации на PF, так как PF+ALTQ не дает возможности создания очереди на виртуальных интерфейсах (bridge, ng*, tun* ).
Визуальную статистику по пользователям, будем смотреть с помощью mrtg. Вышло даже неплохо .
Установленная ОС:
[root@pdcserv ~]# uname -rv
FreeBSD 8.1-RELEASE #0
FreeBSD 8.1-RELEASE #0
Первым делом пересоберем ядро с поддержкой дамминета и PF:
#PF
device pf
device pflog
device pfsync
options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
options ALTQ_NOPCC
#IPFW
options IPFIREWALL
options DUMMYNET
options HZ=1000
device pf
device pflog
device pfsync
options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
options ALTQ_NOPCC
#IPFW
options IPFIREWALL
options DUMMYNET
options HZ=1000
Далее необходимо немного тюнинговать ядро:
[root@pdcserv /etc]# cat /etc/sysctl.conf
net.inet.ip.forwarding=1 #включаем форвардинг пакетов
net.inet.ip.fastforwarding=1 #эта опция действительно ускоряет форвардинг
net.inet.tcp.blackhole=2 #ядро убивает tcp пакеты, приходящие в систему на непрослушиваемые порты
net.inet.udp.blackhole=0 #как и выше, только не убивает ибо traceroute пакеты не покажут этот хоп
net.inet.icmp.drop_redirect=1 #не обращаем внимания на icmp redirect
net.inet.icmp.log_redirect=0 #и не логируем их
net.inet.ip.redirect=0 #не реагируем на icmp redirect
net.inet.ip.sourceroute=0 #отключение маршрутизации от источника
net.inet.ip.accept_sourceroute=0 #старый и бесполезный механизм
net.inet.icmp.bmcastecho=0 #защита от SMURF атак
net.inet.icmp.maskrepl=0 #не отдавать по icmp паску своей подсети
net.link.ether.inet.max_age=30 #переспрашиваем каждые 30 секунд mac адреса в своём arp пространстве
net.inet.tcp.drop_synfin=1 #небольшая защита
net.inet.tcp.syncookies=1 #от доса
kern.ipc.somaxconn=32768 #увеличиваем размер очереди для сокетов
kern.maxfiles=204800 #увеличиваем число открытых файловых дескрипторов
kern.maxfilesperproc=200000 #кол-во ф.д. на каждоый процесс
kern.ipc.nmbclusters=524288 #увеличиваем число сетевых буферов
kern.ipc.maxsockbuf=2097152 #
kern.random.sys.harvest.ethernet=0 #не использовать трафик и прерывания
kern.random.sys.harvest.interrupt=0 #как источник энтропии для random'a
net.inet.ip.dummynet.io_fast=1 #заставляет dummynet работать побыстрее
net.inet.ip.dummynet.hash_size=65535 #
net.inet.ip.dummynet.pipe_slot_limit=2048 #
kern.ipc.shmmax=67108864 #макс. размер сегмента памяти
net.inet.ip.intr_queue_maxlen=8192 #размер очереди ip-пакетов
#net.inet.ip.fw.one_pass=0 # 0=пакеты, прошедшие пайпы не вылетают из фаервола, а дальше идут по нему
net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5
net.inet.ip.dummynet.hash_size=1024
net.inet.ip.fw.dyn_buckets=1024
net.inet.ip.fastforwarding=1 #эта опция действительно ускоряет форвардинг
net.inet.tcp.blackhole=2 #ядро убивает tcp пакеты, приходящие в систему на непрослушиваемые порты
net.inet.udp.blackhole=0 #как и выше, только не убивает ибо traceroute пакеты не покажут этот хоп
net.inet.icmp.drop_redirect=1 #не обращаем внимания на icmp redirect
net.inet.icmp.log_redirect=0 #и не логируем их
net.inet.ip.redirect=0 #не реагируем на icmp redirect
net.inet.ip.sourceroute=0 #отключение маршрутизации от источника
net.inet.ip.accept_sourceroute=0 #старый и бесполезный механизм
net.inet.icmp.bmcastecho=0 #защита от SMURF атак
net.inet.icmp.maskrepl=0 #не отдавать по icmp паску своей подсети
net.link.ether.inet.max_age=30 #переспрашиваем каждые 30 секунд mac адреса в своём arp пространстве
net.inet.tcp.drop_synfin=1 #небольшая защита
net.inet.tcp.syncookies=1 #от доса
kern.ipc.somaxconn=32768 #увеличиваем размер очереди для сокетов
kern.maxfiles=204800 #увеличиваем число открытых файловых дескрипторов
kern.maxfilesperproc=200000 #кол-во ф.д. на каждоый процесс
kern.ipc.nmbclusters=524288 #увеличиваем число сетевых буферов
kern.ipc.maxsockbuf=2097152 #
kern.random.sys.harvest.ethernet=0 #не использовать трафик и прерывания
kern.random.sys.harvest.interrupt=0 #как источник энтропии для random'a
net.inet.ip.dummynet.io_fast=1 #заставляет dummynet работать побыстрее
net.inet.ip.dummynet.hash_size=65535 #
net.inet.ip.dummynet.pipe_slot_limit=2048 #
kern.ipc.shmmax=67108864 #макс. размер сегмента памяти
net.inet.ip.intr_queue_maxlen=8192 #размер очереди ip-пакетов
#net.inet.ip.fw.one_pass=0 # 0=пакеты, прошедшие пайпы не вылетают из фаервола, а дальше идут по нему
net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5
net.inet.ip.dummynet.hash_size=1024
net.inet.ip.fw.dyn_buckets=1024
Перейдем к настройке IPFW(dummynet);
[root@pdcserv /etc]#cat /etc/ipfw.conf
#!/bin/sh
cmd="ipfw -q"
lan=rl0 # LAN
wan=ae0 # WAN
drate=2Mbit/s # download
urate=2Mbit/s # upload
n=10 #Количество пользователей (1:253)
$cmd flush # Очищаем правила
$cmd pipe flush # Очищаем пайпы
$cmd table all flush # Очищаем все таблицы
# download (wan->lan)
$cmd pipe 100 config bw $drate queue 100 noerror
$cmd queue 111 config pipe 100 weight 50 queue 100 mask dst-ip 0xffffffff noerror
# upload (lan->wan)
$cmd pipe 200 config bw $urate queue 100 noerror
$cmd queue 211 config pipe 200 weight 50 queue 100 mask src-ip 0xffffffff noerror
#Создаем очереди по таблицам
$cmd add queue tablearg ip from table\(10\) to any out recv $lan xmit $wan
$cmd add queue tablearg ip from any to table\(11\) out recv $wan xmit $lan
#Генерация правил подсчета трафика по пользователях
i=2
k=`expr $i + $n`
while [ "$i" -lt "$k" ]
do
$cmd add count all from any to 10.10.10.$i/32
$cmd add count all from 10.10.10.$i/32 to any
i=`expr $i + 1`
done
# IPFIREWALL_DEFAULT_TO_ACCEPT
$cmd add allow all from any to any
### Заполняем таблицы: ip номер_пайпы ###
# user_1
#$cmd table 10 add 10.10.10.2/32 211
#$cmd table 11 add 10.10.10.2/32 111
# user_2
#$cmd table 10 add 10.10.10.3/32 211
#$cmd table 11 add 10.10.10.3/32 111
# user_3
#$cmd table 10 add 10.10.10.4/32 211
#$cmd table 11 add 10.10.10.4/32 111
#user_all
$cmd table 10 add 10.10.10.0/24 211
$cmd table 11 add 10.10.10.0/24 111</code>
На PF настраиваем только NAT:
<code>[root@pdcserv /etc]#cat /etc/pf.conf
</code><code>####МАКРОСЫ####
# WAN ISP
ext_if="ae0"
# LAN
int_if="rl0"
LAN="10.10.10.0/24"
#### NAT ####
# Разрешаем ходить в интернет через NAT
nat on $ext_if inet from $LAN to !$LAN -> ($ext_if)
cmd="ipfw -q"
lan=rl0 # LAN
wan=ae0 # WAN
drate=2Mbit/s # download
urate=2Mbit/s # upload
n=10 #Количество пользователей (1:253)
$cmd flush # Очищаем правила
$cmd pipe flush # Очищаем пайпы
$cmd table all flush # Очищаем все таблицы
# download (wan->lan)
$cmd pipe 100 config bw $drate queue 100 noerror
$cmd queue 111 config pipe 100 weight 50 queue 100 mask dst-ip 0xffffffff noerror
# upload (lan->wan)
$cmd pipe 200 config bw $urate queue 100 noerror
$cmd queue 211 config pipe 200 weight 50 queue 100 mask src-ip 0xffffffff noerror
#Создаем очереди по таблицам
$cmd add queue tablearg ip from table\(10\) to any out recv $lan xmit $wan
$cmd add queue tablearg ip from any to table\(11\) out recv $wan xmit $lan
#Генерация правил подсчета трафика по пользователях
i=2
k=`expr $i + $n`
while [ "$i" -lt "$k" ]
do
$cmd add count all from any to 10.10.10.$i/32
$cmd add count all from 10.10.10.$i/32 to any
i=`expr $i + 1`
done
# IPFIREWALL_DEFAULT_TO_ACCEPT
$cmd add allow all from any to any
### Заполняем таблицы: ip номер_пайпы ###
# user_1
#$cmd table 10 add 10.10.10.2/32 211
#$cmd table 11 add 10.10.10.2/32 111
# user_2
#$cmd table 10 add 10.10.10.3/32 211
#$cmd table 11 add 10.10.10.3/32 111
# user_3
#$cmd table 10 add 10.10.10.4/32 211
#$cmd table 11 add 10.10.10.4/32 111
#user_all
$cmd table 10 add 10.10.10.0/24 211
$cmd table 11 add 10.10.10.0/24 111</code>
На PF настраиваем только NAT:
<code>[root@pdcserv /etc]#cat /etc/pf.conf
</code><code>####МАКРОСЫ####
# WAN ISP
ext_if="ae0"
# LAN
int_if="rl0"
LAN="10.10.10.0/24"
#### NAT ####
# Разрешаем ходить в интернет через NAT
nat on $ext_if inet from $LAN to !$LAN -> ($ext_if)
Для автозапуска добавим строчки в /etc/rc.conf:
[root@pdcserv /etc]#cat >> /etc/rc.conf
#pf
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_logfile="/var/log/pf.log"
pflog_flags=""
#ipfw
firewall_enable="YES"
firewall_script="/etc/ipfw.conf"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_logfile="/var/log/pf.log"
pflog_flags=""
#ipfw
firewall_enable="YES"
firewall_script="/etc/ipfw.conf"
Для визуальной статистики отдельно по каждому пользователю, необходимо добавить в конфиг MRTG блоки такого содержания:
#Общий блок
HtmlDir: /usr/local/www/mrtg
ImageDir: /usr/local/www/mrtg/img
LogDir: /usr/local/www/mrtg
Language: russian
Options[^]: growright, unknaszero, nobanner, transparent, noinfo, nopercent, integer
Background[_]: #B0C4DE
XSize[_]: 400
YSize[_]: 100
# ipfw user_2
Target[user_2]: `ipfw show 300 | awk '{ print $3 }' && ipfw show 400 | awk '{ print $3 }'`
Title[user_2]: user_2
Pagetop[user_2]: <H1>user 192.168.100.2</H1>
Options[user_2]: bits
MaxBytes[user_2]:1250000
HtmlDir: /usr/local/www/mrtg
ImageDir: /usr/local/www/mrtg/img
LogDir: /usr/local/www/mrtg
Language: russian
Options[^]: growright, unknaszero, nobanner, transparent, noinfo, nopercent, integer
Background[_]: #B0C4DE
XSize[_]: 400
YSize[_]: 100
# ipfw user_2
Target[user_2]: `ipfw show 300 | awk '{ print $3 }' && ipfw show 400 | awk '{ print $3 }'`
Title[user_2]: user_2
Pagetop[user_2]: <H1>user 192.168.100.2</H1>
Options[user_2]: bits
MaxBytes[user_2]:1250000
Вывод сгенерированных правил для 2-х пользователей:
[root@pdcserv ~]# ipfw show
00100 0 0 queue tablearg ip from table(10) to any out recv rl0 xmit ae0
00200 0 0 queue tablearg ip from any to table(11) out recv ae0 xmit rl0
00300 0 0 count ip from any to 10.10.10.2
00400 0 0 count ip from 10.10.10.2 to any
00500 0 0 count ip from any to 10.10.10.3
00600 0 0 count ip from 10.10.10.3 to any
00700 129 48429 allow ip from any to any
65535 0 0 deny ip from any to any
[root@pdcserv ~]#
00100 0 0 queue tablearg ip from table(10) to any out recv rl0 xmit ae0
00200 0 0 queue tablearg ip from any to table(11) out recv ae0 xmit rl0
00300 0 0 count ip from any to 10.10.10.2
00400 0 0 count ip from 10.10.10.2 to any
00500 0 0 count ip from any to 10.10.10.3
00600 0 0 count ip from 10.10.10.3 to any
00700 129 48429 allow ip from any to any
65535 0 0 deny ip from any to any
[root@pdcserv ~]#
Просмотр текущих динамических очередей:
[root@pdcserv ~]# ipfw queue show
q00211 100 sl. 0 flows (1024 buckets) sched 200 weight 50 lmax 0 pri 0 droptail
mask: 0x00 0xffffffff/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
q00111 100 sl. 0 flows (1024 buckets) sched 100 weight 50 lmax 0 pri 0 droptail
mask: 0x00 0x00000000/0x0000 -> 0xffffffff/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
[root@pdcserv ~]#
q00211 100 sl. 0 flows (1024 buckets) sched 200 weight 50 lmax 0 pri 0 droptail
mask: 0x00 0xffffffff/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
q00111 100 sl. 0 flows (1024 buckets) sched 100 weight 50 lmax 0 pri 0 droptail
mask: 0x00 0x00000000/0x0000 -> 0xffffffff/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
[root@pdcserv ~]#
- Войдите на сайт для отправки комментариев
- Версия для печати
наткнулся на ЭТУ статью., цитата из неё:
что скажешь?
статья в целом хорошая, но:
такие слова всё таки лучше писАть на англ
ато осталось только пробел поставить