Linux Traffic Shaper per IP – Iptables CLASSIFY

Linux Traffic Shaper per IP – Iptables CLASSIFY

Linux Traffic Shaper

Linux Traffic Shaper

В 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

9 comments on “Linux Traffic Shaper per IP – Iptables CLASSIFY

  1. баце евала отлично прекрасно. кефи. high five.
    не хваща някои пакети в кюто примерно тия дето излизат от самия рутер (icmp unreachable и разни от сорта)

  2. Здрасти,

    чул съм, че въпросната конфигурация не важи за NAT. Знаеш ли нещо подобно?
    Тези IP адреси къде се намират?? Можеш ли да дадеш примерен firewall, ама целия с всичките вериги.

    Мерси.

  3. Определено работи по леко от ingress, неудобството е че, ако имаш повече от един WAN трябва да се добавят допълнително правила за него. Също съм и изумен колко точно мери скороста – стрелката на speedtest направо се забива на зададената стойност без да се замисля въобще. Между другото и при мен е в комбинция с masquerade но с едно правило за всички и не виждам никакви отклонения …

  4. за 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

  5. Здравей , пробвах скрипта на opensuse но не иска да ограничи скороста , всичко съм настроил както е описано , има ли нещо по специално за сусето ?

  6. Не съм ползвал 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

  7. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.