Linux Traffic Shaper per IP – Iptables CLASSIFY
В Linux има различни начини според ситуацията разбира се за управление на трафика (Linux Traffic Shaper) по ип адрес. Един от вариантите който аз предпочитам е маркиране на пакети с iptables. Принципно има два вида маркиране с iptables. С IPMARK и CLASSIFY. IPMARK използва опашката filter в tc a CLASSIFY class, така filter отпада и именно поради тази причина предпочитам CLASSIFY.
add interface – Linux Traffic Shaper
tc qdisc add dev eth0 root handle 1: htb default 1 tc qdisc add dev eth1 root handle 1: htb default 1 |
host 1 – speed 1
iptables -t mangle -A POSTROUTING -d 192.168.0.2 -j CLASSIFY --set-class 1:100 iptables -t mangle -A POSTROUTING -s 192.168.0.2 -j CLASSIFY --set-class 1:101 tc class add dev eth0 parent 1: classid 1:100 htb rate 10Mbit tc qdisc add dev eth0 parent 1:100 handle 100: sfq perturb 10 tc class add dev eth1 parent 1: classid 1:101 htb rate 10Mbit tc qdisc add dev eth1 parent 1:101 handle 101: sfq perturb 10 |
host 2 – speed 2
iptables -t mangle -A POSTROUTING -d 192.168.0.3 -j CLASSIFY --set-class 1:102 iptables -t mangle -A POSTROUTING -s 192.168.0.3 -j CLASSIFY --set-class 1:103 tc class add dev eth0 parent 1: classid 1:102 htb rate 20Mbit tc qdisc add dev eth0 parent 1:102 handle 102: sfq perturb 10 tc class add dev eth1 parent 1: classid 1:103 htb rate 20Mbit tc qdisc add dev eth1 parent 1:103 handle 103: sfq perturb 10 |
Script – Linux Traffic Shaper
Ако се стигне до там, че трябва да управляваме няколкостотин адреса ще ни трябва скрипт. Решението на тази задача съм го изпълнил с два файла. Конфигурационен в който съхраняваме адресите и скоростите с които ще ги ограничаваме – /etc/ipclient
192.168.0.2 speed1
192.168.0.3 speed2
#192.168.0.4 speed1
192.168.0.5 speed1 |
И изпълним файл, самият скрипт – /etc/init.d/netscript
DB=/etc/ipclient DEV1=eth0 DEV2=eth1 SPEED1_IN=10Mbit SPEED1_OUT=10Mbit SPEED2_IN=20Mbit SPEED2_OUT=20Mbit echo "remove FIREWAL rules" iptables -F -t mangle echo "start GLOBAL TRAFFIC SHAPER rules" tc qdisc del dev $DEV1 root 2>/dev/null tc qdisc add dev $DEV1 root handle 1: htb r2q 625 default 65 tc class add dev $DEV1 parent 1: classid 1:1 htb rate 1000Mbit tc qdisc del dev $DEV2 root 2>/dev/null tc qdisc add dev $DEV2 root handle 1: htb r2q 625 default 65 tc class add dev $DEV2 parent 1: classid 1:1 htb rate 1000Mbit echo "start TRAFFIC SHAPER IP speed1" ADDR=$(grep -v \# $DB | grep speed1 | awk '{ print $1 }') for IP in $ADDR; do MARK=$(cat $DB | grep -w -n $IP | cut -d":" -f1) UP=$(($MARK + 1000)) DOWN=$(($MARK + 3000)) iptables -t mangle -A POSTROUTING -d $IP -j CLASSIFY --set-class 1:$UP tc class add dev $DEV1 parent 1:1 classid 1:$UP htb rate $SPEED1_IN tc qdisc add dev $DEV1 parent 1:$UP handle $UP: sfq iptables -t mangle -A POSTROUTING -s $IP -j CLASSIFY --set-class 1:$DOWN tc class add dev $DEV2 parent 1:1 classid 1:$DOWN htb rate $SPEED1_OUT tc qdisc add dev $DEV2 parent 1:$DOWN handle $DOWN: sfq done; echo "start TRAFFIC SHAPER IP speed2" ADDR=$(grep -v \# $DB | grep speed2 | awk '{ print $1 }') for IP in $ADDR; do MARK=$(cat $DB | grep -w -n $IP | cut -d":" -f1) UP=$(($MARK + 1000)) DOWN=$(($MARK + 3000)) iptables -t mangle -A POSTROUTING -d $IP -j CLASSIFY --set-class 1:$UP tc class add dev $DEV1 parent 1:1 classid 1:$UP htb rate $SPEED2_IN tc qdisc add dev $DEV1 parent 1:$UP handle $UP: sfq iptables -t mangle -A POSTROUTING -s $IP -j CLASSIFY --set-class 1:$DOWN tc class add dev $DEV2 parent 1:1 classid 1:$DOWN htb rate $SPEED2_OUT tc qdisc add dev $DEV2 parent 1:$DOWN handle $DOWN: sfq done; |
Linux Traffic Shaper per IP – Iptables CLASSIFY
баце евала отлично прекрасно. кефи. high five.
не хваща някои пакети в кюто примерно тия дето излизат от самия рутер (icmp unreachable и разни от сорта)
Здрасти,
чул съм, че въпросната конфигурация не важи за NAT. Знаеш ли нещо подобно?
Тези IP адреси къде се намират?? Можеш ли да дадеш примерен firewall, ама целия с всичките вериги.
Мерси.
Правилата mangle/CLASSIFY просто маркират пакетите а tc взима тази информация за да ограничава скороста тоест – няма общо с NAT и няма проблем да работят заедно.
Виж пример: http://itservice-bg.net/wp-content/uploads/2012/12/shaper-classify.png
Определено работи по леко от ingress, неудобството е че, ако имаш повече от един WAN трябва да се добавят допълнително правила за него. Също съм и изумен колко точно мери скороста – стрелката на speedtest направо се забива на зададената стойност без да се замисля въобще. Между другото и при мен е в комбинция с masquerade но с едно правило за всички и не виждам никакви отклонения …
за kristian kirilov
изпълним файл: /etc/init.d/netscript
###################################################
#!/bin/bash
clear
LOG=/var/log/router.log
DB=/etc/ipclient
DEV1=eth0
DEV2=eth1
SPEED1_IN=50Mbit
SPEED1_OUT=30Mbit
SPEED2_IN=70Mbit
SPEED2_OUT=45Mbit
BURST=2Mbit
TUN=”1 2 3 4″;
echo “check duplicate LAN ip address”
DUPLICATE=$(cat $DB | awk ‘{ print $1 }’ | cut -d”#” -f2 | sort | uniq -d)
for i in ${DUPLICATE}; do
if [ “$DUPLICATE” = “$DUPLICATE” ]; then
echo “Duplicate IP address: ${i} Script will not run”
exit 1
fi
done;
echo “flush GLOBAL FIREWALL rules”
iptables -F
iptables -F -t nat
iptables -F -t mangle
iptables -X
iptables -X -t nat
iptables -X -t mangle
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
echo “start NAT clients rules”
ADDR=$(grep -v \# $DB | grep speed | awk ‘{ print $1 }’)
for IP in $ADDR; do
WAN=$(grep -v \# $DB | grep -w $IP | awk ‘{ print $2 }’)
iptables -t nat -A POSTROUTING -s $IP -o $DEV2 -j SNAT –to $WAN
iptables -t nat -A PREROUTING -d $WAN -i $DEV2 -j DNAT –to $IP
done;
echo “start table T1 clients rules”
ADDR=$(grep -v \# $DB | grep T1 | awk ‘{ print $1 }’)
for IP in $ADDR; do
iptables -A PREROUTING -t mangle -s $IP -j MARK –set-mark 101
done;
echo “start GLOBAL TRAFFIC SHAPER rules”
tc qdisc del dev $DEV1 root 2>/dev/null
tc qdisc add dev $DEV1 root handle 1: htb r2q 625 default 65
tc class add dev $DEV1 parent 1: classid 1:1 htb rate 1000Mbit
tc qdisc del dev $DEV2 root 2>/dev/null
tc qdisc add dev $DEV2 root handle 1: htb r2q 625 default 65
tc class add dev $DEV2 parent 1: classid 1:1 htb rate 1000Mbit
echo “start TRAFFIC SHAPER IP speed1″
ADDR=$(grep -v \# $DB | grep speed1 | awk ‘{ print $1 }’)
for IP in $ADDR; do
MARK=$(cat $DB | grep -w -n $IP | cut -d”:” -f1)
UP=$(($MARK + 1000))
DOWN=$(($MARK + 3000))
iptables -t mangle -A POSTROUTING -d $IP -j CLASSIFY –set-class 1:$UP
tc class add dev $DEV1 parent 1:1 classid 1:$UP htb rate $SPEED1_IN
tc qdisc add dev $DEV1 parent 1:$UP handle $UP: sfq
iptables -t mangle -A POSTROUTING -s $IP -j CLASSIFY –set-class 1:$DOWN
tc class add dev $DEV2 parent 1:1 classid 1:$DOWN htb rate $SPEED1_OUT
tc qdisc add dev $DEV2 parent 1:$DOWN handle $DOWN: sfq
done;
echo “start TRAFFIC SHAPER IP speed2″
ADDR=$(grep -v \# $DB | grep speed2 | awk ‘{ print $1 }’)
for IP in $ADDR; do
MARK=$(cat $DB | grep -w -n $IP | cut -d”:” -f1)
UP=$(($MARK + 1000))
DOWN=$(($MARK + 3000))
iptables -t mangle -A POSTROUTING -d $IP -j CLASSIFY –set-class 1:$UP
tc class add dev $DEV1 parent 1:1 classid 1:$UP htb rate $SPEED2_IN
tc qdisc add dev $DEV1 parent 1:$UP handle $UP: sfq
iptables -t mangle -A POSTROUTING -s $IP -j CLASSIFY –set-class 1:$DOWN
tc class add dev $DEV2 parent 1:1 classid 1:$DOWN htb rate $SPEED2_OUT
tc qdisc add dev $DEV2 parent 1:$DOWN handle $DOWN: sfq
done;
echo “start TRAFFIC SHAPER tunnels”
for i in $TUN; do
iptables -t mangle -A POSTROUTING -o tun$i -j CLASSIFY –set-class 1:600$i
tc qdisc del dev tun$i root 2>/dev/null
tc qdisc add dev tun$i root handle 1: htb r2q 625 default 65
tc class add dev tun$i parent 1: classid 1:600$i htb rate $SPEED1_IN
tc qdisc add dev tun$i parent 1:600$i handle 600$i: sfq
tc qdisc del dev tun$i handle ffff: ingress 2>/dev/null
tc qdisc add dev tun$i handle ffff: ingress
tc filter add dev tun$i parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 \
police rate $SPEED1_OUT burst $BURST drop flowid :1
iptables -t mangle -A POSTROUTING -p tcp –tcp-flags SYN,RST SYN -o tun$i -j TCPMSS –clamp-mss-to-pmtu
done;
echo “start LOGING”
SP1=$(grep -v \# $DB | grep speed1 | wc -l)
SP2=$(grep -v \# $DB | grep speed2 | wc -l)
T1=$(grep -v \# $DB | grep T1 | wc -l)
ALL=$(grep -v \# $DB | wc -l)
echo “$(date +’%F %T’)” netscript Sp1:$SP1 Sp2:$SP2 T1:$T1 All:$ALL Conn:”$(conntrack -C)” >> $LOG
echo Sp1:$SP1 Sp2:$SP2 T1:$T1 All:$ALL
###############################################
конфигурационен файл: /etc/ipclient
10.123.6.36 93.155.130.80 speed1
10.124.6.6 93.155.130.81 speed1
10.126.9.17 93.155.130.82 speed2
10.128.2.8 93.155.130.83 speed1
10.121.8.6 93.155.130.84 speed2
Здравей , пробвах скрипта на opensuse но не иска да ограничи скороста , всичко съм настроил както е описано , има ли нещо по специално за сусето ?
Не съм ползвал Suse досега и нямам представа а дали работи трябва да провериш вървят ли пакети през веригите с:
iptables -nvL -t mangle
tc qdisc show
tc -s qdisc ls dev eth0
tc -s class show dev eth0
tc -s -d class show dev eth0
Както и за eth1
real nice tutorial. I might need some guidance, please.
i have a server with IP 62.38.1.100 and it runs OPEN VPN server. Everyone who gets connected to the OPENVPN server they do get 10.0.8.0/24 IP with 10.0.8.1 to be the gateway.
i would like to limit the speed of the connected machines to 1024Kbps up/down. the server has only one network interface eth0 and tun0 is the virtual interface for the openvpn.
супер бачка :)))