Under the cat described how to shape traffic in Linux and what you need to know.
We will perform traffic shaping using the tc utility from the iproute2 package.
Knowledge without which it is impossible to realize the fullness of traffic management in Linux:
Shape can only be outgoing traffic from the interface. (in connection with which there is a problem with nat, we will talk about it later). Suppose that there is a router between the "Internet" and the subscriber. Two network cards are stuck in the router: eth0 looks at the subscriber, and eth1 into the world. To limit the “download speed”, the rules of shaping are described on eth0, to limit the “return” - on eth1.
It is necessary to understand the difference between rate and ceil. Rate - guaranteed band skipping, Ceil - the maximum band a given class can receive, the rate can not exceed ceil
The rate and ceil parameters for the root class must match. Thus we define the total bandwidth.
The sum of the rates of descendant classes should not exceed the rate of the parent class. Of course you can not do this point, but then there may be problems with the provision of "guaranteed bandwidth."
Class IDs are in hexadecimal and must be between 2 and 2 ^ 16For intermediate classes it is not necessary to create disciplines and filters.Class identifiers within an interface must be unique.In a simple form of presentation, the traffic cutting algorithm looks like this:
1. Create a root discipline for the interface and specify the class where the unclassified traffic will fall.
2. Create a root class and determine the width of the channel.
3. Create a child class for subscriber shaping.
4. Create a shaping discipline for the subscriber class.
5. Create a filter to classify subscriber traffic.
In principle, everything is simple, but in real life you have to spend a lot of nerves to achieve the desired result.
One of the ways to achieve results without spending a lot of nerves is to use the htbinit script (you can take it from
sourceforge.net/projects/htbinit ). The syntax of configs is simple, creating classes is also easy.
To build configurations of average complexity is enough.
Example.
There is a local network, medium size. You need to limit the speed of subscribers according to the price list, address translation (NAT) occurs on another server.
')
Getting htbinit
debian:~# wget downloads.sourceforge.net/project/htbinit/HTB.init/0.8.5/htb.init-v0.8.5?use_mirror=surfnet
debian:~# mv htb.init-v0.8.5 /usr/local/sbin/
debian:~# cd /usr/local/sbin/
debian:/usr/local/sbin# mv htb.init-v0.8.5 htb.init
debian:/usr/local/sbin# chmod +x htb.init
By default, htbinit stores configs in the / etc / sysconfig / htb folder.
debian:~# mkdir -p /etc/sysconfig/htb
We create horse discipline for interface eth0 (the interface looks to the local network, "at the subscriber")
debian:~# touch /etc/sysconfig/htb/eth0
Specify which class will get traffic that does not fall into any of the filters
debian:~# mcedit /etc/sysconfig/htb/eth0
DEFAULT=42
Create a root class
debian:~# touch /etc/sysconfig/htb/eth0-2.root
debian:~# mcedit /etc/sysconfig/htb/eth0-2.root
RATE=100Mbit
You can not specify the CEIL, then it will be equal to the machine RATE.
Create a class for unclassified traffic.
debian:~# touch /etc/sysconfig/htb/eth0-2:42.root
debian:~# mcedit /etc/sysconfig/htb/eth0-2:42.root
RATE=4Kbit
We create the general client class. Let his ID be equal to “D” and we will allocate 10 Mbps for all subscribers.
debian:~# touch /etc/sysconfig/htb/eth0-2:D.sumamry_cilents_class
debian:~# mcedit /etc/sysconfig/htb/eth0-2:D.sumamry_cilents_class
RATE=10Mbit
Now you can do subscribers.
To limit the download speed of 512 kbps, subscriber Vasily needs to:
Create a class for the subscriber Basil. Let the client IDs begin with 255. It is very useful if you need to create some kind of "system" class.
debian:~# touch /etc/sysconfig/htb/eth0-2:D:100.client_login
The interface, class identifier and parent classes are described in the name of the config.
The entry eth0-2: D: 100.client_login means that
eth0- This class belongs to the interface eth0
2 Root class
D Parent class (In our case, the general client class)
100 Class Class ID
client_login The mnemonic component of the file name carries a meaning, is not used in class generation
The file name is generated this way:
1. Interface to which the class belongs.
2. Separator "-" (minus)
3. ID root class
4. Separator ":" (colon)
5. Parent class ID
6. Separator ":" (colon)
7. Client class ID
8. Separator "." (Dot)
9. The mnemonic component of the file name
Points 5 and 6 may be missing, depending on the shaping strategy you choose.
debian:~# mcedit /etc/sysconfig/htb/eth0-2:D:100.client_login
RATE=512Kbit
LEAF=sfq
RULE=0.0.0.0/0,client_ip/32
At least in the config should be 3 lines.
RATE - the band provided by the subscriber.
LEAF - a pointer to the fact that the class is final and it is necessary to create a discipline for it, in our case sfq (“pseudo-fair” distribution of the band)
RULE - we define what falls into the class. You can filter by IP addresses, subnets IP addresses, ports. The number of RULE entries may be more than one.
If we need to map traffic and natit on the same root, then instead of RULE you need to use MARK. The only thing you have to label packages.
An example of the script generating configs for htbinit in the configuration with NAT.
#!/bin/bash
# define variables
declare -a rules
inif="eth0"
outif="eth1"
vlan="10"
workdir="/home/netup"
vardir="${workdir}/var"
htb_dir="/etc/sysconfig/htb"
mysql="/usr/bin/mysql -h host -u user -ppassword -D base"
ipt="/usr/local/sbin/iptables"
IPT_UNLIM="UNLIM_"${vlan}
utm_rules="${vardir}/htb_rules_htb"
htb_rules="${vardir}/htb_rules_utm"
# prepare configs when you first start
[ -e ${htb_rules} ] || touch ${htb_rules}
# complete regeneration of configs
if [ "${1}" = "zopa" ];then
echo ""> ${htb_rules};
fi
# get data (id in hex system)
echo "select id,ip,mask,speed from view_shaper order by id;"|$mysql|sed '1d' > ${utm_rules};
# if you have reached the base and there is a difference with the current config
exp="${utm_rules} ${htb_rules}"
[ -s ${utm_rules} ] && if [ -n "`diff ${exp}`" ]
then
# delete configs need in which is no longer
for i in `diff ${exp}|awk '{if (NF==5)print $2}'|sort -n|uniq`
do
inshaper=${htb_dir}/${inif}-2:${i}.rule_${i};
[ -e ${inshaper} ] && rm ${inshaper};
outshaper=${htb_dir}/${outif}-2:${i}.rule_${i};
[ -e ${outshaper} ] && rm ${outshaper};
done;
# form new configs
rules=(`diff ${exp}|grep "<"|awk '{if (NF==5)print $2,$3,$4,$5}'`)
for i in `seq 1 4 ${#rules[@]}`;
do
id=${rules[$i-1]};
ip=${rules[$i]};
mask=${rules[$i+1]};
rate=${rules[$i+2]};
# Generate the names of configs
inshaper=${htb_dir}"/"${inif}-2:${id}.rule_${id};
outshaper=${htb_dir}/${outif}-2:${id}.rule_${id};
# Calculate brand for packages
inmark="0x"`echo "obase=16; $((0x${id}*2))"|bc`
outmark="0x"`echo "obase=16; $((0x${id}*2+1))"|bc`
# Remove "old" labeling rules
${ipt} -t mangle -S ${IPT_UNLIM}|grep -w ${ip}|awk -v ipt=${ipt} '{$1="-D";system(ipt" -t mangle "$0)}';
# Create config and rules on the internal interface
if [ -e ${inshaper} ]; then
#echo "RULE="0.0.0.0/0,"${ip}"/"${mask}">> ${inshaper}
${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip} -j MARK --set-mark ${inmark}
else
echo "RATE=4096bit" > ${inshaper}
echo "CEIL="$((${rate}*1024))"bit" >>${inshaper}
echo "LEAF=sfq" >> ${inshaper}
#echo "RULE=0.0.0.0/0,"${ip}"/"${mask}>> ${inshaper};
echo "MARK="${inmark}>> ${inshaper};
${ipt} -t mangle -A ${IPT_UNLIM} -d ${ip}/${mask} -j MARK --set-mark ${inmark}
fi
# Create config and rules on the internal interface
if [ -e $outshaper ]; then
#echo "RULE="${ip}"/"${mask}",0.0.0.0/0" >> ${outshaper}
${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip}/${mask} -j MARK --set-mark ${outmark}
else
echo "RATE=4096bit" > ${outshaper}
echo "CEIL="$((${rate}*1024))"bit" >> ${outshaper}
echo "LEAF=sfq" >> ${outshaper}
#echo "RULE="${ip}"/"${mask}",0.0.0.0/0" >> ${outshaper}
echo "MARK="${outmark}>> $outshaper;
${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip}/${mask} -j MARK --set-mark ${outmark}
fi
echo $ip
done;
cp ${exp}
[ -e /var/cache/htb.init ] && rm /var/cache/htb.init
/usr/local/sbin/htb.init restart
fi
For configurations up to 1000-1500 filters, this option is suitable. For larger ones, you already need to use fast hash filters, I will tell you about traffic prioritization in the next article.