Slashdot stories can be listened to in audio form via an RSS feed, as read by our own robotic overlord.

 



Forgot your password?
typodupeerror
Networking

stmfreak's Journal: Bidirectional Traffic Shaping Script

Journal by stmfreak

#!/bin/bash
# Copyright gone. I had lots of help from the Internet,
# this wouldn't have been possible without lots of sources.
# Thanks. Give back what you learn.

# This script has been obscured, you'll want to enter your
# LAN ip subnets and favorite hosts in appropriate places or
# leave those filters commented out.
#
# To start:
# ./script
#
# To stop:
# ./script stop
#
# To monitor:
# ./script status
#

#### Bandwidth Limiting ####
# set link speeds to ~85% of your rated line speed in kbit/s

# INET*, we artificially limit to control costs over our 100Mbps pipe.
INETDWN=4000
INETUP=4000

# WAN* is the 100Mbps switch between hosts in the DMZ, before hitting
# our ISPs pipe.
WANUP=92000
WANDWN=92000

# LAN* is our private and trusted network.
LANUP=92000
LANDWN=92000

### these ratios allowed me to fiddle. I don't fiddle any more.
# The ratios basically say R10 gets 70% of the bandwidth, but
# because we're using an HTB, idle bandwidth will get shared
# among R20 and R30 at a ration of R20/R30. If R20 doesn't want
# the bandwidth either, then R30 gets it all, up to its ceiling.
# I'm still not sure how or if burst works. Have fun!

# set ratios for the queue's rate limits
R10=70
R20=25
R30=5
# set ratios for the queue's ceil limits
C10=100
C20=85
C30=75
# set ratios for the queue's burst limits
B10=100
B20=70
B30=40

# declare our interfaces
WAN=eth0
LAN=eth1

##### status? #####
# report status and exit
if [ "$1" = "status" ]
then
                echo "################## $WAN filters ###################"
                tc -s qdisc ls dev $WAN
                echo
                tc -s class ls dev $WAN
                echo "################## $LAN filters ###################"
                tc -s qdisc ls dev $LAN
                echo
                tc -s class ls dev $LAN
                exit
fi

##### stop #####
tc qdisc del dev $WAN root 2> /dev/null > /dev/null
tc qdisc del dev $WAN ingress 2> /dev/null > /dev/null
tc qdisc del dev $LAN root 2> /dev/null > /dev/null
tc qdisc del dev $LAN ingress 2> /dev/null > /dev/null

# and exit if we're stopping
if [ "$1" = "stop" ]
then
                exit
fi

##################################################################
################## start traffic shaping #########################
# note, these policies only control the rate that traffic goes out
# of each interface. Uploads, so to speak. Trying to control
# downloads is done by either an ingress policer or controlling
# the rate we forward traffic out/up the LAN interface or both
##################################################################

#### setup WAN traffic filters

# install root HTB, point default traffic to 1:30
tc qdisc add dev $WAN root handle 1: htb default 30

# establish rate limited class
tc class add dev $WAN parent 1: classid 1:1 htb \
      rate ${INETUP}kbit burst $[$INETUP*8]

# add local wan class
tc class add dev $WAN parent 1: classid 1:2 htb \
      rate ${WANUP}kbit burst $[$WANUP*8]

# setup classes with different prio levels
tc class add dev $WAN parent 1:1 classid 1:10 htb \
      rate $[$R10*$INETUP/100]kbit ceil $[$C10*$INETUP/100]kbit \
      burst $[$B10*$INETUP/100*8] prio 1
tc class add dev $WAN parent 1:1 classid 1:20 htb \
      rate $[$R20*$INETUP/100]kbit ceil $[$C20*$INETUP/100]kbit \
      burst $[$B20*$INETUP/100*8] prio 2
tc class add dev $WAN parent 1:1 classid 1:30 htb \
      rate $[$R30*$INETUP/100]kbit ceil $[$C30*$INETUP/100]kbit \
      burst $[$B30*$INETUP/100*8] prio 3

# all get stochastic fairness
tc qdisc add dev $WAN parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $WAN parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $WAN parent 1:30 handle 30: sfq perturb 10

# and filter traffic onto each
U32="tc filter add dev $WAN protocol ip parent 1: prio 1 u32"

# traffic to our local external subnet is backdoored
# $U32 match ip dst A.B.C.D/M flowid 1:2

# ICMP is unrestricted to measure line
$U32 match ip protocol 1 0xff flowid 1:10

# http takes the sorta slow path
$U32 match ip sport 80 0xffff flowid 1:20
$U32 match ip sport 443 0xffff flowid 1:20
$U32 match ip dport 80 0xffff flowid 1:20
$U32 match ip dport 443 0xffff flowid 1:20

# ftp-data takes the slow path
$U32 match ip sport 20 0xffff flowid 1:30
$U32 match ip dport 20 0xffff flowid 1:30

# TOS Minimum Delay (ssh, NOT scp)
$U32 match ip tos 0x10 0xff flowid 1:10
# we don't host VoIP anymore, but if we did it goes in 1:10
$U32 match ip tos 0xb8 0xff flowid 1:10
$U32 match ip tos 0x68 0xff flowid 1:10

# this tries to matches downloads and torrent packets
$U32 match ip tos 0x20 0xff flowid 1:30

# traffic to is important, goes into 1:20
# $U32 match ip dst A.B.C.D flowid 1:20

# DNS
$U32 match ip sport 53 0xffff flowid 1:20
$U32 match ip dport 53 0xffff flowid 1:20

# setup ingress policer to keep downloads in check
tc qdisc add dev $WAN handle ffff: ingress

# give packets from lots of headroom
#tc filter add dev $WAN parent ffff: protocol ip prio 1 u32 \
# match ip src A.B.C.D/32 police \
# rate ${WANDWN}kbit burst $[$WANDWN*8] \
# drop flowid :1

# give packets from local subnet some headroom
#tc filter add dev $WAN parent ffff: protocol ip prio 2 u32 \
# match ip src A.B.C.D/M police \
# rate ${WANDWN}kbit burst $[$WANDWN*8] \
# drop flowid :1

# everything else gets rate limited at 110% since we'd rather
# catch it in the LAN shaper than just drop on the floor here
tc filter add dev $WAN parent ffff: protocol ip prio 3 u32 \
      match ip src 0.0.0.0/0 police \
      rate $[11*$INETDWN/10]kbit burst $[$INETDWN*8] \
      drop flowid :1

# end WAN traffic shaping

#### Setup LAN traffic filters
# By rate limiting traffic going out the LAN interface, we do
# a much better job of shaping than merely dropping packets
# with the WAN ingress filter.
#
# This affects DOWNLOADS by employees!

# setup root HTB with default on 1:30
tc qdisc add dev $LAN root handle 1: htb default 30

# here we setup a class for DMZ->LAN traffic aka backdoor
tc class add dev $LAN parent 1: classid 1:1 htb \
      rate ${LANUP}kbit burst $[$LANUP*8] prio 1

# and here, we setup classes for WAN->LAN traffic
tc class add dev $LAN parent 1: classid 1:2 htb \
      rate ${INETDWN}kbit \
      burst $[$INETDWN*8] prio 1
tc class add dev $LAN parent 1:2 classid 1:10 htb \
      rate $[$R10*$INETDWN/100]kbit ceil $[$C10*$INETDWN/100]kbit \
      burst $[$B10*$INETDWN/100*8] prio 1
tc class add dev $LAN parent 1:2 classid 1:20 htb \
      rate $[$R20*$INETDWN/100]kbit ceil $[$C20*$INETDWN/100]kbit \
      burst $[$B20*$INETDWN/100*8] prio 2
tc class add dev $LAN parent 1:2 classid 1:30 htb \
      rate $[$R30*$INETDWN/100]kbit ceil $[$C30*$INETDWN/100]kbit \
      burst $[$B30*$INETDWN/100*8] prio 3

# all get stochastic fairness
tc qdisc add dev $LAN parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $LAN parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $LAN parent 1:30 handle 30: sfq perturb 10

# and filter traffic onto each
U32="tc filter add dev $LAN protocol ip parent 1: prio 1 u32"

# send local traffic to the bypass
$U32 match ip src 127.0.0.1 flowid 1:1
# $U32 match ip src 10.B.C.D/M flowid 1:1

# send traffic to the bypass
# $U32 match ip src A.B.C.D flowid 1:1

# backdoor downloads for my desktop (approved torrents)
# torrent traffic listens on , but establishes conns on many ports
# $U32 match ip dst 10.B.C.D flowid 1:1

# icmp gets high priority
$U32 match ip protocol 1 0xff flowid 1:10

# http takes the sorta slow path
$U32 match ip sport 80 0xffff flowid 1:20
$U32 match ip sport 443 0xffff flowid 1:20
$U32 match ip dport 80 0xffff flowid 1:20
$U32 match ip dport 443 0xffff flowid 1:20

# ftp-data takes the slow path
$U32 match ip sport 20 0xffff flowid 1:30
$U32 match ip dport 20 0xffff flowid 1:30

# ssh should go into important, try 1:10 if you get latency
#$U32 match ip sport 22 0xffff flowid 1:20
#$U32 match ip dport 22 0xffff flowid 1:20

# interactive tos flags, this catches ssh, but not scp
$U32 match ip tos 0x10 0xff flowid 1:10

# one of these three also gets youtube videos from port 80!
#$U32 match ip tos 0xb8 0xff flowid 1:10
#$U32 match ip tos 0x68 0xff flowid 1:10

# this matches downloads and torrent packets
$U32 match ip tos 0x20 0xff flowid 1:30

# end LAN traffic shaping

# notice, no ingress policer here, but you could add one
# if you're worried about massive uploads from your users
# swamping the WAN out bound filters.

To avoid criticism, do nothing, say nothing, be nothing. -- Elbert Hubbard

Working...