Настройка шейпера - для справедливого деления канала между пользователями: различия между версиями

Материал из Wiki МИАЦ ВО
Перейти к навигации Перейти к поиску
(Новая: ==Введение== За основу скрипта был взят материал [http://gazette.linux.ru.net/rus/articles/index-lartc.html Linux Advanced Routing & Traffic Control...)
 
(Скрипт включения шейпера)
Строка 154: Строка 154:
 
# DNS                                                                                         
 
# DNS                                                                                         
 
$ipt -t mangle -A  POST_MY -p UDP  -j MARK --set-mark 1                                       
 
$ipt -t mangle -A  POST_MY -p UDP  -j MARK --set-mark 1                                       
#$ipt -t mangle -A  PRE_MY -p UDP  -j MARK --set-mark 1                                     
 
 
$ipt -t mangle -A  POST_MY -p tcp -m tcp --sport 53 -j MARK --set-mark 1                     
 
$ipt -t mangle -A  POST_MY -p tcp -m tcp --sport 53 -j MARK --set-mark 1                     
#set +x                                                                                     
 
  
 
# HTTP трафик
 
# HTTP трафик
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto http -j MARK --set-mark 0x2
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto http -j MARK --set-mark 0x2
#$ipt -t mangle -A POST_MY -p tcp --sport http  -j MARK --set-mark 0x2   
 
#$ipt -t mangle -A POST_MY -p tcp --dport http  -j MARK --set-mark 0x2   
 
 
$ipt -t mangle -A PRE_MY -p tcp -m layer7 --l7proto http -j MARK --set-mark 0x2
 
$ipt -t mangle -A PRE_MY -p tcp -m layer7 --l7proto http -j MARK --set-mark 0x2
#$ipt -t mangle -A PRE_MY -p tcp  --sport http  -j MARK --set-mark 0x2       
 
#$ipt -t mangle -A PRE_MY -p tcp  --dport http  -j MARK --set-mark 0x2       
 
  
# zaharov 2
+
#те, которые плохие
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4
 
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4
 
# Я любимый
 
#$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_my/255.255.255.255 -j MARK --set-mark 0x1
 
#$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_my/255.255.255.255 -j MARK --set-mark 0x1
 
  
  
 
# FTP Bittonet
 
# FTP Bittonet
 
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto bittorrent -j MARK --set-mark 0x3
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto bittorrent -j MARK --set-mark 0x3
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto directconnect -j MARK --set-mark 0x3
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto directconnect -j MARK --set-mark 0x3
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto ftp -j MARK --set-mark 0x3         
 
$ipt -t mangle -A POST_MY  -m layer7 --l7proto ftp -j MARK --set-mark 0x3         
#$ipt -t mangle -A PRE_MY  -m layer7 --l7proto bittorrent -j MARK --set-mark 0x3 
 
#$ipt -t mangle -A PRE_MY  -m layer7 --l7proto directconnect -j MARK --set-mark 0x3
 
#$ipt -t mangle -A PRE_MY  -m layer7 --l7proto ftp -j MARK --set-mark 0x3       
 
 
 
#ip link set imq0 up
 
  
 +
# Перенаправляем все в IMQ
 
$ipt -t mangle -A POST_MY -j IMQ --todev 0
 
$ipt -t mangle -A POST_MY -j IMQ --todev 0
  
 
+
# Все остальное - сбрасываем
 
$ipt -t mangle -A FORWARD -i eth0 -o eth0 -j DROP
 
$ipt -t mangle -A FORWARD -i eth0 -o eth0 -j DROP
 
$ipt -t mangle -A FORWARD -i eth1 -o eth1 -j DROP
 
$ipt -t mangle -A FORWARD -i eth1 -o eth1 -j DROP
Строка 204: Строка 188:
 
modprobe imq numdevs=4             
 
modprobe imq numdevs=4             
  
 +
# Поднимаем интерфейс IMQ1
 
ip link set imq1 up
 
ip link set imq1 up
 +
  
 
ip link set dev imq1 qlen 1000
 
ip link set dev imq1 qlen 1000
Строка 219: Строка 205:
 
tc class add dev imq1 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 1
 
tc class add dev imq1 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 1
  
# подключаем дисциплины обработки очереди к подклассам - здесь мы используем SFQ для каждого класса.
+
# подключаем дисциплины обработки очереди к подклассам -  
#                       SFQ обеспечит почти честное деление полосы пропускания между соединениями   
+
# здесь мы используем SFQ для каждого класса.
#                       внутри каждого класса.                                                       
+
# SFQ обеспечит почти честное деление полосы пропускания между соединениями   
 +
# внутри каждого класса.                                                       
 
tc qdisc add dev imq1 parent 1:20 handle 20: sfq perturb 10                                         
 
tc qdisc add dev imq1 parent 1:20 handle 20: sfq perturb 10                                         
 
tc qdisc add dev imq1 parent 1:21 handle 21: red limit 1000000 min 5000 max 100000 avpkt 1000 burst 50
 
tc qdisc add dev imq1 parent 1:21 handle 21: red limit 1000000 min 5000 max 100000 avpkt 1000 burst 50
  
 
# направляем трафик в классы по fwmark - мы направляем трафик в классы, в соответствии со значением
 
# направляем трафик в классы по fwmark - мы направляем трафик в классы, в соответствии со значением
#                                       fwmark установленном на пакете (мы будем устанавливать это
+
#       fwmark установленном на пакете (мы будем устанавливать это
#                                       значение утилитой iptables позже). Обратите внимание, что  
+
#       значение утилитой iptables позже). Обратите внимание, что  
#                                       выше мы установили класс по умолчанию 1:26, так что       
+
#       выше мы установили класс по умолчанию 1:26, так что       
#                                       немаркированные пакеты (или с неизвестными значениями fwmark
+
#       немаркированные пакеты (или с неизвестными значениями fwmark
#                                       будут направлены в низкоприоритетный класс.
+
#       будут направлены в низкоприоритетный класс.
 
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
 
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
 
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21
 
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21
Строка 250: Строка 237:
 
                                                                               # пакеты как 26 (низкий приоритет)
 
                                                                               # пакеты как 26 (низкий приоритет)
  
# Наконец, пропустить все эти пакеты через imq0
+
# Наконец, пропустить все эти пакеты через imq1
 
$ipt -t mangle -A MYSHAPER-IN -j IMQ --todev 1
 
$ipt -t mangle -A MYSHAPER-IN -j IMQ --todev 1
  
 
# Конец ограничения входящего потока
 
# Конец ограничения входящего потока
 
#
 
#
####################################################
+
####################################################</pre>
 
 
</pre>
 

Версия 12:43, 6 ноября 2008

Введение

За основу скрипта был взят материал Linux Advanced Routing & Traffic Control HOWTO и статья Управление сетевым трафиком посредством очередей
Опишу тут настройку своего шейпера для справедливого деления канала Internrt для пользователей.
Что он должен обеспечивать.

  1. Исходим из того что пользователи ходят в Инет через VPN (см. abils+VPN+radius+mysql)
  2. Пользователи не должны замечать сильное падение скорости, если, кто-то включил закачку.
  3. Приоритет для нужных пакетов (ssh, ping, и др.)

Предварительная настройка

Для того чтобы шейпер заработал нужно:

  1. Пропатчить kernel, iptables и iproute.

Скрипт включения шейпера

#!/bin/bash                                             
# Грузим модули iptables, если они были не загружены
/sbin/modprobe ip_tables                                
/sbin/modprobe ip_conntrack                             
/sbin/modprobe iptable_filter                           
/sbin/modprobe iptable_mangle                           
/sbin/modprobe iptable_nat                              
/sbin/modprobe ipt_LOG                                  
/sbin/modprobe ipt_limit                                
/sbin/modprobe ipt_state                                
#/sbin/modprobe ipt_owner                               
/sbin/modprobe ipt_REJECT                               
/sbin/modprobe ipt_MASQUERADE                           
/sbin/modprobe ip_conntrack_ftp                         
/sbin/modprobe ip_conntrack_irc                         
/sbin/modprobe ip_nat_ftp                               
/sbin/modprobe ip_nat_irc                               

# Включаем форвардинг
echo "1" > /proc/sys/net/ipv4/ip_forward

#eth2 - внешний интерфейс
#eth0 - внутренний интерфейс


ip_my=172.16.131.10          # Мой IP адрес (себя же нельзя обижать)
ip_bad=172.16.131.13         # Ip адреса, всяких плохих людей, которым надо урезать скорость
ip_bad1=172.16.131.49

ipt=/usr/local/sbin/iptables
ipr=/usr/sbin/tc            
in_net=172.16.131.0/24      # VPN Сеть
out_adr=78.36.165.10        # Наружный адрес
touch /var/lock/subsys/local
#DEV_OUT=eth0               
DEV_OUT=eth2                

RATEOUT=1000                # Максимальная скорость в локальную сеть
DEV_IN=eth1                 
RATEDN=1000                 # Максимальная входящая скорость от прова на внешний интерфейс


# Сбросить все в известное состояние (очищеное)
$ipr qdisc del dev imq0 root 2> /dev/null > /dev/null
$ipr qdisc del dev imq1 root 2> /dev/null > /dev/null


# очистка таблицы mangle
$ipt -t mangle -F       

$ipr qdisc del dev imq0 root &> /dev/null
$ipr qdisc del dev imq1 root &> /dev/null


$ipt -t mangle -D POSTROUTING -o ppp+ -d $in_net -j POST_MY 2> /dev/null > /dev/null
$ipt -t mangle -F POST_MY 2> /dev/null > /dev/null                                  
$ipt -t mangle -X POST_MY 2> /dev/null > /dev/null                                  
$ipt -t mangle -F MYSHAPER-IN 2> /dev/null > /dev/null                              
$ipt -t mangle -X MYSHAPER-IN 2> /dev/null > /dev/null                              

$ipt -t mangle -D PREROUTING -i ppp+ -s $in_net -j PRE_MY  2> /dev/null > /dev/null
$ipt -t mangle -F PRE_MY 2> /dev/null > /dev/null                                  
$ipt -t mangle -X PRE_MY 2> /dev/null > /dev/null                                  

ip link set imq0 down 2> /dev/null > /dev/null
ip link set imq1 down 2> /dev/null > /dev/null
rmmod imq 2> /dev/null > /dev/null            

# Подгружаем модуль IMQ
modprobe imq numdevs=4
ip link set imq0  up  


# ограничение скорости канала -----------------------------------------------------------------

###########################################################
#                                                          
# Ограничение исходящего потока (ограничивает пропускную способность до RATEUP)

# установить размер очереди, соответствующий двухсекундной задержке на низкоприоритетном трафике
ip link set dev imq0 qlen 10                                                                    

# изменяем значение mtu на исходящем устройстве. Понижение значения mtu уменьшит задержку, но
# и немного понизит пропускную способность из-за увеличения числа                            
# заголовков протоколов IP и TCP .                                                           
ip link set dev imq0 mtu 1400                                                                

$ipr qdisc add dev imq0 root handle 1: htb default 14 r2q 1
#$ipr qdisc add dev $ethi root handle 1: htb               
$ipr class add dev imq0  parent 1:  classid 1:1  htb rate $[$RATEOUT]kbit  ceil ${RATEOUT}kbit
# ssh, DNS, Голосовая почта                                                                   
$ipr class add dev imq0 parent 1:1  classid 1:10  htb rate $[$RATEOUT/3]kbit  ceil ${RATEOUT}kbit prio 0
# HTTP                                                                                                  
$ipr class add dev imq0 parent 1:1  classid 1:11  htb rate $[$RATEOUT/4]kbit  ceil ${RATEOUT}kbit prio 1
# ftp, bittonet                                                                                         
$ipr class add dev imq0 parent 1:1  classid 1:12  htb rate $[$RATEOUT/6]kbit  ceil ${RATEOUT}kbit prio 4
# bad users                                                                                             
$ipr class add dev imq0 parent 1:1  classid 1:13  htb rate $[$RATEOUT/8]kbit  ceil $[$RATEOUT/3]kbit  prio 6
# Other                                                                                                     
$ipr class add dev imq0 parent 1:1  classid 1:14  htb rate $[$RATEOUT/4]kbit  ceil ${RATEOUT}kbit prio 3    

$ipr qdisc  add dev imq0 parent 1:10  handle 100: esfq perturb 10
$ipr qdisc  add dev imq0 parent 1:11  handle 110: esfq perturb 10
$ipr qdisc  add dev imq0 parent 1:12  handle 120: esfq perturb 10
$ipr qdisc  add dev imq0 parent 1:13  handle 130: esfq perturb 10
$ipr qdisc  add dev imq0 parent 1:14  handle 140: esfq perturb 10


$ipr filter add dev imq0 protocol ip parent 1:0 prio 0 handle 1 fw flowid 1:10
$ipr filter add dev imq0 protocol ip parent 1:0 prio 1 handle 2 fw flowid 1:11
$ipr filter add dev imq0 protocol ip parent 1:0 prio 2 handle 3 fw flowid 1:12
$ipr filter add dev imq0 protocol ip parent 1:0 prio 4 handle 4 fw flowid 1:13
$ipr filter add dev imq0 protocol ip parent 1:0 prio 3 handle 5 fw flowid 1:14

#set -x
# Создаем правила для перенаправыления пакетов в различные очереди
$ipt -t mangle -N POST_MY
$ipt -t mangle -N PRE_MY 

$ipt -t mangle -I POSTROUTING -o ppp+ -d $in_net   -j POST_MY
$ipt -t mangle -I PREROUTING -i ppp+ -s $in_net -j PRE_MY             

# ICQ
$ipt -t mangle -A POST_MY -p tcp --sport 5190 -j MARK --set-mark 0x2
# интернет-пейджер aol                                              
# ICMP (ping) - высокий приоритет,                                  
$ipt -t mangle -A  POST_MY -p icmp  -j MARK --set-mark 0x1          
$ipt -t mangle -A  POST_MY -m tos --tos Minimize-Delay  -j MARK --set-mark 0x1
$ipt -t mangle -A  POST_MY -m tos --tos Maximize-Throughput  -j MARK --set-mark 0x4
$ipt -t mangle -A  POST_MY -p tcp -m length --length :64 -j MARK --set-mark 0x1    
# маленькие пакеты                                                                 
# скорее всего ACK-пакеты                                                          

# SSH  
$ipt -t mangle -A POST_MY -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1
#$ipt -t mangle -A PRE_MY -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1
# Голсовая почта                                                         
$ipt -t mangle -A POST_MY -p tcp -m tcp --sport 5038 -j MARK --set-mark 0x1
#$ipt -t mangle -A PRE_MY -p tcp -m tcp --sport 2000 -j MARK --set-mark 0x1

# SYN
$ipt -t mangle -A  POST_MY  -p tcp -m tcp --tcp-flags SYN,RST,ACK, SYN -j MARK --set-mark 0x1
# DNS                                                                                        
$ipt -t mangle -A  POST_MY -p UDP  -j MARK --set-mark 1                                      
$ipt -t mangle -A  POST_MY -p tcp -m tcp --sport 53 -j MARK --set-mark 1                     

# HTTP трафик
$ipt -t mangle -A POST_MY  -m layer7 --l7proto http -j MARK --set-mark 0x2
$ipt -t mangle -A PRE_MY -p tcp -m layer7 --l7proto http -j MARK --set-mark 0x2

#те, которые плохие
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad/255.255.255.255 -j MARK --set-mark 0x4
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -s $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4
$ipt -t mangle -A POSTROUTING -o ppp+  -p tcp -d $ip_bad1/255.255.255.255 -j MARK --set-mark 0x4


# FTP Bittonet
$ipt -t mangle -A POST_MY  -m layer7 --l7proto bittorrent -j MARK --set-mark 0x3
$ipt -t mangle -A POST_MY  -m layer7 --l7proto directconnect -j MARK --set-mark 0x3
$ipt -t mangle -A POST_MY   -m layer7 --l7proto ftp -j MARK --set-mark 0x3         

# Перенаправляем все в IMQ
$ipt -t mangle -A POST_MY -j IMQ --todev 0

# Все остальное - сбрасываем
$ipt -t mangle -A FORWARD -i eth0 -o eth0 -j DROP
$ipt -t mangle -A FORWARD -i eth1 -o eth1 -j DROP
$ipt -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

####################################################
#                                                   
# Ограничение входящего потока (ограничивает пропускную способность до RATEDN)

# убедимся, что модуль imq загружен
#exit                              
modprobe imq numdevs=4             

# Поднимаем интерфейс IMQ1
ip link set imq1 up


ip link set dev imq1 qlen 1000
# добавляем дисциплину - низкоприоритетный класс по умолчанию 1:21

tc qdisc add dev imq1 handle 1: root htb default 21 

# добавляем общее ограничение скорости по классу
tc class add dev imq1 parent 1: classid 1:1 htb rate ${RATEDN}kbit

# добавляем подклассы - TCP traffic in 21, non TCP traffic in 20
#                                                               
tc class add dev imq1 parent 1:1 classid 1:20 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 0
tc class add dev imq1 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 1

# подключаем дисциплины обработки очереди к подклассам - 
# здесь мы используем SFQ для каждого класса.
# SFQ обеспечит почти честное деление полосы пропускания между соединениями   
# внутри каждого класса.                                                      
tc qdisc add dev imq1 parent 1:20 handle 20: sfq perturb 10                                         
tc qdisc add dev imq1 parent 1:21 handle 21: red limit 1000000 min 5000 max 100000 avpkt 1000 burst 50

# направляем трафик в классы по fwmark - мы направляем трафик в классы, в соответствии со значением
#        fwmark установленном на пакете (мы будем устанавливать это
#        значение утилитой iptables позже). Обратите внимание, что 
#        выше мы установили класс по умолчанию 1:26, так что       
#        немаркированные пакеты (или с неизвестными значениями fwmark
#        будут направлены в низкоприоритетный класс.
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21

# добавить цепочку MYSHAPER-OUT в таблицу mangle - сейчас мы настроим таблицу, которую будем
#                                                  использовать для фильтрации и установки fwmark
$ipt -t mangle -N MYSHAPER-IN
$ipt -t mangle -I PREROUTING -i $DEV_OUT -j MYSHAPER-IN

# маркируем пакеты с помощью fwmark - устанавливаем значения 20-26 в зависимости от
#                                     нужного класса. Высший приоритет - 20.
$ipt -t mangle -A MYSHAPER-IN -p ! tcp -j MARK --set-mark 20              # Маркировать не-tcp пакеты как высокоприоритетные
$ipt -t mangle -A MYSHAPER-IN -p tcp -m length --length :64 -j MARK --set-mark 20 # маленькие TCP-пакеты - вероято ACK
$ipt -t mangle -A MYSHAPER-IN -p tcp --dport ssh -j MARK --set-mark 20    # secure shell
$ipt -t mangle -A MYSHAPER-IN -p tcp --sport ssh -j MARK --set-mark 20    # secure shell
#$ipt -t mangle -A MYSHAPER-IN -p tcp --dport telnet -j MARK --set-mark 20 # telnet (ew...)
#$ipt -t mangle -A MYSHAPER-IN -p tcp --sport telnet -j MARK --set-mark 20 # telnet (ew...)
$ipt -t mangle -A MYSHAPER-IN -m mark --mark 0 -j MARK --set-mark 21      # избыточно - маркировать немаркированные
                                                                              # пакеты как 26 (низкий приоритет)

# Наконец, пропустить все эти пакеты через imq1
$ipt -t mangle -A MYSHAPER-IN -j IMQ --todev 1

# Конец ограничения входящего потока
#
####################################################