Необходимо было настроит динамический шейпер для локальной сети. Выбор стал между ipfw+dummynet и pf+altq. В результате шейпер решили настроить на dummynet, а правила NAT и фильтрации на PF, так как PF+ALTQ не дает возможности создания очереди на виртуальных интерфейсах (bridge, ng*, tun* ).
Визуальную статистику по пользователям, будем смотреть с помощью mrtg. Вышло даже неплохо .
Установленная ОС:
[root@pdcserv ~]# uname -rv
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
Далее необходимо немного тюнинговать ядро:
[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
Перейдем к настройке 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
На PF настраиваем только NAT:
[root@pdcserv /etc]#cat /etc/pf.conf
####МАКРОСЫ####
# 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»
Для визуальной статистики отдельно по каждому пользователю, необходимо добавить в конфиг 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]:
user 192.168.100.2
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 ~]#
Просмотр текущих динамических очередей:
[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 ~]#
unix.ck.ua