Blog Post View

Denial of service attacks are major nuisance for web hosts, and as a web host you'll have to take every measure to protect your resources from DoS attacks. Our APF, BFD, DDoS and RootKit article describes Linux utilities available to protect from DDoS attack, and also explains installation procedures. This article supplements above article by providing means to control traffic (bandwidth shaping) with Linux "tc" command so that no single machine can waste the entire network bandwidth.

What is Traffic Shaping?

Traffic Shaping (a.k.a Bandwidth Shaping or Packet Shaping) is an attempt to control network traffic by prioritizing network resources and guarantee certain bandwidth based on predefined policy rules. Traffic shaping uses concepts of traffic classification, policy rules, queue disciplines and quality of service (QoS).

Why implement Traffic Shaping?

Network bandwidth is an expensive resource that is being shared among many parties of an organization, and some applications require guaranteed bandwidth and priority. Traffic shaping lets you (1) control network services, (2) limit bandwidths and (3) guarantee Quality Of Service (QoS). Intelligently managed traffic shaping improves network latency, service availablity and bandwidth utilization.

What is Queue Discipline?

A queue discipline (qdisc) is rules that determine the order in which arrivals are serviced. Immagine standing in a restraurant to be seated, and waiting in an emergency room to be serviced by a physician. They both have people waiting in a queue that needs to be serviced, but have different strategies for clearing them.

Restaurants typically use first-in-first-out (FIFO) strategy with an exception when tables with number of seats do not exist for large number of customers. Customers are generally serviced in the order that they've arrived in the queue, or when the table with number of seats available. On the other hand, emergency queue requires different strategy. Regardless of order in which patients arrive, someone in a critical condition requires most attention and then someone with urgent condition. This is just examples of how queues are handled in the real life scenarios, but traffic shaping requires a lot more disciplines (rules) for clearing traffic queues.

Software Requirements

· Linux RPM package called 'iproute' is required.
· Traffic control options (including netlink support) have to enabled on the kernel build in order for certain parts of 'iproute' to function.
· Linux kernels version 2.4 (and above) have most traffic control options turned on as a default. To explore your configuration, try running the following commands. If you can see the command responses below, you have a basic configuration setup.

# ip link list
1: lo:  mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:06:5b:8d:13:a0 brd ff:ff:ff:ff:ff:ff
# ip address show
1: lo:  mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet brd scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:06:5b:8d:13:a0 brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth0
    inet6 fe80::206:5bff:fe8d:13a0/64 scope link
       valid_lft forever preferred_lft forever
# ip route show dev eth0  proto kernel  scope link  src default via dev eth0

Bandwidth Management (Traffic Control)

Linux kernel 2.2 (and above) provides bandwidth management functionality compatible to high-end (dedicated) hardware solution. Linux does offer bandwidth management capability with tc command-line utility, with iptables and iproute2 packages.

We've written a small bash shell script to automate bandwidth shaping function on a linux machine. The downloadable source code is used to limit bandwidth of an interface, both inbound and outbound to 1mbit each. You may modify this script how ever you desire to customize your bandwidth shaping requirements.

#  tc uses the following units when passed as a parameter.
#  kbps: Kilobytes per second
#  mbps: Megabytes per second
#  kbit: Kilobits per second
#  mbit: Megabits per second
#  bps: Bytes per second
#       Amounts of data can be specified in:
#       kb or k: Kilobytes
#       mb or m: Megabytes
#       mbit: Megabits
#       kbit: Kilobits
#  To get the byte figure from bits, divide the number by 8 bit

# Name of the traffic control command.

# The network interface we're planning on limiting bandwidth.
IF=eth0             # Interface

# Download limit (in mega bits)
DNLD=1mbit          # DOWNLOAD Limit

# Upload limit (in mega bits)
UPLD=1mbit          # UPLOAD Limit

# IP address of the machine we are controlling
IP=     # Host IP

# Filter options for limiting the intended interface.
U32="$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32"

start() {

# We'll use Hierarchical Token Bucket (HTB) to shape bandwidth.
# For detailed configuration options, please consult Linux man
# page.

    $TC qdisc add dev $IF root handle 1: htb default 30
    $TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD
    $TC class add dev $IF parent 1: classid 1:2 htb rate $UPLD
    $U32 match ip dst $IP/32 flowid 1:1
    $U32 match ip src $IP/32 flowid 1:2

# The first line creates the root qdisc, and the next two lines
# create two child qdisc that are to be used to shape download
# and upload bandwidth.
# The 4th and 5th line creates the filter to match the interface.
# The 'dst' IP address is used to limit download speed, and the
# 'src' IP address is used to limit upload speed.


stop() {

# Stop the bandwidth shaping.
    $TC qdisc del dev $IF root


restart() {

# Self-explanatory.
    sleep 1


show() {

# Display status of traffic control status.
    $TC -s qdisc ls dev $IF


case "$1" in


    echo -n "Starting bandwidth shaping: "
    echo "done"


    echo -n "Stopping bandwidth shaping: "
    echo "done"


    echo -n "Restarting bandwidth shaping: "
    echo "done"


    echo "Bandwidth shaping status for $IF:"
    echo ""


    echo "Usage: tc.bash {start|stop|restart|show}"


exit 0

The above script has been tested on Centos 4.x system and (Linux AS 2.x) versions. There is also another utility called tcng, which supposely simplify the arcane tc configuration. If you have comments or suggestions on the above script, please contact [email protected].

For detailed explanation of Linux Advanced Routing & Traffic Control HOWTO, please visit website. The above HOWTO also describes method for preventing SYN Floods and ICMP DDoS.

Share this post

Comments (4)

  • Mavis Wifi Reply

    hello,do I have to enter all the IP connected to my network? I'm using hostapd.

    Dec 31, 2018 at 10:51 PM
  • IP Location Reply

    You will have to modify the start() , stop() and show() mothods to include all the IPs that you would like to include. You'll essentially loop through the interfaces, and start or stop one interface at a time.

    Jan 02, 2019 at 05:05 AM
  • martin k Reply

    Hello, I think there might be an error in the script.
    • root in tc is a handle to all egress traffic
    -> to shape incoming traffic you need to create a pseudo device(IFB) to which you forward all traffic and then resend it to yourself as explained with netem here:

    Have your tested your configuration's up and download bandwidth?

    Jul 28, 2019 at 12:20 AM
  • Reply

    Improvement suggestion
    IP=$(/sbin/ip -o -4 addr list $IF | awk '{print $4}' | cut -d/ -f1)

    Feb 26, 2020 at 12:40 PM

Leave a comment

All comments are moderated. Spammy and bot submitted comments are deleted. Please submit the comments that are helpful to others, and we'll approve your comments. A comment that includes outbound link will only be approved if the content is relevant to the topic, and has some value to our readers.

Login To Post Comment