Пытаюсь ограничить трафик по 80 порту. Вот скрипт:DETH="eth3"
tc qdisc del dev eth0 root
tc qdisc add dev $DETH root handle 1: htb
tc class add dev $DETH parent 1: classid 1:1 htb rate 11mbittc class add dev $DETH parent 1:1 classid 1:100 htb rate 5mbit ceil 7mbit
<------>tc class add dev $DETH parent 1:100 classid 1:110 htb rate 1mbit ceil 2mbit
<------>tc class add dev $DETH parent 1:100 classid 1:120 htb rate 1mbit ceil 4mbit
<------>
<------>tc qdisc add dev $DETH parent 1:110 handle 110: sfq perturb 10
<------>tc qdisc add dev $DETH parent 1:120 handle 120: sfq perturb 10
tc filter add dev $DETH parent 1: protocol ip prio 0 u32 match ip sport 80 0xffff classid 1:120
В итоге видно как трафик идёт по цепочкам, но канал не режется и идёт с полной скоростью. Если я задаю правило "tc filter add dev $DETH parent 1: protocol ip prio 0 u32 match ip dst 192.168.1.9 classid 1:110" то по IP режется весь трафик, что мне конечно же не нужно.
Правило которое написано во всех манах и руководствах(в том числе на английском языке) почему то не работает. Если я совмещаю правило порта и IP адреса в одно правило, то эффект пропадает. Видно как пакеты проходят по всем цепочкам, но результат тот же = трафик идёт во всю ширину канала.
Вот как проходят пакеты при работе правила "tc filter add dev $DETH parent 1: protocol ip prio 0 u32 match ip sport 80 0xffff classid 1:120":
# ./stat.sh
class htb 1:110 parent 1:100 leaf 110: prio 0 quantum 12500 rate 1000Kbit ceil 2000Kbit burst 1600b/8 mpu 0b overhead 0b cburst 1600b/8 mpu 0b overhead 0b level 0
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 200000 ctokens: 100000class htb 1:1 root rate 11000Kbit ceil 11000Kbit burst 1597b/8 mpu 0b overhead 0b cburst 1597b/8 mpu 0b overhead 0b level 7
Sent 351570 bytes 460 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 17359 ctokens: 17359class htb 1:100 parent 1:1 rate 5000Kbit ceil 7000Kbit burst 1600b/8 mpu 0b overhead 0b cburst 1598b/8 mpu 0b overhead 0b level 6
Sent 351570 bytes 460 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 130 borrowed: 0 giants: 0
tokens: 38204 ctokens: 27281class htb 1:120 parent 1:100 leaf 120: prio 0 quantum 12500 rate 1000Kbit ceil 4000Kbit burst 1600b/8 mpu 0b overhead 0b cburst 1600b/8 mpu 0b overhead 0b level 0
Sent 351570 bytes 460 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 324 borrowed: 130 giants: 0
tokens: 191000 ctokens: 47750
Вроде как начинаю понимать в чём проблема, но решить пока что не могу.
Дело в том что адрес в локальной сети которому я хочу обрезать канал по порту 80, находится под NAT и чтоб TC его видел, пакеты нужно промаркировать.
Уже по всякому пробовал, чуть ли не в каждую цепочку сунул маркировку пакетов на 80й порт, но эффекта нет.
Применял вот такие правила:
-A PREROUTING -p tcp -m tcp --sport 80 -j MARK --set-mark 47
-A PREROUTING -p tcp -m tcp --dport 80 -j MARK --set-mark 47
-A POSTROUTING -p tcp -m tcp --sport 80 -j MARK --set-mark 47
-A POSTROUTING -p tcp -m tcp --dport 80 -j MARK --set-mark 47
-A FORWARD -p tcp -m tcp --sport 80 -j MARK --set-mark 47
-A FORWARD -p tcp -m tcp --dport 80 -j MARK --set-mark 47В таблицах mangel, nat и filter.
Ничего не помогает. Видно что пакеты маркируются iptables, но TC их не видит.
> Вроде как начинаю понимать в чём проблема, но решить пока что не
> могу.
> Дело в том что адрес в локальной сети которому я хочу обрезать
> канал по порту 80, находится под NAT и чтоб TC его
> видел, пакеты нужно промаркировать.
> Уже по всякому пробовал, чуть ли не в каждую цепочку сунул маркировку
> пакетов на 80й порт, но эффекта нет.
> Применял вот такие правила:...
> В таблицах mangel, nat и filter.
> Ничего не помогает. Видно что пакеты маркируются iptables, но TC их не
> видит.Вот пример вроде рабочий с одного дачного шлюза:
>>BEGIN RC.SHAPER.CONF
# Devices & params
SH1_IMQ_IN="imq0"
SH1_IMQ_OUT="imq1"SH1_IFS_IN="eth0"
SH1_IFS_OUT="eth0"SH2_IMQ_IN="imq2"
SH2_IMQ_OUT="imq3"SH2_IFS_IN="eth1"
SH2_IFS_OUT="eth1"
SH1_CTRL="22 53 54322"
SH1_COMM="110 995 3373 5190"
SH1_SURF="25 80 443 465 3128 8000 8080"
SH1_OUT_DISCIPLINE="esfq limit 64 depth 256 hash dst perturb 16"
SH1_IN_DISCIPLINE="esfq limit 64 depth 256 hash dst perturb 16"SH2_CTRL="22 53 54322"
SH2_COMM="110 995 3373 5190"
SH2_SURF="25 80 443 465 3128 8000 8080"##SH2_OUT_DISCIPLINE="esfq limit 64 depth 256 hash dst perturb 16"
SH2_OUT_DISCIPLINE="esfq limit 64 depth 256 hash src perturb 16"
SH2_IN_DISCIPLINE="esfq limit 64 depth 256 hash dst perturb 16"# Rate to quantum
# req.: MTU < quantum < 60000
# com.: quantum = RATE / R2Q
# quantum is small if: RATE / R2Q < MTU, try --R2Q or ++RATE
# quantum is big if: RATE / R2Q > 60000, try ++R2Q or --RATESH1_R2Q="r2q 24"
SH1_RATEUP="24576"
SH1_RATEDN="24576"SH1_RATE_OUT0=256
SH1_RATE_OUT1=256
SH1_RATE_OUT2=5120
SH1_RATE_OUT3=1024
SH1_RATE_OUT4=$[$SH1_RATEUP - $SH1_RATE_OUT0 - $SH1_RATE_OUT1 - $SH1_RATE_OUT2 - $SH1_RATE_OUT3]SH1_RATE_IN0=256
SH1_RATE_IN1=256
SH1_RATE_IN2=5120
SH1_RATE_IN3=1024
SH1_RATE_IN4=$[$SH1_RATEDN - $SH1_RATE_IN0 - $SH1_RATE_IN1 - $SH1_RATE_IN2 - $SH1_RATE_IN3]SH2_R2Q="r2q 3"
SH2_RATEUP="4096"
SH2_RATEDN="4096"SH2_RATE_OUT0=256
SH2_RATE_OUT1=512
SH2_RATE_OUT2=1024
SH2_RATE_OUT3=1024
SH2_RATE_OUT4=$[$SH2_RATEUP - $SH2_RATE_OUT0 - $SH2_RATE_OUT1 - $SH2_RATE_OUT2 - $SH2_RATE_OUT3]SH2_RATE_IN0=256
SH2_RATE_IN1=512
SH2_RATE_IN2=1024
SH2_RATE_IN3=1024
SH2_RATE_IN4=$[$SH2_RATEDN - $SH2_RATE_IN0 - $SH2_RATE_IN1 - $SH2_RATE_IN2 - $SH2_RATE_IN3]
>>END RC.SHAPER.CONFотрывок из RC.SHAPER
#!/bin/bash
. /etc/rc.d/rc.fw.conf
. /etc/rc.d/rc.shaper.confPATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin
export PATHIPT=/usr/sbin/iptables
LBL_VIP=10
LBL_CTL=20
LBL_STD=30
LBL_AVG=40
LBL_DEF=70shaper_status() {
echo "======================================[QDISC]======================================"
echo "qdisc show dev $SH1_IMQ_IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s qdisc show dev $SH1_IMQ_IN
echo "qdisc show dev $SH1_IMQ_OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s qdisc show dev $SH1_IMQ_OUTecho "qdisc show dev $SH2_IMQ_IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s qdisc show dev $SH2_IMQ_IN
echo "qdisc show dev $SH2_IMQ_OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s qdisc show dev $SH2_IMQ_OUTecho "======================================[CLASS]======================================"
echo "SHAPER >>>> 1 >>>> IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s class show dev $SH1_IMQ_IN
echo "SHAPER >>>> 1 >>>> OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s class show dev $SH1_IMQ_OUTecho "SHAPER >>>> 2 >>>> IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s class show dev $SH2_IMQ_IN
echo "SHAPER >>>> 2 >>>> OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s class show dev $SH2_IMQ_OUT
echo "=====================================[FILTER]====================================="echo "SHAPER 1 IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s filter show dev $SH1_IMQ_IN
echo "SHAPER 1 OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s filter show dev $SH1_IMQ_OUTecho "SHAPER 2 IN >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s filter show dev $SH2_IMQ_IN
echo "SHAPER 2 OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
tc -s filter show dev $SH2_IMQ_OUTecho "======================================[RULES]======================================"
$IPT -t mangle -L SHAPER1-IN -v -x -n 2> /dev/null
$IPT -t mangle -L SHAPER1-OUT -v -x -n 2> /dev/null$IPT -t mangle -L SHAPER2-IN -v -x -n 2> /dev/null
$IPT -t mangle -L SHAPER2-OUT -v -x -n 2> /dev/null
}...
shaper2_outstart() {
ip link set $SH2_IMQ_OUT up
tc qdisc add dev $SH2_IMQ_OUT handle 1: root htb default $LBL_DEF $SH2_R2Q
tc class add dev $SH2_IMQ_OUT parent 1: classid 1:1 htb rate ${SH2_RATEUP}kbit ceil ${SH2_RATEUP}kbit
tc class add dev $SH2_IMQ_OUT parent 1:1 classid 1:$LBL_VIP htb rate ${SH2_RATE_OUT0}kbit ceil ${SH2_RATEUP}kbit prio 0
tc class add dev $SH2_IMQ_OUT parent 1:1 classid 1:$LBL_CTL htb rate ${SH2_RATE_OUT1}kbit ceil ${SH2_RATEUP}kbit prio 1
tc class add dev $SH2_IMQ_OUT parent 1:1 classid 1:$LBL_STD htb rate ${SH2_RATE_OUT2}kbit ceil ${SH2_RATEUP}kbit prio 2
tc class add dev $SH2_IMQ_OUT parent 1:1 classid 1:$LBL_AVG htb rate ${SH2_RATE_OUT3}kbit ceil ${SH2_RATEUP}kbit prio 3
tc class add dev $SH2_IMQ_OUT parent 1:1 classid 1:$LBL_DEF htb rate ${SH2_RATE_OUT4}kbit ceil ${SH2_RATEUP}kbit prio 6
tc qdisc add dev $SH2_IMQ_OUT parent 1:$LBL_VIP handle $LBL_VIP: $SH2_OUT_DISCIPLINE
tc qdisc add dev $SH2_IMQ_OUT parent 1:$LBL_CTL handle $LBL_CTL: $SH2_OUT_DISCIPLINE
tc qdisc add dev $SH2_IMQ_OUT parent 1:$LBL_STD handle $LBL_STD: $SH2_OUT_DISCIPLINE
tc qdisc add dev $SH2_IMQ_OUT parent 1:$LBL_AVG handle $LBL_AVG: $SH2_OUT_DISCIPLINE
tc qdisc add dev $SH2_IMQ_OUT parent 1:$LBL_DEF handle $LBL_DEF: $SH2_OUT_DISCIPLINE
tc filter add dev $SH2_IMQ_OUT parent 1:0 protocol ip prio 0 handle $LBL_VIP fw flowid 1:$LBL_VIP
tc filter add dev $SH2_IMQ_OUT parent 1:0 protocol ip prio 1 handle $LBL_CTL fw flowid 1:$LBL_CTL
tc filter add dev $SH2_IMQ_OUT parent 1:0 protocol ip prio 2 handle $LBL_STD fw flowid 1:$LBL_STD
tc filter add dev $SH2_IMQ_OUT parent 1:0 protocol ip prio 3 handle $LBL_AVG fw flowid 1:$LBL_AVG
tc filter add dev $SH2_IMQ_OUT parent 1:0 protocol ip prio 6 handle $LBL_DEF fw flowid 1:$LBL_DEF
$IPT -t mangle -N SHAPER2-OUT
$IPT -t mangle -A POSTROUTING -o $SH2_IFS_OUT -j SHAPER2-OUT
#$IPT -t mangle -A SHAPER2-OUT -p icmp -j MARK --set-mark $LBL_VIP
$IPT -t mangle -A SHAPER2-OUT -p all -m length --length :128 -j MARK --set-mark $LBL_VIPfor ctrl_out in $SH2_CTRL
do
$IPT -t mangle -A SHAPER2-OUT -p tcp --dport $ctrl_out -j MARK --set-mark $LBL_CTL
$IPT -t mangle -A SHAPER2-OUT -p tcp --sport $ctrl_out -j MARK --set-mark $LBL_CTL
donefor comm_out in $SH2_COMM
do
$IPT -t mangle -A SHAPER2-OUT -p tcp --dport $comm_out -j MARK --set-mark $LBL_STD
$IPT -t mangle -A SHAPER2-OUT -p tcp --sport $comm_out -j MARK --set-mark $LBL_STD
done
$IPT -t mangle -A SHAPER2-OUT -p sctp -j MARK --set-mark $LBL_STDfor surf_out in $SH2_SURF
do
$IPT -t mangle -A SHAPER2-OUT -p tcp --dport $surf_out -j MARK --set-mark $LBL_AVG
$IPT -t mangle -A SHAPER2-OUT -p tcp --sport $surf_out -j MARK --set-mark $LBL_AVG
done$IPT -t mangle -A SHAPER2-OUT -m mark --mark 0 -j MARK --set-mark $LBL_DEF
$IPT -t mangle -A SHAPER2-OUT -j IMQ --todev 3####################################################
echo "Outbound shaping added($SH2_IMQ_OUT), rate: ${SH2_RATEUP}Kbit/sec."
echo "Default rate: ${SH2_RATE_OUT4}Kbit/sec."
}
> Вроде как начинаю понимать в чём проблема, но решить пока что не
> могу.
> Дело в том что адрес в локальной сети которому я хочу обрезать
> канал по порту 80, находится под NAT и чтоб TC его
> видел, пакеты нужно промаркировать.
> Уже по всякому пробовал, чуть ли не в каждую цепочку сунул маркировку
> пакетов на 80й порт, но эффекта нет.
> Применял вот такие правила:В дополнение к предыдущему посту:
из rc.shaper...
shaper_start() {
modprobe imq numdevs=4
modprobe ipt_IMQ#shaper1_instart
shaper1_outstart#shaper2_instart
shaper2_outstart}
shaper_stop() {tc qdisc del dev $SH1_IMQ_IN root 2> /dev/null > /dev/null
tc qdisc del dev $SH1_IMQ_OUT root 2> /dev/null > /dev/nulltc qdisc del dev $SH2_IMQ_IN root 2> /dev/null > /dev/null
tc qdisc del dev $SH2_IMQ_OUT root 2> /dev/null > /dev/null$IPT -t mangle -D PREROUTING -i $SH1_IFS_IN -j IMQ --todev 0 2> /dev/null > /dev/null
$IPT -t mangle -D PREROUTING -i $SH2_IFS_IN -j IMQ --todev 2 2> /dev/null > /dev/null$IPT -t mangle -F SHAPER1-IN 2> /dev/null > /dev/null
$IPT -t mangle -X SHAPER1-IN 2> /dev/null > /dev/null$IPT -t mangle -F SHAPER2-IN 2> /dev/null > /dev/null
$IPT -t mangle -X SHAPER2-IN 2> /dev/null > /dev/null
$IPT -t mangle -D POSTROUTING -o $SH1_IFS_OUT -j IMQ --todev 1 2> /dev/null > /dev/null
$IPT -t mangle -D POSTROUTING -o $SH2_IFS_OUT -j IMQ --todev 3 2> /dev/null > /dev/null$IPT -t mangle -F SHAPER1-OUT 2> /dev/null > /dev/null
$IPT -t mangle -X SHAPER1-OUT 2> /dev/null > /dev/null$IPT -t mangle -F SHAPER2-OUT 2> /dev/null > /dev/null
$IPT -t mangle -X SHAPER2-OUT 2> /dev/null > /dev/nullip link set $SH1_IMQ_IN down 2> /dev/null > /dev/null
ip link set $SH1_IMQ_OUT down 2> /dev/null > /dev/nullip link set $SH2_IMQ_IN down 2> /dev/null > /dev/null
ip link set $SH2_IMQ_OUT down 2> /dev/null > /dev/nullrmmod imq 2> /dev/null > /dev/null
}
...
case "$1" in
'start')
shaper_start
;;
'stop')
shaper_stop
;;
'restart')
shaper_restart
;;
'status')
shaper_status
;;
'halt')
shaper_halt
;;
*)
echo "usage $0 start|stop|restart|status|halt"
esac
Всё заработало, когда я понял что маркировать нужно все пакеты с интерфейса а не только 80й порт. Теперь думаю над тем как разбалансировать между тремя локальными интерфейсами. Т.е. с интерфейса интернет направляю на 3 интерфейса в локальную сеть, необходимо балансировать загруженность канала интернета на 3 интерфейса локалки.