Traffic Control with Linux Command Line tool, "tc"



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 127.0.0.1/8 brd 127.255.255.255 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 216.3.128.12/24 brd 216.3.128.255 scope global eth0
    inet6 fe80::206:5bff:fe8d:13a0/64 scope link 
       valid_lft forever preferred_lft forever
# ip route show
216.3.128.0/24 dev eth0  proto kernel  scope link  src 
216.3.128.12 default via 216.3.128.1 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.

#!/bin/bash
#
#  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.
TC=/sbin/tc

# 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=216.3.128.12     # 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.
    stop
    sleep 1
    start

}

show() {

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

}

case "$1" in

  start)

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

  stop)

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

  restart)

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

  show)

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

  *)

    pwd=$(pwd)
    echo "Usage: tc.bash {start|stop|restart|show}"
    ;;

esac

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 http://www.lartc.org website. The above HOWTO also describes method for preventing SYN Floods and ICMP DDoS.