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.
Share this post
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.
Comments (4)
hello,do I have to enter all the IP connected to my network? I'm using hostapd.
Dec 31, 2018 at 10:51 PMYou 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 AMHello, I think there might be an error in the script.
Jul 28, 2019 at 12:20 AM• 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:
https://wiki.linuxfoundation.org/networking/netem#how_can_i_use_netem_on_incoming_traffic3f
Have your tested your configuration's up and download bandwidth?
Improvement suggestion
Feb 26, 2020 at 12:40 PMIP=$(/sbin/ip -o -4 addr list $IF | awk '{print $4}' | cut -d/ -f1)