18

We have a transparent proxy setup. I tried looking for traffic shaping in Linux, and all I could find online was to limit traffic by interface (eth0/eth1...).

I need to limit the bandwidth (never exceeding a specific limit) by IP address or IP ranges and I can't find a way to do that.

Is there any way to do that?

3 Answers 3

22

The traffic shaping layer of the kernel is, basically, a packet scheduler attached to your network card. So one traffic shaping policy applies to one network card.

What you can do, in your case, is to create a list of IP and bandwidth attached, and then, for each IP, you create:

  • One traffic shaping rule identified by a classid
  • One netfilter rule that will mark packets to a specific mark value
  • One Filter that will bind that packets marks to the classid, thus applying the traffic control rule to the specified packets.

The example given by @Zoredache works, but I personnally prefer to use Netfilter capability instead of TC to filter packets, and HTB instead of CBQ for the shapping algorithm. So you can try something like this (requires Bash 4 for associative arrays):

#! /bin/bash
NETCARD=eth0
MAXBANDWIDTH=100000

# reinit
tc qdisc del dev $NETCARD root handle 1
tc qdisc add dev $NETCARD root handle 1: htb default 9999

# create the default class
tc class add dev $NETCARD parent 1:0 classid 1:9999 htb rate $(( $MAXBANDWIDTH ))kbit ceil $(( $MAXBANDWIDTH ))kbit burst 5k prio 9999

# control bandwidth per IP
declare -A ipctrl
# define list of IP and bandwidth (in kilo bits per seconds) below
ipctrl[192.168.1.1]="256"
ipctrl[192.168.1.2]="128"
ipctrl[192.168.1.3]="512"
ipctrl[192.168.1.4]="32"

mark=0
for ip in "${!ipctrl[@]}"
do
    mark=$(( mark + 1 ))
    bandwidth=${ipctrl[$ip]}

    # traffic shaping rule
    tc class add dev $NETCARD parent 1:0 classid 1:$mark htb rate $(( $bandwidth ))kbit ceil $(( $bandwidth ))kbit burst 5k prio $mark

    # netfilter packet marking rule
    iptables -t mangle -A INPUT -i $NETCARD -s $ip -j CONNMARK --set-mark $mark

    # filter that bind the two
    tc filter add dev $NETCARD parent 1:0 protocol ip prio $mark handle $mark fw flowid 1:$mark

    echo "IP $ip is attached to mark $mark and limited to $bandwidth kbps"
done

#propagate netfilter marks on connections
iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark

-- edit: forgot the default class and to propagate marks at the end of the script.

5
  • umm.. how to add default bandwidth limit for those that not on the list?
    – Kokizzu
    Feb 28, 2013 at 6:13
  • You used $mark as prio definition. Wouldn't be better to use the same priority to all?
    – motobói
    May 15, 2014 at 15:48
  • if I change "iptables -t mangle -A INPUT" to "iptables -t mangle -A OUTPUT" could I control the rate from my server to a particular IP?? Jul 9, 2015 at 1:07
  • how do I restore settings after this ? May 27, 2016 at 7:50
  • Cant' seem to make this work, writing commands manually without loop for a single ip.
    – papar
    Nov 29, 2017 at 10:26
5

Something like this worked for me to limit a contractor's web cam to a limited amount of bandwidth. Check out the man page for tc for details.

#!/bin/bash
set -x

DEV=eth0
export DEV

tc qdisc del dev $DEV root
tc qdisc del dev $DEV root
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit

# setup a class to limit to 1500 kilobits/s
tc class add dev $DEV parent 1: classid 1:1 cbq rate 1500kbit \
   allot 1500 prio 5 bounded isolated

# add traffic from 10.2.1.37 to that class
tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \
   match ip src 10.2.1.37 flowid 1:1
2
  • 3
    CBQ is a bit abandonned... you would find HTB much easier to use and obtain the same result Oct 16, 2010 at 10:39
  • 1
    No need to export DEV if it is only used in this script.... Jan 1, 2016 at 8:38
1

I'm not sure I understand your question correctly.

Transparent proxying (as in Squid for HTTP) is used to control mostly incoming data. While traffic shaping is used to control outgoing data.

You need to provide more details. If you have a lot of workstations behind a HTTP proxy and are trying to limit their download speeds, you'd better go for something like Squid + delay pools.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .