Examples
This is by no means comprehensive. I may add to this when I get more of a chance. There are Wonder Shaper or the ADSL Bandwidth Management HOWTO. (though I feel that they are inadequate or employ the wrong strategies).tc, qdiscs, classes, filters, oh my!
tc, the traffic control tool, is used to configure the Linux kernel to accomplish the shaping, scheduling, policing, and dropping of packets.Each interface by default has a root qdisc. By default, it uses pfifo_fast algorhythm (in our case, it will be configured to use HTB). Think of the root qdisc as the main container that everything resides. Inside the root qdisc, we can classify various types of traffic into classes and attach them to the root handle. After the classes have been defined, filters are used to match and redirect the packets into the right classes.
Using tc
Some example tc commands to create a root handle and attach some classes to it:- tc qdisc add dev eth0 root handle 1: htb default 60 - creates a root handle attached to eth0 using the HTB qdisc and classify packets as classid 60 by default
- tc class add dev eth0 parent 1: classid 1:1 htb rate 116kbit - create a parent class using HTB with a maximum (capped) rate of 116 kilobits/s (about 90% of 128 kilobits/s)
- tc class add dev eth0 parent 1:1 classid 1:10 htb rate 25kbit ceil 116kbit prio 0 - create a leafnode class using HTB with a guaranteed minimum of 25 kilobits/s and a maximum ceiling of 116 kilobits/s and a priority of zero (highest - note that available bandwidth is offered in order of priority)
- tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10 - attach another qdisc handle to class 1:10 using SFQ - this implements the SFQ round robin qdisc inside the HTB that kicks in only when the queue is saturated to ensure that no one "conversation" hogs the pipe.
Some example tc commands to filter packets to the desired classes:
- Create a filter that classifies acknowledgement packets (small ACK packets):tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32\
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:10 - Creates a filter that classifies SSH packets:tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32\
match ip dport 22 0xfffe flowid 1:10
Using iptables (marking) with tc
Some example iptables commands to do similar as above:
- Mark acknowledge packets of an established session between 40 and 100 bytes:
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ACK -m state --state ESTABLISHED -m length --length 40:100 -j MARK --set-mark 20 - Mark SSH packets that starts new sessions with a packet length between 40 and 68 bytes:
iptables -t mangle -A PREROUTING -p tcp --dport 22 --syn -m state --state NEW -m length --length 40:68 -j MARK --set-mark 22
Now use the fw filter to classify the marked packets:
- Create a filter that classifies packets based on the fwmark (20) on the packet as belonging to classid 1:10:
tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:10 - Creates a filter that classifies packets based on the fwmark (22) on the packet as belonging to classid 1:10:
tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:10
Using iptables (classify)
Mmm, classify:
- Classify packets of an established session between 40 and 100 bytes:
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags ALL ACK -m state --state ESTABLISHED -m length --length 40:100 -J CLASSIFY --set-class 1:10 - Classify SSH packets that starts new sessions with a packet length between 40 and 68 bytes:
iptables -t mangle -A POSTROUTING -p tcp --dport 22 --syn -m state --state NEW -m length --length 40:68 -j CLASSIFY --set-class 1:10
- Verify that /lib/modules/<kernel version>/kernel/net/ipv4/netfilter/ipt_CLASSIFY.o and /usr/lib/iptables/libipt_CLASSIFY.so exist to see if you have the required kernel support (note that the path may vary depending on your distribution).
- If you do not have the kernel support and are planning to compile your own kernel, download the source for iptables and the latest patch-o-matic, apply the CLASSIFY patch, enable it in the .config, and also remember to recompile iptables.
- The CLASSIFY target only work in the mangle table and the POSTROUTING chain.
- It's possible to use both the iptables classifier and the tc filters together. Any traffic that does not get classified by iptables will be go through the tc filters.
Some sample scripts
/etc/init.d/shaper:
#!/bin/sh # init script written by shane at knowplace dot org # this script only creates the qdiscs and classes required for shaping, it # does NOT create the necessary filters INTERFACE='eth0' rc_done=" done" rc_failed=" failed" return=$rc_done TC='/sbin/tc' tc_reset () { # Reset everything to a known state (cleared) $TC qdisc del dev $INTERFACE root 2> /dev/null > /dev/null } tc_status () { echo "[qdisc - $INTERFACE]" $TC -s qdisc show dev $INTERFACE echo "------------------------" echo echo "[class - $INTERFACE]" $TC -s class show dev $INTERFACE } tc_showfilter () { echo "[filter - $INTERFACE]" $TC -s filter show dev $INTERFACE } case "$1" in start) echo -n "Starting traffic shaping" tc_reset U320="$TC filter add dev $INTERFACE protocol ip parent 1:0 prio 0 u32" # # dev eth0 - creating qdiscs & classes # $TC qdisc add dev $INTERFACE root handle 1: htb default 60 $TC class add dev $INTERFACE parent 1: classid 1:1 htb rate 116kbit $TC class add dev $INTERFACE parent 1:1 classid 1:10 htb rate 32kbit ceil 116kbit prio 0 $TC class add dev $INTERFACE parent 1:1 classid 1:20 htb rate 22kbit ceil 116kbit prio 1 $TC class add dev $INTERFACE parent 1:1 classid 1:30 htb rate 22kbit ceil 116kbit prio 2 $TC class add dev $INTERFACE parent 1:1 classid 1:40 htb rate 20kbit ceil 116kbit prio 3 $TC class add dev $INTERFACE parent 1:1 classid 1:50 htb rate 18kbit ceil 116kbit prio 4 $TC class add dev $INTERFACE parent 1:1 classid 1:60 htb rate 2kbit ceil 116kbit prio 5 $TC qdisc add dev $INTERFACE parent 1:10 handle 10: sfq perturb 10 $TC qdisc add dev $INTERFACE parent 1:20 handle 20: sfq perturb 10 $TC qdisc add dev $INTERFACE parent 1:30 handle 30: sfq perturb 10 $TC qdisc add dev $INTERFACE parent 1:40 handle 40: sfq perturb 10 $TC qdisc add dev $INTERFACE parent 1:50 handle 50: sfq perturb 10 $TC qdisc add dev $INTERFACE parent 1:60 handle 60: sfq perturb 10 tc_status ;; stop) echo -n "Stopping traffic shaper" tc_reset || return=$rc_failed echo -e "$return" ;; restart|reload) $0 stop && $0 start || return=$rc_failed ;; stats|status) tc_status ;; filter) tc_showfilter ;; *) echo "Usage: $0 {start|stop|restart|stats|filter}" exit 1 esac test "$return" = "$rc_done" || exit 1
Script placeholder:
I'm too lazy to write a custom script for you. =) I use the narc-custom.conf file to insert custom commands via narc
to classify traffic. Below are some example commands. They are provided
here only to show you what could be done. Please feel free to adapt
them to your own needs.
# give "overhead" packets highest priority iptables -t mangle -A POSTROUTING -o eth0 -p tcp --syn -m length --length 40:68 -j CLASSIFY \ --set-class 1:10 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --tcp-flags ALL SYN,ACK -m length --length 40:68 \ -j CLASSIFY --set-class 1:10 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --tcp-flags ALL ACK -m length --length 40:100 \ -j CLASSIFY --set-class 1:10 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --tcp-flags ALL RST -j CLASSIFY --set-class 1:10 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --tcp-flags ALL ACK,RST -j CLASSIFY \ --set-class 1:10 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --tcp-flags ALL ACK,FIN -j CLASSIFY \ --set-class 1:10 # interactive SSH traffic iptables -t mangle -A POSTROUTING -o eth0 -p tcp --sport ssh -m length --length 40:100 \ -j CLASSIFY --set-class 1:20 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --dport ssh -m length --length 40:100 \ -j CLASSIFY --set-class 1:20 # interactive mail or web traffic iptables -t mangle -A POSTROUTING -o eth0 -p tcp -m multiport --sport http,pop,imap,https,imaps \ -j CLASSIFY --set-class 1:30 # dns lookups iptables -t mangle -A POSTROUTING -o eth0 -p tcp --dport domain -j CLASSIFY --set-class 1:30 # ICMP, UDP iptables -t mangle -A POSTROUTING -o eth0 -p udp -j CLASSIFY --set-class 1:40 iptables -t mangle -A POSTROUTING -o eth0 -p icmp -m length --length 28:1500 -m limit \ --limit 2/s --limit-burst 5 -j CLASSIFY --set-class 1:40 # bulk traffic iptables -t mangle -A POSTROUTING -o eth0 -p tcp --sport ssh -m length --length 101: \ -j CLASSIFY --set-class 1:50 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --dport ssh -m length --length 101: \ -j CLASSIFY --set-class 1:50 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --sport 25 -j CLASSIFY --set-class 1:50 iptables -t mangle -A POSTROUTING -o eth0 -p tcp --dport 6667 -j CLASSIFY --set-class 1:50
http://www.knowplace.org/pages/howtos/traffic_shaping_with_linux/examples.php
No comments:
Post a Comment